Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F803962
D11.id260.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Feb 26, 9:02 AM
Size
12 KB
Mime Type
text/x-diff
Expires
Thu, Feb 27, 9:02 AM (4 h, 36 m)
Engine
blob
Format
Raw Data
Handle
576682
Attached To
D11: INP-1313 - Add support for copying content blocks between themes
D11.id260.diff
View Options
Index: core/admin_templates/themes/themes_list.tpl
===================================================================
--- core/admin_templates/themes/themes_list.tpl
+++ core/admin_templates/themes/themes_list.tpl
@@ -7,6 +7,12 @@
<tr>
<td>
<script type="text/javascript">
+ function copy_from_theme($theme_id)
+ {
+ set_hidden_field('copy_from', $theme_id);
+ submit_event('theme','OnCopyData');
+ }
+
//do not rename - this function is used in default grid for double click!
function edit()
{
@@ -24,7 +30,20 @@
function() {
std_delete_items('theme')
} ) );
-
+ a_toolbar.AddButton( new ToolBarButton('copy', '<inp2:m_phrase label="la_ToolTip_CopyDataFrom" escape="1"/>',
+ function() {
+ themes_menu = menuMgr.createMenu(rs('copy_from_theme_menu'));
+ themes_menu.applyBorder(false, false, false, false);
+ themes_menu.dropShadow("none");
+ themes_menu.showIcon = true;
+
+ <inp2:m_DefineElement name="theme_elem">
+ themes_menu.addItem(rs('theme<inp2:Field name="ThemeId"/>'),'<inp2:Field name="Name" js_escape="1"/>','javascript:copy_from_theme(<inp2:Field name="ThemeId"/>);');
+ </inp2:m_DefineElement>
+ <inp2:theme.all_PrintList render_as="theme_elem" per_page="-1"/>
+ renderMenus();
+ nls_showMenu(rs('copy_from_theme_menu'), a_toolbar.GetButtonImage('copy'));
+ } ) );
a_toolbar.AddButton( new ToolBarSeparator('sep1') );
@@ -54,9 +73,21 @@
</tbody>
</table>
+<inp2:m_if check="m_Get" var="not_matched_theme_ids">
+ <inp2:m_RenderElement design="form_message">
+ <inp2:m_Phrase label="la_error_SomeOfThemesWerentMatched"/>
+ <inp2:m_DefineElement name="theme_item">
+ <li><inp2:Field name="Name"/></li>
+ </inp2:m_DefineElement>
+ <ul>
+ <inp2:theme.not-matched_PrintList render_as="theme_item" per_page="-1"/>
+ </ul>
+ </inp2:m_RenderElement>
+</inp2:m_if>
+
<inp2:m_RenderElement name="grid" PrefixSpecial="theme" IdField="ThemeId" grid="Default"/>
<script type="text/javascript">
- Grids['theme'].SetDependantToolbarButtons( new Array('edit', 'delete', 'setprimary') );
+ Grids['theme'].SetDependantToolbarButtons( new Array('edit', 'delete', 'setprimary', 'copy') );
</script>
-<inp2:m_include t="incs/footer"/>
\ No newline at end of file
+<inp2:m_include t="incs/footer"/>
Index: core/install/cache/class_structure.php
===================================================================
--- core/install/cache/class_structure.php
+++ core/install/cache/class_structure.php
@@ -36,6 +36,7 @@
'ConfigurationItem' => '/core/units/configuration/configuration.php',
'ConfigurationTagProcessor' => '/core/units/configuration/configuration_tag_processor.php',
'ConfigurationValidator' => '/core/units/configuration/configuration_validator.php',
+ 'ContentBlockCopier' => '/core/units/helpers/content_block_copier.php',
'ContentEventHandler' => '/core/units/content/content_eh.php',
'ContentTagProcessor' => '/core/units/content/content_tp.php',
'CoreUpgrades' => '/core/install/upgrades.php',
@@ -546,6 +547,13 @@
0 => 'kValidator',
),
),
+ 'ContentBlockCopier' => array(
+ 'type' => 1,
+ 'modifiers' => 0,
+ 'extends' => array(
+ 0 => 'kBase',
+ ),
+ ),
'ContentEventHandler' => array(
'type' => 1,
'modifiers' => 0,
Index: core/install/english.lang
===================================================================
--- core/install/english.lang
+++ core/install/english.lang
@@ -288,6 +288,7 @@
<PHRASE Label="la_error_RequiredColumnsMissing" Module="Core" Type="1">cmVxdWlyZWQgY29sdW1ucyBtaXNzaW5n</PHRASE>
<PHRASE Label="la_error_RootCategoriesDelete" Module="Core" Type="1">Um9vdCBzZWN0aW9uIG9mIHRoZSBtb2R1bGUocykgY2FuIG5vdCBiZSBkZWxldGVkIQ==</PHRASE>
<PHRASE Label="la_error_SelectItemToMove" Module="Core" Type="1">U2VsZWN0IGF0IGxlYXN0IG9uZSBpdGVtIHRvIG1vdmU=</PHRASE>
+ <PHRASE Label="la_error_SomeOfThemesWerentMatched" Module="Core" Type="1">U29tZSBvZiB0aGVtZXMgd2VyZW4ndCBtYXRjaGVk</PHRASE>
<PHRASE Label="la_error_TemplateFileMissing" Module="Core" Type="1">VGVtcGxhdGUgZmlsZSBpcyBtaXNzaW5n</PHRASE>
<PHRASE Label="la_error_TemporaryTableCopyingFailed" Module="Core" Type="1">Q29weWluZyBvcGVyYXRpb24gaW4gVGVtcG9yYXJ5IHRhYmxlcyBoYXMgZmFpbGVkLiBQbGVhc2UgY29udGFjdCB3ZWJzaXRlIGFkbWluaXN0cmF0b3Iu</PHRASE>
<PHRASE Label="la_error_unique" Module="Core" Type="1">UmVjb3JkIGlzIG5vdCB1bmlxdWU=</PHRASE>
@@ -1611,6 +1612,7 @@
<PHRASE Label="la_ToolTip_CloneUser" Module="Core" Type="1">Q2xvbmUgVXNlcnM=</PHRASE>
<PHRASE Label="la_ToolTip_close" Module="Core" Type="1">Q2xvc2U=</PHRASE>
<PHRASE Label="la_ToolTip_Copy" Module="Core" Type="1">Q29weQ==</PHRASE>
+ <PHRASE Label="la_ToolTip_CopyDataFrom" Module="Core" Type="1">Q29weSBEYXRhIEZyb20=</PHRASE>
<PHRASE Label="la_ToolTip_Cut" Module="Core" Type="1">Q3V0</PHRASE>
<PHRASE Label="la_ToolTip_Decline" Module="Core" Type="1">RGVjbGluZQ==</PHRASE>
<PHRASE Label="la_ToolTip_Delete" Module="Core" Type="1">RGVsZXRl</PHRASE>
Index: core/units/helpers/content_block_copier.php
===================================================================
--- /dev/null
+++ core/units/helpers/content_block_copier.php
@@ -0,0 +1,191 @@
+<?php
+/**
+* @version $Id$
+* @package In-Portal
+* @copyright Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+defined('FULL_PATH') or die('restricted access!');
+
+class ContentBlockCopier extends kBase
+{
+
+ /**
+ * Id of theme to copy from.
+ *
+ * @var integer
+ */
+ protected $sourceThemeId;
+
+ /**
+ * Id of theme to copy to.
+ *
+ * @var integer
+ */
+ protected $targetThemeId;
+
+ /**
+ * Categories table name.
+ *
+ * @var string
+ */
+ protected $categoriesTableName;
+
+ /**
+ * Content table name.
+ *
+ * @var string
+ */
+ protected $contentTableName;
+
+ /**
+ * Page revision table name.
+ *
+ * @var string
+ */
+ protected $pageRevisionTableName;
+
+ /**
+ * Sets source theme id, prepares used table names.
+ *
+ * @param integer $source_theme_id Source Theme Id.
+ * @param integer $target_theme_id Target Theme Id.
+ *
+ * @throws LogicException When source and target themes match.
+ */
+ public function __construct($source_theme_id, $target_theme_id)
+ {
+ parent::__construct();
+
+ if ( $source_theme_id == $target_theme_id ) {
+ throw new LogicException('Source theme must differ from target theme');
+ }
+
+ $this->sourceThemeId = $source_theme_id;
+ $this->targetThemeId = $target_theme_id;
+ $this->categoriesTableName = $this->Application->getUnitConfig('c')->getTableName();
+ $this->contentTableName = $this->Application->getUnitConfig('content')->getTableName();
+ $this->pageRevisionTableName = $this->Application->getUnitConfig('page-revision')->getTableName();
+ }
+
+ /**
+ * Copies content blocks from source theme to target theme.
+ *
+ * @return boolean
+ */
+ public function copy()
+ {
+ $matches = $this->getMatchingTemplates();
+
+ if ( !$matches ) {
+ return false;
+ }
+
+ $this->deleteTargetBlocks();
+
+ foreach ( $matches as $match ) {
+ $where_clause = array(
+ 'PageId = ' . $match['SourceCategoryId'],
+ 'RevisionNumber = ' . $match['LiveRevisionNumber'],
+ );
+
+ $sql = 'SELECT *
+ FROM ' . $this->pageRevisionTableName . '
+ WHERE (' . implode(') AND (', $where_clause) . ')';
+ $revision_data = $this->Conn->GetRow($sql);
+
+ if ( !$revision_data ) {
+ continue;
+ }
+
+ $revision_data['PageId'] = $match['TargetCategoryId'];
+ $revision_data['RevisionNumber'] = 1;
+ $live_revision_id = $revision_data['RevisionId'];
+ unset($revision_data['RevisionId']);
+ $this->Conn->doInsert($revision_data, $this->pageRevisionTableName);
+
+ $new_revision_id = $this->Conn->getInsertID();
+
+ $this->Conn->doUpdate(
+ array('LiveRevisionNumber' => 1),
+ $this->categoriesTableName,
+ 'CategoryId = ' . $match['TargetCategoryId']
+ );
+
+ $sql = 'SELECT *
+ FROM ' . $this->contentTableName . '
+ WHERE PageId = ' . $match['SourceCategoryId'] . ' AND RevisionId = ' . $live_revision_id;
+ $blocks = $this->Conn->Query($sql);
+
+ foreach ( $blocks as $block_data ) {
+ $block_data['RevisionId'] = $new_revision_id;
+ $block_data['PageId'] = $match['TargetCategoryId'];
+ unset($block_data['PageContentId']);
+ $this->Conn->doInsert($block_data, $this->contentTableName);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines matching templates.
+ *
+ * @return array
+ */
+ protected function getMatchingTemplates()
+ {
+ $on_clause = array(
+ 'target.ThemeId = ' . $this->targetThemeId,
+ 'target.Template = source.Template',
+ 'target.Type = source.Type',
+ );
+
+ $sql = 'SELECT
+ source.LiveRevisionNumber,
+ source.CategoryId AS SourceCategoryId,
+ target.CategoryId AS TargetCategoryId,
+ source.Template
+ FROM ' . $this->categoriesTableName . ' source
+ JOIN ' . $this->categoriesTableName . ' target
+ ON (' . implode(') AND (', $on_clause) . ')
+ WHERE source.ThemeId = ' . $this->sourceThemeId . ' AND source.Type = 2';
+
+ return $this->Conn->Query($sql);
+ }
+
+ /**
+ * Delete all target blocks.
+ *
+ * @return void
+ */
+ protected function deleteTargetBlocks()
+ {
+ $sql = 'SELECT CategoryId
+ FROM ' . $this->categoriesTableName . '
+ WHERE ThemeId = ' . $this->targetThemeId . ' AND Type = 2';
+ $target_categories = $this->Conn->GetCol($sql);
+
+ if ( !$target_categories ) {
+ return;
+ }
+
+ $target_categories = implode(',', $target_categories);
+
+ $sql = 'DELETE FROM ' . $this->contentTableName . '
+ WHERE PageId IN (' . $target_categories . ')';
+ $this->Conn->Query($sql);
+
+ $sql = 'DELETE FROM ' . $this->pageRevisionTableName . '
+ WHERE PageId IN (' . $target_categories . ')';
+ $this->Conn->Query($sql);
+ }
+
+}
Index: core/units/themes/themes_config.php
===================================================================
--- core/units/themes/themes_config.php
+++ core/units/themes/themes_config.php
@@ -59,7 +59,7 @@
'themes_list' => Array (
'prefixes' => Array ('theme_List'), 'format' => "!la_tab_Themes!",
- 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'setprimary', 'refresh', 'view', 'dbl-click'),
+ 'toolbar_buttons' => array('new_item', 'edit', 'delete', 'setprimary', 'refresh', 'view', 'dbl-click', 'copy'),
),
'themes_edit_general' => Array (
@@ -161,4 +161,4 @@
),
),
),
-);
\ No newline at end of file
+);
Index: core/units/themes/themes_eh.php
===================================================================
--- core/units/themes/themes_eh.php
+++ core/units/themes/themes_eh.php
@@ -27,8 +27,9 @@
{
parent::mapPermissions();
- $permissions = Array(
- 'OnChangeTheme' => Array('self' => true),
+ $permissions = array(
+ 'OnChangeTheme' => array('self' => true),
+ 'OnCopyData' => array('self' => 'edit'),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
@@ -220,6 +221,36 @@
}
/**
+ * Copies content blocks between themes.
+ *
+ * @param kEvent $event Event.
+ *
+ * @return void
+ */
+ protected function OnCopyData(kEvent $event)
+ {
+ $ids = $this->StoreSelectedIDs($event);
+ $not_matched_theme_ids = array();
+ $source_theme_id = (int)$this->Application->GetVar('copy_from');
+
+ foreach ( $ids as $target_theme_id ) {
+ /** @var ContentBlockCopier $content_block_copier */
+ $content_block_copier = $this->Application->makeClass(
+ 'ContentBlockCopier',
+ array($source_theme_id, $target_theme_id)
+ );
+
+ if ( !$content_block_copier->copy() ) {
+ $not_matched_theme_ids[] = $target_theme_id;
+ }
+ }
+
+ if ( count($not_matched_theme_ids) ) {
+ $event->setRedirectParam('not_matched_theme_ids', implode(',', $not_matched_theme_ids));
+ }
+ }
+
+ /**
* Apply system filter to themes list
*
* @param kEvent $event
@@ -254,5 +285,17 @@
$themes = explode('|', substr($themes, 1, -1));
$object->addFilter('domain_filter', '%1$s.ThemeId IN (' . implode(',', $themes) . ')');
}
+
+ if ( $event->Special == 'not-matched' ) {
+ $ids = $this->Application->GetVar('not_matched_theme_ids');
+ $ids = array_filter(array_map('intval', explode(',', $ids)));
+
+ if ( $ids ) {
+ $object->addFilter('not_matched_filter', '%1$s.ThemeId IN (' . implode(',', $ids) . ')');
+ }
+ else {
+ $object->addFilter('not_matched_filter', 'FALSE');
+ }
+ }
}
}
Event Timeline
Log In to Comment