Improved the JCB package export/import feature to insure that the new full paths are also moved, also made a few bug fixes in this area to better deal with divergent data id managment

This commit is contained in:
2018-03-02 03:37:04 +02:00
parent 593a4c7c89
commit 836df43fcc
10 changed files with 403 additions and 138 deletions

View File

@ -767,7 +767,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
protected function moveSmartStuff()
{
// make sure to first unlock files
$this->unLockFiles($this->dir);
$this->unLockFiles();
// set params
$params = JComponentHelper::getParams('com_componentbuilder');
// set custom folder path
@ -796,6 +796,43 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$success = false;
}
}
// now move the dynamic files if found
$dynamicDir = str_replace('//', '/', $this->dir . '/dynamic');
if (JFolder::exists($dynamicDir))
{
// get a list of folders
$folders = JFolder::folders($dynamicDir);
// check if we have files
if(ComponentbuilderHelper::checkArray($folders))
{
foreach ($folders as $folder)
{
$destination = $this->setDynamicPath($folder);
$fullPath = str_replace('//', '/', $dynamicDir . '/' . $folder);
if (!JFolder::exists($fullPath) || !JFolder::copy($fullPath, $destination,'',true))
{
$this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FOLDER_BSB_WAS_NOT_MOVE_TO_S', $folder, $destination), 'error');
$success = false;
}
}
}
// get a list of files
$files = JFolder::files($dynamicDir);
// check if we have files
if(ComponentbuilderHelper::checkArray($files))
{
foreach ($files as $file)
{
$destination = $this->setDynamicPath($file);
$fullPath = str_replace('//', '/', $dynamicDir . '/' . $file);
if (!JFile::exists($fullPath) || !JFile::copy($fullPath, $destination))
{
$this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FILE_BSB_WAS_NOT_MOVE_TO_S', $file, $destination), 'error');
$success = false;
}
}
}
}
return $success;
}
@ -812,19 +849,17 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$unlocker = new FOFEncryptAes($this->sleutle, 128);
// we must first store the current working directory
$joomla = getcwd();
// setup the type path
$customPath = str_replace('//', '/', $this->dir . '/custom');
// go to the custom folder if found
if (JFolder::exists($customPath))
// to avoid that it decrypt the db and info file again we must move per/folder
$folders = array('images', 'custom', 'dynamic');
// loop the folders
foreach ($folders as $folder)
{
$this->unlock($customPath, $unlocker);
}
// setup the type path
$imagesPath = str_replace('//', '/', $this->dir . '/images');
// go to the custom folder if found
if (JFolder::exists($imagesPath))
{
$this->unlock($imagesPath, $unlocker);
$subPath = str_replace('//', '/', $this->dir . '/' . $folder);
// go to the package sub folder if found
if (JFolder::exists($subPath))
{
$this->unlock($subPath, $unlocker);
}
}
// change back to working dir
chdir($joomla);
@ -983,10 +1018,10 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
foreach($values as $value)
{
// first check if exist (only add if it does not)
if (!$this->getLocalItem($value, $table, 1))
if (!$this->getLocalItem($value, $table, 1, 1, true))
{
// add the diverged data
$this->addLocalItem($value, $table);
$this->addLocalItem($value, $table, true);
}
}
}
@ -1223,15 +1258,16 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
/**
* Prep the item
*
* @param object $item The item to prep
* @param string $type The type of values
* @param string $action The action (add/update)
* @param object $item The item to prep
* @param string $type The type of values
* @param string $action The action (add/update)
* @param bool $diverged The diverged data switch
*
* @return mixed false on failure
* object on success
*
**/
protected function prepItem($item, &$type, $action)
protected function prepItem($item, &$type, $action, $diverged = false)
{
// remove access
if (isset($item->access))
@ -1528,8 +1564,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$item = ComponentbuilderHelper::convertRepeatableFields($item, $updaterR);
break;
case 'component_admin_views':
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
// diverged id already updated
if (!$diverged)
{
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
}
// repeatable fields to update
$updaterR = array(
// repeatablefield => checker
@ -1546,8 +1586,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$this->updateSubformsIDs($item, 'component_admin_views', $updaterT);
break;
case 'component_site_views':
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
// diverged id already updated
if (!$diverged)
{
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
}
// repeatable fields to update
$updaterR = array(
// repeatablefield => checker
@ -1564,8 +1608,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$this->updateSubformsIDs($item, 'component_site_views', $updaterT);
break;
case 'component_custom_admin_views':
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
// diverged id already updated
if (!$diverged)
{
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
}
// repeatable fields to update
$updaterR = array(
// repeatablefield => checker
@ -1582,8 +1630,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$this->updateSubformsIDs($item, 'component_custom_admin_views', $updaterT);
break;
case 'component_updates':
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
// diverged id already updated
if (!$diverged)
{
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
}
// repeatable fields to update
$updaterR = array(
// repeatablefield => checker
@ -1593,8 +1645,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$item = ComponentbuilderHelper::convertRepeatableFields($item, $updaterR);
break;
case 'component_mysql_tweaks':
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
// diverged id already updated
if (!$diverged)
{
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
}
// repeatable fields to update
$updaterR = array(
// repeatablefield => checker
@ -1611,8 +1667,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$this->updateSubformsIDs($item, 'component_mysql_tweaks', $updaterT);
break;
case 'component_custom_admin_menus':
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
// diverged id already updated
if (!$diverged)
{
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
}
// repeatable fields to update
$updaterR = array(
// repeatablefield => checker
@ -1629,8 +1689,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$this->updateSubformsIDs($item, 'component_custom_admin_menus', $updaterT);
break;
case 'component_config':
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
// diverged id already updated
if (!$diverged)
{
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
}
// repeatable fields to update
$updaterR = array(
// repeatablefield => checker
@ -1647,8 +1711,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$this->updateSubformsIDs($item, 'component_config', $updaterT);
break;
case 'component_dashboard':
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
// diverged id already updated
if (!$diverged)
{
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
}
// repeatable fields to update
$updaterR = array(
// repeatablefield => checker
@ -1658,8 +1726,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
$item = ComponentbuilderHelper::convertRepeatableFields($item, $updaterR);
break;
case 'component_files_folders':
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
// diverged id already updated
if (!$diverged)
{
// update the joomla_component ID where needed
$item = $this->setNewID($item, 'joomla_component', 'joomla_component', $type);
}
// repeatable fields to update
$updaterR = array(
// repeatablefield => checker
@ -1784,8 +1856,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
break;
case 'admin_fields':
case 'admin_fields_conditions':
// update the admin_view ID where needed
$item = $this->setNewID($item, 'admin_view', 'admin_view', $type);
// diverged id already updated
if (!$diverged)
{
// update the admin_view ID where needed
$item = $this->setNewID($item, 'admin_view', 'admin_view', $type);
}
// set the updater
if ('admin_fields' === $type)
{
@ -2006,17 +2082,18 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
/**
* add the local item
*
* @param object $item The item to update
* @param string $type The type of values
* @param object $item The item to update
* @param string $type The type of values
* @param bool $diverged The diverged data switch
*
* @return mixed false on failure
* ID int on success
*
**/
protected function addLocalItem(&$item, &$type)
protected function addLocalItem(&$item, &$type, $diverged = false)
{
// prep the item
if ($add = $this->prepItem($item, $type, 'add'))
if ($add = $this->prepItem($item, $type, 'add', $diverged))
{
// insert/add the item
if ($result = $this->_db->insertObject('#__componentbuilder_' . $type, $add))
@ -2034,16 +2111,17 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
/**
* Get the local item
*
* @param object $item The item to get
* @param string $type The type of values
* @param bool $retry The retry switch
* @param bool $get The query get switch
* @param object $item The item to get
* @param string $type The type of values
* @param bool $retry The retry switch
* @param bool $get The query get switch
* @param bool $diverged The diverged data switch
*
* @return mixed false on failure
* ID int on success
*
**/
protected function getLocalItem(&$item, &$type, $retry = false, $get = 1)
protected function getLocalItem(&$item, &$type, $retry = false, $get = 1, $diverged = false)
{
$query = $this->_db->getQuery(true);
$query->select('a.*');
@ -2154,7 +2232,15 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
// get by admin_view (since there should only be one of each name)
$getter = array('admin_view');
$this->specialValue = array();
$this->specialValue['admin_view'] = $this->newID['admin_view'][(int) $item->admin_view];
// Yet if diverged it makes sense that the ID is updated.
if ($diverged)
{
$this->specialValue['admin_view'] = (int) $item->admin_view;
}
elseif (isset($this->newID['admin_view'][(int) $item->admin_view]))
{
$this->specialValue['admin_view'] = $this->newID['admin_view'][(int) $item->admin_view];
}
break;
case 'fieldtype':
// get by name (since there should only be one of each name)
@ -2304,10 +2390,23 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
case 'component_config':
case 'component_dashboard':
case 'component_files_folders':
// get by admin_view (since there should only be one of each name)
// get by joomla_component (since there should only be one of each component)
$getter = array('joomla_component');
$this->specialValue = array();
$this->specialValue['joomla_component'] = $this->newID['joomla_component'][(int) $item->joomla_component];
// Yet if diverged it makes sense that the ID is updated.
if ($diverged)
{
$this->specialValue['joomla_component'] = (int) $item->joomla_component;
}
elseif (isset($this->newID['joomla_component'][(int) $item->joomla_component]))
{
$this->specialValue['joomla_component'] = $this->newID['joomla_component'][(int) $item->joomla_component];
}
// (TODO) I have seen this happen, seems dangerous!
else
{
return false;
}
break;
case 'language_translation':
// get by English translation since there should just be one
@ -2544,6 +2643,34 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy
}
return false;
}
/**
* Update constant path with real full path value
*
* @param string $path The full path
*
* @return string The updated path
*
*/
protected function setFullPath($path)
{
return str_replace(array_keys(ComponentbuilderHelper::$constantPaths), array_values(ComponentbuilderHelper::$constantPaths), $path);
}
/**
* Convert the name to a path
*
* @param string $path The path name
*
* @return string The full path *
*/
protected function setDynamicPath($path)
{
// now convert to path
$path = str_replace('__v_d_m__', '/', $path);
// add the full path if possible
return str_replace('//', '/', $this->setFullPath($path));
}
protected function getAlias($name,$type = false)
{

View File

@ -273,17 +273,24 @@ class ComponentbuilderModelJoomla_components extends JModelList
// add to pks
$pks[] = $item->id;
}
// array of tables linked to joomla_component
$linkedTables = array(
'custom_code' => 'component',
'component_files_folders' => 'joomla_component',
'component_admin_views' => 'joomla_component',
'component_config' => 'joomla_component',
'component_site_views' => 'joomla_component',
'component_custom_admin_views' => 'joomla_component',
'component_updates' => 'joomla_component',
'component_mysql_tweaks' => 'joomla_component',
'component_custom_admin_menus' => 'joomla_component',
'component_dashboard' => 'joomla_component' );
// load all tables linked to joomla_component
$this->setData('custom_code', $pks, 'component');
$this->setData('component_files_folders', $pks, 'joomla_component');
$this->setData('component_admin_views', $pks, 'joomla_component');
$this->setData('component_config', $pks, 'joomla_component');
$this->setData('component_site_views', $pks, 'joomla_component');
$this->setData('component_custom_admin_views', $pks, 'joomla_component');
$this->setData('component_updates', $pks, 'joomla_component');
$this->setData('component_mysql_tweaks', $pks, 'joomla_component');
$this->setData('component_custom_admin_menus', $pks, 'joomla_component');
$this->setData('component_dashboard', $pks, 'joomla_component');
foreach($linkedTables as $table => $field)
{
$this->setData($table, $pks, $field);
}
// add fields and conditions
if (isset($this->exportIDs['admin_view']) && ComponentbuilderHelper::checkArray($this->exportIDs['admin_view']))
{
@ -320,7 +327,8 @@ class ComponentbuilderModelJoomla_components extends JModelList
{
$this->setData('custom_code', array_values($this->exportIDs['custom_code']), 'id');
}
// has any data been set
// has any data been set for this component
if (isset($this->smartExport['joomla_component']) && ComponentbuilderHelper::checkArray($this->smartExport['joomla_component']))
{
// set the folder and move the files of each component to the folder
@ -553,6 +561,10 @@ class ComponentbuilderModelJoomla_components extends JModelList
$this->moveIt($this->getValues($item->addfiles, 'subform', 'file', null), 'file');
// build folders
$this->moveIt($this->getValues($item->addfolders, 'subform', 'folder', null), 'folder');
// build full path files
$this->moveIt($this->getValues($item->addfilesfullpath, 'subform', 'filepath', null), 'file', true);
// build full path folders
$this->moveIt($this->getValues($item->addfoldersfullpath, 'subform', 'folderpath', null), 'folder', true);
}
// actions to take if table is component_config
if ('component_config' === $table)
@ -777,19 +789,18 @@ class ComponentbuilderModelJoomla_components extends JModelList
$locker = new FOFEncryptAes($this->key, 128);
// we must first store the current working directory
$joomla = getcwd();
// setup the type path
$customPath = $this->packagePath . '/custom';
// go to the custom folder if found
if (JFolder::exists($customPath))
// to avoid that it encrypt the db and info file again we must move per/folder
$folders = array('images', 'custom', 'dynamic');
// loop the folders
foreach ($folders as $folder)
{
$this->lock($customPath, $locker);
}
// setup the type path
$imagesPath = $this->packagePath . '/images';
// go to the custom folder if found
if (JFolder::exists($imagesPath))
{
$this->lock($imagesPath, $locker);
// the sub path
$subPath = $this->packagePath.'/'.$folder;
// go to the package sub folder if found
if (JFolder::exists($subPath))
{
$this->lock($subPath, $locker);
}
}
// change back to working dir
chdir($joomla);
@ -823,7 +834,7 @@ class ComponentbuilderModelJoomla_components extends JModelList
*
* @return bool
*/
protected function moveIt($paths, $type)
protected function moveIt($paths, $type, $dynamic = false)
{
// make sure we have an array
if (!ComponentbuilderHelper::checkArray($paths))
@ -834,11 +845,20 @@ class ComponentbuilderModelJoomla_components extends JModelList
if ('file' === $type || 'folder' === $type)
{
$folderName = 'custom';
// if these are full paths use dynamic folder
if ($dynamic)
{
$folderName = 'dynamic';
}
}
if ('image' === $type)
elseif ('image' === $type)
{
$folderName = 'images';
}
else
{
return false;
}
// setup the type path
$tmpPath = str_replace('//', '/', $this->packagePath . '/' . $folderName);
// create type path if not set
@ -850,19 +870,31 @@ class ComponentbuilderModelJoomla_components extends JModelList
// now move it
foreach ($paths as $item)
{
// make sure we have a string
if (ComponentbuilderHelper::checkString($item))
{
// if the file type
if ('file' === $type)
{
// TODO we must add the new all over files to this... will be a little tricky.
$tmpFilePath = str_replace('//', '/', $tmpPath.'/'.$item);
$customFilePath = str_replace('//', '/', $this->customPath.'/'.$item);
// if dynamic paths
if ($dynamic)
{
$tmpFilePath = $tmpPath.'/'.$this->setDynamicPathName($item);
$customFilePath = str_replace('//', '/', $this->setFullPath($item));
}
else
{
$tmpFilePath = str_replace('//', '/', $tmpPath.'/'.$item);
$customFilePath = str_replace('//', '/', $this->customPath.'/'.$item);
}
// now check if file exist
if (!JFile::exists($tmpFilePath) && JFile::exists($customFilePath))
{
// move the file to its place
JFile::copy($customFilePath, $tmpFilePath);
}
}
// if the image type
if ('image' === $type)
{
$imageName = basename($item);
@ -882,10 +914,20 @@ class ComponentbuilderModelJoomla_components extends JModelList
JFile::copy($customImagePath, $tmpImagePath);
}
}
// if the folder type
if ('folder' === $type)
{
$tmpFolderPath = str_replace('//', '/', $tmpPath.'/'.$item);
$customFolderPath = str_replace('//', '/', $this->customPath.'/'.$item);
// if dynamic paths
if ($dynamic)
{
$tmpFolderPath = $tmpPath.'/'.$this->setDynamicPathName($item);
$customFolderPath = str_replace('//', '/', $this->setFullPath($item));
}
else
{
$tmpFolderPath = str_replace('//', '/', $tmpPath.'/'.$item);
$customFolderPath = str_replace('//', '/', $this->customPath.'/'.$item);
}
if (!JFolder::exists($tmpFolderPath) && JFolder::exists($customFolderPath))
{
// move the folder to its place
@ -1252,6 +1294,48 @@ class ComponentbuilderModelJoomla_components extends JModelList
}
}
}
/**
* Convert the path to a name
*
* @param string $path The full path
*
* @return string The path name
*
*/
protected function setDynamicPathName($path)
{
// remove the full path if possible
$path = str_replace('//', '/', $this->setConstantPath($path));
// now convert to string
return str_replace('/', '__v_d_m__', $path);
}
/**
* Update real full path value with constant path string
*
* @param string $path The full path
*
* @return string The updated path
*
*/
protected function setConstantPath($path)
{
return str_replace(array_values(ComponentbuilderHelper::$constantPaths), array_keys(ComponentbuilderHelper::$constantPaths), $path);
}
/**
* Update constant path with real full path value
*
* @param string $path The full path
*
* @return string The updated path
*
*/
protected function setFullPath($path)
{
return str_replace(array_keys(ComponentbuilderHelper::$constantPaths), array_values(ComponentbuilderHelper::$constantPaths), $path);
}
/**
* Get the keys of the values to search custom code in