Index: branches/1.3.x/units/widgets/widgets_config.php =================================================================== --- branches/1.3.x/units/widgets/widgets_config.php (revision 16171) +++ branches/1.3.x/units/widgets/widgets_config.php (revision 16172) @@ -1,219 +1,213 @@ 'widget', 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), 'EventHandlerClass' => Array ('class' => 'WidgetEventHandler', 'file' => 'widget_eh.php', 'build_event' => 'OnBuild'), 'TagProcessorClass' => Array ('class' => 'WidgetTagProcessor', 'file' => 'widget_tp.php', 'build_event' => 'OnBuild'), 'AutoLoad' => true, 'QueryString' => Array ( 1 => 'id', 2 => 'Page', 3 => 'PerPage', 4 => 'event', 5 => 'mode', ), - // in case, when one method does everything - 'RewriteListener' => 'WidgetRewriteListener', - - // in case, when building and parsing is done by separate methods -// 'RewriteListener' => Array ('WidgetRewriteBuilder', 'WidgetRewriteParser'), - 'IDField' => 'WidgetId', 'StatusField' => Array ('Status'), 'TableName' => TABLE_PREFIX.'Widgets', /* 'ForeignKey' => 'ParentId', // field title in TableName, linking record to a parent 'ParentTableKey' => 'ParentId', // id (or other key) field title in parent's table 'ParentPrefix' => 'parent', 'AutoDelete' => true, // delete these items when parent is being deleted 'AutoClone' => true, // clone these items when parent is being cloned */ // used to build editing links in admin grids 'AdminTemplatePath' => 'widgets', 'AdminTemplatePrefix' => 'widget_', 'TitlePresets' => Array ( 'default' => Array ( 'new_status_labels' => Array ('widget' => '!la_title_AddingWidget!'), 'edit_status_labels' => Array ('widget' => '!la_title_EditingWidget!'), 'new_titlefield' => Array ('widget' => '!la_title_NewWidget!'), ), 'widget_list' => Array ( 'prefixes' => Array ('widget_List'), 'format' => '#section_label#', 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'approve', 'decline', 'export', 'import', 'view', 'dbl-click',), ), 'widget_edit' => Array ( 'prefixes' => Array ('widget'), 'format' => '#widget_status# - #widget_titlefield#', 'toolbar_buttons' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), ), ), 'PermSection' => Array ('main' => 'custom:widgets'), 'Sections' => Array ( 'custom:widgets' => Array ( 'parent' => 'custom', 'icon' => 'custom', 'label' => 'la_tab_Widgets', 'url' => Array ('t' => 'custom/widgets/widget_list', 'pass' => 'm'), 'permissions' => Array ('view', 'add', 'edit', 'delete'), 'priority' => 1, 'type' => stTREE, ), ), 'TitleField' => 'Title', // field, used in bluebar when editing existing item // Use %1$s for local table name with prefix, %2$s for calculated fields 'ListSQLs' => Array ( // key - special, value - list select sql '' => ' SELECT %1$s.* %2$s FROM %1$s', ), 'ListSortings' => Array ( '' => Array ( // 'ForcedSorting' => Array ('Priority' => 'desc'), 'Sorting' => Array ('Title' => 'asc'), ) ), 'CalculatedFields' => array( '' => array( 'VirtualActionField' => '%1$s.WidgetId', ) ), 'VirtualFields' => Array ( 'VirtualActionField' => Array ('type' => 'string', 'default' => ''), ), 'Fields' => Array ( 'WidgetId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'Title' => Array ( 'type' => 'string', 'max_len' => 255, 'required' => 1, 'default' => '', 'not_null' => 1, ), 'Description' => Array ( 'type' => 'string', 'formatter' => 'kFormatter', 'using_fck' => 1, 'default' => null, ), 'Email' => Array ( 'type' => 'string', 'formatter' => 'kFormatter', 'regexp' => '/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', 'sample_value' => 'email@domain.com', 'not_null' => 1, 'default' => '', 'error_msgs' => Array ('invalid_format' => '!la_invalid_email!'), ), 'Type' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'use_phrases' => 1, 'options' => Array ( 1 => 'la_opt_Default', 2 => 'la_opt_Custom', ), 'not_null' => 1, 'default' => 1, 'required' => 1, ), 'Phone' => Array ( 'type' => 'string', 'formatter' => 'kFormatter', 'default' => '', 'using_fck' => 1, 'not_null' => 1), 'Qty' => Array ( 'type' => 'double', 'required' => 0, 'not_null' => 1, 'default' => 0 ), 'Status' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => array (1 => 'la_Active', 2 => 'la_Pending', 0 => 'la_Disabled'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2, ), 'CreatedOn' => Array ( 'type' => 'int', 'formatter' => 'kDateFormatter', 'time_format' => '', 'input_time_format' => '', 'default' => '#NOW#', ), 'Good' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0 ), 'BirthTime' => Array ( 'type' => 'int', 'formatter' => 'kDateFormatter', 'date_format' => '', 'input_date_format' => '', 'default' => null ), 'Image' => Array ( 'type' => 'string', 'formatter' => 'kUploadFormatter', 'max_size' => MAX_UPLOAD_SIZE, // in Bytes ! 'file_types' => '*.jpg;*.jpeg;*.gif;*.png;*.bmp', 'files_description' => '!la_hint_ImageFiles!', 'upload_dir' => '/system/user_files/', // relative to project's home 'as_image' => true, 'thumb_format' => 'resize:100x100', 'multiple' => false, // false or max number of files - will be stored as serialized array of paths 'direct_links' => false, // use direct file urls or send files through wrapper (requires mod_mime_magic) 'filename_prefix' => '', 'filename_suffix' => '', 'storage_engine' => StorageEngine::HASH, 'required' => 1, 'default' => null ), 'DataFile' => Array ( 'type' => 'string', 'formatter' => 'kUploadFormatter', 'max_size' => MAX_UPLOAD_SIZE, // in Bytes ! 'file_types' => '*.*', 'files_description' => '!la_hint_AllFiles!', 'upload_dir' => '/system/user_files/', // relative to project's home 'as_image' => false, 'multiple' => 5, // false or max number of files - will be stored as serialized array of paths 'direct_links' => true, // use direct file urls or send files through wrapper (requires mod_mime_magic) 'default' => null ), ), 'Grids' => Array ( 'Default' => Array ( // 'Icons' => Array ('default' => 'icon16_custom.gif'), 'Fields' => Array ( 'WidgetId' => Array ('title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter'), 'Title' => Array ('title' => 'column:la_fld_Name', 'data_block' => 'grid_custom_td'), 'Image' => Array ('data_block' => 'grid_image_td', 'filter_block' => 'grid_empty_filter', 'width' => 120), 'Type' => Array ('filter_block' => 'grid_options_filter'), 'Status' => Array ('filter_block' => 'grid_options_filter'), 'Good' => Array ('filter_block' => 'grid_like_filter'), 'Qty' => Array ('header_block' => 'grid_column_title_no_sorting', 'filter_block' => 'grid_range_filter'), 'Email' => Array ('filter_block' => 'grid_like_filter'), 'Phone' => Array ('filter_block' => 'grid_like_filter'), 'CreatedOn' => Array ('filter_block' => 'grid_date_range_filter'), 'Description' => Array ('filter_block' => 'grid_like_filter'), 'VirtualActionField' => Array ('title' => 'column:la_fld_Action', 'data_block' => 'grid_delete_td'), ), ), ), /*'ConfigMapping' => Array ( 'PerPage' => 'Perpage_Widgets', 'ShortListPerPage' => 'Perpage_Widgets_Short', ),*/ -); \ No newline at end of file +); Index: branches/1.3.x/units/widgets/widget_eh.php =================================================================== --- branches/1.3.x/units/widgets/widget_eh.php (revision 16171) +++ branches/1.3.x/units/widgets/widget_eh.php (revision 16172) @@ -1,319 +1,196 @@ Array ('self' => true), 'OnCustomEvent' => Array ('self' => true), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Checks user permission to execute given $event * * @param kEvent $event * @return bool * @access public */ public function CheckPermission(kEvent $event) { $skip_permissions_check_events = Array ( 'OnAnotherCustomEvent', ); if ( in_array($event->Name, $skip_permissions_check_events) ) { return true; } return parent::CheckPermission($event); } /** * Set custom query for the list * * @param kEvent $event */ function OnCustomEvent($event) { $object = $event->getObject(); /* @var $object kDBList */ } /** * Apply any custom changes to list's sql query * * @param kEvent $event * @return void * @access protected * @see kDBEventHandler::OnListBuild() */ protected function SetCustomQuery(kEvent $event) { parent::SetCustomQuery($event); $object = $event->getObject(); /* @var $object kDBList */ # identifying event based on special and setting filter if ( $event->Special == 'custom-special' ) { // $object->addFilter('primary_filter', '%1$s.Status = ' . STATUS_DISABLED); } } /** * Occurs before creating item * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); } /** * Occurs before updating item * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemUpdate(kEvent $event) { parent::OnBeforeItemUpdate($event); } /** * Occurs before deleting item, id of item being * deleted is stored as 'id' event param * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemDelete(kEvent $event) { parent::OnBeforeItemDelete($event); } /** * Occurs before loading item, 'id' parameter * allows to get id of item being loaded * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemLoad(kEvent $event) { parent::OnBeforeItemLoad($event); } /** * Occurs after creating item * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemCreate(kEvent $event) { parent::OnAfterItemCreate($event); } /** * Occurs after updating item * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemUpdate(kEvent $event) { parent::OnAfterItemUpdate($event); } /** * Occurs after deleting item, id of deleted item * is stored as 'id' param of event * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemDelete(kEvent $event) { parent::OnAfterItemDelete($event); } /** * Loads user images * * @param kEvent $event * @return void * @access protected */ protected function OnAfterItemLoad(kEvent $event) { parent::OnAfterItemLoad($event); } - /** - * Builds/parses widget part of url - * - * @param int $rewrite_mode Mode in what rewrite listener was called. Possbile two modes: REWRITE_MODE_BUILD, REWRITE_MODE_PARSE. - * @param string $prefix Prefix, that listener uses for system integration - * @param Array $params Params, that are used for url building or created during url parsing. - * @param Array $url_parts Url parts to parse (only for parsing). - * @param bool $keep_events Keep event names in resulting url (only for building). - * @return bool Return true to continue to next listener; return false (when building) not to rewrite given prefix; return false (when parsing) to stop processing at this listener. - */ - function WidgetRewriteListener($rewrite_mode = REWRITE_MODE_BUILD, $prefix, &$params, &$url_parts, $keep_events = false) - { - if ($rewrite_mode == REWRITE_MODE_BUILD) { - return $this->WidgetRewriteBuilder($rewrite_mode, $prefix, $params, $url_parts, $keep_events); - } - - if ($rewrite_mode == REWRITE_MODE_PARSE) { - return $this->WidgetRewriteParser($rewrite_mode, $prefix, $params, $url_parts); - } - - return true; - } - - /** - * Builds/parses widget part of url - * - * @param int $rewrite_mode Mode in what rewrite listener was called. Possbile two modes: REWRITE_MODE_BUILD, REWRITE_MODE_PARSE. - * @param string $prefix Prefix, that listener uses for system integration - * @param Array $params Params, that are used for url building or created during url parsing. - * @param Array $url_parts Url parts to parse (only for parsing). - * @param bool $keep_events Keep event names in resulting url (only for building). - * @return bool Return true to continue to next listener; return false (when building) not to rewrite given prefix; return false (when parsing) to stop processing at this listener. - */ - function WidgetRewriteBuilder($rewrite_mode = REWRITE_MODE_BUILD, $prefix, &$params, &$url_parts, $keep_events = false) - { - $template = $this->Application->getPhysicalTemplate($params['t']); - - if ( $template == 'widgets/widget_detail' ) { - // this is default template for this prefix, so don't add it to resulting url - $params['pass_template'] = false; - } - - $rewrite_processor = $this->Application->recallObject('kRewriteUrlProcessor'); - /* @var $rewrite_processor kRewriteUrlProcessor */ - - $processed_params = $rewrite_processor->getProcessedParams($prefix, $params, $keep_events); - - if ( $processed_params === false ) { - return ''; - } - - $ret = Array ('', ''); - - $filename = isset($params[$prefix . '_filename']) ? $params[$prefix . '_filename'] : $this->Application->GetVar($prefix . '_filename'); - unset($params[$prefix . '_filename']); - - if ( $processed_params[$prefix . '_id'] > 0 ) { - // add id - if ( !$filename ) { - $sql = 'SELECT Title - FROM ' . TABLE_PREFIX . 'Widgets - WHERE WidgetId = ' . $processed_params[$prefix . '_id']; - $filename = $this->Conn->GetOne($sql); - } - - $ret[0] .= 'widgets/' . $filename . '/'; - } - elseif ( $processed_params[$prefix . '_Page'] > 1 ) { - // add page, only when ID is missing - $ret[1] .= $processed_params[$prefix . '_Page'] . '/'; - } - - $ret[0] = rtrim($ret[0], '/'); - $ret[1] = rtrim($ret[1], '/'); - - return array_map('mb_strtolower', $ret); - } - - /** - * Builds/parses widget part of url - * - * @param int $rewrite_mode Mode in what rewrite listener was called. Possbile two modes: REWRITE_MODE_BUILD, REWRITE_MODE_PARSE. - * @param string $prefix Prefix, that listener uses for system integration - * @param Array $params Params, that are used for url building or created during url parsing. - * @param Array $url_parts Url parts to parse (only for parsing). - * @return bool Return true to continue to next listener; return false (when building) not to rewrite given prefix; return false (when parsing) to stop processing at this listener. - */ - function WidgetRewriteParser($rewrite_mode = REWRITE_MODE_BUILD, $prefix, &$params, &$url_parts) - { - $widget_id = 0; - $widget_filename = ''; - $widget_index = array_search('widgets', $url_parts); - - if ( $widget_index !== false && isset($url_parts[$widget_index + 1]) ) { - $widget_filename = $url_parts[$widget_index + 1]; - } - - $rewrite_processor = $this->Application->recallObject('kRewriteUrlProcessor'); - /* @var $rewrite_processor kRewriteUrlProcessor */ - - if ( $widget_filename ) { - $sql = 'SELECT WidgetId - FROM ' . TABLE_PREFIX . 'Widgets - WHERE Title = ' . $this->Conn->qstr($widget_filename); - $widget_id = $this->Conn->GetOne($sql); - - if ( $widget_id ) { - $params[$this->Prefix . '_id'] = $widget_id; - $params[$this->Prefix . '_filename'] = $widget_filename; - $params['pass'][] = $this->Prefix; - - $rewrite_processor->partParsed('widgets'); - $rewrite_processor->partParsed($widget_filename); - } - } - - if ( $widget_id && !$rewrite_processor->moreToParse() ) { - // widget was last url part - use default template - $params['t'] = 'widgets/widget_detail'; - } - - return true; - } -} \ No newline at end of file +} Index: branches/1.3.x/units/widgets/WidgetRouter.php =================================================================== --- branches/1.3.x/units/widgets/WidgetRouter.php (revision 0) +++ branches/1.3.x/units/widgets/WidgetRouter.php (revision 16172) @@ -0,0 +1,119 @@ +getBuildTemplate(); + + if ( $template == 'widgets/widget_detail' ) { + // This is default template for this prefix, so don't add it to resulting url. + $this->setBuildParam('pass_template', false); + } + + $build_params = $this->extractBuildParams(); + + if ( $build_params === false ) { + return ''; + } + + $ret = array('', ''); + + $filename = $this->getBuildParam('@filename'); + $this->setBuildParam('@filename'); + + if ( $build_params[$this->buildPrefix . '_id'] > 0 ) { + // Add id. + if ( !$filename ) { + $sql = 'SELECT Title + FROM ' . TABLE_PREFIX . 'Widgets + WHERE WidgetId = ' . $build_params[$this->buildPrefix . '_id']; + $filename = $this->Conn->GetOne($sql); + } + + $ret[0] .= 'widgets/' . $filename . '/'; + } + elseif ( $build_params[$this->buildPrefix . '_Page'] > 1 ) { + // Add page, only when ID is missing. + $ret[1] .= $build_params[$this->buildPrefix . '_Page'] . '/'; + } + + $ret[0] = rtrim($ret[0], '/'); + $ret[1] = rtrim($ret[1], '/'); + + return array_map('mb_strtolower', $ret); + } + + /** + * Parses url part. + * + * @param array $url_parts Url parts to parse. + * @param array $params Parameters, that are used for url building or created during url parsing. + * + * @return boolean Return true to continue to next router; return false to stop processing at this router. + */ + public function parse(array &$url_parts, array &$params) + { + $widget_id = 0; + $widget_filename = ''; + $widget_index = array_search('widgets', $url_parts); + + if ( $widget_index !== false && isset($url_parts[$widget_index + 1]) ) { + $widget_filename = $url_parts[$widget_index + 1]; + } + + if ( $widget_filename ) { + $sql = 'SELECT WidgetId + FROM ' . TABLE_PREFIX . 'Widgets + WHERE Title = ' . $this->Conn->qstr($widget_filename); + $widget_id = $this->Conn->GetOne($sql); + + if ( $widget_id ) { + $params[$this->buildPrefix . '_id'] = $widget_id; + $params[$this->buildPrefix . '_filename'] = $widget_filename; + $params['pass'][] = $this->buildPrefix; + + $this->partParsed('widgets'); + $this->partParsed($widget_filename); + } + } + + if ( $widget_id && !$this->moreToParse() ) { + // Widget was last url part - use default template. + $params['t'] = 'widgets/widget_detail'; + } + + return true; + } + +} Property changes on: branches/1.3.x/units/widgets/WidgetRouter.php ___________________________________________________________________ Added: svn:eol-style + LF Index: branches/1.3.x/install/cache/class_structure.php =================================================================== --- branches/1.3.x/install/cache/class_structure.php (revision 16171) +++ branches/1.3.x/install/cache/class_structure.php (revision 16172) @@ -1,141 +1,149 @@ 2, 'classes' => array( 'CustomEventHandler' => '/modules/custom/units/sections/custom_eh.php', 'CustomUpgrades' => '/modules/custom/install/upgrades.php', 'EArticleEventHandler' => '/modules/custom/units/sections/articles/e_article_eh.php', 'EArticleTagProcessor' => '/modules/custom/units/sections/articles/e_article_tp.php', 'ECategoryEventHandler' => '/modules/custom/units/sections/categories/e_category_eh.php', 'ECategoryTagProcessor' => '/modules/custom/units/sections/categories/e_category_tp.php', 'ELinkEventHandler' => '/modules/custom/units/sections/links/e_link_eh.php', 'ELinkTagProcessor' => '/modules/custom/units/sections/links/e_link_tp.php', 'EProductEventHandler' => '/modules/custom/units/sections/products/e_product_eh.php', 'EProductTagProcessor' => '/modules/custom/units/sections/products/e_product_tp.php', 'EReviewEventHandler' => '/modules/custom/units/sections/reviews/e_review_eh.php', 'EUserEventHandler' => '/modules/custom/units/sections/users/e_user_eh.php', 'EUserTagProcessor' => '/modules/custom/units/sections/users/e_user_tp.php', 'SampleHelper' => '/modules/custom/units/helpers/sample_helper.php', 'WidgetEventHandler' => '/modules/custom/units/widgets/widget_eh.php', + 'WidgetRouter' => '/modules/custom/units/widgets/WidgetRouter.php', 'WidgetTagProcessor' => '/modules/custom/units/widgets/widget_tp.php', ), 'class_info' => array( 'CustomEventHandler' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'kEventHandler', ), ), 'CustomUpgrades' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'kUpgradeHelper', ), ), 'EArticleEventHandler' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'ArticlesEventHandler', ), ), 'EArticleTagProcessor' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'ArticlesTagProcessor', ), ), 'ECategoryEventHandler' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'CategoriesEventHandler', ), ), 'ECategoryTagProcessor' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'CategoriesTagProcessor', ), ), 'ELinkEventHandler' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'LinksEventHandler', ), ), 'ELinkTagProcessor' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'LinkTagProcessor', ), ), 'EProductEventHandler' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'ProductsEventHandler', ), ), 'EProductTagProcessor' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'ProductsTagProcessor', ), ), 'EReviewEventHandler' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'ReviewsEventHandler', ), ), 'EUserEventHandler' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'UsersEventHandler', ), ), 'EUserTagProcessor' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'UsersTagProcessor', ), ), 'SampleHelper' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'kHelper', ), ), 'WidgetEventHandler' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'kDBEventHandler', ), ), + 'WidgetRouter' => array( + 'type' => 1, + 'modifiers' => 0, + 'extends' => array( + 0 => 'AbstractRouter', + ), + ), 'WidgetTagProcessor' => array( 'type' => 1, 'modifiers' => 0, 'extends' => array( 0 => 'kDBTagProcessor', ), ), ), );