Index: branches/5.2.x/core/units/filters/item_filter_eh.php =================================================================== diff -u -N -r15145 -r15165 --- branches/5.2.x/core/units/filters/item_filter_eh.php (.../item_filter_eh.php) (revision 15145) +++ branches/5.2.x/core/units/filters/item_filter_eh.php (.../item_filter_eh.php) (revision 15165) @@ -1,159 +1,159 @@ - Array ('self' => true), - ); - - $this->permMapping = array_merge($this->permMapping, $permissions); - } - - /** - * 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); - - if ( !$this->Application->isAdmin ) { - $object = $event->getObject(); - /* @var $object kDBList */ - - $prefix_info = $this->Application->processPrefix($event->getEventParam('prefix')); - - $object->addFilter('prefix_filter', '%1$s.ItemPrefix = ' . $this->Conn->qstr($prefix_info['prefix'])); - $object->addFilter('status_filter', '%1$s.Enabled = 1'); - - if ( $event->Special == 'used' ) { - $filters = array_keys($this->Application->GetVar('filters', Array ())); - - if ( $filters ) { - $filters = $this->Conn->qstrArray($filters); - $object->addFilter('field_filter', '%1$s.FilterField IN (' . implode(',', $filters) . ')'); - } - else { - $object->addFilter('field_filter', 'FALSE'); - } - } - - $exclude_filters = $this->Application->GetVar('exclude_filters'); - - if ( $exclude_filters ) { - $exclude_filters = $this->Conn->qstrArray(explode(',', $exclude_filters)); - $object->addFilter('field_filter', '%1$s.FilterField NOT IN (' . implode(',', $exclude_filters) . ')'); - } - - if ( $event->getEventParam('per_page') === false ) { - $event->setEventParam('per_page', -1); - } - } - } - - /** - * Validates filter settings - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnBeforeItemValidate(kEvent $event) - { - parent::OnBeforeItemValidate($event); - - $object = $event->getObject(); - /* @var $object kDBItem */ - - $prefix = $object->GetDBField('ItemPrefix'); - - if ( $prefix ) { - if ( !$this->Application->prefixRegistred($prefix) ) { - $object->SetError('ItemPrefix', 'not_registered'); - } - - $field = $object->GetDBField('FilterField'); - - if ( $field ) { - $fields = $this->Application->getUnitOption($prefix, 'Fields'); - $virtual_fields = $this->Application->getUnitOption($prefix, 'VirtualFields'); - - if ( !isset($fields[$field]) && !isset($virtual_fields[$field]) ) { - $object->SetError('FilterField', 'non_existing', null, Array ($prefix)); - } - } - } - - $object->setRequired('RangeCount', $object->GetDBField('FilterType') == 'range'); - } - - /** - * Load item if id is available - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function LoadItem(kEvent $event) - { - static $cache = null; - - if ( $this->Application->isAdmin ) { - parent::LoadItem($event); - - return; - } - - $object = $event->getObject(); - /* @var $object kDBItem */ - - if ( !isset($cache) ) { - $cache = $this->Conn->Query($object->GetSelectSQL(), 'FilterKey'); - } - - $filter_key = $event->getEventParam('prefix') . '_' . $event->getEventParam('field'); - - if ( isset($cache[$filter_key]) ) { - $object->LoadFromHash($cache[$filter_key]); - } - - if ( $object->isLoaded() ) { - $actions = $this->Application->recallObject('kActions'); - /* @var $actions Params */ - - $actions->Set($event->getPrefixSpecial() . '_id', $object->GetID()); - } - else { - $object->setID(false); - } - } -} + Array ('self' => true), + ); + + $this->permMapping = array_merge($this->permMapping, $permissions); + } + + /** + * 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); + + if ( !$this->Application->isAdmin ) { + $object = $event->getObject(); + /* @var $object kDBList */ + + $prefix_info = $this->Application->processPrefix($event->getEventParam('prefix')); + + $object->addFilter('prefix_filter', '%1$s.ItemPrefix = ' . $this->Conn->qstr($prefix_info['prefix'])); + $object->addFilter('status_filter', '%1$s.Enabled = 1'); + + if ( $event->Special == 'used' ) { + $filters = array_keys($this->Application->GetVar('filters', Array ())); + + if ( $filters ) { + $filters = $this->Conn->qstrArray($filters); + $object->addFilter('field_filter', '%1$s.FilterField IN (' . implode(',', $filters) . ')'); + } + else { + $object->addFilter('field_filter', 'FALSE'); + } + } + + $exclude_filters = $this->Application->GetVar('exclude_filters'); + + if ( $exclude_filters ) { + $exclude_filters = $this->Conn->qstrArray(explode(',', $exclude_filters)); + $object->addFilter('field_filter', '%1$s.FilterField NOT IN (' . implode(',', $exclude_filters) . ')'); + } + + if ( $event->getEventParam('per_page') === false ) { + $event->setEventParam('per_page', -1); + } + } + } + + /** + * Validates filter settings + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemValidate(kEvent $event) + { + parent::OnBeforeItemValidate($event); + + $object = $event->getObject(); + /* @var $object kDBItem */ + + $prefix = $object->GetDBField('ItemPrefix'); + + if ( $prefix ) { + if ( !$this->Application->prefixRegistred($prefix) ) { + $object->SetError('ItemPrefix', 'not_registered'); + } + + $field = $object->GetDBField('FilterField'); + + if ( $field ) { + $fields = $this->Application->getUnitOption($prefix, 'Fields'); + $virtual_fields = $this->Application->getUnitOption($prefix, 'VirtualFields'); + + if ( !isset($fields[$field]) && !isset($virtual_fields[$field]) ) { + $object->SetError('FilterField', 'non_existing', null, Array ($prefix)); + } + } + } + + $object->setRequired('RangeCount', $object->GetDBField('FilterType') == 'range'); + } + + /** + * Load item if id is available + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function LoadItem(kEvent $event) + { + static $cache = null; + + if ( $this->Application->isAdmin ) { + parent::LoadItem($event); + + return; + } + + $object = $event->getObject(); + /* @var $object kDBItem */ + + if ( !isset($cache) ) { + $cache = $this->Conn->Query($object->GetSelectSQL(), 'FilterKey'); + } + + $filter_key = $event->getEventParam('prefix') . '_' . $event->getEventParam('field'); + + if ( isset($cache[$filter_key]) ) { + $object->LoadFromHash($cache[$filter_key]); + } + + if ( $object->isLoaded() ) { + $actions = $this->Application->recallObject('kActions'); + /* @var $actions Params */ + + $actions->Set($event->getPrefixSpecial() . '_id', $object->GetID()); + } + else { + $object->setID(false); + } + } +} Index: branches/5.2.x/core/admin_templates/promo_blocks/promo_block_edit.tpl =================================================================== diff -u -N -r14929 -r15165 --- branches/5.2.x/core/admin_templates/promo_blocks/promo_block_edit.tpl (.../promo_block_edit.tpl) (revision 14929) +++ branches/5.2.x/core/admin_templates/promo_blocks/promo_block_edit.tpl (.../promo_block_edit.tpl) (revision 15165) @@ -1,190 +1,190 @@ - - - - - - - - - - - - -
- - - - - - -
- - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - " id="" value="" tabindex="" size="" datepickerIcon="core/admin_templates/img/calendar_icon.gif">  - " - style="cursor: pointer; margin-right: 5px" - title="Date selector" - /> - - - " id="" value=""> - - - - " id="" value="" tabindex="" size="" datepickerIcon="core/admin_templates/img/calendar_icon.gif">  - " - style="cursor: pointer; margin-right: 5px" - title="Date selector" - /> - - - " id="" value=""> - -
-
- - - - + + + + + + + + + + + + +
+ + + + + + +
+ + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + " id="" value="" tabindex="" size="" datepickerIcon="core/admin_templates/img/calendar_icon.gif">  + " + style="cursor: pointer; margin-right: 5px" + title="Date selector" + /> + + + " id="" value=""> + + + + " id="" value="" tabindex="" size="" datepickerIcon="core/admin_templates/img/calendar_icon.gif">  + " + style="cursor: pointer; margin-right: 5px" + title="Date selector" + /> + + + " id="" value=""> + +
+
+ + + + Index: branches/5.2.x/core/units/spam_reports/spam_report_tp.php =================================================================== diff -u -N -r15152 -r15165 --- branches/5.2.x/core/units/spam_reports/spam_report_tp.php (.../spam_report_tp.php) (revision 15152) +++ branches/5.2.x/core/units/spam_reports/spam_report_tp.php (.../spam_report_tp.php) (revision 15165) @@ -1,6 +1,6 @@ Name == 'OnItemBuild' ) { - return true; - } - - if ( $event->Name == 'OnGetInfo' || $event->Name == 'OnDiscard' ) { - return $this->Application->isAdminUser; - } - - $perm_helper = $this->Application->recallObject('PermissionsHelper'); - /* @var $perm_helper kPermissionsHelper */ - - if ( $event->Name == 'OnSave' ) { - $perm_status = $this->Application->CheckPermission('CATEGORY.REVISION.ADD', 0) || $this->Application->CheckPermission('CATEGORY.REVISION.ADD.PENDING', 0); - - return $perm_helper->finalizePermissionCheck($event, $perm_status); - } - - if ( $event->Name == 'OnPublish' || $event->Name == 'OnDecline' ) { - $perm_status = $this->Application->CheckPermission('CATEGORY.REVISION.MODERATE', 0); - - return $perm_helper->finalizePermissionCheck($event, $perm_status); - } - - return parent::CheckPermission($event); - } - - /** - * Lists all current page revisions - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function SetCustomQuery(kEvent $event) - { - parent::SetCustomQuery($event); - - $object = $event->getObject(); - /* @var $object kDBList */ - - $page_id = $event->getEventParam('page_id'); - - if ( $this->Application->isAdmin ) { - $user_id = $this->Application->RecallVar('user_id'); - } - else { - $user_id = $this->Application->RecallVar('admin_user_id'); - } - - $object->addFilter('draft_filter', 'IF(%1$s.IsDraft = 1, %1$s.CreatedById = ' . $user_id . ', TRUE)'); - - if ( $page_id !== false ) { - $object->addFilter('parent_filter', '%1$s.PageId = ' . $page_id); - } - } - - /** - * Returns current page revision - * - * @param kEvent $event - * @return int - * @access public - */ - public function getPassedID(kEvent $event) - { - if ( $event->Special == 'current' ) { - $page = $this->Application->recallObject('st.-virtual'); - /* @var $page kDBItem */ - - $page_helper = $this->Application->recallObject('PageHelper'); - /* @var $page_helper PageHelper */ - - $page_id = $page->GetID(); - $revision_clause = $page_helper->getRevsionWhereClause($page_id, $page->GetDBField('LiveRevisionNumber')); - - $sql = 'SELECT RevisionId - FROM ' . TABLE_PREFIX . 'PageRevisions - WHERE (PageId = ' . $page_id . ') AND (' . $revision_clause . ') - ORDER BY IsDraft DESC, RevisionNumber DESC'; - $id = $this->Conn->GetOne($sql); - - if ( $id ) { - return $id; - } - - // no revisions -> create live revision - $object = $event->getObject(); - /* @var $object kDBItem */ - - $object->SetDBField('PageId', $page_id); - $object->SetDBField('RevisionNumber', 1); - $object->SetDBField('Status', STATUS_ACTIVE); - $object->Create(); - - return $object->GetID(); - } - - return parent::getPassedID($event); - } - - /** - * Remembers, who created revision - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnBeforeItemCreate(kEvent $event) - { - parent::OnBeforeItemCreate($event); - - $object = $event->getObject(); - /* @var $object kDBItem */ - - if ( $this->Application->isAdmin ) { - $object->SetDBField('CreatedById', $this->Application->RecallVar('user_id')); - } - else { - $object->SetDBField('CreatedById', $this->Application->RecallVar('admin_user_id')); - } - } - - /** - * Updates revision creation time - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnBeforeItemUpdate(kEvent $event) - { - parent::OnBeforeItemUpdate($event); - - $object = $event->getObject(); - /* @var $object kDBItem */ - - if ( $object->GetDBField('IsDraft') == 0 && $object->GetOriginalField('IsDraft') == 1 ) { - $object->SetDBField('CreatedOn_date', adodb_mktime()); - $object->SetDBField('CreatedOn_time', adodb_mktime()); - } - } - - /** - * Creates new content blocks based on source revision - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnAfterItemCreate(kEvent $event) - { - parent::OnAfterItemCreate($event); - - $object = $event->getObject(); - /* @var $object kDBItem */ - - if ( !$object->GetDBField('FromRevisionId') ) { - return ; - } - - $content = $this->Application->recallObject('content.-item', null, Array ('skip_autoload' => true)); - /* @var $content kDBItem */ - - $sql = $content->GetSelectSQL() . ' - WHERE pr.RevisionId = ' . $object->GetDBField('FromRevisionId'); - $content_blocks = $this->Conn->Query($sql); - - foreach ($content_blocks as $content_block) { - $content->LoadFromHash($content_block); - $content->SetDBField('RevisionId', $object->GetID()); - $content->Create(); - } - } - - /** - * Mark revision as current, once it's approved - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnAfterItemUpdate(kEvent $event) - { - parent::OnAfterItemUpdate($event); - - $object = $event->getObject(); - /* @var $object kDBItem */ - - $status = $object->GetDBField('Status'); - - if ( $status != $object->GetOriginalField('Status') && $status == STATUS_ACTIVE ) { - $page = $this->Application->recallObject('c.revision', null, Array ('skip_autoload' => true)); - /* @var $page kDBItem */ - - $page->Load($object->GetDBField('PageId')); - $page->SetDBField('LiveRevisionNumber', $object->GetDBField('RevisionNumber')); - $page->Update(); - } - } - - /** - * Returns user, who are editing current page right now - * - * @param kEvent $event - */ - function OnGetInfo($event) - { - $event->status = kEvent::erSTOP; - - if ( $this->Application->GetVar('ajax') != 'yes' ) { - return ; - } - - $page_helper = $this->Application->recallObject('PageHelper'); - /* @var $page_helper PageHelper */ - - $page_id = $this->Application->GetVar('m_cat_id'); - echo json_encode( $page_helper->getPageInfo($page_id) ); - } - - /** - * Saves user draft into live revision - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnSave(kEvent $event) - { - $revision_id = $this->getCurrentDraftRevision($event); - - if ( $revision_id ) { - $object = $event->getObject(Array ('skip_autoload' => true)); - /* @var $object kDBItem */ - - $object->Load($revision_id); - $object->SetDBField('IsDraft', 0); - $object->SetDBField('RevisionNumber', $this->getNextAvailableRevision($event)); - - if ( $this->Application->CheckPermission('CATEGORY.REVISION.ADD', 0) ) { - $object->SetDBField('Status', STATUS_ACTIVE); - } - elseif ( $this->Application->CheckPermission('CATEGORY.REVISION.ADD.PENDING', 0) ) { - $object->SetDBField('Status', STATUS_PENDING); - } - - $object->Update(); - } - - $event->SetRedirectParam('opener', 'u'); - } - - /** - * Discards user draft - * - * @param kEvent $event - */ - function OnDiscard($event) - { - $revision_id = $this->getCurrentDraftRevision($event); - - if ( $revision_id ) { - $temp_handler = $this->Application->recallObject($event->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler'); - /* @var $temp_handler kTempTablesHandler */ - - $temp_handler->DeleteItems($event->Prefix, $event->Special, Array ($revision_id)); - } - - $event->SetRedirectParam('opener', 'u'); - } - - /** - * Makes revision live - * - * @param kEvent $event - */ - function OnPublish($event) - { - $revision = $this->Application->recallObject('page-revision.current'); - /* @var $revision kDBItem */ - - if ( !$revision->isLoaded() || $revision->GetDBField('Status') == STATUS_ACTIVE || $revision->GetDBField('IsDraft') ) { - return ; - } - - $revision->SetDBField('Status', STATUS_ACTIVE); - $revision->Update(); - - $event->SetRedirectParam('opener', 'u'); - } - - /** - * Denies changes made in revision - * - * @param kEvent $event - */ - function OnDecline($event) - { - $revision = $this->Application->recallObject('page-revision.current'); - /* @var $revision kDBItem */ - - if ( !$revision->isLoaded() || $revision->GetDBField('Status') == STATUS_DISABLED || $revision->GetDBField('IsLive') || $revision->GetDBField('IsDraft') ) { - return ; - } - - $revision->SetDBField('Status', STATUS_DISABLED); - $revision->Update(); - - $event->SetRedirectParam('opener', 'u'); - } - - /** - * Returns revision id of user's draft - * - * @param kEvent $event - * @return int - */ - function getCurrentDraftRevision($event) - { - $where_clause = Array ( - 'IsDraft = 1', - 'PageId = ' . $this->Application->GetVar('m_cat_id'), - 'CreatedById = ' . $this->Application->RecallVar('user_id'), - ); - - $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . ' - FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' - WHERE (' . implode(') AND (', $where_clause) . ')'; - - return $this->Conn->GetOne($sql); - } - - /** - * Returns next available revision number for current page - * - * @param kEvent $event - * @return int - */ - function getNextAvailableRevision($event) - { - $sql = 'SELECT MAX(RevisionNumber) - FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' - WHERE PageId = ' . $this->Application->GetVar('m_cat_id'); - $max_revision = (int)$this->Conn->GetOne($sql); - - return $max_revision + 1; - } -} +Name == 'OnItemBuild' ) { + return true; + } + + if ( $event->Name == 'OnGetInfo' || $event->Name == 'OnDiscard' ) { + return $this->Application->isAdminUser; + } + + $perm_helper = $this->Application->recallObject('PermissionsHelper'); + /* @var $perm_helper kPermissionsHelper */ + + if ( $event->Name == 'OnSave' ) { + $perm_status = $this->Application->CheckPermission('CATEGORY.REVISION.ADD', 0) || $this->Application->CheckPermission('CATEGORY.REVISION.ADD.PENDING', 0); + + return $perm_helper->finalizePermissionCheck($event, $perm_status); + } + + if ( $event->Name == 'OnPublish' || $event->Name == 'OnDecline' ) { + $perm_status = $this->Application->CheckPermission('CATEGORY.REVISION.MODERATE', 0); + + return $perm_helper->finalizePermissionCheck($event, $perm_status); + } + + return parent::CheckPermission($event); + } + + /** + * Lists all current page revisions + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function SetCustomQuery(kEvent $event) + { + parent::SetCustomQuery($event); + + $object = $event->getObject(); + /* @var $object kDBList */ + + $page_id = $event->getEventParam('page_id'); + + if ( $this->Application->isAdmin ) { + $user_id = $this->Application->RecallVar('user_id'); + } + else { + $user_id = $this->Application->RecallVar('admin_user_id'); + } + + $object->addFilter('draft_filter', 'IF(%1$s.IsDraft = 1, %1$s.CreatedById = ' . $user_id . ', TRUE)'); + + if ( $page_id !== false ) { + $object->addFilter('parent_filter', '%1$s.PageId = ' . $page_id); + } + } + + /** + * Returns current page revision + * + * @param kEvent $event + * @return int + * @access public + */ + public function getPassedID(kEvent $event) + { + if ( $event->Special == 'current' ) { + $page = $this->Application->recallObject('st.-virtual'); + /* @var $page kDBItem */ + + $page_helper = $this->Application->recallObject('PageHelper'); + /* @var $page_helper PageHelper */ + + $page_id = $page->GetID(); + $revision_clause = $page_helper->getRevsionWhereClause($page_id, $page->GetDBField('LiveRevisionNumber')); + + $sql = 'SELECT RevisionId + FROM ' . TABLE_PREFIX . 'PageRevisions + WHERE (PageId = ' . $page_id . ') AND (' . $revision_clause . ') + ORDER BY IsDraft DESC, RevisionNumber DESC'; + $id = $this->Conn->GetOne($sql); + + if ( $id ) { + return $id; + } + + // no revisions -> create live revision + $object = $event->getObject(); + /* @var $object kDBItem */ + + $object->SetDBField('PageId', $page_id); + $object->SetDBField('RevisionNumber', 1); + $object->SetDBField('Status', STATUS_ACTIVE); + $object->Create(); + + return $object->GetID(); + } + + return parent::getPassedID($event); + } + + /** + * Remembers, who created revision + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemCreate(kEvent $event) + { + parent::OnBeforeItemCreate($event); + + $object = $event->getObject(); + /* @var $object kDBItem */ + + if ( $this->Application->isAdmin ) { + $object->SetDBField('CreatedById', $this->Application->RecallVar('user_id')); + } + else { + $object->SetDBField('CreatedById', $this->Application->RecallVar('admin_user_id')); + } + } + + /** + * Updates revision creation time + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(kEvent $event) + { + parent::OnBeforeItemUpdate($event); + + $object = $event->getObject(); + /* @var $object kDBItem */ + + if ( $object->GetDBField('IsDraft') == 0 && $object->GetOriginalField('IsDraft') == 1 ) { + $object->SetDBField('CreatedOn_date', adodb_mktime()); + $object->SetDBField('CreatedOn_time', adodb_mktime()); + } + } + + /** + * Creates new content blocks based on source revision + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnAfterItemCreate(kEvent $event) + { + parent::OnAfterItemCreate($event); + + $object = $event->getObject(); + /* @var $object kDBItem */ + + if ( !$object->GetDBField('FromRevisionId') ) { + return ; + } + + $content = $this->Application->recallObject('content.-item', null, Array ('skip_autoload' => true)); + /* @var $content kDBItem */ + + $sql = $content->GetSelectSQL() . ' + WHERE pr.RevisionId = ' . $object->GetDBField('FromRevisionId'); + $content_blocks = $this->Conn->Query($sql); + + foreach ($content_blocks as $content_block) { + $content->LoadFromHash($content_block); + $content->SetDBField('RevisionId', $object->GetID()); + $content->Create(); + } + } + + /** + * Mark revision as current, once it's approved + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnAfterItemUpdate(kEvent $event) + { + parent::OnAfterItemUpdate($event); + + $object = $event->getObject(); + /* @var $object kDBItem */ + + $status = $object->GetDBField('Status'); + + if ( $status != $object->GetOriginalField('Status') && $status == STATUS_ACTIVE ) { + $page = $this->Application->recallObject('c.revision', null, Array ('skip_autoload' => true)); + /* @var $page kDBItem */ + + $page->Load($object->GetDBField('PageId')); + $page->SetDBField('LiveRevisionNumber', $object->GetDBField('RevisionNumber')); + $page->Update(); + } + } + + /** + * Returns user, who are editing current page right now + * + * @param kEvent $event + */ + function OnGetInfo($event) + { + $event->status = kEvent::erSTOP; + + if ( $this->Application->GetVar('ajax') != 'yes' ) { + return ; + } + + $page_helper = $this->Application->recallObject('PageHelper'); + /* @var $page_helper PageHelper */ + + $page_id = $this->Application->GetVar('m_cat_id'); + echo json_encode( $page_helper->getPageInfo($page_id) ); + } + + /** + * Saves user draft into live revision + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnSave(kEvent $event) + { + $revision_id = $this->getCurrentDraftRevision($event); + + if ( $revision_id ) { + $object = $event->getObject(Array ('skip_autoload' => true)); + /* @var $object kDBItem */ + + $object->Load($revision_id); + $object->SetDBField('IsDraft', 0); + $object->SetDBField('RevisionNumber', $this->getNextAvailableRevision($event)); + + if ( $this->Application->CheckPermission('CATEGORY.REVISION.ADD', 0) ) { + $object->SetDBField('Status', STATUS_ACTIVE); + } + elseif ( $this->Application->CheckPermission('CATEGORY.REVISION.ADD.PENDING', 0) ) { + $object->SetDBField('Status', STATUS_PENDING); + } + + $object->Update(); + } + + $event->SetRedirectParam('opener', 'u'); + } + + /** + * Discards user draft + * + * @param kEvent $event + */ + function OnDiscard($event) + { + $revision_id = $this->getCurrentDraftRevision($event); + + if ( $revision_id ) { + $temp_handler = $this->Application->recallObject($event->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler'); + /* @var $temp_handler kTempTablesHandler */ + + $temp_handler->DeleteItems($event->Prefix, $event->Special, Array ($revision_id)); + } + + $event->SetRedirectParam('opener', 'u'); + } + + /** + * Makes revision live + * + * @param kEvent $event + */ + function OnPublish($event) + { + $revision = $this->Application->recallObject('page-revision.current'); + /* @var $revision kDBItem */ + + if ( !$revision->isLoaded() || $revision->GetDBField('Status') == STATUS_ACTIVE || $revision->GetDBField('IsDraft') ) { + return ; + } + + $revision->SetDBField('Status', STATUS_ACTIVE); + $revision->Update(); + + $event->SetRedirectParam('opener', 'u'); + } + + /** + * Denies changes made in revision + * + * @param kEvent $event + */ + function OnDecline($event) + { + $revision = $this->Application->recallObject('page-revision.current'); + /* @var $revision kDBItem */ + + if ( !$revision->isLoaded() || $revision->GetDBField('Status') == STATUS_DISABLED || $revision->GetDBField('IsLive') || $revision->GetDBField('IsDraft') ) { + return ; + } + + $revision->SetDBField('Status', STATUS_DISABLED); + $revision->Update(); + + $event->SetRedirectParam('opener', 'u'); + } + + /** + * Returns revision id of user's draft + * + * @param kEvent $event + * @return int + */ + function getCurrentDraftRevision($event) + { + $where_clause = Array ( + 'IsDraft = 1', + 'PageId = ' . $this->Application->GetVar('m_cat_id'), + 'CreatedById = ' . $this->Application->RecallVar('user_id'), + ); + + $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . ' + FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' + WHERE (' . implode(') AND (', $where_clause) . ')'; + + return $this->Conn->GetOne($sql); + } + + /** + * Returns next available revision number for current page + * + * @param kEvent $event + * @return int + */ + function getNextAvailableRevision($event) + { + $sql = 'SELECT MAX(RevisionNumber) + FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' + WHERE PageId = ' . $this->Application->GetVar('m_cat_id'); + $max_revision = (int)$this->Conn->GetOne($sql); + + return $max_revision + 1; + } +} Index: branches/5.2.x/core/units/promo_blocks/promo_block_eh.php =================================================================== diff -u -N -r15145 -r15165 --- branches/5.2.x/core/units/promo_blocks/promo_block_eh.php (.../promo_block_eh.php) (revision 15145) +++ branches/5.2.x/core/units/promo_blocks/promo_block_eh.php (.../promo_block_eh.php) (revision 15165) @@ -1,349 +1,349 @@ - 'OnChangePriority', - 'OnMassMoveDown' => 'OnChangePriority', - ); - - $this->eventMethods = array_merge($this->eventMethods, $events_map); - } - - /** - * Allows to override standard permission mapping - * - * @return void - * @access protected - * @see kEventHandler::$permMapping - */ - protected function mapPermissions() - { - parent::mapPermissions(); - - $permissions = Array ( - 'OnItemBuild' => Array ('self' => true), - 'OnSetSticky' => Array ('self' => 'view'), - 'OnRegisterView' => Array ('self' => true), - 'OnFollowLink' => Array ('self' => true), - 'OnResetCounters' => Array ('self' => 'add|edit'), - ); - - $this->permMapping = array_merge($this->permMapping, $permissions); - } - - /** - * Sets default value for promo block group - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnPreCreate(kEvent $event) - { - parent::OnPreCreate($event); - - $object = $event->getObject(); - /* @var $object kDBItem */ - - $promo_block_group = $this->Application->recallObject('promo-block-group'); - /* @var $promo_block_group kDBItem */ - - $object->SetDBField('PromoBlockGroupId', $promo_block_group->GetID()); - } - - /** - * Processes OnMassMoveUp, OnMassMoveDown events - * - * @param kEvent $event - */ - function OnChangePriority($event) - { - $this->Application->SetVar('priority_prefix', $event->getPrefixSpecial()); - $event->CallSubEvent('priority:' . $event->Name); - } - - /** - * 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 */ - - if ( $this->Application->isAdmin ) { - $promo_block_group = $this->Application->recallObject('promo-block-group'); - /* @var $promo_block_group kDBItem */ - - $object->addFilter('promo_group_filter', '%1$s.PromoBlockGroupId = ' . $promo_block_group->GetID()); - return; - } - - $group_id = $event->getEventParam('group_id'); - - if ( !$group_id ) { - $page = $this->Application->recallObject('st'); - /* @var $page CategoriesItem */ - - $group_id = $page->GetDBField('PromoBlockGroupId'); - } - - $object->addFilter('status_filter', '%1$s.Status = ' . STATUS_ACTIVE); - $object->addFilter('scheduled_from_filter', '%1$s.ScheduleFromDate IS NULL OR %1$s.ScheduleFromDate <= ' . TIMENOW); - $object->addFilter('scheduled_to_filter', '%1$s.ScheduleToDate IS NULL OR %1$s.ScheduleToDate >= ' . TIMENOW); - $object->addFilter('promo_group_filter', $group_id ? '%1$s.PromoBlockGroupId = ' . $group_id : 'FALSE'); - } - - /** - * Set's block as sticky - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnSetSticky(kEvent $event) - { - $object = $event->getObject( Array('skip_autoload' => true) ); - /* @var $object kDBItem */ - - $ids = $this->StoreSelectedIDs($event); - - if ( $ids ) { - $id = array_shift($ids); - - $sql = 'UPDATE ' . $object->TableName . ' - SET Sticky = 0'; - $this->Conn->Query($sql); - - $sql = 'UPDATE ' . $object->TableName . ' - SET Sticky = 1, Status = ' . STATUS_ACTIVE . ' - WHERE BlockId = ' . $id; - $this->Conn->Query($sql); - } - - $this->clearSelectedIDs($event); - } - - - /** - * Set Required fields - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnBeforeItemCreate(kEvent $event) - { - parent::OnBeforeItemCreate($event); - - $this->_itemChanged($event); - } - - /** - * Set Required fields - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnBeforeItemUpdate(kEvent $event) - { - parent::OnBeforeItemUpdate($event); - - $this->_itemChanged($event); - } - - /** - * Schedule dates - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function _itemChanged(kEvent $event) - { - $object = $event->getObject(); - /* @var $object kDBItem */ - - $date_from = $object->GetDBField('ScheduleFromDate_date'); - $date_to = $object->GetDBField('ScheduleToDate_date'); - - if ( $date_from && $date_to && $date_from >= $date_to ) { - $object->SetError('ScheduleFromDate_date', 'wrong_date_interval'); - } - - $object->setRequired('CategoryId', $object->GetDBField('LinkType') == PromoBlockType::INTERNAL); - $object->setRequired('ExternalLink', $object->GetDBField('LinkType') == PromoBlockType::EXTERNAL); - } - - /** - * Registers view of the promo block - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnRegisterView(kEvent $event) - { - $this->_incrementField($event, 'NumberOfViews'); - } - - /** - * Registers click on the promo block - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnFollowLink(kEvent $event) - { - $object = $event->getObject(); - /* @var $object kDBItem */ - - $this->_incrementField($event, 'NumberOfClicks', false); - - if ( $object->GetDBField('LinkType') == 1 ) { // Internal - $sql = 'SELECT NamedParentPath - FROM ' . TABLE_PREFIX . 'Categories - WHERE CategoryId = ' . $object->GetDBField('CategoryId'); - $event->redirect = $this->Conn->GetOne($sql); - - $event->SetRedirectParam('pass', 'm'); - } - else { - $ext_url = $object->GetDBField('ExternalLink'); - $event->redirect = 'external:' . (preg_match('/^(http|ftp):\\/\\/.*/', $ext_url) ? $ext_url : $this->Application->BaseURL() . $ext_url); - } - } - - /** - * Increment given promo block counters - * - * @param kEvent $event - * @param string $field - * @param bool $is_ajax - * @return void - * @access protected - */ - protected function _incrementField(kEvent $event, $field, $is_ajax = true) - { - if ( $is_ajax ) { - $event->status = kEvent::erSTOP; - - if ( $this->Application->GetVar('ajax') != 'yes' ) { - return ; - } - } - - $object = $event->getObject(); - /* @var $object kDBItem */ - - if ( !$object->isLoaded() ) { - echo 'FAILED'; - return ; - } - - // don't use kDBItem::Update to support concurrent view updates from different visitors - $sql = 'UPDATE ' . $object->TableName . ' - SET ' . $field . ' = ' . $field . ' + 1 - WHERE ' . $object->IDField . ' = ' . $object->GetID(); - $this->Conn->Query($sql); - - echo 'OK'; - } - - /** - * Resets promo block counters - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnResetCounters(kEvent $event) - { - $object = $event->getObject( Array ('skip_autoload' => true) ); - /* @var $object kDBItem */ - - $ids = $this->StoreSelectedIDs($event); - - foreach ($ids as $id) { - $object->Load($id); - $object->SetDBField('NumberOfViews', 0); - $object->SetDBField('NumberOfClicks', 0); - $object->Update(); - } - - $this->clearSelectedIDs($event); - } - - /** - * Occurs, when config was parsed, allows to change config data dynamically - * - * @param kEvent $event - * @return void - * @access protected - */ - protected function OnAfterConfigRead(kEvent $event) - { - parent::OnAfterConfigRead($event); - - $category_helper = $this->Application->recallObject('CategoryHelper'); - /* @var $category_helper CategoryHelper */ - - $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); - - $fields['CategoryId']['options'] = $category_helper->getStructureTreeAsOptions(); - - // images multilang fields - $a_image = Array( - 'type' => 'string', 'max_len' => 255, - 'formatter' => 'kUploadFormatter', 'upload_dir' => IMAGES_PATH . 'promo_blocks/', - 'multiple' => 1, 'thumb_format' => 'resize:100x100', - 'file_types' => '*.jpg;*.gif;*.png', 'files_description' => '!la_hint_ImageFiles!', - 'required' => 1, 'not_null' => 1, 'default' => '', - ); - - // get active languages - $sql = 'SELECT LanguageId - FROM ' . TABLE_PREFIX . 'Languages'; - $languages = $this->Conn->GetCol($sql); - - foreach ($languages AS $lang_id) { - $fields['l' . $lang_id . '_Image'] = $a_image; - } - - $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); - } -} + 'OnChangePriority', + 'OnMassMoveDown' => 'OnChangePriority', + ); + + $this->eventMethods = array_merge($this->eventMethods, $events_map); + } + + /** + * Allows to override standard permission mapping + * + * @return void + * @access protected + * @see kEventHandler::$permMapping + */ + protected function mapPermissions() + { + parent::mapPermissions(); + + $permissions = Array ( + 'OnItemBuild' => Array ('self' => true), + 'OnSetSticky' => Array ('self' => 'view'), + 'OnRegisterView' => Array ('self' => true), + 'OnFollowLink' => Array ('self' => true), + 'OnResetCounters' => Array ('self' => 'add|edit'), + ); + + $this->permMapping = array_merge($this->permMapping, $permissions); + } + + /** + * Sets default value for promo block group + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnPreCreate(kEvent $event) + { + parent::OnPreCreate($event); + + $object = $event->getObject(); + /* @var $object kDBItem */ + + $promo_block_group = $this->Application->recallObject('promo-block-group'); + /* @var $promo_block_group kDBItem */ + + $object->SetDBField('PromoBlockGroupId', $promo_block_group->GetID()); + } + + /** + * Processes OnMassMoveUp, OnMassMoveDown events + * + * @param kEvent $event + */ + function OnChangePriority($event) + { + $this->Application->SetVar('priority_prefix', $event->getPrefixSpecial()); + $event->CallSubEvent('priority:' . $event->Name); + } + + /** + * 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 */ + + if ( $this->Application->isAdmin ) { + $promo_block_group = $this->Application->recallObject('promo-block-group'); + /* @var $promo_block_group kDBItem */ + + $object->addFilter('promo_group_filter', '%1$s.PromoBlockGroupId = ' . $promo_block_group->GetID()); + return; + } + + $group_id = $event->getEventParam('group_id'); + + if ( !$group_id ) { + $page = $this->Application->recallObject('st'); + /* @var $page CategoriesItem */ + + $group_id = $page->GetDBField('PromoBlockGroupId'); + } + + $object->addFilter('status_filter', '%1$s.Status = ' . STATUS_ACTIVE); + $object->addFilter('scheduled_from_filter', '%1$s.ScheduleFromDate IS NULL OR %1$s.ScheduleFromDate <= ' . TIMENOW); + $object->addFilter('scheduled_to_filter', '%1$s.ScheduleToDate IS NULL OR %1$s.ScheduleToDate >= ' . TIMENOW); + $object->addFilter('promo_group_filter', $group_id ? '%1$s.PromoBlockGroupId = ' . $group_id : 'FALSE'); + } + + /** + * Set's block as sticky + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnSetSticky(kEvent $event) + { + $object = $event->getObject( Array('skip_autoload' => true) ); + /* @var $object kDBItem */ + + $ids = $this->StoreSelectedIDs($event); + + if ( $ids ) { + $id = array_shift($ids); + + $sql = 'UPDATE ' . $object->TableName . ' + SET Sticky = 0'; + $this->Conn->Query($sql); + + $sql = 'UPDATE ' . $object->TableName . ' + SET Sticky = 1, Status = ' . STATUS_ACTIVE . ' + WHERE BlockId = ' . $id; + $this->Conn->Query($sql); + } + + $this->clearSelectedIDs($event); + } + + + /** + * Set Required fields + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemCreate(kEvent $event) + { + parent::OnBeforeItemCreate($event); + + $this->_itemChanged($event); + } + + /** + * Set Required fields + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(kEvent $event) + { + parent::OnBeforeItemUpdate($event); + + $this->_itemChanged($event); + } + + /** + * Schedule dates + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function _itemChanged(kEvent $event) + { + $object = $event->getObject(); + /* @var $object kDBItem */ + + $date_from = $object->GetDBField('ScheduleFromDate_date'); + $date_to = $object->GetDBField('ScheduleToDate_date'); + + if ( $date_from && $date_to && $date_from >= $date_to ) { + $object->SetError('ScheduleFromDate_date', 'wrong_date_interval'); + } + + $object->setRequired('CategoryId', $object->GetDBField('LinkType') == PromoBlockType::INTERNAL); + $object->setRequired('ExternalLink', $object->GetDBField('LinkType') == PromoBlockType::EXTERNAL); + } + + /** + * Registers view of the promo block + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnRegisterView(kEvent $event) + { + $this->_incrementField($event, 'NumberOfViews'); + } + + /** + * Registers click on the promo block + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnFollowLink(kEvent $event) + { + $object = $event->getObject(); + /* @var $object kDBItem */ + + $this->_incrementField($event, 'NumberOfClicks', false); + + if ( $object->GetDBField('LinkType') == 1 ) { // Internal + $sql = 'SELECT NamedParentPath + FROM ' . TABLE_PREFIX . 'Categories + WHERE CategoryId = ' . $object->GetDBField('CategoryId'); + $event->redirect = $this->Conn->GetOne($sql); + + $event->SetRedirectParam('pass', 'm'); + } + else { + $ext_url = $object->GetDBField('ExternalLink'); + $event->redirect = 'external:' . (preg_match('/^(http|ftp):\\/\\/.*/', $ext_url) ? $ext_url : $this->Application->BaseURL() . $ext_url); + } + } + + /** + * Increment given promo block counters + * + * @param kEvent $event + * @param string $field + * @param bool $is_ajax + * @return void + * @access protected + */ + protected function _incrementField(kEvent $event, $field, $is_ajax = true) + { + if ( $is_ajax ) { + $event->status = kEvent::erSTOP; + + if ( $this->Application->GetVar('ajax') != 'yes' ) { + return ; + } + } + + $object = $event->getObject(); + /* @var $object kDBItem */ + + if ( !$object->isLoaded() ) { + echo 'FAILED'; + return ; + } + + // don't use kDBItem::Update to support concurrent view updates from different visitors + $sql = 'UPDATE ' . $object->TableName . ' + SET ' . $field . ' = ' . $field . ' + 1 + WHERE ' . $object->IDField . ' = ' . $object->GetID(); + $this->Conn->Query($sql); + + echo 'OK'; + } + + /** + * Resets promo block counters + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnResetCounters(kEvent $event) + { + $object = $event->getObject( Array ('skip_autoload' => true) ); + /* @var $object kDBItem */ + + $ids = $this->StoreSelectedIDs($event); + + foreach ($ids as $id) { + $object->Load($id); + $object->SetDBField('NumberOfViews', 0); + $object->SetDBField('NumberOfClicks', 0); + $object->Update(); + } + + $this->clearSelectedIDs($event); + } + + /** + * Occurs, when config was parsed, allows to change config data dynamically + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnAfterConfigRead(kEvent $event) + { + parent::OnAfterConfigRead($event); + + $category_helper = $this->Application->recallObject('CategoryHelper'); + /* @var $category_helper CategoryHelper */ + + $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); + + $fields['CategoryId']['options'] = $category_helper->getStructureTreeAsOptions(); + + // images multilang fields + $a_image = Array( + 'type' => 'string', 'max_len' => 255, + 'formatter' => 'kUploadFormatter', 'upload_dir' => IMAGES_PATH . 'promo_blocks/', + 'multiple' => 1, 'thumb_format' => 'resize:100x100', + 'file_types' => '*.jpg;*.gif;*.png', 'files_description' => '!la_hint_ImageFiles!', + 'required' => 1, 'not_null' => 1, 'default' => '', + ); + + // get active languages + $sql = 'SELECT LanguageId + FROM ' . TABLE_PREFIX . 'Languages'; + $languages = $this->Conn->GetCol($sql); + + foreach ($languages AS $lang_id) { + $fields['l' . $lang_id . '_Image'] = $a_image; + } + + $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); + } +} Index: branches/5.2.x/core/units/promo_block_groups/promo_block_group_eh.php =================================================================== diff -u -N -r15145 -r15165 --- branches/5.2.x/core/units/promo_block_groups/promo_block_group_eh.php (.../promo_block_group_eh.php) (revision 15145) +++ branches/5.2.x/core/units/promo_block_groups/promo_block_group_eh.php (.../promo_block_group_eh.php) (revision 15165) @@ -1,6 +1,6 @@ path = $this->Application->ConfigValue('Backup_Path'); - } - - /** - * Backup all data - * - * @return bool - */ - function initBackup() - { - $file_helper = $this->Application->recallObject('FileHelper'); - /* @var $file_helper FileHelper */ - - if (!$file_helper->CheckFolder($this->path) || !is_writable($this->path)) { - $this->Application->SetVar('error_msg', $this->Application->Phrase('la_Text_backup_access')); - - return false; - } - - $tables = $this->_getBackupTables(); - - $backup_progress = Array ( - 'table_num' => 0, - 'table_names' => $tables, - 'table_count' => count($tables), - 'record_count' => 0, - 'file_name' => $this->getBackupFile( adodb_mktime() ), - ); - - $this->Application->RemoveVar('adm.backupcomplete_filename'); - $this->Application->RemoveVar('adm.backupcomplete_filesize'); - - $fp = fopen($backup_progress['file_name'], 'a'); - - // write down module versions, used during backup - foreach ($this->Application->ModuleInfo as $module_name => $module_info) { - fwrite($fp, '# ' . $module_name . ' Version: ' . $module_info['Version'] . ";\n"); - } - - fwrite($fp, "#------------------------------------------\n\n"); - - // write down table structure - $out = Array (); - - foreach ($tables as $table) { - $out[] = $this->_getCreateTableSql($table); - } - - fwrite($fp, implode("\n", $out) . "\n"); - fclose($fp); - - $this->Application->StoreVar('adm.backup_status', serialize($backup_progress)); - - return true; - } - - /** - * Returns tables, that can be backed up - * - * @return Array - * @access protected - */ - protected function _getBackupTables() - { - $ret = Array (); - $tables = $this->Conn->GetCol('SHOW TABLES LIKE "' . TABLE_PREFIX . '%"'); - - foreach ($tables as $table) { - if ( strpos($table, 'ses_') === false ) { - $ret[] = $table; - } - } - - return $ret; - } - - public function performBackup() - { - $backup_progress = unserialize($this->Application->RecallVar('adm.backup_status')); - $current_table = $backup_progress['table_names'][ $backup_progress['table_num'] ]; - - // get records - $a_records = $this->_getInsertIntoSql($current_table, $backup_progress['record_count'], self::BACKUP_PER_STEP); - - if ( $a_records['num'] < self::BACKUP_PER_STEP ) { - $backup_progress['table_num']++; - $backup_progress['record_count'] = 0; - } - else { - $backup_progress['record_count'] += self::BACKUP_PER_STEP; - } - - if ( $a_records['sql'] ) { - $fp = fopen($backup_progress['file_name'], 'a'); - fwrite($fp, $a_records['sql']); - fclose($fp); - } - - $percent = ($backup_progress['table_num'] / $backup_progress['table_count']) * 100; - - if ( $percent >= 100 ) { - $percent = 100; - $this->Application->StoreVar('adm.backupcomplete_filename', $backup_progress['file_name']); - $this->Application->StoreVar('adm.backupcomplete_filesize', round(filesize($backup_progress['file_name']) / 1024 / 1024, 2)); // Mbytes - } - else { - $this->Application->StoreVar('adm.backup_status', serialize($backup_progress)); - } - - return round($percent); - - } - - /** - * Returns sql, that will insert given amount of data into given table - * - * @param string $table - * @param int $start - * @param int $limit - * @return Array - * @access protected - */ - protected function _getInsertIntoSql($table, $start, $limit) - { - $sql = 'SELECT * - FROM ' . $table . ' - ' . $this->Conn->getLimitClause($start, $limit); - $a_data = $this->Conn->Query($sql); - - if ( !$a_data ) { - return Array ('num' => 0, 'sql' => '',); - } - - $ret = ''; - $fields_sql = $this->_getFieldsSql( $a_data[0] ); - - foreach ($a_data AS $a_row) { - $values_sql = ''; - - foreach ($a_row as $field_value) { - $values_sql .= $this->Conn->qstr($field_value) . ','; - } - - $values_sql = substr($values_sql, 0, -1); - - $sql = 'INSERT INTO ' . $table . ' (' . $fields_sql . ') VALUES (' . $values_sql . ');'; - $sql = str_replace("\n", "\\n", $sql); - $sql = str_replace("\r", "\\r", $sql); - $ret .= $sql . "\n"; - } - - if ( strlen(TABLE_PREFIX) ) { - $ret = str_replace('INSERT INTO ' . TABLE_PREFIX, 'INSERT INTO ', $ret); - } - - return Array ('num' => count($a_data), 'sql' => $ret); - } - - /** - * Builds field list part of INSERT INTO statement based on given fields - * - * @param Array $row - * @return string - */ - protected function _getFieldsSql($row) - { - $ret = ''; - $a_fields = array_keys($row); - - foreach ($a_fields AS $field_name) { - $ret .= '`' . $field_name . '`,'; - } - - return substr($ret, 0, -1); - } - - /** - * Returns sql, that will create given table - * - * @param string $table - * @param string $crlf - * @return string - */ - protected function _getCreateTableSql($table, $crlf = "\n") - { - $this->Conn->Query('SET SQL_QUOTE_SHOW_CREATE = 0'); - $tmp_res = $this->Conn->Query('SHOW CREATE TABLE ' . $table); - - if ( !is_array($tmp_res) || !isset($tmp_res[0]) ) { - return ''; - } - - // add drop table & create table - $schema_create = 'DROP TABLE IF EXISTS ' . $table . ';' . $crlf; - $schema_create .= '# --------------------------------------------------------' . $crlf; - $schema_create .= str_replace("\n", $crlf, $tmp_res[0]['Create Table']); - - // remove table prefix from dump - if ( strlen(TABLE_PREFIX) ) { - $schema_create = str_replace('DROP TABLE IF EXISTS ' . TABLE_PREFIX, 'DROP TABLE ', $schema_create); - $schema_create = str_replace('CREATE TABLE ' . TABLE_PREFIX, 'CREATE TABLE ', $schema_create); - } - - // remove any table properties (e.g. auto-increment, collation, etc) - $last_brace_pos = strrpos($schema_create, ')'); - - if ( $last_brace_pos !== false ) { - $schema_create = substr($schema_create, 0, $last_brace_pos + 1); - } - - $schema_create .= "\n# --------------------------------------------------------\n"; - - return $schema_create; - } - - public function initRestore() - { - $file = $this->getBackupFile(); - - $restoreProgress = Array ( - 'file_pos' => 0, - 'file_name' => $file, - 'file_size' => filesize($file), - ); - - $this->Application->RemoveVar('adm.restore_success'); - $this->Application->StoreVar('adm.restore_status', serialize($restoreProgress)); - } - - /** - * Restores part of backup file - * - * @return int - * @access public - */ - public function performRestore() - { - $restore_progress = unserialize($this->Application->RecallVar('adm.restore_status')); - $filename = $restore_progress['file_name']; - $file_offset = $restore_progress['file_pos']; - $size = filesize($filename); - - if ( $file_offset > $size ) { - return self::FAILED_READING_BACKUP_FILE; - } - - $fp = fopen($filename, "r"); - if ( !$fp ) { - return self::FAILED_READING_BACKUP_FILE; - } - - if ( $file_offset > 0 ) { - fseek($fp, $file_offset); - } - else { - $end_of_sql = FALSE; - $sql = ""; - - while ( !feof($fp) && !$end_of_sql ) { - $line = fgets($fp); - - if ( substr($line, 0, 11) == "INSERT INTO" ) { - $end_of_sql = TRUE; - } - else { - $sql .= $line; - $file_offset = ftell($fp) - strlen($line); - } - } - - if ( strlen($sql) ) { - $error = $this->runSchemaText($sql); - - if ( $error != '' ) { - $this->Application->StoreVar('adm.restore_error', $error); - - return self::SQL_ERROR_DURING_RESTORE; - } - } - - fseek($fp, $file_offset); - } - - $lines_read = 0; - $all_sqls = Array (); - - while ( $lines_read < self::RESTORE_PER_STEP && !feof($fp) ) { - $sql = fgets($fp); - - if ( strlen($sql) ) { - $all_sqls[] = $sql; - $lines_read++; - } - } - - $file_offset = !feof($fp) ? ftell($fp) : $size; - - fclose($fp); - - if ( count($all_sqls) > 0 ) { - $error = $this->runSQLText($all_sqls); - - if ( $error != '' ) { - $this->Application->StoreVar('adm.restore_error', $error); - - return self::SQL_ERROR_DURING_RESTORE; - } - } - - $restore_progress['file_pos'] = $file_offset; - $this->Application->StoreVar('adm.restore_status', serialize($restore_progress)); - - return round($file_offset / $size * 100); - } - - /** - * Adds table prefix to given sql set - * - * @param string $sql - * @return void - * @access protected - */ - protected function addTablePrefix(&$sql) - { - $table_prefix = 'restore' . TABLE_PREFIX; - - if ( strlen($table_prefix) > 0 ) { - $replacements = Array ('INSERT INTO ', 'UPDATE ', 'ALTER TABLE ', 'DELETE FROM ', 'REPLACE INTO '); - - foreach ($replacements as $replacement) { - $sql = str_replace($replacement, $replacement . $table_prefix, $sql); - } - } - - $sql = str_replace('CREATE TABLE ', 'CREATE TABLE IF NOT EXISTS ' . $table_prefix, $sql); - $sql = str_replace('DROP TABLE ', 'DROP TABLE IF EXISTS ' . $table_prefix, $sql); - } - - /** - * Run given schema sqls and return error, if any - * - * @param $sql - * @return string - * @access protected - */ - protected function runSchemaText($sql) - { - $this->addTablePrefix($sql); - - $commands = explode("# --------------------------------------------------------", $sql); - - if ( count($commands) > 0 ) { - $commands = array_map('trim', $commands); - - foreach ($commands as $cmd) { - if ( strlen($cmd) > 0 ) { - $this->Conn->Query($cmd); - - if ( $this->Conn->hasError() ) { - return $this->Conn->getErrorMsg() . " COMMAND:
$cmd
"; - } - } - } - } - - return ''; - } - - /** - * Runs given sqls and return error message, if any - * - * @param $all_sqls - * @return string - * @access protected - */ - protected function runSQLText($all_sqls) - { - $line = 0; - - while ( $line < count($all_sqls) ) { - $sql = $all_sqls[$line]; - - if ( strlen(trim($sql)) > 0 && substr($sql, 0, 1) != "#" ) { - $this->addTablePrefix($sql); - $sql = trim($sql); - - if ( strlen($sql) > 0 ) { - $this->Conn->Query($sql); - - if ( $this->Conn->hasError() ) { - return $this->Conn->getErrorMsg() . " COMMAND:
$sql
"; - } - } - } - - $line++; - } - - return ''; - } - - /** - * Replaces current tables with restored tables - * - * @return void - * @access public - */ - public function replaceRestoredFiles() - { - // gather restored table names - $tables = $this->Conn->GetCol('SHOW TABLES'); - $mask_restore_table = '/^restore' . TABLE_PREFIX . '(.*)$/'; - - foreach ($tables as $table) { - if ( preg_match($mask_restore_table, $table) ) { - $old_table = substr($table, 7); - - $this->Conn->Query('DROP TABLE IF EXISTS ' . $old_table); - $this->Conn->Query('CREATE TABLE ' . $old_table . ' LIKE ' . $table); - $this->Conn->Query('INSERT INTO ' . $old_table . ' SELECT * FROM ' . $table); - $this->Conn->Query('DROP TABLE ' . $table); - } - } - } - - /** - * Deletes current backup file - * - * @return void - * @access public - */ - public function delete() - { - @unlink($this->getBackupFile()); - } - - /** - * Returns path to current backup file - * - * @param int|null $backup_date - * @return string - * @access protected - */ - protected function getBackupFile($backup_date = null) - { - if ( !isset($backup_date) ) { - $backup_date = $this->Application->GetVar('backupdate'); - } - - return $this->path . '/dump' . $backup_date . '.txt'; - } - - /** - * Returns list of backup files, available for restore - * - * @return Array - * @access public - */ - public function getBackupFiles() - { - $file_helper = $this->Application->recallObject('FileHelper'); - /* @var $file_helper FileHelper */ - - $ret = Array (); - $backup_path = $this->Application->ConfigValue('Backup_Path'); - $file_helper->CheckFolder($backup_path); - $backup_files = glob($backup_path . DIRECTORY_SEPARATOR . 'dump*.txt'); - - if ( !$backup_files ) { - return Array (); - } - - foreach ($backup_files as $backup_file) { - $ret[] = Array ( - 'filedate' => preg_replace('/^dump([\d]+)\.txt$/', '\\1', basename($backup_file)), - 'filesize' => filesize($backup_file)); - } - - rsort($ret); - - return $ret; - } +path = $this->Application->ConfigValue('Backup_Path'); + } + + /** + * Backup all data + * + * @return bool + */ + function initBackup() + { + $file_helper = $this->Application->recallObject('FileHelper'); + /* @var $file_helper FileHelper */ + + if (!$file_helper->CheckFolder($this->path) || !is_writable($this->path)) { + $this->Application->SetVar('error_msg', $this->Application->Phrase('la_Text_backup_access')); + + return false; + } + + $tables = $this->_getBackupTables(); + + $backup_progress = Array ( + 'table_num' => 0, + 'table_names' => $tables, + 'table_count' => count($tables), + 'record_count' => 0, + 'file_name' => $this->getBackupFile( adodb_mktime() ), + ); + + $this->Application->RemoveVar('adm.backupcomplete_filename'); + $this->Application->RemoveVar('adm.backupcomplete_filesize'); + + $fp = fopen($backup_progress['file_name'], 'a'); + + // write down module versions, used during backup + foreach ($this->Application->ModuleInfo as $module_name => $module_info) { + fwrite($fp, '# ' . $module_name . ' Version: ' . $module_info['Version'] . ";\n"); + } + + fwrite($fp, "#------------------------------------------\n\n"); + + // write down table structure + $out = Array (); + + foreach ($tables as $table) { + $out[] = $this->_getCreateTableSql($table); + } + + fwrite($fp, implode("\n", $out) . "\n"); + fclose($fp); + + $this->Application->StoreVar('adm.backup_status', serialize($backup_progress)); + + return true; + } + + /** + * Returns tables, that can be backed up + * + * @return Array + * @access protected + */ + protected function _getBackupTables() + { + $ret = Array (); + $tables = $this->Conn->GetCol('SHOW TABLES LIKE "' . TABLE_PREFIX . '%"'); + + foreach ($tables as $table) { + if ( strpos($table, 'ses_') === false ) { + $ret[] = $table; + } + } + + return $ret; + } + + public function performBackup() + { + $backup_progress = unserialize($this->Application->RecallVar('adm.backup_status')); + $current_table = $backup_progress['table_names'][ $backup_progress['table_num'] ]; + + // get records + $a_records = $this->_getInsertIntoSql($current_table, $backup_progress['record_count'], self::BACKUP_PER_STEP); + + if ( $a_records['num'] < self::BACKUP_PER_STEP ) { + $backup_progress['table_num']++; + $backup_progress['record_count'] = 0; + } + else { + $backup_progress['record_count'] += self::BACKUP_PER_STEP; + } + + if ( $a_records['sql'] ) { + $fp = fopen($backup_progress['file_name'], 'a'); + fwrite($fp, $a_records['sql']); + fclose($fp); + } + + $percent = ($backup_progress['table_num'] / $backup_progress['table_count']) * 100; + + if ( $percent >= 100 ) { + $percent = 100; + $this->Application->StoreVar('adm.backupcomplete_filename', $backup_progress['file_name']); + $this->Application->StoreVar('adm.backupcomplete_filesize', round(filesize($backup_progress['file_name']) / 1024 / 1024, 2)); // Mbytes + } + else { + $this->Application->StoreVar('adm.backup_status', serialize($backup_progress)); + } + + return round($percent); + + } + + /** + * Returns sql, that will insert given amount of data into given table + * + * @param string $table + * @param int $start + * @param int $limit + * @return Array + * @access protected + */ + protected function _getInsertIntoSql($table, $start, $limit) + { + $sql = 'SELECT * + FROM ' . $table . ' + ' . $this->Conn->getLimitClause($start, $limit); + $a_data = $this->Conn->Query($sql); + + if ( !$a_data ) { + return Array ('num' => 0, 'sql' => '',); + } + + $ret = ''; + $fields_sql = $this->_getFieldsSql( $a_data[0] ); + + foreach ($a_data AS $a_row) { + $values_sql = ''; + + foreach ($a_row as $field_value) { + $values_sql .= $this->Conn->qstr($field_value) . ','; + } + + $values_sql = substr($values_sql, 0, -1); + + $sql = 'INSERT INTO ' . $table . ' (' . $fields_sql . ') VALUES (' . $values_sql . ');'; + $sql = str_replace("\n", "\\n", $sql); + $sql = str_replace("\r", "\\r", $sql); + $ret .= $sql . "\n"; + } + + if ( strlen(TABLE_PREFIX) ) { + $ret = str_replace('INSERT INTO ' . TABLE_PREFIX, 'INSERT INTO ', $ret); + } + + return Array ('num' => count($a_data), 'sql' => $ret); + } + + /** + * Builds field list part of INSERT INTO statement based on given fields + * + * @param Array $row + * @return string + */ + protected function _getFieldsSql($row) + { + $ret = ''; + $a_fields = array_keys($row); + + foreach ($a_fields AS $field_name) { + $ret .= '`' . $field_name . '`,'; + } + + return substr($ret, 0, -1); + } + + /** + * Returns sql, that will create given table + * + * @param string $table + * @param string $crlf + * @return string + */ + protected function _getCreateTableSql($table, $crlf = "\n") + { + $this->Conn->Query('SET SQL_QUOTE_SHOW_CREATE = 0'); + $tmp_res = $this->Conn->Query('SHOW CREATE TABLE ' . $table); + + if ( !is_array($tmp_res) || !isset($tmp_res[0]) ) { + return ''; + } + + // add drop table & create table + $schema_create = 'DROP TABLE IF EXISTS ' . $table . ';' . $crlf; + $schema_create .= '# --------------------------------------------------------' . $crlf; + $schema_create .= str_replace("\n", $crlf, $tmp_res[0]['Create Table']); + + // remove table prefix from dump + if ( strlen(TABLE_PREFIX) ) { + $schema_create = str_replace('DROP TABLE IF EXISTS ' . TABLE_PREFIX, 'DROP TABLE ', $schema_create); + $schema_create = str_replace('CREATE TABLE ' . TABLE_PREFIX, 'CREATE TABLE ', $schema_create); + } + + // remove any table properties (e.g. auto-increment, collation, etc) + $last_brace_pos = strrpos($schema_create, ')'); + + if ( $last_brace_pos !== false ) { + $schema_create = substr($schema_create, 0, $last_brace_pos + 1); + } + + $schema_create .= "\n# --------------------------------------------------------\n"; + + return $schema_create; + } + + public function initRestore() + { + $file = $this->getBackupFile(); + + $restoreProgress = Array ( + 'file_pos' => 0, + 'file_name' => $file, + 'file_size' => filesize($file), + ); + + $this->Application->RemoveVar('adm.restore_success'); + $this->Application->StoreVar('adm.restore_status', serialize($restoreProgress)); + } + + /** + * Restores part of backup file + * + * @return int + * @access public + */ + public function performRestore() + { + $restore_progress = unserialize($this->Application->RecallVar('adm.restore_status')); + $filename = $restore_progress['file_name']; + $file_offset = $restore_progress['file_pos']; + $size = filesize($filename); + + if ( $file_offset > $size ) { + return self::FAILED_READING_BACKUP_FILE; + } + + $fp = fopen($filename, "r"); + if ( !$fp ) { + return self::FAILED_READING_BACKUP_FILE; + } + + if ( $file_offset > 0 ) { + fseek($fp, $file_offset); + } + else { + $end_of_sql = FALSE; + $sql = ""; + + while ( !feof($fp) && !$end_of_sql ) { + $line = fgets($fp); + + if ( substr($line, 0, 11) == "INSERT INTO" ) { + $end_of_sql = TRUE; + } + else { + $sql .= $line; + $file_offset = ftell($fp) - strlen($line); + } + } + + if ( strlen($sql) ) { + $error = $this->runSchemaText($sql); + + if ( $error != '' ) { + $this->Application->StoreVar('adm.restore_error', $error); + + return self::SQL_ERROR_DURING_RESTORE; + } + } + + fseek($fp, $file_offset); + } + + $lines_read = 0; + $all_sqls = Array (); + + while ( $lines_read < self::RESTORE_PER_STEP && !feof($fp) ) { + $sql = fgets($fp); + + if ( strlen($sql) ) { + $all_sqls[] = $sql; + $lines_read++; + } + } + + $file_offset = !feof($fp) ? ftell($fp) : $size; + + fclose($fp); + + if ( count($all_sqls) > 0 ) { + $error = $this->runSQLText($all_sqls); + + if ( $error != '' ) { + $this->Application->StoreVar('adm.restore_error', $error); + + return self::SQL_ERROR_DURING_RESTORE; + } + } + + $restore_progress['file_pos'] = $file_offset; + $this->Application->StoreVar('adm.restore_status', serialize($restore_progress)); + + return round($file_offset / $size * 100); + } + + /** + * Adds table prefix to given sql set + * + * @param string $sql + * @return void + * @access protected + */ + protected function addTablePrefix(&$sql) + { + $table_prefix = 'restore' . TABLE_PREFIX; + + if ( strlen($table_prefix) > 0 ) { + $replacements = Array ('INSERT INTO ', 'UPDATE ', 'ALTER TABLE ', 'DELETE FROM ', 'REPLACE INTO '); + + foreach ($replacements as $replacement) { + $sql = str_replace($replacement, $replacement . $table_prefix, $sql); + } + } + + $sql = str_replace('CREATE TABLE ', 'CREATE TABLE IF NOT EXISTS ' . $table_prefix, $sql); + $sql = str_replace('DROP TABLE ', 'DROP TABLE IF EXISTS ' . $table_prefix, $sql); + } + + /** + * Run given schema sqls and return error, if any + * + * @param $sql + * @return string + * @access protected + */ + protected function runSchemaText($sql) + { + $this->addTablePrefix($sql); + + $commands = explode("# --------------------------------------------------------", $sql); + + if ( count($commands) > 0 ) { + $commands = array_map('trim', $commands); + + foreach ($commands as $cmd) { + if ( strlen($cmd) > 0 ) { + $this->Conn->Query($cmd); + + if ( $this->Conn->hasError() ) { + return $this->Conn->getErrorMsg() . " COMMAND:
$cmd
"; + } + } + } + } + + return ''; + } + + /** + * Runs given sqls and return error message, if any + * + * @param $all_sqls + * @return string + * @access protected + */ + protected function runSQLText($all_sqls) + { + $line = 0; + + while ( $line < count($all_sqls) ) { + $sql = $all_sqls[$line]; + + if ( strlen(trim($sql)) > 0 && substr($sql, 0, 1) != "#" ) { + $this->addTablePrefix($sql); + $sql = trim($sql); + + if ( strlen($sql) > 0 ) { + $this->Conn->Query($sql); + + if ( $this->Conn->hasError() ) { + return $this->Conn->getErrorMsg() . " COMMAND:
$sql
"; + } + } + } + + $line++; + } + + return ''; + } + + /** + * Replaces current tables with restored tables + * + * @return void + * @access public + */ + public function replaceRestoredFiles() + { + // gather restored table names + $tables = $this->Conn->GetCol('SHOW TABLES'); + $mask_restore_table = '/^restore' . TABLE_PREFIX . '(.*)$/'; + + foreach ($tables as $table) { + if ( preg_match($mask_restore_table, $table) ) { + $old_table = substr($table, 7); + + $this->Conn->Query('DROP TABLE IF EXISTS ' . $old_table); + $this->Conn->Query('CREATE TABLE ' . $old_table . ' LIKE ' . $table); + $this->Conn->Query('INSERT INTO ' . $old_table . ' SELECT * FROM ' . $table); + $this->Conn->Query('DROP TABLE ' . $table); + } + } + } + + /** + * Deletes current backup file + * + * @return void + * @access public + */ + public function delete() + { + @unlink($this->getBackupFile()); + } + + /** + * Returns path to current backup file + * + * @param int|null $backup_date + * @return string + * @access protected + */ + protected function getBackupFile($backup_date = null) + { + if ( !isset($backup_date) ) { + $backup_date = $this->Application->GetVar('backupdate'); + } + + return $this->path . '/dump' . $backup_date . '.txt'; + } + + /** + * Returns list of backup files, available for restore + * + * @return Array + * @access public + */ + public function getBackupFiles() + { + $file_helper = $this->Application->recallObject('FileHelper'); + /* @var $file_helper FileHelper */ + + $ret = Array (); + $backup_path = $this->Application->ConfigValue('Backup_Path'); + $file_helper->CheckFolder($backup_path); + $backup_files = glob($backup_path . DIRECTORY_SEPARATOR . 'dump*.txt'); + + if ( !$backup_files ) { + return Array (); + } + + foreach ($backup_files as $backup_file) { + $ret[] = Array ( + 'filedate' => preg_replace('/^dump([\d]+)\.txt$/', '\\1', basename($backup_file)), + 'filesize' => filesize($backup_file)); + } + + rsort($ret); + + return $ret; + } } \ No newline at end of file Index: branches/5.2.x/core/install/step_templates/sys_config.tpl =================================================================== diff -u -N -r14842 -r15165 --- branches/5.2.x/core/install/step_templates/sys_config.tpl (.../sys_config.tpl) (revision 14842) +++ branches/5.2.x/core/install/step_templates/sys_config.tpl (.../sys_config.tpl) (revision 15165) @@ -1,57 +1,57 @@ - Array ('type' => 'text', 'title' => 'Web Path to Installation', 'section' => 'Misc', 'required' => 1, 'default' => '/'), - 'WriteablePath' => Array ('type' => 'text', 'title' => 'Path to Writable folder', 'section' => 'Misc', 'required' => 1, 'default' => '/system'), - 'RestrictedPath' => Array ('type' => 'text', 'title' => 'Path to Restricted folder', 'section' => 'Misc', 'required' => 1, 'default' => '/system/.restricted'), - 'AdminDirectory' => Array ('type' => 'text', 'title' => 'Path to Admin folder', 'section' => 'Misc', 'default' => '/admin'), - 'AdminPresetsDirectory' => Array ('type' => 'text', 'title' => 'Path to Admin Interface Presets folder', 'section' => 'Misc', 'default' => '/admin'), - 'ApplicationClass' => Array ('type' => 'text', 'title' => 'Name of Base Application Class', 'section' => 'Misc', 'default' => 'kApplication'), - 'ApplicationPath' => Array ('type' => 'text', 'title' => 'Path to Base Application Class file', 'section' => 'Misc', 'default' => '/core/kernel/application.php'), - 'CacheHandler' => Array ('type' => 'select', 'title' => 'Output Caching Engine', 'section' => 'Misc', 'default' => 'Fake'), - 'MemcacheServers' => Array ('type' => 'text', 'title' => 'Location of Memcache Servers', 'section' => 'Misc', 'default' => 'localhost:11211'), - 'CompressionEngine' => Array ('type' => 'select', 'title' => 'CSS/JS Compression Engine', 'section' => 'Misc', 'default' => ''), - ); - - $settings['CacheHandler']['options'] = $this->toolkit->getWorkingCacheHandlers(); - $settings['CompressionEngine']['options'] = $this->toolkit->getWorkingCompressionEngines(); - - $row_class = 'table-color2'; - - foreach ($settings as $config_var => $output_params) { - $row_class = $row_class == 'table-color1' ? 'table-color2' : 'table-color1'; - ?> - - - *' : ''); ?>: - - - toolkit->getSystemConfig($output_params['section'], $config_var, $output_params['default']); - - if ( $output_params['type'] == 'text' ) { - echo ''; - } - else { - echo ''; - } - ?> - - - + Array ('type' => 'text', 'title' => 'Web Path to Installation', 'section' => 'Misc', 'required' => 1, 'default' => '/'), + 'WriteablePath' => Array ('type' => 'text', 'title' => 'Path to Writable folder', 'section' => 'Misc', 'required' => 1, 'default' => '/system'), + 'RestrictedPath' => Array ('type' => 'text', 'title' => 'Path to Restricted folder', 'section' => 'Misc', 'required' => 1, 'default' => '/system/.restricted'), + 'AdminDirectory' => Array ('type' => 'text', 'title' => 'Path to Admin folder', 'section' => 'Misc', 'default' => '/admin'), + 'AdminPresetsDirectory' => Array ('type' => 'text', 'title' => 'Path to Admin Interface Presets folder', 'section' => 'Misc', 'default' => '/admin'), + 'ApplicationClass' => Array ('type' => 'text', 'title' => 'Name of Base Application Class', 'section' => 'Misc', 'default' => 'kApplication'), + 'ApplicationPath' => Array ('type' => 'text', 'title' => 'Path to Base Application Class file', 'section' => 'Misc', 'default' => '/core/kernel/application.php'), + 'CacheHandler' => Array ('type' => 'select', 'title' => 'Output Caching Engine', 'section' => 'Misc', 'default' => 'Fake'), + 'MemcacheServers' => Array ('type' => 'text', 'title' => 'Location of Memcache Servers', 'section' => 'Misc', 'default' => 'localhost:11211'), + 'CompressionEngine' => Array ('type' => 'select', 'title' => 'CSS/JS Compression Engine', 'section' => 'Misc', 'default' => ''), + ); + + $settings['CacheHandler']['options'] = $this->toolkit->getWorkingCacheHandlers(); + $settings['CompressionEngine']['options'] = $this->toolkit->getWorkingCompressionEngines(); + + $row_class = 'table-color2'; + + foreach ($settings as $config_var => $output_params) { + $row_class = $row_class == 'table-color1' ? 'table-color2' : 'table-color1'; + ?> + + + *' : ''); ?>: + + + toolkit->getSystemConfig($output_params['section'], $config_var, $output_params['default']); + + if ( $output_params['type'] == 'text' ) { + echo ''; + } + else { + echo ''; + } + ?> + + + Index: branches/5.2.x/core/units/filters/item_filter_tp.php =================================================================== diff -u -N -r15152 -r15165 --- branches/5.2.x/core/units/filters/item_filter_tp.php (.../item_filter_tp.php) (revision 15152) +++ branches/5.2.x/core/units/filters/item_filter_tp.php (.../item_filter_tp.php) (revision 15165) @@ -1,322 +1,322 @@ -Application->isAdmin ) { - return ; - } - - $block_params['filter_field'] = $object->GetDBField('FilterField'); - $block_params['filter_type'] = $object->GetDBField('FilterType'); - } - - /** - * Lists filter options - * - * @param Array $params - * @return string - * @access protected - */ - protected function ListFilterOptions($params) - { - static $cache = Array (); - - $object = $this->getObject($params); - /* @var $object kDBItem */ - - // get item list to be filtered - $this->Application->ProcessParsedTag($params['prefix'], 'InitList', $params); - $tag_processor = $this->Application->recallTagProcessor( $params['prefix'] ); - $item_list = $tag_processor->GetList($params); - - $filter_type = $object->GetDBField('FilterType'); - $filter_field = $object->GetDBField('FilterField'); - $cache_key = $filter_field . '_' . $filter_type; - - if ( !isset($cache[$cache_key]) ) { - $cache[$cache_key] = Array ('counts' => Array (), 'options' => Array ()); - - $field_sql = $item_list->isCalculatedField($filter_field) ? $item_list->extractCalculatedFields('`' . $filter_field . '`', 1, true) : '`' . $item_list->TableName . '`.`' . $filter_field . '`'; - $sql = $item_list->getCountSQL( $item_list->GetSelectSQL(true, false, $field_sql) ); - - if ( in_array($filter_type, Array ('select', 'radio', 'checkbox')) ) { - $options = $item_list->GetFieldOption($filter_field, 'options', false, Array ()); - - if ( $item_list->GetFieldOption($filter_field, 'use_phrases') ) { - $options = array_map(Array (&$this->Application, 'Phrase'), $options); - } - - $cache[$cache_key]['options'] = $options; - - $count_sql = str_replace('COUNT(*) AS count', 'COUNT(*), ' . $field_sql . ' AS GroupField', $sql) . ' GROUP BY GroupField'; - $cache[$cache_key]['counts'] = $this->Conn->GetCol($count_sql, 'GroupField'); - } - elseif ( $filter_type == 'range' ) { - $filter_params = $this->Application->GetVar('filter_params', Array ()); - $filter_params = isset($filter_params[$filter_field]) ? $filter_params[$filter_field] : Array (); - - if ( isset($filter_params['max_value']) ) { - $max_value = $filter_params['max_value']; - } - else { - $max_sql = str_replace('COUNT(*) AS count', 'MAX(' . $field_sql . ')', $sql); - $max_value = $this->Conn->GetOne($max_sql); - } - - if ( !$max_value ) { - return ''; - } - - $range_start = 0; - $range_count = $object->GetDBField('RangeCount'); - $max_value = $this->getClosestValue($max_value / $range_count) * $range_count; - - if ( $max_value <= $range_count ) { - $range_count = floor($range_count / 2); - } - - $range_size = $max_value / $range_count; - -// $range_size = ceil( $max_value / $range_count ); -// $max_value = $range_size * $range_count; // to compensate diff, created by "ceil" function usage - - $options = Array (); - $count_clause = ''; - $if_clause_mask = 'IF(%s BETWEEN %s AND %s, %s, %%s)'; - - for ($range_number = 0; $range_number < $range_count; $range_number++) { - $range_end = $range_start + $range_size; - $option_key = sprintf('%01.2f', $range_start) . '-' . sprintf('%01.2f', $range_end); - $options[$option_key] = $this->applyFormatting($range_start, $params); - - $sql_part = sprintf($if_clause_mask, $field_sql, $range_start, $range_end, $this->Conn->qstr($option_key)); - $count_clause = $count_clause ? sprintf($count_clause, $sql_part) : $sql_part; - $range_start = $range_end; - } - - $options[sprintf('%01.2f', $range_start) . '-' . sprintf('%01.2f', $range_start)] = $this->applyFormatting($range_start, $params); - - $cache[$cache_key]['max_value'] = $max_value; - $cache[$cache_key]['options'] = $options; - - $count_clause = sprintf($count_clause, $this->Conn->qstr($option_key)); - $count_sql = str_replace('COUNT(*) AS count', 'COUNT(*), ' . $count_clause . ' AS GroupField', $sql) . ' GROUP BY GroupField'; - $cache[$cache_key]['counts'] = $this->Conn->GetCol($count_sql, 'GroupField'); - } - } - - $options = $cache[$cache_key]['options']; - $counts = $cache[$cache_key]['counts']; - - if ( !$options || array_sum($counts) == 0 ) { - // no options in the filter OR no records to operate on - return ''; - } - - if ( $filter_type != 'range' ) { - $counts[''] = array_sum($counts); - $options = kUtil::array_merge_recursive(Array ('' => 'All'), $options); - } - - $ret = ''; - $block_params = $this->prepareTagParams($params); - $block_params['name'] = $params['render_as']; - $selected_value = $this->getFilterValue($filter_field); - - if ( $filter_type == 'range' && $params['type'] == 'count' ) { - // don't display last count, that corresponds to fake option - array_pop($options); - } - - $last_option_title = end($options); - - foreach ($options as $option_key => $option_title) { - $block_params['key'] = $option_key; - $block_params['title'] = $option_title; - $block_params['count'] = isset($counts[$option_key]) ? $counts[$option_key] : 0; - $block_params['is_last'] = $option_title == $last_option_title; - - if ( strpos($selected_value, '|') === false ) { - $block_params['selected'] = "$selected_value" === "$option_key"; - } - else { - $block_params['selected'] = strpos($selected_value, '|' . $option_key . '|') !== false; - } - - $ret .= $this->Application->ParseBlock($block_params); - } - - // set global vars to be used by jQuery UI slider - if ( $filter_type == 'range' ) { - $max_value = $cache[$cache_key]['max_value']; - - $this->Application->SetVar('min_range_value', 0); - $this->Application->SetVar('max_range_value', $max_value); - - $range_count = $object->GetDBField('RangeCount'); - - if ( $max_value <= $range_count ) { - $range_count = floor($range_count / 2); - } - - $range_size = $max_value / $range_count; - $this->Application->SetVar('range_step', $range_size); - -// $this->Application->SetVar('range_step', 1); - - if ( $selected_value ) { - list ($from_selected_value, $to_selected_value) = explode('-', $selected_value); - - $this->Application->SetVar('selected_from_range', $from_selected_value); - $this->Application->SetVar('selected_to_range', $to_selected_value); - } - else { - $this->Application->SetVar('selected_from_range', 0); - $this->Application->SetVar('selected_to_range', $max_value); - } - } - - if ( $ret ) { - $this->Application->Parser->DataExists = true; - } - - return $ret; - } - - /** - * Formats value to display in filter - * - * @param mixed $value - * @param Array $params - * @return string - */ - function applyFormatting($value, $params) - { - if ( isset($params['currency']) && $params['currency']) { - $iso = $this->GetISO($params['currency']); - $value = $this->ConvertCurrency($value, $iso); - - $decimal_tag = isset($params['decimal_tag']) ? $params['decimal_tag'] : ''; - $value = $this->AddCurrencySymbol($value, $iso, $decimal_tag); - } - - return $value; - } - - /** - * Returns next closest value to given one - * - * @param float $value - * @return int - * @access protected - */ - protected function getClosestValue($value) - { - $scale = Array (0, 1, 2, 5, 10, 20, 25, 30, 40, 50, 100, 150, 200, 250, 300, 400, 500, 1000, 1500, 2000, 2500, 3000, 5000, 10000); - - foreach ($scale as $scale_value) { - if ( $scale_value >= $value ) { - return $scale_value; - } - } - - return end($scale); - } - - /** - * Filter input name - * - * @param Array $params - * @return string - * @access protected - */ - protected function FilterInputName($params) - { - $field = $this->Application->Parser->GetParam('filter_field'); - - $ret = 'filters[' . $field . ']'; - - if (array_key_exists('as_preg', $params) && $params['as_preg']) { - $ret = preg_quote($ret, '/'); - } - - return $ret; - } - - /** - * Returns filter value - * - * @param Array $params - * @return string - * @access protected - */ - protected function FilterField($params) - { - $field = $this->Application->Parser->GetParam('filter_field'); - - return $this->getFilterValue($field); - } - - /** - * Returns filter value - * - * @param string $field - * @return string - * @access protected - */ - protected function getFilterValue($field) - { - $filters = $this->Application->GetVar('filters', Array ()); - - return array_key_exists($field, $filters) ? $filters[$field] : ''; - } - - /** - * Returns calculated range slider height - * - * @param Array $params - * @return string - * @access protected - */ - protected function SliderHeight($params) - { - // range count could be dynamically changed in PrintFilterOptions tag - $max_value = $this->Application->GetVar('max_range_value'); - - if ( $max_value !== false ) { - $range_count = $max_value / $this->Application->GetVar('range_step'); - } - else { - $object = $this->getObject($params); - /* @var $object kDBItem */ - - $range_count = $object->GetDBField('RangeCount'); - } - - return $range_count * $params['factor']; - } -} +Application->isAdmin ) { + return ; + } + + $block_params['filter_field'] = $object->GetDBField('FilterField'); + $block_params['filter_type'] = $object->GetDBField('FilterType'); + } + + /** + * Lists filter options + * + * @param Array $params + * @return string + * @access protected + */ + protected function ListFilterOptions($params) + { + static $cache = Array (); + + $object = $this->getObject($params); + /* @var $object kDBItem */ + + // get item list to be filtered + $this->Application->ProcessParsedTag($params['prefix'], 'InitList', $params); + $tag_processor = $this->Application->recallTagProcessor( $params['prefix'] ); + $item_list = $tag_processor->GetList($params); + + $filter_type = $object->GetDBField('FilterType'); + $filter_field = $object->GetDBField('FilterField'); + $cache_key = $filter_field . '_' . $filter_type; + + if ( !isset($cache[$cache_key]) ) { + $cache[$cache_key] = Array ('counts' => Array (), 'options' => Array ()); + + $field_sql = $item_list->isCalculatedField($filter_field) ? $item_list->extractCalculatedFields('`' . $filter_field . '`', 1, true) : '`' . $item_list->TableName . '`.`' . $filter_field . '`'; + $sql = $item_list->getCountSQL( $item_list->GetSelectSQL(true, false, $field_sql) ); + + if ( in_array($filter_type, Array ('select', 'radio', 'checkbox')) ) { + $options = $item_list->GetFieldOption($filter_field, 'options', false, Array ()); + + if ( $item_list->GetFieldOption($filter_field, 'use_phrases') ) { + $options = array_map(Array (&$this->Application, 'Phrase'), $options); + } + + $cache[$cache_key]['options'] = $options; + + $count_sql = str_replace('COUNT(*) AS count', 'COUNT(*), ' . $field_sql . ' AS GroupField', $sql) . ' GROUP BY GroupField'; + $cache[$cache_key]['counts'] = $this->Conn->GetCol($count_sql, 'GroupField'); + } + elseif ( $filter_type == 'range' ) { + $filter_params = $this->Application->GetVar('filter_params', Array ()); + $filter_params = isset($filter_params[$filter_field]) ? $filter_params[$filter_field] : Array (); + + if ( isset($filter_params['max_value']) ) { + $max_value = $filter_params['max_value']; + } + else { + $max_sql = str_replace('COUNT(*) AS count', 'MAX(' . $field_sql . ')', $sql); + $max_value = $this->Conn->GetOne($max_sql); + } + + if ( !$max_value ) { + return ''; + } + + $range_start = 0; + $range_count = $object->GetDBField('RangeCount'); + $max_value = $this->getClosestValue($max_value / $range_count) * $range_count; + + if ( $max_value <= $range_count ) { + $range_count = floor($range_count / 2); + } + + $range_size = $max_value / $range_count; + +// $range_size = ceil( $max_value / $range_count ); +// $max_value = $range_size * $range_count; // to compensate diff, created by "ceil" function usage + + $options = Array (); + $count_clause = ''; + $if_clause_mask = 'IF(%s BETWEEN %s AND %s, %s, %%s)'; + + for ($range_number = 0; $range_number < $range_count; $range_number++) { + $range_end = $range_start + $range_size; + $option_key = sprintf('%01.2f', $range_start) . '-' . sprintf('%01.2f', $range_end); + $options[$option_key] = $this->applyFormatting($range_start, $params); + + $sql_part = sprintf($if_clause_mask, $field_sql, $range_start, $range_end, $this->Conn->qstr($option_key)); + $count_clause = $count_clause ? sprintf($count_clause, $sql_part) : $sql_part; + $range_start = $range_end; + } + + $options[sprintf('%01.2f', $range_start) . '-' . sprintf('%01.2f', $range_start)] = $this->applyFormatting($range_start, $params); + + $cache[$cache_key]['max_value'] = $max_value; + $cache[$cache_key]['options'] = $options; + + $count_clause = sprintf($count_clause, $this->Conn->qstr($option_key)); + $count_sql = str_replace('COUNT(*) AS count', 'COUNT(*), ' . $count_clause . ' AS GroupField', $sql) . ' GROUP BY GroupField'; + $cache[$cache_key]['counts'] = $this->Conn->GetCol($count_sql, 'GroupField'); + } + } + + $options = $cache[$cache_key]['options']; + $counts = $cache[$cache_key]['counts']; + + if ( !$options || array_sum($counts) == 0 ) { + // no options in the filter OR no records to operate on + return ''; + } + + if ( $filter_type != 'range' ) { + $counts[''] = array_sum($counts); + $options = kUtil::array_merge_recursive(Array ('' => 'All'), $options); + } + + $ret = ''; + $block_params = $this->prepareTagParams($params); + $block_params['name'] = $params['render_as']; + $selected_value = $this->getFilterValue($filter_field); + + if ( $filter_type == 'range' && $params['type'] == 'count' ) { + // don't display last count, that corresponds to fake option + array_pop($options); + } + + $last_option_title = end($options); + + foreach ($options as $option_key => $option_title) { + $block_params['key'] = $option_key; + $block_params['title'] = $option_title; + $block_params['count'] = isset($counts[$option_key]) ? $counts[$option_key] : 0; + $block_params['is_last'] = $option_title == $last_option_title; + + if ( strpos($selected_value, '|') === false ) { + $block_params['selected'] = "$selected_value" === "$option_key"; + } + else { + $block_params['selected'] = strpos($selected_value, '|' . $option_key . '|') !== false; + } + + $ret .= $this->Application->ParseBlock($block_params); + } + + // set global vars to be used by jQuery UI slider + if ( $filter_type == 'range' ) { + $max_value = $cache[$cache_key]['max_value']; + + $this->Application->SetVar('min_range_value', 0); + $this->Application->SetVar('max_range_value', $max_value); + + $range_count = $object->GetDBField('RangeCount'); + + if ( $max_value <= $range_count ) { + $range_count = floor($range_count / 2); + } + + $range_size = $max_value / $range_count; + $this->Application->SetVar('range_step', $range_size); + +// $this->Application->SetVar('range_step', 1); + + if ( $selected_value ) { + list ($from_selected_value, $to_selected_value) = explode('-', $selected_value); + + $this->Application->SetVar('selected_from_range', $from_selected_value); + $this->Application->SetVar('selected_to_range', $to_selected_value); + } + else { + $this->Application->SetVar('selected_from_range', 0); + $this->Application->SetVar('selected_to_range', $max_value); + } + } + + if ( $ret ) { + $this->Application->Parser->DataExists = true; + } + + return $ret; + } + + /** + * Formats value to display in filter + * + * @param mixed $value + * @param Array $params + * @return string + */ + function applyFormatting($value, $params) + { + if ( isset($params['currency']) && $params['currency']) { + $iso = $this->GetISO($params['currency']); + $value = $this->ConvertCurrency($value, $iso); + + $decimal_tag = isset($params['decimal_tag']) ? $params['decimal_tag'] : ''; + $value = $this->AddCurrencySymbol($value, $iso, $decimal_tag); + } + + return $value; + } + + /** + * Returns next closest value to given one + * + * @param float $value + * @return int + * @access protected + */ + protected function getClosestValue($value) + { + $scale = Array (0, 1, 2, 5, 10, 20, 25, 30, 40, 50, 100, 150, 200, 250, 300, 400, 500, 1000, 1500, 2000, 2500, 3000, 5000, 10000); + + foreach ($scale as $scale_value) { + if ( $scale_value >= $value ) { + return $scale_value; + } + } + + return end($scale); + } + + /** + * Filter input name + * + * @param Array $params + * @return string + * @access protected + */ + protected function FilterInputName($params) + { + $field = $this->Application->Parser->GetParam('filter_field'); + + $ret = 'filters[' . $field . ']'; + + if (array_key_exists('as_preg', $params) && $params['as_preg']) { + $ret = preg_quote($ret, '/'); + } + + return $ret; + } + + /** + * Returns filter value + * + * @param Array $params + * @return string + * @access protected + */ + protected function FilterField($params) + { + $field = $this->Application->Parser->GetParam('filter_field'); + + return $this->getFilterValue($field); + } + + /** + * Returns filter value + * + * @param string $field + * @return string + * @access protected + */ + protected function getFilterValue($field) + { + $filters = $this->Application->GetVar('filters', Array ()); + + return array_key_exists($field, $filters) ? $filters[$field] : ''; + } + + /** + * Returns calculated range slider height + * + * @param Array $params + * @return string + * @access protected + */ + protected function SliderHeight($params) + { + // range count could be dynamically changed in PrintFilterOptions tag + $max_value = $this->Application->GetVar('max_range_value'); + + if ( $max_value !== false ) { + $range_count = $max_value / $this->Application->GetVar('range_step'); + } + else { + $object = $this->getObject($params); + /* @var $object kDBItem */ + + $range_count = $object->GetDBField('RangeCount'); + } + + return $range_count * $params['factor']; + } +} Index: branches/5.2.x/core/kernel/managers/url_processor.php =================================================================== diff -u -N -r14714 -r15165 --- branches/5.2.x/core/kernel/managers/url_processor.php (.../url_processor.php) (revision 14714) +++ branches/5.2.x/core/kernel/managers/url_processor.php (.../url_processor.php) (revision 15165) @@ -1,127 +1,127 @@ -setManager($manager); - } - - /** - * Sets reference to url manager - * - * @param kUrlManager $manager - * @return void - * @access public - */ - public function setManager(&$manager) - { - $this->manager =& $manager; - } - - /** - * Returns sorted array of passed prefixes (to build url from) - * - * @param string $pass - * @return Array - * @access protected - */ - protected function getPassInfo($pass = 'all') - { - if ( !$pass ) { - $pass = 'all'; - } - - $pass = trim( - preg_replace( - '/(?<=,|\\A)all(?=,|\\z)/', - trim($this->Application->GetVar('passed'), ','), - trim($pass, ',') - ), - ','); - - if ( !$pass ) { - return Array (); - } - - $pass_info = array_unique(explode(',', $pass)); // array( prefix[.special], prefix[.special] ... - - // we need to keep that sorting despite the sorting below, because this sorts prefixes with same priority by name - sort($pass_info, SORT_STRING); // to be prefix1,prefix1.special1,prefix1.special2,prefix3.specialX - - foreach ($pass_info as $prefix) { - list ($prefix_only,) = explode('.', $prefix, 2); - $sorted[$prefix] = $this->Application->getUnitOption($prefix_only, 'RewritePriority', 0); - } - - asort($sorted, SORT_NUMERIC); - $pass_info = array_keys($sorted); - - // ensure that "m" prefix is at the beginning - $main_index = array_search('m', $pass_info); - if ( $main_index !== false ) { - unset($pass_info[$main_index]); - array_unshift($pass_info, 'm'); - } - - return $pass_info; - } - - /** - * Builds url - * - * @param string $t - * @param Array $params - * @param string $pass - * @param bool $pass_events - * @param bool $env_var - * @return string - * @access public - */ - abstract public function build($t, $params, $pass='all', $pass_events = false, $env_var = true); - - /** - * Parses given string into a set of variables - * - * @abstract - * @param string $string - * @param string $pass_name - * @return Array - * @access public - */ - abstract public function parse($string, $pass_name = 'passed'); - - /** - * Builds env part that corresponds prefix passed - * - * @param string $prefix_special item's prefix & [special] - * @param Array $params url params - * @param bool $pass_events - * @return string - * @access protected - */ - abstract protected function BuildModuleEnv($prefix_special, &$params, $pass_events = false); +setManager($manager); + } + + /** + * Sets reference to url manager + * + * @param kUrlManager $manager + * @return void + * @access public + */ + public function setManager(&$manager) + { + $this->manager =& $manager; + } + + /** + * Returns sorted array of passed prefixes (to build url from) + * + * @param string $pass + * @return Array + * @access protected + */ + protected function getPassInfo($pass = 'all') + { + if ( !$pass ) { + $pass = 'all'; + } + + $pass = trim( + preg_replace( + '/(?<=,|\\A)all(?=,|\\z)/', + trim($this->Application->GetVar('passed'), ','), + trim($pass, ',') + ), + ','); + + if ( !$pass ) { + return Array (); + } + + $pass_info = array_unique(explode(',', $pass)); // array( prefix[.special], prefix[.special] ... + + // we need to keep that sorting despite the sorting below, because this sorts prefixes with same priority by name + sort($pass_info, SORT_STRING); // to be prefix1,prefix1.special1,prefix1.special2,prefix3.specialX + + foreach ($pass_info as $prefix) { + list ($prefix_only,) = explode('.', $prefix, 2); + $sorted[$prefix] = $this->Application->getUnitOption($prefix_only, 'RewritePriority', 0); + } + + asort($sorted, SORT_NUMERIC); + $pass_info = array_keys($sorted); + + // ensure that "m" prefix is at the beginning + $main_index = array_search('m', $pass_info); + if ( $main_index !== false ) { + unset($pass_info[$main_index]); + array_unshift($pass_info, 'm'); + } + + return $pass_info; + } + + /** + * Builds url + * + * @param string $t + * @param Array $params + * @param string $pass + * @param bool $pass_events + * @param bool $env_var + * @return string + * @access public + */ + abstract public function build($t, $params, $pass='all', $pass_events = false, $env_var = true); + + /** + * Parses given string into a set of variables + * + * @abstract + * @param string $string + * @param string $pass_name + * @return Array + * @access public + */ + abstract public function parse($string, $pass_name = 'passed'); + + /** + * Builds env part that corresponds prefix passed + * + * @param string $prefix_special item's prefix & [special] + * @param Array $params url params + * @param bool $pass_events + * @return string + * @access protected + */ + abstract protected function BuildModuleEnv($prefix_special, &$params, $pass_events = false); } \ No newline at end of file Index: branches/5.2.x/admin/system_presets/simple/inp_ckconfig.js =================================================================== diff -u -N -r15042 -r15165 --- branches/5.2.x/admin/system_presets/simple/inp_ckconfig.js (.../inp_ckconfig.js) (revision 15042) +++ branches/5.2.x/admin/system_presets/simple/inp_ckconfig.js (.../inp_ckconfig.js) (revision 15165) @@ -1,96 +1,96 @@ -// Preview -//CKEDITOR.config.PreviewUrl = ''; -//CKEDITOR.config.ContentId = ''; - -//CKEDITOR.config.PreloadImages = [ CKEDITOR.config.SkinPath + 'images/toolbar.start.gif', CKEDITOR.config.SkinPath + 'images/toolbar.buttonarrow.gif', CKEDITOR.config.BasePath + 'plugins/images/document.gif' ] ; - -//CKEDITOR.config.PluginsPath = CKEDITOR.config.BasePath + 'plugins/' ; - -CKEDITOR.config.extraPlugins = 'my_link,my_document,my_maximize,MediaEmbed'; - -//CKEDITOR.plugins.add('MySource'); -//CKEDITOR.plugins.add('MyPreview'); -//CKEDITOR.plugins.add('MyLink'); -//CKEDITOR.plugins.add('MyImage'); -//CKEDITOR.plugins.add('document', 'en,ru'); - -CKEDITOR.config.protectedSource.push( /(]+>)|(<\/inp2:[^\>]+>)|(]+\/>)/gi ) ; - -CKEDITOR.config.documentIconsUrl = '/system/user_files/icons'; // for document custom plugin - -CKEDITOR.config.toolbar_Default = [ - ['Styles'], - ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'], - ['NumberedList', 'BulletedList', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'], - ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'], - ['Find', 'Replace', 'Scayt'] -]; - -CKEDITOR.config.toolbar_DebugMode = [ - ['Cut','Copy','Paste','PasteText','PasteFromWord','-','NewPage','SelectAll','-','Find','Replace','-','Print','Preview','-',/*My*/ 'Link','Unlink','Anchor','HorizontalRule','-',/*My*/ 'Image','Flash','MediaEmbed','Document','Table','SpecialChar'], - '/', - ['Bold','Italic','Underline','Strike','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','NumberedList','BulletedList','Outdent','Indent','-','Subscript','Superscript','-','TextColor','BGColor','-','Undo','Redo'], - '/', - ['Styles','Font','FontSize','RemoveFormat','-','Scayt','-', /*My*/'Source', 'Maximize', 'ShowBlocks'] -]; - -//CKEDITOR.config.toolbar_Full = [ -// [ 'Source','-','Save','NewPage','DocProps','Preview','Print','-','Templates' ], -// [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ], -// [ 'Find','Replace','-','SelectAll','-','SpellChecker', 'Scayt' ], -// [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ], -// '/', -// [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ], -// [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl' ], -// [ 'Link','Unlink','Anchor' ], -// [ 'Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak' ], -// '/', -// [ 'Styles','Format','Font','FontSize' ], -// [ 'TextColor','BGColor' ], -// [ 'Maximize', 'ShowBlocks','-','About' ] -//]; - -CKEDITOR.config.enterMode = CKEDITOR.ENTER_BR ; // p | div | br -CKEDITOR.config.shiftEnterMode = CKEDITOR.ENTER_P ; // p | div | br - -CKEDITOR.config.keystrokes = [ - [ CKEDITOR.CTRL + 65 /*A*/, true ], - [ CKEDITOR.CTRL + 67 /*C*/, true ], - [ CKEDITOR.CTRL + 70 /*F*/, true ], - [ CKEDITOR.CTRL + 83 /*S*/, true ], - [ CKEDITOR.CTRL + 84 /*T*/, true ], - [ CKEDITOR.CTRL + 88 /*X*/, true ], - [ CKEDITOR.CTRL + 86 /*V*/, 'Paste' ], - [ CKEDITOR.CTRL + 45 /*INS*/, true ], - [ CKEDITOR.SHIFT + 45 /*INS*/, 'Paste' ], - [ CKEDITOR.CTRL + 88 /*X*/, 'Cut' ], - [ CKEDITOR.SHIFT + 46 /*DEL*/, 'Cut' ], - [ CKEDITOR.CTRL + 90 /*Z*/, 'Undo' ], - [ CKEDITOR.CTRL + 89 /*Y*/, 'Redo' ], - [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 /*Z*/, 'Redo' ], - [ CKEDITOR.CTRL + 76 /*L*/, 'Link' ], - [ CKEDITOR.CTRL + 66 /*B*/, 'Bold' ], - [ CKEDITOR.CTRL + 73 /*I*/, 'Italic' ], - [ CKEDITOR.CTRL + 85 /*U*/, 'Underline' ], - [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 83 /*S*/, 'Save' ], - [ CKEDITOR.CTRL + CKEDITOR.ALT + 13 /*ENTER*/, 'FitWindow' ] -] ; - -//CKEDITOR.config.menu_groups = 'generic,anchor,flash,select,textarea,checkbox,radio,textfield,hiddenfield,imagebutton,button,bulletedlist,numberedlist,table,form'; - -CKEDITOR.config.font_names = 'Arial Narrow;Arial;Sans-Serif;Serif;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ; -CKEDITOR.config.fontSize_sizes = 'xx-small;x-small;small;medium;large;x-large;xx-large' ; - -CKEDITOR.config.filebrowserBrowseUrl = CKEDITOR.basePath + 'ckfinder/ckfinder.html'; -CKEDITOR.config.filebrowserUploadUrl = CKEDITOR.basePath + 'ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files'; - -CKEDITOR.config.filebrowserImageBrowseUrl = CKEDITOR.basePath + 'ckfinder/ckfinder.html?type=Images'; -CKEDITOR.config.filebrowserImageUploadUrl = CKEDITOR.basePath + 'ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images'; - -CKEDITOR.config.filebrowserFlashBrowseUrl = CKEDITOR.basePath + 'ckfinder/ckfinder.html?type=Flash'; -CKEDITOR.config.filebrowserFlashUploadUrl = CKEDITOR.basePath + 'ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Flash'; - -CKEDITOR.config.filebrowserDocumentBrowseUrl = CKEDITOR.basePath + 'ckfinder/ckfinder.html?type=Documents'; - -// add ability to browse for documents -//CKEDITOR.config.documentsBrowser = true ; +// Preview +//CKEDITOR.config.PreviewUrl = ''; +//CKEDITOR.config.ContentId = ''; + +//CKEDITOR.config.PreloadImages = [ CKEDITOR.config.SkinPath + 'images/toolbar.start.gif', CKEDITOR.config.SkinPath + 'images/toolbar.buttonarrow.gif', CKEDITOR.config.BasePath + 'plugins/images/document.gif' ] ; + +//CKEDITOR.config.PluginsPath = CKEDITOR.config.BasePath + 'plugins/' ; + +CKEDITOR.config.extraPlugins = 'my_link,my_document,my_maximize,MediaEmbed'; + +//CKEDITOR.plugins.add('MySource'); +//CKEDITOR.plugins.add('MyPreview'); +//CKEDITOR.plugins.add('MyLink'); +//CKEDITOR.plugins.add('MyImage'); +//CKEDITOR.plugins.add('document', 'en,ru'); + +CKEDITOR.config.protectedSource.push( /(]+>)|(<\/inp2:[^\>]+>)|(]+\/>)/gi ) ; + +CKEDITOR.config.documentIconsUrl = '/system/user_files/icons'; // for document custom plugin + +CKEDITOR.config.toolbar_Default = [ + ['Styles'], + ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'], + ['NumberedList', 'BulletedList', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'], + ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'], + ['Find', 'Replace', 'Scayt'] +]; + +CKEDITOR.config.toolbar_DebugMode = [ + ['Cut','Copy','Paste','PasteText','PasteFromWord','-','NewPage','SelectAll','-','Find','Replace','-','Print','Preview','-',/*My*/ 'Link','Unlink','Anchor','HorizontalRule','-',/*My*/ 'Image','Flash','MediaEmbed','Document','Table','SpecialChar'], + '/', + ['Bold','Italic','Underline','Strike','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','NumberedList','BulletedList','Outdent','Indent','-','Subscript','Superscript','-','TextColor','BGColor','-','Undo','Redo'], + '/', + ['Styles','Font','FontSize','RemoveFormat','-','Scayt','-', /*My*/'Source', 'Maximize', 'ShowBlocks'] +]; + +//CKEDITOR.config.toolbar_Full = [ +// [ 'Source','-','Save','NewPage','DocProps','Preview','Print','-','Templates' ], +// [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ], +// [ 'Find','Replace','-','SelectAll','-','SpellChecker', 'Scayt' ], +// [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ], +// '/', +// [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ], +// [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl' ], +// [ 'Link','Unlink','Anchor' ], +// [ 'Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak' ], +// '/', +// [ 'Styles','Format','Font','FontSize' ], +// [ 'TextColor','BGColor' ], +// [ 'Maximize', 'ShowBlocks','-','About' ] +//]; + +CKEDITOR.config.enterMode = CKEDITOR.ENTER_BR ; // p | div | br +CKEDITOR.config.shiftEnterMode = CKEDITOR.ENTER_P ; // p | div | br + +CKEDITOR.config.keystrokes = [ + [ CKEDITOR.CTRL + 65 /*A*/, true ], + [ CKEDITOR.CTRL + 67 /*C*/, true ], + [ CKEDITOR.CTRL + 70 /*F*/, true ], + [ CKEDITOR.CTRL + 83 /*S*/, true ], + [ CKEDITOR.CTRL + 84 /*T*/, true ], + [ CKEDITOR.CTRL + 88 /*X*/, true ], + [ CKEDITOR.CTRL + 86 /*V*/, 'Paste' ], + [ CKEDITOR.CTRL + 45 /*INS*/, true ], + [ CKEDITOR.SHIFT + 45 /*INS*/, 'Paste' ], + [ CKEDITOR.CTRL + 88 /*X*/, 'Cut' ], + [ CKEDITOR.SHIFT + 46 /*DEL*/, 'Cut' ], + [ CKEDITOR.CTRL + 90 /*Z*/, 'Undo' ], + [ CKEDITOR.CTRL + 89 /*Y*/, 'Redo' ], + [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 /*Z*/, 'Redo' ], + [ CKEDITOR.CTRL + 76 /*L*/, 'Link' ], + [ CKEDITOR.CTRL + 66 /*B*/, 'Bold' ], + [ CKEDITOR.CTRL + 73 /*I*/, 'Italic' ], + [ CKEDITOR.CTRL + 85 /*U*/, 'Underline' ], + [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 83 /*S*/, 'Save' ], + [ CKEDITOR.CTRL + CKEDITOR.ALT + 13 /*ENTER*/, 'FitWindow' ] +] ; + +//CKEDITOR.config.menu_groups = 'generic,anchor,flash,select,textarea,checkbox,radio,textfield,hiddenfield,imagebutton,button,bulletedlist,numberedlist,table,form'; + +CKEDITOR.config.font_names = 'Arial Narrow;Arial;Sans-Serif;Serif;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ; +CKEDITOR.config.fontSize_sizes = 'xx-small;x-small;small;medium;large;x-large;xx-large' ; + +CKEDITOR.config.filebrowserBrowseUrl = CKEDITOR.basePath + 'ckfinder/ckfinder.html'; +CKEDITOR.config.filebrowserUploadUrl = CKEDITOR.basePath + 'ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files'; + +CKEDITOR.config.filebrowserImageBrowseUrl = CKEDITOR.basePath + 'ckfinder/ckfinder.html?type=Images'; +CKEDITOR.config.filebrowserImageUploadUrl = CKEDITOR.basePath + 'ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images'; + +CKEDITOR.config.filebrowserFlashBrowseUrl = CKEDITOR.basePath + 'ckfinder/ckfinder.html?type=Flash'; +CKEDITOR.config.filebrowserFlashUploadUrl = CKEDITOR.basePath + 'ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Flash'; + +CKEDITOR.config.filebrowserDocumentBrowseUrl = CKEDITOR.basePath + 'ckfinder/ckfinder.html?type=Documents'; + +// add ability to browse for documents +//CKEDITOR.config.documentsBrowser = true ; Index: branches/5.2.x/core/install/step_templates/sys_requirements.tpl =================================================================== diff -u -N -r15130 -r15165 --- branches/5.2.x/core/install/step_templates/sys_requirements.tpl (.../sys_requirements.tpl) (revision 15130) +++ branches/5.2.x/core/install/step_templates/sys_requirements.tpl (.../sys_requirements.tpl) (revision 15165) @@ -1,75 +1,75 @@ - - %s - '; - - $error_tpl = ' - - %s - %s - '; - - $check_titles = Array ( - 'php_version' => 'PHP version: 5.3.2+ (required)', - 'url_rewriting' => 'URL Rewriting Support (optional)', - 'java' => 'Java (optional)', - 'sep1' => 'PHP extensions:', - 'memcache' => '- Memcache (optional)', - 'curl' => '- Curl (required)', - 'simplexml' => '- SimpleXML (required)', - 'freetype' => '- Freetype (required)', - 'gd_version' => '- GD 1.8+ (required)', - 'jpeg' => '- jpeg (required)', - 'mysql' => '- MySQL (required)', - 'json' => '- JSON (required)', - 'sep2' => 'PHP settings:', - 'memory_limit' => "- ini_set('memory_limit', ...) works (optional)", - 'date.timezone' => "- ini_get('date.timezone') - timezone set (required)", - 'variables_order' => "- ini_get('variables_order') - contains \"GPC\" string", - 'output_buffering' => "- ini_get('output_buffering') > 0 - buffering works (required)", - ); - - $output = sprintf($heading_tpl, 'Server-side requirements'); - $check_results = $this->toolkit->CallPrerequisitesMethod('core/', 'CheckSystemRequirements'); - - /*$required_checks = Array ( - 'php_version', 'simplexml', 'curl', 'freetype', 'gd_version', - 'jpeg', 'mysql', 'date.timezone', 'output_buffering', - ); - - $required_checks = array_diff($required_checks, array_keys( array_filter($check_results) ));*/ - - foreach ($check_titles AS $key => $title) { - if ( substr($key, 0, 3) == 'sep' ) { - $check_result = ''; - } - else { - $check_result = $check_results[$key] ? '[PASSED]' : '[FAILED]'; - } - - $output .= sprintf($error_tpl, $title, $check_result); - } - - $output .= sprintf($heading_tpl, 'Client-side requirements', 'text'); - $output .= sprintf($error_tpl, 'Cookies enabled', '[FAILED]'); - $output .= sprintf($error_tpl, 'JavaScript enabled', '[FAILED]'); - - $output .= ''; - $output .= ''; - - $output .= ""; - - echo $output; -?> + + %s + '; + + $error_tpl = ' + + %s + %s + '; + + $check_titles = Array ( + 'php_version' => 'PHP version: 5.3.2+ (required)', + 'url_rewriting' => 'URL Rewriting Support (optional)', + 'java' => 'Java (optional)', + 'sep1' => 'PHP extensions:', + 'memcache' => '- Memcache (optional)', + 'curl' => '- Curl (required)', + 'simplexml' => '- SimpleXML (required)', + 'freetype' => '- Freetype (required)', + 'gd_version' => '- GD 1.8+ (required)', + 'jpeg' => '- jpeg (required)', + 'mysql' => '- MySQL (required)', + 'json' => '- JSON (required)', + 'sep2' => 'PHP settings:', + 'memory_limit' => "- ini_set('memory_limit', ...) works (optional)", + 'date.timezone' => "- ini_get('date.timezone') - timezone set (required)", + 'variables_order' => "- ini_get('variables_order') - contains \"GPC\" string", + 'output_buffering' => "- ini_get('output_buffering') > 0 - buffering works (required)", + ); + + $output = sprintf($heading_tpl, 'Server-side requirements'); + $check_results = $this->toolkit->CallPrerequisitesMethod('core/', 'CheckSystemRequirements'); + + /*$required_checks = Array ( + 'php_version', 'simplexml', 'curl', 'freetype', 'gd_version', + 'jpeg', 'mysql', 'date.timezone', 'output_buffering', + ); + + $required_checks = array_diff($required_checks, array_keys( array_filter($check_results) ));*/ + + foreach ($check_titles AS $key => $title) { + if ( substr($key, 0, 3) == 'sep' ) { + $check_result = ''; + } + else { + $check_result = $check_results[$key] ? '[PASSED]' : '[FAILED]'; + } + + $output .= sprintf($error_tpl, $title, $check_result); + } + + $output .= sprintf($heading_tpl, 'Client-side requirements', 'text'); + $output .= sprintf($error_tpl, 'Cookies enabled', '[FAILED]'); + $output .= sprintf($error_tpl, 'JavaScript enabled', '[FAILED]'); + + $output .= ''; + $output .= ''; + + $output .= ""; + + echo $output; +?> Index: branches/5.2.x/core/units/page_revisions/page_revisions_config.php =================================================================== diff -u -N -r15056 -r15165 --- branches/5.2.x/core/units/page_revisions/page_revisions_config.php (.../page_revisions_config.php) (revision 15056) +++ branches/5.2.x/core/units/page_revisions/page_revisions_config.php (.../page_revisions_config.php) (revision 15165) @@ -1,93 +1,93 @@ - 'page-revision', - 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), - 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), - 'EventHandlerClass' => Array ('class' => 'PageRevisionEventHandler', 'file' => 'page_revision_eh.php', 'build_event' => 'OnBuild'), - 'TagProcessorClass' => Array ('class' => 'PageRevisionTagProcessor', 'file' => 'page_revision_tp.php', 'build_event' => 'OnBuild'), - 'AutoLoad' => true, - 'QueryString' => Array ( - 1 => 'id', - 2 => 'Page', - 3 => 'PerPage', - 4 => 'event', - 5 => 'mode', // needed? - ), - - 'IDField' => 'RevisionId', - 'ParentTableKey' => 'CategoryId', // linked field in master table - 'ForeignKey' => 'PageId', // linked field in subtable - 'ParentPrefix' => 'c', - 'AutoDelete' => true, - 'AutoClone' => true, - - 'TitleField' => 'RevisionNumber', - - 'TableName' => TABLE_PREFIX . 'PageRevisions', - - 'ListSQLs' => Array ( - '' => ' SELECT %1$s.* %2$s - FROM %1$s - LEFT JOIN ' . TABLE_PREFIX . '%3$sCategories c ON c.CategoryId = %1$s.PageId - LEFT JOIN ' . TABLE_PREFIX . 'Users created_by ON created_by.PortalUserId = %1$s.CreatedById' - ), - - 'SubItems' => Array ('content'), - - 'ListSortings' => Array ( - '' => Array ( - 'Sorting' => Array ('IsDraft' => 'desc', 'RevisionNumber' => 'desc'), - ) - ), - - 'CalculatedFields' => Array ( - '' => Array ( - 'CreatedBy' => 'created_by.Username', - 'IsLive' => 'IF(%1$s.RevisionNumber = c.LiveRevisionNumber, 1, 0)', - ), - ), - - 'Fields' => Array ( - 'RevisionId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), - 'PageId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), - 'RevisionNumber' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), - 'IsDraft' => Array ( - 'type' => 'int', - 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, - 'not_null' => 1, 'default' => 0 - ), - 'FromRevisionId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), - 'CreatedById' => Array ( - 'type' => 'int', - 'formatter' => 'kLEFTFormatter', 'options' => Array (USER_ROOT => 'root', USER_GUEST => 'Guest'), 'left_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Users WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Username', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!'), 'sample_value' => 'Guest', 'required' => 1, - 'default' => NULL - ), - 'CreatedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'), - 'AutoSavedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL), - 'Status' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Pending', 1 => 'la_opt_Published', 0 => 'la_opt_Declined'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2) - ), - - 'VirtualFields' => Array ( - 'CreatedBy' => Array ('type' => 'string', 'default' => ''), - 'IsLive' => Array ( - 'type' => 'int', - 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, - 'default' => 0, - ) - ), - ); + 'page-revision', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'PageRevisionEventHandler', 'file' => 'page_revision_eh.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'PageRevisionTagProcessor', 'file' => 'page_revision_tp.php', 'build_event' => 'OnBuild'), + 'AutoLoad' => true, + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + 5 => 'mode', // needed? + ), + + 'IDField' => 'RevisionId', + 'ParentTableKey' => 'CategoryId', // linked field in master table + 'ForeignKey' => 'PageId', // linked field in subtable + 'ParentPrefix' => 'c', + 'AutoDelete' => true, + 'AutoClone' => true, + + 'TitleField' => 'RevisionNumber', + + 'TableName' => TABLE_PREFIX . 'PageRevisions', + + 'ListSQLs' => Array ( + '' => ' SELECT %1$s.* %2$s + FROM %1$s + LEFT JOIN ' . TABLE_PREFIX . '%3$sCategories c ON c.CategoryId = %1$s.PageId + LEFT JOIN ' . TABLE_PREFIX . 'Users created_by ON created_by.PortalUserId = %1$s.CreatedById' + ), + + 'SubItems' => Array ('content'), + + 'ListSortings' => Array ( + '' => Array ( + 'Sorting' => Array ('IsDraft' => 'desc', 'RevisionNumber' => 'desc'), + ) + ), + + 'CalculatedFields' => Array ( + '' => Array ( + 'CreatedBy' => 'created_by.Username', + 'IsLive' => 'IF(%1$s.RevisionNumber = c.LiveRevisionNumber, 1, 0)', + ), + ), + + 'Fields' => Array ( + 'RevisionId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'PageId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'RevisionNumber' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'IsDraft' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0 + ), + 'FromRevisionId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'CreatedById' => Array ( + 'type' => 'int', + 'formatter' => 'kLEFTFormatter', 'options' => Array (USER_ROOT => 'root', USER_GUEST => 'Guest'), 'left_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Users WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Username', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!'), 'sample_value' => 'Guest', 'required' => 1, + 'default' => NULL + ), + 'CreatedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'), + 'AutoSavedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL), + 'Status' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Pending', 1 => 'la_opt_Published', 0 => 'la_opt_Declined'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2) + ), + + 'VirtualFields' => Array ( + 'CreatedBy' => Array ('type' => 'string', 'default' => ''), + 'IsLive' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'default' => 0, + ) + ), + ); Index: branches/5.2.x/core/units/promo_blocks/promo_blocks_config.php =================================================================== diff -u -N -r14929 -r15165 --- branches/5.2.x/core/units/promo_blocks/promo_blocks_config.php (.../promo_blocks_config.php) (revision 14929) +++ branches/5.2.x/core/units/promo_blocks/promo_blocks_config.php (.../promo_blocks_config.php) (revision 15165) @@ -1,139 +1,139 @@ - 'promo-block', - 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), - 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), - 'EventHandlerClass' => Array ('class' => 'PromoBlockEventHandler', 'file' => 'promo_block_eh.php', 'build_event' => 'OnBuild'), - 'TagProcessorClass' => Array ('class' => 'PromoBlockTagProcessor', 'file' => 'promo_block_tp.php', 'build_event' => 'OnBuild'), - - 'AutoLoad' => true, - - 'QueryString' => Array ( - 1 => 'id', - 2 => 'Page', - 3 => 'PerPage', - 4 => 'event', - 5 => 'mode', - ), - - 'IDField' => 'BlockId', - - 'TableName' => TABLE_PREFIX . 'PromoBlocks', - - 'TitleField' => 'Title', - - 'TitlePresets' => Array ( - 'default' => Array ( - 'new_status_labels' => Array ('promo-block' => '!la_title_AddingPromoBlock!'), - 'edit_status_labels' => Array ('promo-block' => '!la_title_EditingPromoBlock!'), - ), - - 'promo_block_list' => Array ('prefixes' => Array ('promo-block-group', 'promo-block_List'), 'format' => "!la_tab_PromoBlocks! - #promo-block-group_titlefield# (#promo-block_recordcount#)"), - 'promo_block_edit' => Array ('prefixes' => Array ('promo-block'), 'format' => "#promo-block_status# '#promo-block_titlefield#'"), - ), - - 'PermSection' => Array('main' => 'in-portal:promo_block_groups'), - - 'CalculatedFields' => Array ( - '' => Array ( - 'ConversionPercent' => 'IF(%1$s.NumberOfViews > 0, NumberOfClicks / NumberOfViews * 100, NULL)', - ), - ), - - 'ListSQLs' => Array ( - '' => ' SELECT %1$s.* %2$s FROM %1$s', - ), - - 'ListSortings' => Array ( - '' => Array ( - 'Sorting' => Array ('Priority' => 'desc'), - ) - ), - - 'Fields' => Array ( - 'BlockId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), - 'PromoBlockGroupId' => Array ( - 'type' => 'int', - 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'PromoBlockGroups ORDER BY Title', 'option_title_field' => 'Title', 'option_key_field' => 'PromoBlockGroupId', - 'not_null' => 1, 'required' => 1, 'default' => 0, - ), - 'Title' => Array ( - 'type' => 'string', 'max_len' => 50, - 'not_null' => 1, 'required' => 1, 'default' => '', - ), - 'Status' => Array ( - 'type' => 'int', - 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Enabled', 0 => 'la_Disabled'), 'use_phrases' => 1, - 'not_null' => 1, 'default' => 1, - ), - 'Priority' => Array( - 'type' => 'int', - 'formatter' => 'kOptionsFormatter', 'options' => Array (), - 'not_null' => 1, 'required' => 1, 'default' => 0 - ), - 'Sticky' => Array ( - 'type' => 'int', - 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, - 'not_null' => 1, 'default' => 0, - ), - 'CSSClassName' => Array( - 'type' => 'string', - 'formatter' => 'kOptionsFormatter', - 'options' => Array('promo-orange' => 'Orange', 'promo-green' => 'Green', 'promo-blue' => 'Blue'), - 'not_null' => 1, 'default' => '', - ), - 'LinkType' => Array ( - 'type' => 'int', - 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_opt_Internal', 2 => 'la_opt_External'), 'use_phrases' => 1, - 'not_null' => 1, 'required' => 1, 'default' => 0, - ), - 'CategoryId' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'default' => NULL), - 'ExternalLink' => Array('type' => 'string', 'not_null' => 1, 'default' => ''), - 'OpenInNewWindow' => Array ( - 'type' => 'int', - 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, - 'not_null' => 1, 'default' => 0 - ), - 'ScheduleFromDate' => Array ( - 'type' => 'int', - 'formatter' => 'kDateFormatter', 'time_format' => '', 'input_time_format' => '', - 'error_msgs' => Array ('wrong_date_interval' => '!la_ToDateMustBeGreaterThanFromDate!'), - 'default' => null, - ), - 'ScheduleToDate' => Array ( - 'type' => 'int', - 'formatter' => 'kDateFormatter', 'time_format' => '', 'input_time_format' => '', - 'error_field' => 'ScheduleFromDate', - 'default' => null, - ), - 'NumberOfClicks' => Array ('type' => 'int', 'default' => 0, 'not_null' => 1), - 'NumberOfViews' => Array ('type' => 'int', 'default' => 0, 'not_null' => 1), - 'Html' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'using_fck' => 1, 'default' => null), - ), - - 'VirtualFields' => Array( - 'ConversionPercent' => Array('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.0f', 'default' => NULL), - ), - - 'Grids' => Array ( - 'Default' => Array ( - 'Fields' => Array ( - 'BlockId' => Array ('title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter'), - 'Title' => Array ('filter_block' => 'grid_like_filter'), - 'Status' => Array ('filter_block' => 'grid_options_filter'), - 'Priority' => Array ('title' => 'column:la_fld_Order', 'filter_block' => 'grid_range_filter'), - 'Sticky' => Array ('filter_block' => 'grid_options_filter'), - 'CSSClassName' => Array ('filter_block' => 'grid_options_filter'), - 'LinkType' => Array ('filter_block' => 'grid_options_filter'), - 'CategoryId' => Array ('title' => 'column:la_fld_Category', 'filter_block' => 'grid_options_filter'), - 'ExternalLink' => Array ('filter_block' => 'grid_like_filter'), - 'ScheduleFromDate' => Array ('title' => 'la_col_ScheduleFromDate', 'filter_block' => 'grid_date_range_filter'), - 'ScheduleToDate' => Array ('title' => 'la_col_ScheduleToDate', 'filter_block' => 'grid_date_range_filter'), - 'NumberOfClicks' => Array ('filter_block' => 'grid_range_filter'), - 'NumberOfViews' => Array ('filter_block' => 'grid_range_filter'), - 'ConversionPercent' => Array ('filter_block' => 'grid_range_filter'), - ), - ), - ), -); + 'promo-block', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'PromoBlockEventHandler', 'file' => 'promo_block_eh.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'PromoBlockTagProcessor', 'file' => 'promo_block_tp.php', 'build_event' => 'OnBuild'), + + 'AutoLoad' => true, + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + 5 => 'mode', + ), + + 'IDField' => 'BlockId', + + 'TableName' => TABLE_PREFIX . 'PromoBlocks', + + 'TitleField' => 'Title', + + 'TitlePresets' => Array ( + 'default' => Array ( + 'new_status_labels' => Array ('promo-block' => '!la_title_AddingPromoBlock!'), + 'edit_status_labels' => Array ('promo-block' => '!la_title_EditingPromoBlock!'), + ), + + 'promo_block_list' => Array ('prefixes' => Array ('promo-block-group', 'promo-block_List'), 'format' => "!la_tab_PromoBlocks! - #promo-block-group_titlefield# (#promo-block_recordcount#)"), + 'promo_block_edit' => Array ('prefixes' => Array ('promo-block'), 'format' => "#promo-block_status# '#promo-block_titlefield#'"), + ), + + 'PermSection' => Array('main' => 'in-portal:promo_block_groups'), + + 'CalculatedFields' => Array ( + '' => Array ( + 'ConversionPercent' => 'IF(%1$s.NumberOfViews > 0, NumberOfClicks / NumberOfViews * 100, NULL)', + ), + ), + + 'ListSQLs' => Array ( + '' => ' SELECT %1$s.* %2$s FROM %1$s', + ), + + 'ListSortings' => Array ( + '' => Array ( + 'Sorting' => Array ('Priority' => 'desc'), + ) + ), + + 'Fields' => Array ( + 'BlockId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'PromoBlockGroupId' => Array ( + 'type' => 'int', + 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'PromoBlockGroups ORDER BY Title', 'option_title_field' => 'Title', 'option_key_field' => 'PromoBlockGroupId', + 'not_null' => 1, 'required' => 1, 'default' => 0, + ), + 'Title' => Array ( + 'type' => 'string', 'max_len' => 50, + 'not_null' => 1, 'required' => 1, 'default' => '', + ), + 'Status' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Enabled', 0 => 'la_Disabled'), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 1, + ), + 'Priority' => Array( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (), + 'not_null' => 1, 'required' => 1, 'default' => 0 + ), + 'Sticky' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + 'CSSClassName' => Array( + 'type' => 'string', + 'formatter' => 'kOptionsFormatter', + 'options' => Array('promo-orange' => 'Orange', 'promo-green' => 'Green', 'promo-blue' => 'Blue'), + 'not_null' => 1, 'default' => '', + ), + 'LinkType' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_opt_Internal', 2 => 'la_opt_External'), 'use_phrases' => 1, + 'not_null' => 1, 'required' => 1, 'default' => 0, + ), + 'CategoryId' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'default' => NULL), + 'ExternalLink' => Array('type' => 'string', 'not_null' => 1, 'default' => ''), + 'OpenInNewWindow' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0 + ), + 'ScheduleFromDate' => Array ( + 'type' => 'int', + 'formatter' => 'kDateFormatter', 'time_format' => '', 'input_time_format' => '', + 'error_msgs' => Array ('wrong_date_interval' => '!la_ToDateMustBeGreaterThanFromDate!'), + 'default' => null, + ), + 'ScheduleToDate' => Array ( + 'type' => 'int', + 'formatter' => 'kDateFormatter', 'time_format' => '', 'input_time_format' => '', + 'error_field' => 'ScheduleFromDate', + 'default' => null, + ), + 'NumberOfClicks' => Array ('type' => 'int', 'default' => 0, 'not_null' => 1), + 'NumberOfViews' => Array ('type' => 'int', 'default' => 0, 'not_null' => 1), + 'Html' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'using_fck' => 1, 'default' => null), + ), + + 'VirtualFields' => Array( + 'ConversionPercent' => Array('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.0f', 'default' => NULL), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Fields' => Array ( + 'BlockId' => Array ('title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter'), + 'Title' => Array ('filter_block' => 'grid_like_filter'), + 'Status' => Array ('filter_block' => 'grid_options_filter'), + 'Priority' => Array ('title' => 'column:la_fld_Order', 'filter_block' => 'grid_range_filter'), + 'Sticky' => Array ('filter_block' => 'grid_options_filter'), + 'CSSClassName' => Array ('filter_block' => 'grid_options_filter'), + 'LinkType' => Array ('filter_block' => 'grid_options_filter'), + 'CategoryId' => Array ('title' => 'column:la_fld_Category', 'filter_block' => 'grid_options_filter'), + 'ExternalLink' => Array ('filter_block' => 'grid_like_filter'), + 'ScheduleFromDate' => Array ('title' => 'la_col_ScheduleFromDate', 'filter_block' => 'grid_date_range_filter'), + 'ScheduleToDate' => Array ('title' => 'la_col_ScheduleToDate', 'filter_block' => 'grid_date_range_filter'), + 'NumberOfClicks' => Array ('filter_block' => 'grid_range_filter'), + 'NumberOfViews' => Array ('filter_block' => 'grid_range_filter'), + 'ConversionPercent' => Array ('filter_block' => 'grid_range_filter'), + ), + ), + ), +); Index: branches/5.2.x/core/units/helpers/page_helper.php =================================================================== diff -u -N -r15137 -r15165 --- branches/5.2.x/core/units/helpers/page_helper.php (.../page_helper.php) (revision 15137) +++ branches/5.2.x/core/units/helpers/page_helper.php (.../page_helper.php) (revision 15165) @@ -1,315 +1,315 @@ -getHistoryPermissionAndUser($page_id); - - $where_clause = Array ( - 'pr.PageId = ' . $page_id, - 'pr.CreatedById <> ' . $user_id, - 'pr.IsDraft = 1', - ); - - $sql = 'SELECT CASE pr.CreatedById WHEN ' . USER_ROOT . ' THEN "root" WHEN ' . USER_GUEST . ' THEN "Guest" ELSE u.Username END - FROM ' . $this->Application->getUnitOption('page-revision', 'TableName') . ' pr - LEFT JOIN ' . TABLE_PREFIX . 'Users u ON u.PortalUserId = pr.CreatedById - WHERE (' . implode(') AND (', $where_clause) . ')'; - $users = $this->Conn->GetCol($sql); - - $page_revisions = Array (); - - if ( $history_permission ) { - $tag_params = Array ('per_page' => -1, 'skip_parent_filter' => 1, 'requery' => 1, 'page_id' => $page_id); - - $revisions = $this->Application->recallObject('page-revision.list', 'page-revision_List', $tag_params); - /* @var $revisions kDBList */ - - $revisions->Query(); - $revisions->GoFirst(); - - $status_options = $revisions->GetFieldOptions('Status'); - $draft_label = $this->Application->Phrase('la_Draft', false, true); - $title_label = $this->Application->Phrase('la_RevisionNumber', false, true); - $by_label = $this->Application->Phrase('la_By', false, true); - - while ( !$revisions->EOL() ) { - $status = $revisions->GetDBField('Status'); - $status_label = $this->Application->Phrase($status_options['options'][$status], false, true); - - $page_revisions[ 'r' . $revisions->GetDBField('RevisionNumber') ] = Array ( - 'title' => $revisions->GetDBField('IsDraft') ? $draft_label : sprintf($title_label, $revisions->GetDBField('RevisionNumber')), - 'status' => $status, - 'status_label' => mb_strtolower($status_label), - 'datetime' => $revisions->GetField('CreatedOn'), - 'author' => $by_label . ': ' . $revisions->GetField('CreatedById'), - 'draft' => (int)$revisions->GetDBField('IsDraft'), - ); - - $revisions->GoNext(); - } - } - - $current_revision = $this->Application->recallObject('page-revision.current'); - /* @var $current_revision kDBItem */ - - $revision_status = $current_revision->GetDBField('Status'); - $status_options = $current_revision->GetFieldOptions('Status'); - $status_label = $this->Application->Phrase($status_options['options'][$revision_status], false, true); - - $revision_phase = $current_revision->GetDBField('IsDraft') ? 'la_title_EditingDraft' : 'la_title_ViewingRevision'; - $revision_title = sprintf($this->Application->Phrase($revision_phase, false, true), $current_revision->GetDBField('RevisionNumber'), mb_strtolower($status_label)); - $current_revision_info = Array ('title' => $revision_title, 'status' => $revision_status, 'saved' => ''); - - $autosave_time = $current_revision->GetDBField('AutoSavedOn'); - - if ( $autosave_time ) { - $phrase = $this->Application->Phrase($current_revision->GetDBField('IsDraft') ? 'la_DraftSavedAt' : 'la_SavedAt', false, true); - $current_revision_info['saved'] = sprintf($phrase, $current_revision->GetField('AutoSavedOn_time') . ' (' . $this->getAgoTime($autosave_time) . ')'); - } - - $currently_editing = $this->getPluralPhrase( - count($users), - Array ( - 'phrase1' => 'la_PageCurrentlyEditing1', - 'phrase2' => 'la_PageCurrentlyEditing2', - 'phrase5' => 'la_PageCurrentlyEditing5', - ), - false, true - ); - - $currently_editing = sprintf($currently_editing, implode(', ', $users)); - - return Array ('current_revision' => $current_revision_info, 'editors' => $users, 'editors_warning' => $currently_editing, 'revisions' => $page_revisions); - } - - /** - * Returns time passed between 2 given dates in "X minutes Y seconds ago" format - * - * @param int $from_date - * @param int $to_date - * @return string - */ - function getAgoTime($from_date, $to_date = null, $max_levels = 1) - { - $blocks = Array ( - Array ('name' => 'year', 'amount' => 60*60*24*365), - Array ('name' => 'month' ,'amount' => 60*60*24*31), - Array ('name' => 'week', 'amount' => 60*60*24*7), - Array ('name' => 'day', 'amount' => 60*60*24), - Array ('name' => 'hour', 'amount' => 60*60), - Array ('name' => 'minute', 'amount' => 60), - Array ('name' => 'second', 'amount' => 1), - ); - - if ( !isset($to_date) ) { - $to_date = adodb_mktime(); - } - - $diff = abs($to_date - $from_date); - - if ( $diff == 0 ) { - return 'now'; - } - - $current_level = 1; - $result = Array (); - - foreach ($blocks as $block) { - if ($current_level > $max_levels) { - break; - } - - if ( $diff / $block['amount'] >= 1 ) { - $amount = floor($diff / $block['amount']); - $plural = $amount > 1 ? 's' : ''; - - $result[] = $amount . ' ' . $block['name'] . $plural; - $diff -= $amount * $block['amount']; - $current_level++; - } - } - - return implode(' ', $result) . ' ago'; - } - - /** - * Returns where clause for loading correct revision for a given page - * - * @param int $page_id - * @param int $live_revision_number - * @param string $table_name - * @return string - */ - function getRevsionWhereClause($page_id, $live_revision_number, $table_name = '') - { - $revision = (int)$this->Application->GetVar('revision'); - list ($user_id, $has_permission) = $this->getHistoryPermissionAndUser($page_id); - - if ( $has_permission && $revision ) { - $revision_clause = $table_name . 'RevisionNumber = ' . $revision . ' AND ' . $table_name . 'IsDraft = 0'; - } - else { - $editing_mode = $this->Application->GetVar('editing_mode'); // not in a EDITING_MODE constant, while in admin console - $revision_clause = $table_name . 'RevisionNumber = ' . $live_revision_number . ' AND ' . $table_name . 'IsDraft = 0'; - - if ( $this->Application->GetVar('preview') || $editing_mode == EDITING_MODE_CONTENT ) { - $revision_clause = '(' . $table_name . 'CreatedById = ' . $user_id . ' AND ' . $table_name . 'IsDraft = 1) OR (' . $revision_clause . ')'; - } - } - - return $revision_clause; - } - - /** - * Returns current admin user id (even, when called from front-end) and it's revision history view permission - * - * @param int $page_id - * @return Array - */ - function getHistoryPermissionAndUser($page_id) - { - $user_id = (int)$this->Application->RecallVar($this->Application->isAdmin ? 'user_id' : 'admin_user_id'); - $history_permission = $this->Application->CheckAdminPermission('CATEGORY.REVISION.HISTORY.VIEW', 0, $page_id); - - return Array ($user_id, $history_permission); - } - - /** - * Creates new content block in every revision that misses it. Plus creates first page revision - * - * @param int $page_id - * @param int $num - */ - function createNewContentBlock($page_id, $num) - { - $sql = 'SELECT pc.PageContentId, pr.RevisionId - FROM ' . TABLE_PREFIX . 'PageRevisions pr - LEFT JOIN ' . TABLE_PREFIX . 'PageContent pc ON pc.RevisionId = pr.RevisionId AND pc.ContentNum = ' . $num . ' - WHERE pr.PageId = ' . $page_id; - $revisions = $this->Conn->GetCol($sql, 'RevisionId'); - - if ( !$revisions ) { - // no revisions for a page -> create a live revision - $revision = $this->Application->recallObject('page-revision.live', null, Array ('skip_autoload' => true)); - /* @var $revision kDBItem */ - - $revision->SetDBField('PageId', $page_id); - $revision->SetDBField('RevisionNumber', 1); - $revision->SetDBField('Status', STATUS_ACTIVE); - $revision->Create(); - - $revisions[ $revision->GetID() ] = NULL; - } - - $content_block = $this->Application->recallObject('content.new', null, Array ('skip_autoload' => true)); - /* @var $content_block kDBItem */ - - $content_block->SetDBField('PageId', $page_id); - $content_block->SetDBField('ContentNum', $num); - - foreach ($revisions as $revision_id => $content_block_id) { - if ( is_numeric($content_block_id) ) { - continue; - } - - $content_block->SetDBField('RevisionId', $revision_id); - $content_block->Create(); - } - } - - /** - * Loads content block by it's number - * - * @param kDBItem $content_block - * @param CategoriesItem $page - * @param int $num - * - * @return bool - */ - function loadContentBlock(&$content_block, &$page, $num) - { - $page_id = $page->GetID(); - - if ( !EDITING_MODE && !$this->Application->GetVar('preview') ) { - $revision_clause = 'pr.RevisionNumber = ' . $page->GetDBField('LiveRevisionNumber') . ' AND pr.IsDraft = 0'; - } - else { - $revision_clause = $this->getRevsionWhereClause($page_id, $page->GetDBField('LiveRevisionNumber'), 'pr.'); - } - - - $sql = $content_block->GetSelectSQL() . ' - WHERE (' . $content_block->TableName . '.PageId = ' . $page_id . ') AND (' . $content_block->TableName . '.ContentNum = ' . $num . ') AND (' . $revision_clause . ') - ORDER BY pr.IsDraft DESC, pr.RevisionNumber DESC'; - $content_data = $this->Conn->GetRow($sql); - - $content_block->LoadFromHash($content_data); - - return $content_block->isLoaded(); - } - - /** - * Returns phrase based on given number - * - * @param int $number - * @param Array $forms - * @return string - */ - function getPluralPhrase($number, $forms, $allow_editing = true, $use_admin = false) - { - // normalize given forms - if ( !array_key_exists('phrase5', $forms) ) { - $forms['phrase5'] = $forms['phrase2']; - } - - $phrase_type = $this->getPluralPhraseType($number); - - return $this->Application->Phrase( $forms['phrase' . $phrase_type], $allow_editing, $use_admin ); - } - - /** - * Returns phrase type based on given number - * - * @param int $number - * @return int - */ - function getPluralPhraseType($number) - { - $last_digit = substr($number, -1); - $last_but_one_digit = strlen($number) > 1 ? substr($number, -2, 1) : false; - $phrase_type = '5'; - - if ($last_but_one_digit != 1) { - if ($last_digit == 1) { - $phrase_type = '1'; - } - elseif ($last_digit >= 2 && $last_digit <= 4) { - $phrase_type = '2'; - } - } - - return $phrase_type; - } -} +getHistoryPermissionAndUser($page_id); + + $where_clause = Array ( + 'pr.PageId = ' . $page_id, + 'pr.CreatedById <> ' . $user_id, + 'pr.IsDraft = 1', + ); + + $sql = 'SELECT CASE pr.CreatedById WHEN ' . USER_ROOT . ' THEN "root" WHEN ' . USER_GUEST . ' THEN "Guest" ELSE u.Username END + FROM ' . $this->Application->getUnitOption('page-revision', 'TableName') . ' pr + LEFT JOIN ' . TABLE_PREFIX . 'Users u ON u.PortalUserId = pr.CreatedById + WHERE (' . implode(') AND (', $where_clause) . ')'; + $users = $this->Conn->GetCol($sql); + + $page_revisions = Array (); + + if ( $history_permission ) { + $tag_params = Array ('per_page' => -1, 'skip_parent_filter' => 1, 'requery' => 1, 'page_id' => $page_id); + + $revisions = $this->Application->recallObject('page-revision.list', 'page-revision_List', $tag_params); + /* @var $revisions kDBList */ + + $revisions->Query(); + $revisions->GoFirst(); + + $status_options = $revisions->GetFieldOptions('Status'); + $draft_label = $this->Application->Phrase('la_Draft', false, true); + $title_label = $this->Application->Phrase('la_RevisionNumber', false, true); + $by_label = $this->Application->Phrase('la_By', false, true); + + while ( !$revisions->EOL() ) { + $status = $revisions->GetDBField('Status'); + $status_label = $this->Application->Phrase($status_options['options'][$status], false, true); + + $page_revisions[ 'r' . $revisions->GetDBField('RevisionNumber') ] = Array ( + 'title' => $revisions->GetDBField('IsDraft') ? $draft_label : sprintf($title_label, $revisions->GetDBField('RevisionNumber')), + 'status' => $status, + 'status_label' => mb_strtolower($status_label), + 'datetime' => $revisions->GetField('CreatedOn'), + 'author' => $by_label . ': ' . $revisions->GetField('CreatedById'), + 'draft' => (int)$revisions->GetDBField('IsDraft'), + ); + + $revisions->GoNext(); + } + } + + $current_revision = $this->Application->recallObject('page-revision.current'); + /* @var $current_revision kDBItem */ + + $revision_status = $current_revision->GetDBField('Status'); + $status_options = $current_revision->GetFieldOptions('Status'); + $status_label = $this->Application->Phrase($status_options['options'][$revision_status], false, true); + + $revision_phase = $current_revision->GetDBField('IsDraft') ? 'la_title_EditingDraft' : 'la_title_ViewingRevision'; + $revision_title = sprintf($this->Application->Phrase($revision_phase, false, true), $current_revision->GetDBField('RevisionNumber'), mb_strtolower($status_label)); + $current_revision_info = Array ('title' => $revision_title, 'status' => $revision_status, 'saved' => ''); + + $autosave_time = $current_revision->GetDBField('AutoSavedOn'); + + if ( $autosave_time ) { + $phrase = $this->Application->Phrase($current_revision->GetDBField('IsDraft') ? 'la_DraftSavedAt' : 'la_SavedAt', false, true); + $current_revision_info['saved'] = sprintf($phrase, $current_revision->GetField('AutoSavedOn_time') . ' (' . $this->getAgoTime($autosave_time) . ')'); + } + + $currently_editing = $this->getPluralPhrase( + count($users), + Array ( + 'phrase1' => 'la_PageCurrentlyEditing1', + 'phrase2' => 'la_PageCurrentlyEditing2', + 'phrase5' => 'la_PageCurrentlyEditing5', + ), + false, true + ); + + $currently_editing = sprintf($currently_editing, implode(', ', $users)); + + return Array ('current_revision' => $current_revision_info, 'editors' => $users, 'editors_warning' => $currently_editing, 'revisions' => $page_revisions); + } + + /** + * Returns time passed between 2 given dates in "X minutes Y seconds ago" format + * + * @param int $from_date + * @param int $to_date + * @return string + */ + function getAgoTime($from_date, $to_date = null, $max_levels = 1) + { + $blocks = Array ( + Array ('name' => 'year', 'amount' => 60*60*24*365), + Array ('name' => 'month' ,'amount' => 60*60*24*31), + Array ('name' => 'week', 'amount' => 60*60*24*7), + Array ('name' => 'day', 'amount' => 60*60*24), + Array ('name' => 'hour', 'amount' => 60*60), + Array ('name' => 'minute', 'amount' => 60), + Array ('name' => 'second', 'amount' => 1), + ); + + if ( !isset($to_date) ) { + $to_date = adodb_mktime(); + } + + $diff = abs($to_date - $from_date); + + if ( $diff == 0 ) { + return 'now'; + } + + $current_level = 1; + $result = Array (); + + foreach ($blocks as $block) { + if ($current_level > $max_levels) { + break; + } + + if ( $diff / $block['amount'] >= 1 ) { + $amount = floor($diff / $block['amount']); + $plural = $amount > 1 ? 's' : ''; + + $result[] = $amount . ' ' . $block['name'] . $plural; + $diff -= $amount * $block['amount']; + $current_level++; + } + } + + return implode(' ', $result) . ' ago'; + } + + /** + * Returns where clause for loading correct revision for a given page + * + * @param int $page_id + * @param int $live_revision_number + * @param string $table_name + * @return string + */ + function getRevsionWhereClause($page_id, $live_revision_number, $table_name = '') + { + $revision = (int)$this->Application->GetVar('revision'); + list ($user_id, $has_permission) = $this->getHistoryPermissionAndUser($page_id); + + if ( $has_permission && $revision ) { + $revision_clause = $table_name . 'RevisionNumber = ' . $revision . ' AND ' . $table_name . 'IsDraft = 0'; + } + else { + $editing_mode = $this->Application->GetVar('editing_mode'); // not in a EDITING_MODE constant, while in admin console + $revision_clause = $table_name . 'RevisionNumber = ' . $live_revision_number . ' AND ' . $table_name . 'IsDraft = 0'; + + if ( $this->Application->GetVar('preview') || $editing_mode == EDITING_MODE_CONTENT ) { + $revision_clause = '(' . $table_name . 'CreatedById = ' . $user_id . ' AND ' . $table_name . 'IsDraft = 1) OR (' . $revision_clause . ')'; + } + } + + return $revision_clause; + } + + /** + * Returns current admin user id (even, when called from front-end) and it's revision history view permission + * + * @param int $page_id + * @return Array + */ + function getHistoryPermissionAndUser($page_id) + { + $user_id = (int)$this->Application->RecallVar($this->Application->isAdmin ? 'user_id' : 'admin_user_id'); + $history_permission = $this->Application->CheckAdminPermission('CATEGORY.REVISION.HISTORY.VIEW', 0, $page_id); + + return Array ($user_id, $history_permission); + } + + /** + * Creates new content block in every revision that misses it. Plus creates first page revision + * + * @param int $page_id + * @param int $num + */ + function createNewContentBlock($page_id, $num) + { + $sql = 'SELECT pc.PageContentId, pr.RevisionId + FROM ' . TABLE_PREFIX . 'PageRevisions pr + LEFT JOIN ' . TABLE_PREFIX . 'PageContent pc ON pc.RevisionId = pr.RevisionId AND pc.ContentNum = ' . $num . ' + WHERE pr.PageId = ' . $page_id; + $revisions = $this->Conn->GetCol($sql, 'RevisionId'); + + if ( !$revisions ) { + // no revisions for a page -> create a live revision + $revision = $this->Application->recallObject('page-revision.live', null, Array ('skip_autoload' => true)); + /* @var $revision kDBItem */ + + $revision->SetDBField('PageId', $page_id); + $revision->SetDBField('RevisionNumber', 1); + $revision->SetDBField('Status', STATUS_ACTIVE); + $revision->Create(); + + $revisions[ $revision->GetID() ] = NULL; + } + + $content_block = $this->Application->recallObject('content.new', null, Array ('skip_autoload' => true)); + /* @var $content_block kDBItem */ + + $content_block->SetDBField('PageId', $page_id); + $content_block->SetDBField('ContentNum', $num); + + foreach ($revisions as $revision_id => $content_block_id) { + if ( is_numeric($content_block_id) ) { + continue; + } + + $content_block->SetDBField('RevisionId', $revision_id); + $content_block->Create(); + } + } + + /** + * Loads content block by it's number + * + * @param kDBItem $content_block + * @param CategoriesItem $page + * @param int $num + * + * @return bool + */ + function loadContentBlock(&$content_block, &$page, $num) + { + $page_id = $page->GetID(); + + if ( !EDITING_MODE && !$this->Application->GetVar('preview') ) { + $revision_clause = 'pr.RevisionNumber = ' . $page->GetDBField('LiveRevisionNumber') . ' AND pr.IsDraft = 0'; + } + else { + $revision_clause = $this->getRevsionWhereClause($page_id, $page->GetDBField('LiveRevisionNumber'), 'pr.'); + } + + + $sql = $content_block->GetSelectSQL() . ' + WHERE (' . $content_block->TableName . '.PageId = ' . $page_id . ') AND (' . $content_block->TableName . '.ContentNum = ' . $num . ') AND (' . $revision_clause . ') + ORDER BY pr.IsDraft DESC, pr.RevisionNumber DESC'; + $content_data = $this->Conn->GetRow($sql); + + $content_block->LoadFromHash($content_data); + + return $content_block->isLoaded(); + } + + /** + * Returns phrase based on given number + * + * @param int $number + * @param Array $forms + * @return string + */ + function getPluralPhrase($number, $forms, $allow_editing = true, $use_admin = false) + { + // normalize given forms + if ( !array_key_exists('phrase5', $forms) ) { + $forms['phrase5'] = $forms['phrase2']; + } + + $phrase_type = $this->getPluralPhraseType($number); + + return $this->Application->Phrase( $forms['phrase' . $phrase_type], $allow_editing, $use_admin ); + } + + /** + * Returns phrase type based on given number + * + * @param int $number + * @return int + */ + function getPluralPhraseType($number) + { + $last_digit = substr($number, -1); + $last_but_one_digit = strlen($number) > 1 ? substr($number, -2, 1) : false; + $phrase_type = '5'; + + if ($last_but_one_digit != 1) { + if ($last_digit == 1) { + $phrase_type = '1'; + } + elseif ($last_digit >= 2 && $last_digit <= 4) { + $phrase_type = '2'; + } + } + + return $phrase_type; + } +} Index: branches/5.2.x/core/kernel/managers/plain_url_processor.php =================================================================== diff -u -N -r15137 -r15165 --- branches/5.2.x/core/kernel/managers/plain_url_processor.php (.../plain_url_processor.php) (revision 15137) +++ branches/5.2.x/core/kernel/managers/plain_url_processor.php (.../plain_url_processor.php) (revision 15165) @@ -1,295 +1,295 @@ - $this->manager->getTemplateName()); - } - - $vars = Array (); - $more_vars = strpos($env_var, '&'); - - if ( $more_vars !== false ) { - parse_str(substr($env_var, $more_vars + 1), $vars); - $env_var = substr($env_var, 0, $more_vars); - } - - // replace escaped ":" symbol not to explode by it - $env_var = str_replace('\:', '_&+$$+&_', $env_var); // replace escaped "=" with spec-chars :) - $parts = explode(':', $env_var); - - if ( !$this->Application->RewriteURLs() || ($this->Application->RewriteURLs() && $this->Application->GetVar('rewrite') != 'on') ) { - $vars = array_merge($vars, $this->extractSIDAndTemplate($parts)); - } - - if ( $parts ) { - $passed = Array (); - - foreach ($parts as $mixed_part) { - list ($passed[], $processed_vars) = $this->_parseEnvPart($mixed_part); - $vars = array_merge($vars, $processed_vars); - } - - $vars[$pass_name] = implode(',', array_unique($passed)); - } - - return $vars; - } - - /** - * Retrieves SessionID and current template from given ENV parts - * - * @param Array $parts - * @return array - * @access protected - */ - protected function extractSIDAndTemplate(&$parts) - { - $template = ''; - $vars = Array (); - - if ( preg_match('/^([\d]+|)-(.*)$/', $parts[0], $regs) ) { - // first "env" component matches "sid-template" format - // (will be false, when mod-rewrite url to home page is built) - $sid = $regs[1]; - $template = $regs[2]; - array_shift($parts); - - if ( $sid ) { - // Save Session ID - $this->Application->SetVar('sid', $sid); - $vars['sid'] = $sid; - } - } - - // Save Template Name - $vars['t'] = $this->manager->getTemplateName($template); - - return $vars; - } - - /** - * Converts environment part into variable array (based on query map for given prefix) - * - * @param string $mixed_part - * @return Array - * @access protected - */ - protected function _parseEnvPart($mixed_part) - { - // In-portal old style env conversion - adds '-' between prefix and first var - $mixed_part = str_replace('_&+$$+&_', ':', $mixed_part); - $mixed_part = preg_replace("/^([a-zA-Z]+)([0-9]+)-(.*)/", "$1-$2-$3", $mixed_part); - - // replace escaped "-" symbol not to explode by it - $escaped_part = str_replace('\-', '_&+$$+&_', $mixed_part); - $escaped_part = explode('-', $escaped_part); - - $mixed_part = Array(); - foreach ($escaped_part as $escaped_val) { - $mixed_part[] = str_replace('_&+$$+&_', '-', $escaped_val); - } - - $vars = Array (); - $prefix_special = array_shift($mixed_part); // l.pick, l - - $http_query = $this->Application->recallObject('HTTPQuery'); - /* @var $http_query kHTTPQuery */ - - $query_map = $http_query->discoverUnit($prefix_special); // from $_GET['env'] - - // if config is not defined for prefix in QueryString, then don't process it - if ($query_map) { - foreach ($query_map as $index => $var_name) { - // l_id, l_page, l_bla-bla-bla - $val = $mixed_part[$index - 1]; - if ($val == '') $val = false; - $vars[$prefix_special.'_'.$var_name] = $val; - } - } - - return Array ($prefix_special, $vars); - } - - /** - * Builds url - * - * @param string $t - * @param Array $params - * @param string $pass - * @param bool $pass_events - * @param bool $env_var - * @return string - * @access public - */ - public function build($t, $params, $pass='all', $pass_events = false, $env_var = true) - { - if ( $this->Application->GetVar('admin') || (array_key_exists('admin', $params) && $params['admin']) ) { - $params['admin'] = 1; - - if ( !array_key_exists('editing_mode', $params) ) { - $params['editing_mode'] = EDITING_MODE; - } - } - - $session = $this->Application->recallObject('Session'); - /* @var $session Session */ - - $ssl = isset($params['__SSL__']) ? $params['__SSL__'] : 0; - $sid = $session->NeedQueryString() && !$this->Application->RewriteURLs($ssl) ? $this->Application->GetSID() : ''; - - $ret = ''; - if ( $env_var ) { - $ret = ENV_VAR_NAME . '='; - } - - $ret .= $sid . '-'; // SID-TEMPLATE - - $encode = false; - if ( isset($params['__URLENCODE__']) ) { - $encode = $params['__URLENCODE__']; - unset($params['__URLENCODE__']); - } - - if ( isset($params['__SSL__']) ) { - unset($params['__SSL__']); - } - - $env_string = ''; - $category_id = isset($params['m_cat_id']) ? $params['m_cat_id'] : $this->Application->GetVar('m_cat_id'); - - $item_id = false; - $pass_info = $this->getPassInfo($pass); - - if ( $pass_info ) { - if ( $pass_info[0] == 'm' ) { - array_shift($pass_info); - } - - foreach ($pass_info as $pass_element) { - list($prefix) = explode('.', $pass_element); - $require_rewrite = $this->Application->findModule('Var', $prefix); - - if ( $require_rewrite ) { - $item_id = isset($params[$pass_element . '_id']) ? $params[$pass_element . '_id'] : $this->Application->GetVar($pass_element . '_id'); - } - - $env_string .= ':' . $this->BuildModuleEnv($pass_element, $params, $pass_events); - } - } - - if ( strtolower($t) == '__default__' ) { - if ( is_numeric($item_id) ) { - $this->manager->initRewrite(); - $t = $this->manager->rewrite->GetItemTemplate($category_id, $pass_element); // $pass_element should be the last processed element - // $t = $this->Application->getCategoryCache($category_id, 'item_templates'); - } - elseif ( $category_id ) { - $t = strtolower(preg_replace('/^Content\//i', '', $this->Application->getCategoryCache($category_id, 'filenames'))); - } - else { - $t = 'index'; - } - } - - $ret .= $t . ':' . $this->BuildModuleEnv('m', $params, $pass_events) . $env_string; - - unset($params['pass'], $params['opener'], $params['m_event']); - - if ( array_key_exists('escape', $params) && $params['escape'] ) { - $ret = addslashes($ret); - unset($params['escape']); - } - - if ( $params ) { - $params_str = ''; - $join_string = $encode ? '&' : '&'; - - foreach ($params as $param => $value) { - $params_str .= $join_string . $param . '=' . $value; - } - - $ret .= $params_str; - } - - if ( $encode ) { - $ret = str_replace('\\', '%5C', $ret); - } - - return $ret; - } - - /** - * Builds env part that corresponds prefix passed - * - * @param string $prefix_special item's prefix & [special] - * @param Array $params url params - * @param bool $pass_events - * @return string - * @access public - */ - public function BuildModuleEnv($prefix_special, &$params, $pass_events = false) - { - list($prefix) = explode('.', $prefix_special); - $query_vars = $this->Application->getUnitOption($prefix, 'QueryString', Array ()); - /* @var $query_vars Array */ - - //if pass events is off and event is not implicitly passed - if ( !$pass_events && !isset($params[$prefix_special . '_event']) ) { - $params[$prefix_special . '_event'] = ''; // remove event from url if requested - //otherwise it will use value from get_var - } - - if ( !$query_vars ) { - return ''; - } - - $tmp_string = Array (0 => $prefix_special); - foreach ($query_vars as $index => $var_name) { - //if value passed in params use it, otherwise use current from application - $var_name = $prefix_special . '_' . $var_name; - $tmp_string[$index] = isset($params[$var_name]) ? $params[$var_name] : $this->Application->GetVar($var_name); - - if ( isset($params[$var_name]) ) { - unset($params[$var_name]); - } - } - - $escaped = array (); - foreach ($tmp_string as $tmp_val) { - $escaped[] = str_replace(Array ('-', ':'), Array ('\-', '\:'), $tmp_val); - } - - $ret = implode('-', $escaped); - if ( $this->Application->getUnitOption($prefix, 'PortalStyleEnv') == true ) { - $ret = preg_replace('/^([a-zA-Z]+)-([0-9]+)-(.*)/', '\\1\\2-\\3', $ret); - } - - return $ret; - } + $this->manager->getTemplateName()); + } + + $vars = Array (); + $more_vars = strpos($env_var, '&'); + + if ( $more_vars !== false ) { + parse_str(substr($env_var, $more_vars + 1), $vars); + $env_var = substr($env_var, 0, $more_vars); + } + + // replace escaped ":" symbol not to explode by it + $env_var = str_replace('\:', '_&+$$+&_', $env_var); // replace escaped "=" with spec-chars :) + $parts = explode(':', $env_var); + + if ( !$this->Application->RewriteURLs() || ($this->Application->RewriteURLs() && $this->Application->GetVar('rewrite') != 'on') ) { + $vars = array_merge($vars, $this->extractSIDAndTemplate($parts)); + } + + if ( $parts ) { + $passed = Array (); + + foreach ($parts as $mixed_part) { + list ($passed[], $processed_vars) = $this->_parseEnvPart($mixed_part); + $vars = array_merge($vars, $processed_vars); + } + + $vars[$pass_name] = implode(',', array_unique($passed)); + } + + return $vars; + } + + /** + * Retrieves SessionID and current template from given ENV parts + * + * @param Array $parts + * @return array + * @access protected + */ + protected function extractSIDAndTemplate(&$parts) + { + $template = ''; + $vars = Array (); + + if ( preg_match('/^([\d]+|)-(.*)$/', $parts[0], $regs) ) { + // first "env" component matches "sid-template" format + // (will be false, when mod-rewrite url to home page is built) + $sid = $regs[1]; + $template = $regs[2]; + array_shift($parts); + + if ( $sid ) { + // Save Session ID + $this->Application->SetVar('sid', $sid); + $vars['sid'] = $sid; + } + } + + // Save Template Name + $vars['t'] = $this->manager->getTemplateName($template); + + return $vars; + } + + /** + * Converts environment part into variable array (based on query map for given prefix) + * + * @param string $mixed_part + * @return Array + * @access protected + */ + protected function _parseEnvPart($mixed_part) + { + // In-portal old style env conversion - adds '-' between prefix and first var + $mixed_part = str_replace('_&+$$+&_', ':', $mixed_part); + $mixed_part = preg_replace("/^([a-zA-Z]+)([0-9]+)-(.*)/", "$1-$2-$3", $mixed_part); + + // replace escaped "-" symbol not to explode by it + $escaped_part = str_replace('\-', '_&+$$+&_', $mixed_part); + $escaped_part = explode('-', $escaped_part); + + $mixed_part = Array(); + foreach ($escaped_part as $escaped_val) { + $mixed_part[] = str_replace('_&+$$+&_', '-', $escaped_val); + } + + $vars = Array (); + $prefix_special = array_shift($mixed_part); // l.pick, l + + $http_query = $this->Application->recallObject('HTTPQuery'); + /* @var $http_query kHTTPQuery */ + + $query_map = $http_query->discoverUnit($prefix_special); // from $_GET['env'] + + // if config is not defined for prefix in QueryString, then don't process it + if ($query_map) { + foreach ($query_map as $index => $var_name) { + // l_id, l_page, l_bla-bla-bla + $val = $mixed_part[$index - 1]; + if ($val == '') $val = false; + $vars[$prefix_special.'_'.$var_name] = $val; + } + } + + return Array ($prefix_special, $vars); + } + + /** + * Builds url + * + * @param string $t + * @param Array $params + * @param string $pass + * @param bool $pass_events + * @param bool $env_var + * @return string + * @access public + */ + public function build($t, $params, $pass='all', $pass_events = false, $env_var = true) + { + if ( $this->Application->GetVar('admin') || (array_key_exists('admin', $params) && $params['admin']) ) { + $params['admin'] = 1; + + if ( !array_key_exists('editing_mode', $params) ) { + $params['editing_mode'] = EDITING_MODE; + } + } + + $session = $this->Application->recallObject('Session'); + /* @var $session Session */ + + $ssl = isset($params['__SSL__']) ? $params['__SSL__'] : 0; + $sid = $session->NeedQueryString() && !$this->Application->RewriteURLs($ssl) ? $this->Application->GetSID() : ''; + + $ret = ''; + if ( $env_var ) { + $ret = ENV_VAR_NAME . '='; + } + + $ret .= $sid . '-'; // SID-TEMPLATE + + $encode = false; + if ( isset($params['__URLENCODE__']) ) { + $encode = $params['__URLENCODE__']; + unset($params['__URLENCODE__']); + } + + if ( isset($params['__SSL__']) ) { + unset($params['__SSL__']); + } + + $env_string = ''; + $category_id = isset($params['m_cat_id']) ? $params['m_cat_id'] : $this->Application->GetVar('m_cat_id'); + + $item_id = false; + $pass_info = $this->getPassInfo($pass); + + if ( $pass_info ) { + if ( $pass_info[0] == 'm' ) { + array_shift($pass_info); + } + + foreach ($pass_info as $pass_element) { + list($prefix) = explode('.', $pass_element); + $require_rewrite = $this->Application->findModule('Var', $prefix); + + if ( $require_rewrite ) { + $item_id = isset($params[$pass_element . '_id']) ? $params[$pass_element . '_id'] : $this->Application->GetVar($pass_element . '_id'); + } + + $env_string .= ':' . $this->BuildModuleEnv($pass_element, $params, $pass_events); + } + } + + if ( strtolower($t) == '__default__' ) { + if ( is_numeric($item_id) ) { + $this->manager->initRewrite(); + $t = $this->manager->rewrite->GetItemTemplate($category_id, $pass_element); // $pass_element should be the last processed element + // $t = $this->Application->getCategoryCache($category_id, 'item_templates'); + } + elseif ( $category_id ) { + $t = strtolower(preg_replace('/^Content\//i', '', $this->Application->getCategoryCache($category_id, 'filenames'))); + } + else { + $t = 'index'; + } + } + + $ret .= $t . ':' . $this->BuildModuleEnv('m', $params, $pass_events) . $env_string; + + unset($params['pass'], $params['opener'], $params['m_event']); + + if ( array_key_exists('escape', $params) && $params['escape'] ) { + $ret = addslashes($ret); + unset($params['escape']); + } + + if ( $params ) { + $params_str = ''; + $join_string = $encode ? '&' : '&'; + + foreach ($params as $param => $value) { + $params_str .= $join_string . $param . '=' . $value; + } + + $ret .= $params_str; + } + + if ( $encode ) { + $ret = str_replace('\\', '%5C', $ret); + } + + return $ret; + } + + /** + * Builds env part that corresponds prefix passed + * + * @param string $prefix_special item's prefix & [special] + * @param Array $params url params + * @param bool $pass_events + * @return string + * @access public + */ + public function BuildModuleEnv($prefix_special, &$params, $pass_events = false) + { + list($prefix) = explode('.', $prefix_special); + $query_vars = $this->Application->getUnitOption($prefix, 'QueryString', Array ()); + /* @var $query_vars Array */ + + //if pass events is off and event is not implicitly passed + if ( !$pass_events && !isset($params[$prefix_special . '_event']) ) { + $params[$prefix_special . '_event'] = ''; // remove event from url if requested + //otherwise it will use value from get_var + } + + if ( !$query_vars ) { + return ''; + } + + $tmp_string = Array (0 => $prefix_special); + foreach ($query_vars as $index => $var_name) { + //if value passed in params use it, otherwise use current from application + $var_name = $prefix_special . '_' . $var_name; + $tmp_string[$index] = isset($params[$var_name]) ? $params[$var_name] : $this->Application->GetVar($var_name); + + if ( isset($params[$var_name]) ) { + unset($params[$var_name]); + } + } + + $escaped = array (); + foreach ($tmp_string as $tmp_val) { + $escaped[] = str_replace(Array ('-', ':'), Array ('\-', '\:'), $tmp_val); + } + + $ret = implode('-', $escaped); + if ( $this->Application->getUnitOption($prefix, 'PortalStyleEnv') == true ) { + $ret = preg_replace('/^([a-zA-Z]+)-([0-9]+)-(.*)/', '\\1\\2-\\3', $ret); + } + + return $ret; + } } \ No newline at end of file Index: branches/5.2.x/core/admin_templates/permission_types/permission_type_edit.tpl =================================================================== diff -u -N -r14662 -r15165 --- branches/5.2.x/core/admin_templates/permission_types/permission_type_edit.tpl (.../permission_type_edit.tpl) (revision 14662) +++ branches/5.2.x/core/admin_templates/permission_types/permission_type_edit.tpl (.../permission_type_edit.tpl) (revision 15165) @@ -1,82 +1,82 @@ - - - - - - - - - - - - -
- -
- - - - -
- - - - - - - - - - - - - - - - - -
-
- - + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + + + + + + + + + + + + + + +
+
+ + Index: branches/5.2.x/core/units/promo_block_groups/promo_block_group_tp.php =================================================================== diff -u -N -r15152 -r15165 --- branches/5.2.x/core/units/promo_block_groups/promo_block_group_tp.php (.../promo_block_group_tp.php) (revision 15152) +++ branches/5.2.x/core/units/promo_block_groups/promo_block_group_tp.php (.../promo_block_group_tp.php) (revision 15165) @@ -1,6 +1,6 @@ getObject($params); - /* @var $object kDBItem */ - - $page_helper = $this->Application->recallObject('PageHelper'); - /* @var $page_helper PageHelper */ - - return $page_helper->getAgoTime( $object->GetDBField('AutoSavedOn') ); - } -} +getObject($params); + /* @var $object kDBItem */ + + $page_helper = $this->Application->recallObject('PageHelper'); + /* @var $page_helper PageHelper */ + + return $page_helper->getAgoTime( $object->GetDBField('AutoSavedOn') ); + } +} Index: branches/5.2.x/core/units/filters/filters_config.php =================================================================== diff -u -N -r15037 -r15165 --- branches/5.2.x/core/units/filters/filters_config.php (.../filters_config.php) (revision 15037) +++ branches/5.2.x/core/units/filters/filters_config.php (.../filters_config.php) (revision 15165) @@ -1,6 +1,6 @@ HTTPQuery = $this->Application->recallObject('HTTPQuery'); - - // domain based primary language - $this->primaryLanguageId = $this->Application->siteDomainField('PrimaryLanguageId'); - - if (!$this->primaryLanguageId) { - // when domain-based language not found -> use site-wide language - $this->primaryLanguageId = $this->Application->GetDefaultLanguageId(); - } - - // domain based primary theme - $this->primaryThemeId = $this->Application->siteDomainField('PrimaryThemeId'); - - if (!$this->primaryThemeId) { - // when domain-based theme not found -> use site-wide theme - $this->primaryThemeId = $this->Application->GetDefaultThemeId(true); - } - - $this->_initRewriteListeners(); - } - - /** - * Parses url - * - * @return void - */ - public function parseRewriteURL() - { - $url = $this->Application->GetVar('_mod_rw_url_'); - - if ($url) { - foreach ($this->_urlEndings as $url_ending) { - if (substr($url, strlen($url) - strlen($url_ending)) == $url_ending) { - $url = substr($url, 0, strlen($url) - strlen($url_ending)); - $default_ending = $this->Application->ConfigValue('ModRewriteUrlEnding'); - - // user manually typed url with different url ending -> redirect to same url with default url ending - if (($url_ending != $default_ending) && $this->Application->ConfigValue('ForceModRewriteUrlEnding')) { - $target_url = $this->Application->BaseURL() . $url . $default_ending; - $this->Application->Redirect('external:' . $target_url, Array ('response_code' => 301)); - } - - break; - } - } - } - - $cached = $this->_getCachedUrl($url); - - if ( $cached !== false ) { - $vars = $cached['vars']; - $passed = $cached['passed']; - } - else { - $vars = $this->parse($url); - $passed = $vars['pass']; // also used in bottom of this method - unset($vars['pass']); - - if ( !$this->_partsToParse ) { - // don't cache 404 Not Found - $this->_setCachedUrl($url, Array ('vars' => $vars, 'passed' => $passed)); - } - - if ( $this->Application->GetVarDirect('t', 'Post') ) { - // template from POST overrides template from URL. - $vars['t'] = $this->Application->GetVarDirect('t', 'Post'); - - if ( isset($vars['is_virtual']) && $vars['is_virtual'] ) { - $vars['m_cat_id'] = 0; // this is virtual template category (for Proj-CMS) - } - } - - unset($vars['is_virtual']); - } - - foreach ($vars as $name => $value) { - $this->HTTPQuery->Set($name, $value); - } - - $this->_initAll(); // also will use parsed language to load phrases from it - - $this->HTTPQuery->finalizeParsing($passed); - } - - /** - * Returns url parsing result from cache or false, when not yet parsed - * - * @param $url - * @return Array|bool - * @access protected - */ - protected function _getCachedUrl($url) - { - if (!$url) { - return false; - } - - $sql = 'SELECT * - FROM ' . TABLE_PREFIX . 'CachedUrls - WHERE Hash = ' . crc32($url) . ' AND DomainId = ' . (int)$this->Application->siteDomainField('DomainId'); - $data = $this->Conn->GetRow($sql); - - if ($data) { - $lifetime = (int)$data['LifeTime']; // in seconds - if (($lifetime > 0) && ($data['Cached'] + $lifetime < adodb_mktime())) { - // delete expired - $sql = 'DELETE FROM ' . TABLE_PREFIX . 'CachedUrls - WHERE UrlId = ' . $data['UrlId']; - $this->Conn->Query($sql); - - return false; - } - - return unserialize($data['ParsedVars']); - } - - return false; - } - - /** - * Caches url - * - * @param string $url - * @param Array $data - * @return void - * @access protected - */ - protected function _setCachedUrl($url, $data) - { - if (!$url) { - return ; - } - - $vars = $data['vars']; - $passed = $data['passed']; - sort($passed); - - // get expiration - if ($vars['m_cat_id'] > 0) { - $sql = 'SELECT PageExpiration - FROM ' . TABLE_PREFIX . 'Categories - WHERE CategoryId = ' . $vars['m_cat_id']; - $expiration = $this->Conn->GetOne($sql); - } - - // get prefixes - $prefixes = Array (); - $m_index = array_search('m', $passed); - - if ($m_index !== false) { - unset($passed[$m_index]); - - if ($vars['m_cat_id'] > 0) { - $prefixes[] = 'c:' . $vars['m_cat_id']; - } - - $prefixes[] = 'lang:' . $vars['m_lang']; - $prefixes[] = 'theme:' . $vars['m_theme']; - } - - foreach ($passed as $prefix) { - if (array_key_exists($prefix . '_id', $vars) && is_numeric($vars[$prefix . '_id'])) { - $prefixes[] = $prefix . ':' . $vars[$prefix . '_id']; - } - else { - $prefixes[] = $prefix; - } - } - - $fields_hash = Array ( - 'Url' => $url, - 'Hash' => crc32($url), - 'DomainId' => (int)$this->Application->siteDomainField('DomainId'), - 'Prefixes' => $prefixes ? '|' . implode('|', $prefixes) . '|' : '', - 'ParsedVars' => serialize($data), - 'Cached' => adodb_mktime(), - 'LifeTime' => isset($expiration) && is_numeric($expiration) ? $expiration : -1 - ); - - $this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'CachedUrls'); - } - - /** - * Loads all registered rewrite listeners, so they could be quickly accessed later - * - * @access protected - */ - protected function _initRewriteListeners() - { - static $init_done = false; - - if ($init_done || count($this->Application->RewriteListeners) == 0) { - // not initialized OR mod-rewrite url with missing config cache - return ; - } - - foreach ($this->Application->RewriteListeners as $prefix => $listener_data) { - foreach ($listener_data['listener'] as $index => $rewrite_listener) { - list ($listener_prefix, $listener_method) = explode(':', $rewrite_listener); - - // don't use temp variable, since it will swap objects in Factory in PHP5 - $this->rewriteListeners[$prefix][$index] = Array (); - $this->rewriteListeners[$prefix][$index][0] = $this->Application->recallObject($listener_prefix); - $this->rewriteListeners[$prefix][$index][1] = $listener_method; - } - } - - define('MOD_REWRITE_URL_ENDING', $this->Application->ConfigValue('ModRewriteUrlEnding')); - - $init_done = true; - } - - /** - * Parses given string into a set of variables (url in this case) - * - * @param string $string - * @param string $pass_name - * @return Array - * @access public - */ - public function parse($string, $pass_name = 'pass') - { - $vars = Array ($pass_name => Array ('m')); - $url_parts = $string ? explode('/', trim(mb_strtolower($string, 'UTF-8'), '/')) : Array (); - - $this->_partsToParse = $url_parts; - - if ( ($this->HTTPQuery->Get('rewrite') == 'on') || !$url_parts ) { - $this->_setDefaultValues($vars); - } - - if ( !$url_parts ) { - $this->_initAll(); - $vars['t'] = $this->Application->UrlManager->getTemplateName(); - - return $vars; - } - - $this->_parseLanguage($url_parts, $vars); - $this->_parseTheme($url_parts, $vars); - - // http://site-url///[_]/