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; + } +}