Permalink
Browse files

ADDED: Ability to configure the resulting url a lot better. Attempted…

… to create both a route and url generator system that works from a single string pattern, although it may not be very robust.

FIXED: phpdoc comments are a lot more complete
ADDED: Filter function for class registration
  • Loading branch information...
Damian Mooyman
Damian Mooyman committed Feb 29, 2012
1 parent ef9f27b commit 6474b4be72c6d6dbf4cead259ff5ddb3438c8f3c
View
@@ -2,12 +2,38 @@
/**
* Configuration class for the datelink module
+ * Provides a static wrapper to the module route handler instance
+ * @author Damian Mooyman
*/
class DateLink
{
+ /**
+ * Class to use for implementation of IDateLinkrouter
+ * @see IDateLinkRouter
+ * @var string
+ */
public static $router_class = 'DateLinkRouter';
- public static $default_url_pattern = '$Month!/$URLSegment!/$Action/$ID/$OtherID';
+ /**
+ * Default value for the url pattern to use in routing
+ * Care must be taken when constructing this, as it must follow some exact rules:
+ * - $Year MUST appear somewhere as too many wildcards will cause it to match too many false positives in routing
+ * - This pattern is used both in routing and in building URLS for date linked pages. When building links everything
+ * after the // will be cut off and have any $action appended on the end
+ * - The $ParentLink field will be replaced with the actual parent url both in routing and in building links
+ * - You can use $Year, $Month, $MonthName, $Date, $Weekday, $ParentLink, $URLSegment and constants
+ * - You can use #$Month and #$Date for zero-padded versions
+ * - All patterns before the // should end with ! to tell Silverstripe that this is a required pattern
+ * @see DateLinkRouter::urlPattern
+ * @var string
+ */
+ public static $default_url_pattern = '$ParentLink!/$Year!/$Month!/$URLSegment!//$Action/$ID/$OtherID';
+
+ /**
+ * Default value for the date field to use
+ * @see DateLinkRouter::dateField
+ * @var string
+ */
public static $default_date_field = 'Created';
/**
@@ -23,34 +49,61 @@ class DateLink
public static function instance()
{
if (!self::$_instance)
- self::$_instance = new self::$router_class(self::$default_date_field);
+ self::$_instance = new self::$router_class(self::$default_date_field, self::$default_url_pattern);
return self::$_instance;
}
/**
- * Registers pages within the route table using the class type as an identifier
- * @param type $classType
+ * Registers a class beneath which all child pages will be date-mapped.
+ * @param type $className Name of the class to register
+ * @param callback|boolean $filter a boolean, callback, or other closure that can be passed instances of the
+ * specified class to determine if it should be consitered when filtering
*/
- public static function register_class($classType)
+ public static function register_class($className, $filter = true)
{
- self::instance()->RegisterClass($classType);
- }
-
- public static function register_link($link)
- {
- self::instance()->RegisterLink($link);
+ self::instance()->RegisterClass($className, $filter);
}
+ /**
+ * Sets the field to extract the date from
+ * @param string $field Name of the date field
+ */
public static function set_date_field($field)
{
self::instance()->setDateField($field);
}
-
+
+ /**
+ * Gets the field to extract the date from
+ * @return string Name of the date field
+ */
public static function get_date_field()
{
return self::instance()->getDateField();
}
+ /**
+ * Sets the pattern to use when routing and generating links
+ * @param string $pattern The pattern to use
+ */
+ public static function set_url_pattern($pattern)
+ {
+ self::instance()->setURLPattern($pattern);
+ }
+
+ /**
+ * Gets the pattern to use when routing and generating links
+ * @return string The pattern used
+ */
+ public static function get_url_pattern()
+ {
+ return self::instance()->getURLPattern();
+ }
+
+ /**
+ * Instructs the module to refresh the routing XML cache file
+ * This may not be called during manifest initialisation (_config.php) as database access is not available
+ */
public static function refresh_cache()
{
self::instance()->RefreshCache();
@@ -1,9 +1,8 @@
<?php
/**
- * Decorates the holder page of any dated-linked page
- *
- * @author Damo
+ * Allows the date link cache to update during dev/build
+ * @author Damian Mooyman
*/
class DateLinkHolderDecorator extends SiteTreeDecorator
{
@@ -1,9 +1,8 @@
<?php
/**
- * Description of DateLinkPageDecorator
- *
- * @author Damo
+ * Provides functionality required for date-linked pages to generate urls and to refresh the cache
+ * @author Damian Mooyman
*/
class DateLinkPageDecorator extends SiteTreeDecorator
{
@@ -14,24 +13,62 @@ public function onAfterWrite()
DateLink::refresh_cache();
}
+ /**
+ * Using the same rules that were used to generate the routing table, attempt to generate the original matching
+ * url that corresponds to the current page
+ * @param string|null $action The requested page action
+ * @return string the relative page url
+ */
public function DatedRelativeLink($action = null)
{
+ // Fixes the "please use full link" hack that ContentController::link uses to request full parent controller links.
+ if ($action === true)
+ $action = null;
+
$parentLink = $this->owner->Parent()->RelativeLink();
- $URLSegment = $this->owner->URLSegment;
- $date = $this->owner->getField(DateLink::get_date_field());
+ $urlSegment = $this->owner->URLSegment;
- // Fixes the "please use full link" hack that ContentController::link uses to request full page links.
- if($action === true)
- $action = null;
+ // Determine raw date
+ $fieldName = DateLink::get_date_field();
+ $dateValue = $this->owner->$fieldName;
+
+ // Handles the outlying case where this page has no date set, in which case we revert to a quick
+ // implementation of the traditional RelativeLink function
+ if (!$dateValue)
+ return Controller::join_links($parentLink, $urlSegment, '/', $action);
+ $date = new DateTime($dateValue);
+
+ // Get pattern to use as a base for this link
+ $pattern = DateLink::get_url_pattern();
+
+ // Substitute parent link
+ $parentLink = trim($parentLink, "/");
+ $pattern = preg_replace('/\$ParentLink!?/i', $parentLink, $pattern);
- if (!$date)
- return Controller::join_links($parentLink, $URLSegment, '/', $action);
+ // Substitute parent segment
+ $pattern = preg_replace('/\$URLSegment!?/i', $urlSegment, $pattern);
+
+ // Mapping of wildcards to date formats (in order of replacement)
+ $replacements = array(
+ '#$Month' => 'm',
+ '$MonthName' => 'F',
+ '$Month' => 'n',
+ '#$Date' => 'd',
+ '$Date' => 'j',
+ '$Year' => 'Y',
+ '$Weekday' => 'l'
+ );
- // Merge all elements together
- $parsedDate = date_parse($date);
- $year = $parsedDate['year'];
- $month = $parsedDate['month'];
- return Controller::join_links($parentLink, $year, $month, $URLSegment, '/', $action);
+ // Extract various date elements
+ foreach ($replacements as $search => $dateFormat)
+ {
+ $dateText = $date->format($dateFormat);
+ $quotedSearch = preg_quote($search);
+ $pattern = preg_replace("/$quotedSearch!?/i", $dateText, $pattern);
+ }
+
+ // Replace everything after the // with /$action
+ return preg_replace('/\/\/.*$/', "/$action", $pattern);
}
}
@@ -2,8 +2,7 @@
/**
* Handles urls that match dated link routes
- *
- * @author Damo
+ * @author Damian Mooyman
* @see ModelAsController
*/
class DateLinkController extends ModelAsController
Oops, something went wrong.

0 comments on commit 6474b4b

Please sign in to comment.