Component-Builder-fork/admin/helpers/compiler/b_Structure.php

3098 lines
88 KiB
PHP

<?php
/**
* @package Joomla.Component.Builder
*
* @created 30th April, 2015
* @author Llewellyn van der Merwe <http://www.joomlacomponentbuilder.com>
* @github Joomla Component Builder <https://github.com/vdm-io/Joomla-Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
use Joomla\CMS\Filesystem\File;
use Joomla\CMS\Filesystem\Folder;
/**
* Structure class
*/
class Structure extends Get
{
/**
* The folder counter
*
* @var int
*/
public $folderCount = 0;
/**
* The file counter
*
* @var int
*/
public $fileCount = 0;
/**
* The page counter
*
* @var int
*/
public $pageCount = 0;
/**
* The line counter
*
* @var int
*/
public $lineCount = 0;
/**
* The field counter
*
* @var int
*/
public $fieldCount = 0;
/**
* The seconds counter
*
* @var int
*/
public $seconds = 0;
/**
* The actual seconds counter
*
* @var int
*/
public $actualSeconds = 0;
/**
* The folder seconds counter
*
* @var int
*/
public $folderSeconds = 0;
/**
* The file seconds counter
*
* @var int
*/
public $fileSeconds = 0;
/**
* The line seconds counter
*
* @var int
*/
public $lineSeconds = 0;
/**
* The seconds debugging counter
*
* @var int
*/
public $secondsDebugging = 0;
/**
* The seconds planning counter
*
* @var int
*/
public $secondsPlanning = 0;
/**
* The seconds mapping counter
*
* @var int
*/
public $secondsMapping = 0;
/**
* The seconds office counter
*
* @var int
*/
public $secondsOffice = 0;
/**
* The total hours counter
*
* @var int
*/
public $totalHours = 0;
/**
* The debugging hours counter
*
* @var int
*/
public $debuggingHours = 0;
/**
* The planning hours counter
*
* @var int
*/
public $planningHours = 0;
/**
* The mapping hours counter
*
* @var int
*/
public $mappingHours = 0;
/**
* The office hours counter
*
* @var int
*/
public $officeHours = 0;
/**
* The actual Total Hours counter
*
* @var int
*/
public $actualTotalHours = 0;
/**
* The actual hours spent counter
*
* @var int
*/
public $actualHoursSpent = 0;
/**
* The actual days spent counter
*
* @var int
*/
public $actualDaysSpent = 0;
/**
* The total days counter
*
* @var int
*/
public $totalDays = 0;
/**
* The actual Total Days counter
*
* @var int
*/
public $actualTotalDays = 0;
/**
* The project week time counter
*
* @var int
*/
public $projectWeekTime = 0;
/**
* The project month time counter
*
* @var int
*/
public $projectMonthTime = 0;
/**
* The template path
*
* @var string
*/
public $templatePath;
/**
* The custom template path
*
* @var string
*/
public $templatePathCustom;
/**
* The Joomla Version Data
*
* @var object
*/
public $joomlaVersionData;
/**
* Static File Content
*
* @var array
*/
public $fileContentStatic = array();
/**
* Extention Custom Fields
*
* @var array
*/
public $extentionCustomfields = array();
/**
* Extention Tracking Files Moved
*
* @var array
*/
public $extentionTrackingFilesMoved = array();
/**
* The standard folders
*
* @var array
*/
public $stdFolders = array('site', 'admin', 'media');
/**
* The standard root files
*
* @var array
*/
public $stdRootFiles
= array('access.xml', 'config.xml', 'controller.php', 'index.html',
'README.txt');
/**
* Dynamic File Content
*
* @var array
*/
public $fileContentDynamic = array();
/**
* The Component Sales name
*
* @var string
*/
public $componentSalesName;
/**
* The Component Backup name
*
* @var string
*/
public $componentBackupName;
/**
* The Component Folder name
*
* @var string
*/
public $componentFolderName;
/**
* The Component path
*
* @var string
*/
public $componentPath;
/**
* The Dynamic paths
*
* @var array
*/
public $dynamicPaths = array();
/**
* The not new static items
*
* @var array
*/
public $notNew = array();
/**
* Update the file content
*
* @var array
*/
public $updateFileContent = array();
/**
* The new files
*
* @var array
*/
public $newFiles = array();
/**
* The Checkin Switch
*
* @var boolean
*/
public $addCheckin = false;
/**
* The Move Folders Switch
*
* @var boolean
*/
public $setMoveFolders = false;
/**
* The array of last modified dates
*
* @var array
*/
protected $lastModifiedDate = array();
/**
* The default view switch
*
* @var bool/string
*/
public $dynamicDashboard = false;
/**
* The default view type
*
* @var string
*/
public $dynamicDashboardType;
/**
* Constructor
*/
public function __construct($config = array())
{
// first we run the perent constructor
if (parent::__construct($config))
{
// set the standard admin file
$this->stdRootFiles[] = $this->componentData->name_code . '.php';
// set incase no extra admin folder are loaded
$this->fileContentStatic[$this->hhh . 'EXSTRA_ADMIN_FOLDERS'
. $this->hhh]
= '';
// set incase no extra site folder are loaded
$this->fileContentStatic[$this->hhh . 'EXSTRA_SITE_FOLDERS'
. $this->hhh]
= '';
// set incase no extra media folder are loaded
$this->fileContentStatic[$this->hhh . 'EXSTRA_MEDIA_FOLDERS'
. $this->hhh]
= '';
// set incase no extra admin files are loaded
$this->fileContentStatic[$this->hhh . 'EXSTRA_ADMIN_FILES'
. $this->hhh]
= '';
// set incase no extra site files are loaded
$this->fileContentStatic[$this->hhh . 'EXSTRA_SITE_FILES'
. $this->hhh]
= '';
// set incase no extra media files are loaded
$this->fileContentStatic[$this->hhh . 'EXSTRA_MEDIA_FILES'
. $this->hhh]
= '';
// run global updater
ComponentbuilderHelper::runGlobalUpdater();
// set the template path
$this->templatePath = $this->compilerPath . '/joomla_'
. $config['version'];
// set some default names
$this->componentSalesName = 'com_'
. $this->componentData->sales_name . '__J'
. $this->joomlaVersion;
$this->componentBackupName = 'com_'
. $this->componentData->sales_name . '_v' . str_replace(
'.', '_', $this->componentData->component_version
) . '__J' . $this->joomlaVersion;
$this->componentFolderName = 'com_'
. $this->componentData->name_code . '_v' . str_replace(
'.', '_', $this->componentData->component_version
) . '__J' . $this->joomlaVersion;
// set component folder path
$this->componentPath = $this->compilerPath . '/'
. $this->componentFolderName;
// set the template path for custom
$this->templatePathCustom = $this->params->get(
'custom_folder_path', JPATH_COMPONENT_ADMINISTRATOR . '/custom'
);
// make sure there is no old build
$this->removeFolder($this->componentPath);
// load the libraries files/folders and url's
$this->setLibraries();
// load the module files/folders and url's
$this->buildModules();
// load the plugin files/folders and url's
$this->buildPlugins();
// set the Joomla Version Data
$this->joomlaVersionData = $this->setJoomlaVersionData();
// Trigger Event: jcb_ce_onAfterSetJoomlaVersionData
$this->triggerEvent(
'jcb_ce_onAfterSetJoomlaVersionData',
array(&$this->componentContext, &$this->joomlaVersionData)
);
// set the dashboard
$this->setDynamicDashboard();
// set the new folders
if (!$this->setFolders())
{
return false;
}
// set all static folders and files
if (!$this->setStatic())
{
return false;
}
// set all the dynamic folders and files
if (!$this->setDynamique())
{
return false;
}
return true;
}
return false;
}
/**
* Set the line number in comments
*
* @param int $nr The line number
*
* @return string
*
*/
private function setLine($nr)
{
if ($this->debugLinenr)
{
return ' [Structure ' . $nr . ']';
}
return '';
}
/**
* Build the Modules files, folders, url's and config
*
* @return void
*
*/
private function buildModules()
{
if (ComponentbuilderHelper::checkArray($this->joomlaModules))
{
// Trigger Event: jcb_ce_onBeforeSetModules
$this->triggerEvent(
'jcb_ce_onBeforeBuildModules',
array(&$this->componentContext, &$this->joomlaModules)
);
foreach ($this->joomlaModules as $module)
{
if (ComponentbuilderHelper::checkObject($module)
&& isset($module->folder_name)
&& ComponentbuilderHelper::checkString(
$module->folder_name
))
{
// module path
$module->folder_path = $this->compilerPath . '/'
. $module->folder_name;
// set the module paths
$this->dynamicPaths[$module->key] = $module->folder_path;
// make sure there is no old build
$this->removeFolder($module->folder_path);
// creat the main module folder
$this->createFolder($module->folder_path);
// set main mod file
$fileDetails = array('path' => $module->folder_path . '/'
. $module->file_name . '.php',
'name' => $module->file_name . '.php',
'zip' => $module->file_name . '.php');
$this->writeFile(
$fileDetails['path'],
'<?php' . PHP_EOL . '// main modfile' .
PHP_EOL . $this->hhh . 'BOM' . $this->hhh . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL .
$this->hhh . 'MODCODE' . $this->hhh
);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
// set custom_get
if ($module->custom_get)
{
$fileDetails = array('path' => $module->folder_path
. '/data.php',
'name' => 'data.php',
'zip' => 'data.php');
$this->writeFile(
$fileDetails['path'],
'<?php' . PHP_EOL . '// get data file' .
PHP_EOL . $this->hhh . 'BOM' . $this->hhh . PHP_EOL
.
PHP_EOL . '// No direct access to this file'
. PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL . PHP_EOL .
'/**' . PHP_EOL .
' * Module ' . $module->official_name . ' Data'
. PHP_EOL .
' */' . PHP_EOL .
"class " . $module->class_data_name
. ' extends \JObject' . PHP_EOL .
"{" . $this->hhh . 'DYNAMICGETS' . $this->hhh . "}"
. PHP_EOL
);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
}
// set helper file
if ($module->add_class_helper >= 1)
{
$fileDetails = array('path' => $module->folder_path
. '/helper.php',
'name' => 'helper.php',
'zip' => 'helper.php');
$this->writeFile(
$fileDetails['path'],
'<?php' . PHP_EOL . '// helper file' .
PHP_EOL . $this->hhh . 'BOM' . $this->hhh . PHP_EOL
.
PHP_EOL . '// No direct access to this file'
. PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL .
$this->hhh . 'HELPERCODE' . $this->hhh
);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
}
// set main xml file
$fileDetails = array('path' => $module->folder_path . '/'
. $module->file_name . '.xml',
'name' => $module->file_name . '.xml',
'zip' => $module->file_name . '.xml');
$this->writeFile(
$fileDetails['path'],
$this->getModuleXMLTemplate($module)
);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
// set tmpl folder
$this->createFolder($module->folder_path . '/tmpl');
// set default file
$fileDetails = array('path' => $module->folder_path
. '/tmpl/default.php',
'name' => 'default.php',
'zip' => 'tmpl/default.php');
$this->writeFile(
$fileDetails['path'],
'<?php' . PHP_EOL . '// default tmpl' .
PHP_EOL . $this->hhh . 'BOM' . $this->hhh . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL .
$this->hhh . 'MODDEFAULT' . $this->hhh
);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
// set install script if needed
if ($module->add_install_script)
{
$fileDetails = array('path' => $module->folder_path
. '/script.php',
'name' => 'script.php',
'zip' => 'script.php');
$this->writeFile(
$fileDetails['path'],
'<?php' . PHP_EOL . '// Script template' .
PHP_EOL . $this->hhh . 'BOM' . $this->hhh . PHP_EOL
.
PHP_EOL . '// No direct access to this file'
. PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL .
$this->hhh . 'INSTALLCLASS' . $this->hhh
);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
}
// set readme if found
if ($module->addreadme)
{
$fileDetails = array('path' => $module->folder_path
. '/README.md',
'name' => 'README.md',
'zip' => 'README.md');
$this->writeFile($fileDetails['path'], $module->readme);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
}
// set the folders target path
$target_path = '';
if ($module->target_client === 'administrator')
{
$target_path = '/administrator';
}
// check if we have custom fields needed for scripts
$module->add_scripts_field = false;
$field_script_bucket = array();
// add any css from the fields
if (($css = $this->getCustomScriptBuilder(
'css_view', $module->key
)) !== null
&& ComponentbuilderHelper::checkString($css))
{
// make sure this script does not have PHP
if (strpos($css, '<?php') === false)
{
// make sure the field is added
$module->add_scripts_field = true;
// create the css folder
$this->createFolder($module->folder_path . '/css');
// add the CSS file
$fileDetails = array('path' => $module->folder_path
. '/css/mod_admin.css',
'name' => 'mod_admin.css',
'zip' => 'mod_admin.css');
$this->writeFile(
$fileDetails['path'],
$this->hhh . 'BOM' . $this->hhh . PHP_EOL
. PHP_EOL . $css
);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
// add the field script
$field_script_bucket[] = $this->_t(2) . "//"
. $this->setLine(__LINE__) . " Custom CSS";
$field_script_bucket[] = $this->_t(2)
. "\$document->addStyleSheet('" . $target_path
. "/modules/" . $module->folder_name
. "/css/mod_admin.css', ['version' => 'auto', 'relative' => true]);";
}
}
// add any JavaScript from the fields
if (($javascript = $this->getCustomScriptBuilder(
'view_footer', $module->key
)) !== null
&& ComponentbuilderHelper::checkString($javascript))
{
// make sure this script does not have PHP
if (strpos($javascript, '<?php') === false)
{
// make sure the field is added
$module->add_scripts_field = true;
// add the JavaScript file
$this->createFolder($module->folder_path . '/js');
// add the CSS file
$fileDetails = array('path' => $module->folder_path
. '/js/mod_admin.js',
'name' => 'mod_admin.js',
'zip' => 'mod_admin.js');
$this->writeFile(
$fileDetails['path'],
$this->hhh . 'BOM' . $this->hhh . PHP_EOL
. PHP_EOL . $javascript
);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
// add the field script
$field_script_bucket[] = $this->_t(2) . "//"
. $this->setLine(__LINE__) . " Custom JS";
$field_script_bucket[] = $this->_t(2)
. "\$document->addScript('" . $target_path
. "/modules/" . $module->folder_name
. "/js/mod_admin.js', ['version' => 'auto', 'relative' => true]);";
}
}
// set fields folders if needed
if ($module->add_scripts_field
|| (isset($module->fields_rules_paths)
&& $module->fields_rules_paths == 2))
{
// create fields folder
$this->createFolder($module->folder_path . '/fields');
// add the custom script field
if ($module->add_scripts_field)
{
$fileDetails = array('path' => $module->folder_path
. '/fields/modadminvvvvvvvdm.php',
'name' => 'modadminvvvvvvvdm.php',
'zip' => 'modadminvvvvvvvdm.php');
$this->writeFile(
$fileDetails['path'],
$this->getModAdminVvvvvvvdm(
$field_script_bucket
)
);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
}
}
// set rules folders if needed
if (isset($module->fields_rules_paths)
&& $module->fields_rules_paths == 2)
{
// create rules folder
$this->createFolder($module->folder_path . '/rules');
}
// set forms folder if needed
if (isset($module->form_files)
&& ComponentbuilderHelper::checkArray(
$module->form_files
))
{
// create forms folder
$this->createFolder($module->folder_path . '/forms');
// set the template files
foreach ($module->form_files as $file => $fields)
{
// set file details
$fileDetails = array('path' => $module->folder_path
. '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file
. '.xml');
// build basic XML
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<!--' . $this->setLine(__LINE__)
. ' default paths of ' . $file
. ' form points to ' . $this->componentCodeName
. ' -->';
// search if we must add the component path
$add_component_path = false;
foreach ($fields as $field_name => $fieldsets)
{
if (!$add_component_path)
{
foreach ($fieldsets as $fieldset => $field)
{
if (!$add_component_path
&& isset(
$module->fieldsets_paths[$file
. $field_name . $fieldset]
)
&& $module->fieldsets_paths[$file
. $field_name . $fieldset] == 1)
{
$add_component_path = true;
}
}
}
}
// only add if part of the component field types path is required
if ($add_component_path)
{
$xml .= PHP_EOL . '<form';
$xml .= PHP_EOL . $this->_t(1)
. 'addrulepath="/administrator/components/com_'
. $this->componentCodeName
. '/models/rules"';
$xml .= PHP_EOL . $this->_t(1)
. 'addfieldpath="/administrator/components/com_'
. $this->componentCodeName
. '/models/fields"';
$xml .= PHP_EOL . '>';
}
else
{
$xml .= PHP_EOL . '<form>';
}
// add the fields
foreach ($fields as $field_name => $fieldsets)
{
// check if we have an double fields naming set
$field_name_inner = '';
$field_name_outer = $field_name;
if (strpos($field_name, '.') !== false)
{
$field_names = explode('.', $field_name);
if (count((array) $field_names) == 2)
{
$field_name_outer = $field_names[0];
$field_name_inner = $field_names[1];
}
}
$xml .= PHP_EOL . $this->_t(1)
. '<fields name="' . $field_name_outer
. '">';
foreach ($fieldsets as $fieldset => $field)
{
// default to the field set name
$label = $fieldset;
if (isset(
$module->fieldsets_label[$file
. $field_name . $fieldset]
))
{
$label = $module->fieldsets_label[$file
. $field_name . $fieldset];
}
// add path to module rules and custom fields
if (isset(
$module->fieldsets_paths[$file
. $field_name . $fieldset]
)
&& $module->fieldsets_paths[$file
. $field_name . $fieldset] == 2)
{
$xml .= PHP_EOL . $this->_t(1) . '<!--'
. $this->setLine(__LINE__)
. ' default paths of ' . $fieldset
. ' fieldset points to the module -->';
$xml .= PHP_EOL . $this->_t(1)
. '<fieldset name="' . $fieldset
. '" label="' . $label . '"';
$xml .= PHP_EOL . $this->_t(2)
. 'addrulepath="/modules/'
. strtolower($module->code_name)
. '/rules"';
$xml .= PHP_EOL . $this->_t(2)
. 'addfieldpath="/modules/'
. strtolower($module->code_name)
. '/fields"';
$xml .= PHP_EOL . $this->_t(1) . '>';
}
else
{
$xml .= PHP_EOL . $this->_t(1)
. '<fieldset name="' . $fieldset
. '" label="' . $label . '">';
}
// check if we have an inner field set
if (ComponentbuilderHelper::checkString(
$field_name_inner
))
{
$xml .= PHP_EOL . $this->_t(1)
. '<fields name="'
. $field_name_inner . '">';
}
// add the placeholder of the fields
$xml .= $this->hhh . 'FIELDSET_' . $file
. $field_name . $fieldset . $this->hhh;
// check if we have an inner field set
if (ComponentbuilderHelper::checkString(
$field_name_inner
))
{
$xml .= PHP_EOL . $this->_t(1)
. '</fields>';
}
$xml .= PHP_EOL . $this->_t(1)
. '</fieldset>';
}
$xml .= PHP_EOL . $this->_t(1) . '</fields>';
}
$xml .= PHP_EOL . '</form>';
// add xml to file
$this->writeFile($fileDetails['path'], $xml);
$this->newFiles[$module->key][] = $fileDetails;
// count the file created
$this->fileCount++;
}
}
// set SQL stuff if needed
if ($module->add_sql || $module->add_sql_uninstall)
{
// create SQL folder
$this->createFolder($module->folder_path . '/sql');
// create mysql folder
$this->createFolder(
$module->folder_path . '/sql/mysql'
);
// now set the install file
if ($module->add_sql)
{
$this->writeFile(
$module->folder_path . '/sql/mysql/install.sql',
$module->sql
);
// count the file created
$this->fileCount++;
}
// now set the uninstall file
if ($module->add_sql_uninstall)
{
$this->writeFile(
$module->folder_path
. '/sql/mysql/uninstall.sql',
$module->sql_uninstall
);
// count the file created
$this->fileCount++;
}
}
// creat the language folder
$this->createFolder($module->folder_path . '/language');
// also create the lang tag folder
$this->createFolder(
$module->folder_path . '/language/' . $this->langTag
);
// check if this lib has files
if (isset($module->files)
&& ComponentbuilderHelper::checkArray($module->files))
{
// add to component files
foreach ($module->files as $file)
{
// set the path finder
$file['target_type'] = $module->target_type;
$file['target_id'] = $module->id;
$this->componentData->files[] = $file;
}
}
// check if this lib has folders
if (isset($module->folders)
&& ComponentbuilderHelper::checkArray($module->folders))
{
// add to component folders
foreach ($module->folders as $folder)
{
// set the path finder
$folder['target_type'] = $module->target_type;
$folder['target_id'] = $module->id;
$this->componentData->folders[] = $folder;
}
}
// check if this module has urls
if (isset($module->urls)
&& ComponentbuilderHelper::checkArray($module->urls))
{
// add to component urls
foreach ($module->urls as $n => &$url)
{
// should we add the local folder
if (isset($url['type']) && $url['type'] > 1
&& isset($url['url'])
&& ComponentbuilderHelper::checkString(
$url['url']
))
{
// set file name
$fileName = basename($url['url']);
// get the file contents
$data = ComponentbuilderHelper::getFileContents(
$url['url']
);
// build sub path
if (strpos($fileName, '.js') !== false)
{
$path = '/js';
}
elseif (strpos($fileName, '.css') !== false)
{
$path = '/css';
}
else
{
$path = '';
}
// create sub media path if not set
$this->createFolder(
$module->folder_path . $path
);
// set the path to module file
$url['path'] = $module->folder_path . $path
. '/' . $fileName; // we need this for later
// write data to path
$this->writeFile($url['path'], $data);
// count the file created
$this->fileCount++;
}
}
}
}
}
}
}
/**
* Build the Plugins files, folders, url's and config
*
* @return void
*
*/
private function buildPlugins()
{
if (ComponentbuilderHelper::checkArray($this->joomlaPlugins))
{
// Trigger Event: jcb_ce_onBeforeSetPlugins
$this->triggerEvent(
'jcb_ce_onBeforeBuildPlugins',
array(&$this->componentContext, &$this->joomlaPlugins)
);
foreach ($this->joomlaPlugins as $plugin)
{
if (ComponentbuilderHelper::checkObject($plugin)
&& isset($plugin->folder_name)
&& ComponentbuilderHelper::checkString(
$plugin->folder_name
))
{
// plugin path
$plugin->folder_path = $this->compilerPath . '/'
. $plugin->folder_name;
// set the plugin paths
$this->dynamicPaths[$plugin->key] = $plugin->folder_path;
// make sure there is no old build
$this->removeFolder($plugin->folder_path);
// creat the main component folder
$this->createFolder($plugin->folder_path);
// set main class file
$fileDetails = array('path' => $plugin->folder_path . '/'
. $plugin->file_name . '.php',
'name' => $plugin->file_name . '.php',
'zip' => $plugin->file_name . '.php');
$this->writeFile(
$fileDetails['path'],
'<?php' . PHP_EOL . '// Plugin main class template' .
PHP_EOL . $this->hhh . 'BOM' . $this->hhh . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL .
$this->hhh . 'MAINCLASS' . $this->hhh
);
$this->newFiles[$plugin->key][] = $fileDetails;
// count the file created
$this->fileCount++;
// set main xml file
$fileDetails = array('path' => $plugin->folder_path . '/'
. $plugin->file_name . '.xml',
'name' => $plugin->file_name . '.xml',
'zip' => $plugin->file_name . '.xml');
$this->writeFile(
$fileDetails['path'],
$this->getPluginXMLTemplate($plugin)
);
$this->newFiles[$plugin->key][] = $fileDetails;
// count the file created
$this->fileCount++;
// set install script if needed
if ($plugin->add_install_script)
{
$fileDetails = array('path' => $plugin->folder_path
. '/script.php',
'name' => 'script.php',
'zip' => 'script.php');
$this->writeFile(
$fileDetails['path'],
'<?php' . PHP_EOL . '// Script template' .
PHP_EOL . $this->hhh . 'BOM' . $this->hhh . PHP_EOL
.
PHP_EOL . '// No direct access to this file'
. PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL .
$this->hhh . 'INSTALLCLASS' . $this->hhh
);
$this->newFiles[$plugin->key][] = $fileDetails;
// count the file created
$this->fileCount++;
}
// set readme if found
if ($plugin->addreadme)
{
$fileDetails = array('path' => $plugin->folder_path
. '/README.md',
'name' => 'README.md',
'zip' => 'README.md');
$this->writeFile($fileDetails['path'], $plugin->readme);
$this->newFiles[$plugin->key][] = $fileDetails;
// count the file created
$this->fileCount++;
}
// set fields & rules folders if needed
if (isset($plugin->fields_rules_paths)
&& $plugin->fields_rules_paths == 2)
{
// create fields folder
$this->createFolder($plugin->folder_path . '/fields');
// create rules folder
$this->createFolder($plugin->folder_path . '/rules');
}
// set forms folder if needed
if (isset($plugin->form_files)
&& ComponentbuilderHelper::checkArray(
$plugin->form_files
))
{
// create forms folder
$this->createFolder($plugin->folder_path . '/forms');
// set the template files
foreach ($plugin->form_files as $file => $fields)
{
// set file details
$fileDetails = array('path' => $plugin->folder_path
. '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file
. '.xml');
// biuld basic XML
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<!--' . $this->setLine(__LINE__)
. ' default paths of ' . $file
. ' form points to ' . $this->componentCodeName
. ' -->';
// search if we must add the component path
$add_component_path = false;
foreach ($fields as $field_name => $fieldsets)
{
if (!$add_component_path)
{
foreach ($fieldsets as $fieldset => $field)
{
if (!$add_component_path
&& isset(
$plugin->fieldsets_paths[$file
. $field_name . $fieldset]
)
&& $plugin->fieldsets_paths[$file
. $field_name . $fieldset] == 1)
{
$add_component_path = true;
}
}
}
}
// only add if part of the component field types path is required
if ($add_component_path)
{
$xml .= PHP_EOL . '<form';
$xml .= PHP_EOL . $this->_t(1)
. 'addrulepath="/administrator/components/com_'
. $this->componentCodeName
. '/models/rules"';
$xml .= PHP_EOL . $this->_t(1)
. 'addfieldpath="/administrator/components/com_'
. $this->componentCodeName
. '/models/fields"';
$xml .= PHP_EOL . '>';
}
else
{
$xml .= PHP_EOL . '<form>';
}
// add the fields
foreach ($fields as $field_name => $fieldsets)
{
// check if we have an double fields naming set
$field_name_inner = '';
$field_name_outer = $field_name;
if (strpos($field_name, '.') !== false)
{
$field_names = explode('.', $field_name);
if (count((array) $field_names) == 2)
{
$field_name_outer = $field_names[0];
$field_name_inner = $field_names[1];
}
}
$xml .= PHP_EOL . $this->_t(1)
. '<fields name="' . $field_name_outer
. '">';
foreach ($fieldsets as $fieldset => $field)
{
// default to the field set name
$label = $fieldset;
if (isset(
$plugin->fieldsets_label[$file
. $field_name . $fieldset]
))
{
$label = $plugin->fieldsets_label[$file
. $field_name . $fieldset];
}
// add path to plugin rules and custom fields
if (isset(
$plugin->fieldsets_paths[$file
. $field_name . $fieldset]
)
&& $plugin->fieldsets_paths[$file
. $field_name . $fieldset] == 2)
{
$xml .= PHP_EOL . $this->_t(1) . '<!--'
. $this->setLine(__LINE__)
. ' default paths of ' . $fieldset
. ' fieldset points to the plugin -->';
$xml .= PHP_EOL . $this->_t(1)
. '<fieldset name="' . $fieldset
. '" label="' . $label . '"';
$xml .= PHP_EOL . $this->_t(2)
. 'addrulepath="/plugins/'
. strtolower($plugin->group) . '/'
. strtolower($plugin->code_name)
. '/rules"';
$xml .= PHP_EOL . $this->_t(2)
. 'addfieldpath="/plugins/'
. strtolower($plugin->group) . '/'
. strtolower($plugin->code_name)
. '/fields"';
$xml .= PHP_EOL . $this->_t(1) . '>';
}
else
{
$xml .= PHP_EOL . $this->_t(1)
. '<fieldset name="' . $fieldset
. '" label="' . $label . '">';
}
// check if we have an inner field set
if (ComponentbuilderHelper::checkString(
$field_name_inner
))
{
$xml .= PHP_EOL . $this->_t(1)
. '<fields name="'
. $field_name_inner . '">';
}
// add the placeholder of the fields
$xml .= $this->hhh . 'FIELDSET_' . $file
. $field_name . $fieldset . $this->hhh;
// check if we have an inner field set
if (ComponentbuilderHelper::checkString(
$field_name_inner
))
{
$xml .= PHP_EOL . $this->_t(1)
. '</fields>';
}
$xml .= PHP_EOL . $this->_t(1)
. '</fieldset>';
}
$xml .= PHP_EOL . $this->_t(1) . '</fields>';
}
$xml .= PHP_EOL . '</form>';
// add xml to file
$this->writeFile($fileDetails['path'], $xml);
$this->newFiles[$plugin->key][] = $fileDetails;
// count the file created
$this->fileCount++;
}
}
// set SQL stuff if needed
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
// create SQL folder
$this->createFolder($plugin->folder_path . '/sql');
// create mysql folder
$this->createFolder(
$plugin->folder_path . '/sql/mysql'
);
// now set the install file
if ($plugin->add_sql)
{
$this->writeFile(
$plugin->folder_path . '/sql/mysql/install.sql',
$plugin->sql
);
// count the file created
$this->fileCount++;
}
// now set the uninstall file
if ($plugin->add_sql_uninstall)
{
$this->writeFile(
$plugin->folder_path
. '/sql/mysql/uninstall.sql',
$plugin->sql_uninstall
);
// count the file created
$this->fileCount++;
}
}
// creat the language folder path
$this->createFolder($plugin->folder_path . '/language');
// also creat the lang tag folder path
$this->createFolder(
$plugin->folder_path . '/language/' . $this->langTag
);
// check if this lib has files
if (isset($plugin->files)
&& ComponentbuilderHelper::checkArray($plugin->files))
{
// add to component files
foreach ($plugin->files as $file)
{
// set the path finder
$file['target_type'] = $plugin->target_type;
$file['target_id'] = $plugin->id;
$this->componentData->files[] = $file;
}
}
// check if this lib has folders
if (isset($plugin->folders)
&& ComponentbuilderHelper::checkArray($plugin->folders))
{
// add to component folders
foreach ($plugin->folders as $folder)
{
// set the path finder
$folder['target_type'] = $plugin->target_type;
$folder['target_id'] = $plugin->id;
$this->componentData->folders[] = $folder;
}
}
// check if this plugin has urls
if (isset($plugin->urls)
&& ComponentbuilderHelper::checkArray($plugin->urls))
{
// add to component urls
foreach ($plugin->urls as $n => &$url)
{
// should we add the local folder
if (isset($url['type']) && $url['type'] > 1
&& isset($url['url'])
&& ComponentbuilderHelper::checkString(
$url['url']
))
{
// set file name
$fileName = basename($url['url']);
// get the file contents
$data = ComponentbuilderHelper::getFileContents(
$url['url']
);
// build sub path
if (strpos($fileName, '.js') !== false)
{
$path = '/js';
}
elseif (strpos($fileName, '.css') !== false)
{
$path = '/css';
}
else
{
$path = '';
}
// create sub media media folder path if not set
$this->createFolder(
$plugin->folder_path . $path
);
// set the path to plugin file
$url['path'] = $plugin->folder_path . $path
. '/' . $fileName; // we need this for later
// write data to path
$this->writeFile($url['path'], $data);
// count the file created
$this->fileCount++;
}
}
}
}
}
}
}
/**
* Create Path if not exist
*
* @return void
*/
private function createFolder($path)
{
// check if the path exist
if (!Folder::exists(
$path
))
{
// create the path
Folder::create(
$path
);
// count the folder created
$this->folderCount++;
// add index.html (boring I know)
$this->indexHTML(
$path, ''
);
}
}
/**
* Build the Libraries files, folders, url's and config
*
* @return void
*
*/
private function setLibraries()
{
if (ComponentbuilderHelper::checkArray($this->libraries))
{
// Trigger Event: jcb_ce_onBeforeSetLibraries
$this->triggerEvent(
'jcb_ce_onBeforeSetLibraries',
array(&$this->componentContext, &$this->libraries)
);
// creat the main component folder
if (!Folder::exists($this->componentPath))
{
Folder::create($this->componentPath);
// count the folder created
$this->folderCount++;
$this->indexHTML('');
}
// create media path if not set
$this->createFolder($this->componentPath . '/media');
foreach ($this->libraries as $id => &$library)
{
if (ComponentbuilderHelper::checkObject($library))
{
// check if this lib has files
if (isset($library->files)
&& ComponentbuilderHelper::checkArray($library->files))
{
// add to component files
foreach ($library->files as $file)
{
$this->componentData->files[] = $file;
}
}
// check if this lib has folders
if (isset($library->folders)
&& ComponentbuilderHelper::checkArray(
$library->folders
))
{
// add to component folders
foreach ($library->folders as $folder)
{
$this->componentData->folders[] = $folder;
}
}
// check if this lib has urls
if (isset($library->urls)
&& ComponentbuilderHelper::checkArray($library->urls))
{
// build media folder path
$libFolder = strtolower(
preg_replace(
'/\s+/', '-',
ComponentbuilderHelper::safeString(
$library->name, 'filename', ' ', false
)
)
);
$mediaPath = '/media/' . $libFolder;
// should we add the local folder
$addLocalFolder = false;
// add to component urls
foreach ($library->urls as $n => &$url)
{
if (isset($url['type']) && $url['type'] > 1
&& isset($url['url'])
&& ComponentbuilderHelper::checkString(
$url['url']
))
{
// create media/lib path if not set
$this->createFolder(
$this->componentPath . $mediaPath
);
// add local folder
$addLocalFolder = true;
// set file name
$fileName = basename($url['url']);
// get the file contents
$data = ComponentbuilderHelper::getFileContents(
$url['url']
);
// build sub path
if (strpos($fileName, '.js') !== false)
{
$path = '/js';
}
elseif (strpos($fileName, '.css') !== false)
{
$path = '/css';
}
else
{
$path = '';
}
// create sub media path if not set
$this->createFolder(
$this->componentPath . $mediaPath . $path
);
// set the path to library file
$url['path'] = $mediaPath . $path . '/'
. $fileName; // we need this for later
// set full path
$path = $this->componentPath . $url['path'];
// write data to path
$this->writeFile($path, $data);
// count the file created
$this->fileCount++;
}
}
// only add if local
if ($addLocalFolder)
{
// add folder to xml of media folders
$this->fileContentStatic[$this->hhh
. 'EXSTRA_MEDIA_FOLDERS' . $this->hhh]
.= PHP_EOL . $this->_t(2) . "<folder>"
. $libFolder . "</folder>";
}
}
// if config fields are found load into component config (avoiding dublicates)
if (isset($library->how) && $library->how > 1
&& isset($library->config)
&& ComponentbuilderHelper::checkArray($library->config))
{
foreach ($library->config as $cofig)
{
$found = array_filter(
$this->componentData->config,
function ($item) use ($cofig) {
return $item['field'] == $cofig['field'];
}
);
// set the config data if not found
if (!ComponentbuilderHelper::checkArray($found))
{
$this->componentData->config[] = $cofig;
}
}
}
}
}
}
}
/**
* set the dynamic dashboard if set
*
* @return void
*
*/
private function setDynamicDashboard()
{
// only add the dynamic dashboard if all checks out
if (isset($this->componentData->dashboard_type)
&& 2 == $this->componentData->dashboard_type
&& isset($this->componentData->dashboard)
&& ComponentbuilderHelper::checkString(
$this->componentData->dashboard
)
&& strpos($this->componentData->dashboard, '_') !== false)
{
// set the default view
$getter = explode('_', $this->componentData->dashboard);
if (count((array) $getter) == 2 && is_numeric($getter[1]))
{
// the pointers
$t = ComponentbuilderHelper::safeString($getter[0], 'U');
$id = (int) $getter[1];
// the dynamic stuff
$targets = array('A' => 'admin_views',
'C' => 'custom_admin_views');
$names = array('A' => 'admin view',
'C' => 'custom admin view');
$types = array('A' => 'adminview', 'C' => 'customadminview');
$keys = array('A' => 'name_list', 'C' => 'code');
// check the target values
if (isset($targets[$t]) && $id > 0)
{
// set the type name
$type_names = ComponentbuilderHelper::safeString(
$targets[$t], 'w'
);
// set the dynamic dash
if (isset($this->componentData->{$targets[$t]})
&& ComponentbuilderHelper::checkArray(
$this->componentData->{$targets[$t]}
))
{
// search the target views
$dashboard = (array) array_filter(
$this->componentData->{$targets[$t]},
function ($view) use ($id, $t, $types) {
if (isset($view[$types[$t]])
&& $id == $view[$types[$t]])
{
return true;
}
return false;
}
);
// set dashboard
if (ComponentbuilderHelper::checkArray($dashboard))
{
$dashboard = array_values($dashboard)[0];
}
// check if view was found (this should be true)
if (isset($dashboard['settings'])
&& isset($dashboard['settings']->{$keys[$t]}))
{
$this->dynamicDashboard
= ComponentbuilderHelper::safeString(
$dashboard['settings']->{$keys[$t]}
);
$this->dynamicDashboardType
= $targets[$t];
}
else
{
// set massage that something is wrong
$this->app->enqueueMessage(
JText::_('<hr /><h3>Dashboard Error</h3>'),
'Error'
);
$this->app->enqueueMessage(
JText::sprintf(
'The <b>%s</b> (<b>%s</b>) is not available in your component! Please insure to only used %s, for a dynamic dashboard, that are still linked to your component.',
$names[$t], $this->componentData->dashboard,
$type_names
), 'Error'
);
}
}
else
{
// set massage that something is wrong
$this->app->enqueueMessage(
JText::_('<hr /><h3>Dashboard Error</h3>'), 'Error'
);
$this->app->enqueueMessage(
JText::sprintf(
'The <b>%s</b> (<b>%s</b>) is not available in your component! Please insure to only used %s, for a dynamic dashboard, that are still linked to your component.',
$names[$t], $this->componentData->dashboard,
$type_names
), 'Error'
);
}
}
else
{
// the target value is wrong
$this->app->enqueueMessage(
JText::_('<hr /><h3>Dashboard Error</h3>'), 'Error'
);
$this->app->enqueueMessage(
JText::sprintf(
'The <b>%s</b> value for the dynamic dashboard is invalid.',
$this->componentData->dashboard
), 'Error'
);
}
}
else
{
// the target value is wrong
$this->app->enqueueMessage(
JText::_('<hr /><h3>Dashboard Error</h3>'), 'Error'
);
$this->app->enqueueMessage(
JText::sprintf(
'The <b>%s</b> value for the dynamic dashboard is invalid.',
$this->componentData->dashboard
), 'Error'
);
}
// if default was changed to dynamic dashboard the remove default tab and methods
if (ComponentbuilderHelper::checkString($this->dynamicDashboard))
{
// dynamic dashboard is used
$this->componentData->dashboard_tab = '';
$this->componentData->php_dashboard_methods = '';
}
}
}
/**
* Write data to file
*
* @return bool true on success
*
*/
public function writeFile($path, $data)
{
return ComponentbuilderHelper::writeFile($path, $data);
}
/**
* Build the Initial Folders
*
* @return void
*
*/
private function setFolders()
{
if (ComponentbuilderHelper::checkObject(
$this->joomlaVersionData->create
))
{
// creat the main component folder
if (!Folder::exists($this->componentPath))
{
Folder::create($this->componentPath);
// count the folder created
$this->folderCount++;
$this->indexHTML('');
}
// now build all folders needed for this component
foreach ($this->joomlaVersionData->create as $main => $folders)
{
$this->createFolder($this->componentPath . '/' . $main);
if (ComponentbuilderHelper::checkObject($folders))
{
foreach ($folders as $sub => $subFolders)
{
$this->createFolder(
$this->componentPath . '/' . $main . '/' . $sub
);
if (ComponentbuilderHelper::checkObject($subFolders))
{
foreach ($subFolders as $sub_2 => $subFolders_2)
{
$this->createFolder(
$this->componentPath . '/' . $main . '/'
. $sub . '/' . $sub_2
);
if (ComponentbuilderHelper::checkObject(
$subFolders_2
))
{
foreach (
$subFolders_2 as $sub_3 => $subFolders_3
)
{
$this->createFolder(
$this->componentPath . '/' . $main
. '/' . $sub . '/' . $sub_2 . '/'
. $sub_3
);
if (ComponentbuilderHelper::checkObject(
$subFolders_3
))
{
foreach (
$subFolders_3 as $sub_4 =>
$subFolders_4
)
{
$this->createFolder(
$this->componentPath . '/'
. $main . '/' . $sub . '/'
. $sub_2 . '/' . $sub_3
. '/' . $sub_4
);
if (ComponentbuilderHelper::checkObject(
$subFolders_4
))
{
foreach (
$subFolders_4 as $sub_5
=> $subFolders_5
)
{
$this->createFolder(
$this->componentPath
. '/' . $main . '/'
. $sub . '/'
. $sub_2 . '/'
. $sub_3 . '/'
. $sub_4 . '/'
. $sub_5
);
if (ComponentbuilderHelper::checkObject(
$subFolders_5
))
{
foreach (
$subFolders_5 as
$sub_6 =>
$subFolders_6
)
{
$this->createFolder(
$this->componentPath
. '/'
. $main
. '/'
. $sub
. '/'
. $sub_2
. '/'
. $sub_3
. '/'
. $sub_4
. '/'
. $sub_5
. '/'
. $sub_6
);
if (ComponentbuilderHelper::checkObject(
$subFolders_6
))
{
foreach (
$subFolders_6
as
$sub_7
=>
$subFolders_7
)
{
$this->createFolder(
$this->componentPath
. '/'
. $main
. '/'
. $sub
. '/'
. $sub_2
. '/'
. $sub_3
. '/'
. $sub_4
. '/'
. $sub_5
. '/'
. $sub_6
. '/'
. $sub_7
);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return true;
}
return false;
}
/**
* Set the Static File & Folder
*
* @return boolean
*
*/
private function setStatic()
{
if (ComponentbuilderHelper::checkObject(
$this->joomlaVersionData->move->static
))
{
$codeName = $this->componentCodeName;
// TODO needs more looking at this must be dynamic actually
$this->notNew[] = 'LICENSE.txt';
// do license check
$LICENSE = false;
$licenseChecker = strtolower($this->componentData->license);
if (strpos($licenseChecker, 'gnu') !== false
&& strpos(
$licenseChecker, '2'
) !== false
&& (strpos($licenseChecker, 'gpl') !== false
|| strpos(
$licenseChecker, 'general public license'
) !== false))
{
$LICENSE
= true; // we only add version 2 auto at this time (TODO)
}
// do README check
$README = false;
// add the README file if needed
if ($this->componentData->addreadme)
{
$README = true;
}
// start moving
foreach (
$this->joomlaVersionData->move->static as $ftem => $details
)
{
// set item
$item = $details->naam;
// do the file renaming
if ($details->rename)
{
if ($details->rename === 'new')
{
$new = $details->newName;
}
else
{
$new = str_replace($details->rename, $codeName, $item);
}
}
else
{
$new = $item;
}
// if not gnu/gpl license dont add the LICENSE.txt file
if ($item === 'LICENSE.txt' && !$LICENSE)
{
continue;
}
// if not needed do not add
if (($item === 'README.md' || $item === 'README.txt')
&& !$README)
{
continue;
}
// check if we have a target value
if (isset($details->_target))
{
// set destination path
$zipPath = str_replace(
$details->_target['type'] . '/', '', $details->path
);
$path = str_replace(
$details->_target['type'] . '/',
$this->dynamicPaths[$details->_target['key']] . '/',
$details->path
);
}
else
{
// set destination path
$zipPath = str_replace('c0mp0n3nt/', '', $details->path);
$path = str_replace(
'c0mp0n3nt/', $this->componentPath . '/', $details->path
);
}
// set the template folder path
$templatePath = (isset($details->custom) && $details->custom)
? (($details->custom !== 'full') ? $this->templatePathCustom
. '/' : '') : $this->templatePath . '/';
// set the final paths
$currentFullPath = (preg_match('/^[a-z]:/i', $item)) ? $item
: $templatePath . '/' . $item;
$currentFullPath = str_replace('//', '/', $currentFullPath);
$packageFullPath = str_replace('//', '/', $path . '/' . $new);
$zipFullPath = str_replace(
'//', '/', $zipPath . '/' . $new
);
// now move the file
if ($details->type === 'file')
{
if (!File::exists($currentFullPath))
{
$this->app->enqueueMessage(
JText::_('<hr /><h3>File Path Error</h3>'), 'Error'
);
$this->app->enqueueMessage(
JText::sprintf(
'The file path: <b>%s</b> does not exist, and was not added!',
$currentFullPath
), 'Error'
);
}
else
{
// get base name && get the path only
$packageFullPath0nly = str_replace(
basename($packageFullPath), '', $packageFullPath
);
// check if path exist, if not creat it
if (!Folder::exists($packageFullPath0nly))
{
Folder::create($packageFullPath0nly);
}
// move the file to its place
File::copy($currentFullPath, $packageFullPath);
// count the file created
$this->fileCount++;
// store the new files
if (!in_array($ftem, $this->notNew))
{
if (isset($details->_target))
{
$this->newFiles[$details->_target['key']][]
= array('path' => $packageFullPath,
'name' => $new,
'zip' => $zipFullPath);
}
else
{
$this->newFiles['static'][]
= array('path' => $packageFullPath,
'name' => $new,
'zip' => $zipFullPath);
}
}
// ensure we update this file if needed
if (isset($this->updateFileContent[$ftem])
&& $this->updateFileContent[$ftem])
{
// remove the pointer
unset($this->updateFileContent[$ftem]);
// set the full path
$this->updateFileContent[$packageFullPath]
= $packageFullPath;
}
}
}
elseif ($details->type === 'folder')
{
if (!Folder::exists($currentFullPath))
{
$this->app->enqueueMessage(
JText::_('<hr /><h3>Folder Path Error</h3>'),
'Error'
);
$this->app->enqueueMessage(
JText::sprintf(
'The folder path: <b>%s</b> does not exist, and was not added!',
$currentFullPath
), 'Error'
);
}
else
{
// move the folder to its place
Folder::copy(
$currentFullPath, $packageFullPath, '', true
);
// count the folder created
$this->folderCount++;
}
}
// only add if no target found since those belong to plugins and modules
if (!isset($details->_target))
{
// check if we should add the dynamic folder moving script to the installer script
$checker = array_values((array) explode('/', $zipFullPath));
// TODO <-- this may not be the best way, will keep an eye on this.
// We basicly only want to check if a folder is added that is not in the stdFolders array
if (isset($checker[0])
&& ComponentbuilderHelper::checkString($checker[0])
&& !in_array($checker[0], $this->stdFolders))
{
// check if we should add the dynamic folder moving script to the installer script
if (!$this->setMoveFolders)
{
// add the setDynamicF0ld3rs() method to the install scipt.php file
$this->setMoveFolders = true;
// set message that this was done (will still add a tutorial link later)
$this->app->enqueueMessage(
JText::_(
'<hr /><h3>Dynamic folder(s) were detected.</h3>'
), 'Notice'
);
$this->app->enqueueMessage(
JText::sprintf(
'A method (setDynamicF0ld3rs) was added to the install <b>script.php</b> of this package to insure that the folder(s) are copied into the correct place when this component is installed!'
), 'Notice'
);
}
}
elseif (count((array) $checker) == 2
&& ComponentbuilderHelper::checkString($checker[0]))
{
$add_to_extra = false;
// set the target
$eNAME = 'FILES';
$ename = 'filename';
// this should not happen and must have been caught by the above if statment
if ($details->type === 'folder')
{
// only folders outside the standard folder are added
$eNAME = 'FOLDERS';
$ename = 'folder';
$add_to_extra = true;
}
// if this is a file, it can only be added to the admin/site/media folders
// all other folders are moved as a whole so their files do not need to be declared
elseif (in_array($checker[0], $this->stdFolders)
&& !in_array($checker[1], $this->stdRootFiles))
{
$add_to_extra = true;
}
// add if valid folder/file
if ($add_to_extra)
{
// set the tab
$eTab = $this->_t(2);
if ('admin' === $checker[0])
{
$eTab = $this->_t(3);
}
// set the xml file
$this->fileContentStatic[$this->hhh . 'EXSTRA_'
. ComponentbuilderHelper::safeString(
$checker[0], 'U'
) . '_' . $eNAME . $this->hhh]
.= PHP_EOL . $eTab . "<" . $ename . ">"
. $checker[1] . "</" . $ename . ">";
}
}
}
}
return true;
}
return false;
}
/**
* Set the Dynamic File & Folder
*
* @return boolean
*
*/
private function setDynamique()
{
$back = false;
$front = false;
if ((isset($this->joomlaVersionData->move->dynamic)
&& ComponentbuilderHelper::checkObject(
$this->joomlaVersionData->move->dynamic
))
&& (isset($this->componentData->admin_views)
&& ComponentbuilderHelper::checkArray(
$this->componentData->admin_views
)))
{
if (!ComponentbuilderHelper::checkString($this->dynamicDashboard))
{
// setup dashboard
$target = array('admin' => $this->componentData->name_code);
$this->buildDynamique($target, 'dashboard');
}
// now the rest of the views
foreach ($this->componentData->admin_views as $nr => $view)
{
if (ComponentbuilderHelper::checkObject($view['settings']))
{
$created = $this->getCreatedDate($view);
$modified = $this->getLastModifiedDate($view);
if ($view['settings']->name_list != 'null')
{
$target
= array('admin' => $view['settings']->name_list);
$config = array($this->hhh . 'CREATIONDATE'
. $this->hhh => $created,
$this->hhh . 'BUILDDATE'
. $this->hhh => $modified,
$this->hhh . 'VERSION'
. $this->hhh => $view['settings']->version);
$this->buildDynamique($target, 'list', false, $config);
}
if ($view['settings']->name_single != 'null')
{
$target
= array('admin' => $view['settings']->name_single);
$config = array($this->hhh . 'CREATIONDATE'
. $this->hhh => $created,
$this->hhh . 'BUILDDATE'
. $this->hhh => $modified,
$this->hhh . 'VERSION'
. $this->hhh => $view['settings']->version);
$this->buildDynamique(
$target, 'single', false, $config
);
}
if (isset($view['edit_create_site_view'])
&& is_numeric(
$view['edit_create_site_view']
)
&& $view['edit_create_site_view'] > 0)
{
// setup the front site edit-view files
$target
= array('site' => $view['settings']->name_single);
$config = array($this->hhh . 'CREATIONDATE'
. $this->hhh => $created,
$this->hhh . 'BUILDDATE'
. $this->hhh => $modified,
$this->hhh . 'VERSION'
. $this->hhh => $view['settings']->version);
$this->buildDynamique($target, 'edit', false, $config);
}
}
// quick set of checkin once
if (isset($view['checkin']) && $view['checkin'] == 1
&& !$this->addCheckin)
{
// switch to add checking to config
$this->addCheckin = true;
}
}
$back = true;
}
if ((isset($this->joomlaVersionData->move->dynamic)
&& ComponentbuilderHelper::checkObject(
$this->joomlaVersionData->move->dynamic
))
&& (isset($this->componentData->site_views)
&& ComponentbuilderHelper::checkArray(
$this->componentData->site_views
)))
{
foreach ($this->componentData->site_views as $nr => $view)
{
$created = $this->getCreatedDate($view);
$modified = $this->getLastModifiedDate($view);
if ($view['settings']->main_get->gettype == 2)
{
// set list view
$target = array('site' => $view['settings']->code);
$config = array($this->hhh . 'CREATIONDATE'
. $this->hhh => $created,
$this->hhh . 'BUILDDATE'
. $this->hhh => $modified,
$this->hhh . 'VERSION'
. $this->hhh => $view['settings']->version);
$this->buildDynamique($target, 'list', false, $config);
}
elseif ($view['settings']->main_get->gettype == 1)
{
// set single view
$target = array('site' => $view['settings']->code);
$config = array($this->hhh . 'CREATIONDATE'
. $this->hhh => $created,
$this->hhh . 'BUILDDATE'
. $this->hhh => $modified,
$this->hhh . 'VERSION'
. $this->hhh => $view['settings']->version);
$this->buildDynamique($target, 'single', false, $config);
}
}
$front = true;
}
if ((isset($this->joomlaVersionData->move->dynamic)
&& ComponentbuilderHelper::checkObject(
$this->joomlaVersionData->move->dynamic
))
&& (isset($this->componentData->custom_admin_views)
&& ComponentbuilderHelper::checkArray(
$this->componentData->custom_admin_views
)))
{
foreach ($this->componentData->custom_admin_views as $nr => $view)
{
$created = $this->getCreatedDate($view);
$modified = $this->getLastModifiedDate($view);
if ($view['settings']->main_get->gettype == 2)
{
// set list view$view
$target = array('custom_admin' => $view['settings']->code);
$config = array($this->hhh . 'CREATIONDATE'
. $this->hhh => $created,
$this->hhh . 'BUILDDATE'
. $this->hhh => $modified,
$this->hhh . 'VERSION'
. $this->hhh => $view['settings']->version);
$this->buildDynamique($target, 'list', false, $config);
}
elseif ($view['settings']->main_get->gettype == 1)
{
// set single view
$target = array('custom_admin' => $view['settings']->code);
$config = array($this->hhh . 'CREATIONDATE'
. $this->hhh => $created,
$this->hhh . 'BUILDDATE'
. $this->hhh => $modified,
$this->hhh . 'VERSION'
. $this->hhh => $view['settings']->version);
$this->buildDynamique($target, 'single', false, $config);
}
}
$back = true;
}
// check if we had success
if ($back || $front)
{
return true;
}
return false;
}
/**
* move the fields and Rules
*
* @param array $field The field data
* @param string $path The path to move to
*
* @return void
*
*/
public function moveFieldsRules($field, $path)
{
// check if we have a subform or repeatable field
if ($field['type_name'] === 'subform'
|| $field['type_name'] === 'repeatable')
{
// since we could have a custom field or rule inside
$this->moveMultiFieldsRules($field, $path);
}
else
{
// check if this is a custom field that should be moved
if (isset($this->extentionCustomfields[$field['type_name']]))
{
$check = md5($path . 'type' . $field['type_name']);
// lets check if we already moved this
if (!isset($this->extentionTrackingFilesMoved[$check]))
{
// check files exist
if (File::exists(
$this->componentPath . '/admin/models/fields/'
. $field['type_name'] . '.php'
))
{
// copy the custom field
File::copy(
$this->componentPath . '/admin/models/fields/'
. $field['type_name'] . '.php',
$path . '/fields/' . $field['type_name'] . '.php'
);
}
// stop from doing this again.
$this->extentionTrackingFilesMoved[$check] = true;
}
}
// check if this has validation that should be moved
if (isset($this->validationLinkedFields[$field['field']]))
{
$check = md5(
$path . 'rule'
. $this->validationLinkedFields[$field['field']]
);
// lets check if we already moved this
if (!isset($this->extentionTrackingFilesMoved[$check]))
{
// check files exist
if (File::exists(
$this->componentPath . '/admin/models/rules/'
. $this->validationLinkedFields[$field['field']]
. '.php'
))
{
// copy the custom field
File::copy(
$this->componentPath . '/admin/models/rules/'
. $this->validationLinkedFields[$field['field']]
. '.php', $path . '/rules/'
. $this->validationLinkedFields[$field['field']]
. '.php'
);
}
// stop from doing this again.
$this->extentionTrackingFilesMoved[$check] = true;
}
}
}
}
/**
* move the fields and Rules of multi fields
*
* @param array $multi_field The field data
* @param string $path The path to move to
*
* @return void
*
*/
protected function moveMultiFieldsRules($multi_field, $path)
{
// get the fields ids
$ids = array_map(
'trim',
explode(
',',
ComponentbuilderHelper::getBetween(
$multi_field['settings']->xml, 'fields="', '"'
)
)
);
if (ComponentbuilderHelper::checkArray($ids))
{
foreach ($ids as $id)
{
// setup the field
$field = array();
$field['field'] = $id;
$this->setFieldDetails($field);
// move field and rules if needed
$this->moveFieldsRules($field, $path);
}
}
}
/**
* get the created date of the (view)
*
* @param array $view The view values
*
* @return string Last Modified Date
*
*/
public function getCreatedDate($view)
{
if (isset($view['settings']->created)
&& ComponentbuilderHelper::checkString($view['settings']->created))
{
// first set the main date
$date = strtotime($view['settings']->created);
}
else
{
// first set the main date
$date = strtotime("now");
}
return JFactory::getDate($date)->format('jS F, Y');
}
/**
* get the last modified date of a MVC (view)
*
* @param array $view The view values
*
* @return string Last Modified Date
*
*/
public function getLastModifiedDate($view)
{
// first set the main date
if (isset($view['settings']->modified)
&& ComponentbuilderHelper::checkString($view['settings']->modified)
&& '0000-00-00 00:00:00' !== $view['settings']->modified)
{
$date = strtotime($view['settings']->modified);
}
else
{
// use todays date
$date = strtotime("now");
}
// search for the last modified date
if (isset($view['adminview']))
{
$id = $view['adminview'] . 'admin';
// now check if value has been set
if (!isset($this->lastModifiedDate[$id]))
{
if (isset($view['settings']->fields)
&& ComponentbuilderHelper::checkArray(
$view['settings']->fields
))
{
foreach ($view['settings']->fields as $field)
{
if (isset($field['settings'])
&& ComponentbuilderHelper::checkObject(
$field['settings']
)
&& isset($field['settings']->modified)
&& ComponentbuilderHelper::checkString(
$field['settings']->modified
)
&& '0000-00-00 00:00:00'
!== $field['settings']->modified)
{
$anotherDate = strtotime(
$field['settings']->modified
);
if ($anotherDate > $date)
{
$date = $anotherDate;
}
}
}
}
}
}
elseif (isset($view['siteview']))
{
$id = $view['siteview'] . 'site';
// now check if value has been set
if (!isset($this->lastModifiedDate[$id]))
{
if (isset($view['settings']->main_get->modified)
&& ComponentbuilderHelper::checkString(
$view['settings']->main_get->modified
)
&& '0000-00-00 00:00:00'
!== $view['settings']->main_get->modified)
{
$anotherDate = strtotime(
$view['settings']->main_get->modified
);
if ($anotherDate > $date)
{
$date = $anotherDate;
}
}
}
}
elseif (isset($view['customadminview']))
{
$id = $view['customadminview'] . 'customadmin';
// now check if value has been set
if (!isset($this->lastModifiedDate[$id]))
{
if (isset($view['settings']->main_get->modified)
&& ComponentbuilderHelper::checkString(
$view['settings']->main_get->modified
)
&& '0000-00-00 00:00:00'
!== $view['settings']->main_get->modified)
{
$anotherDate = strtotime(
$view['settings']->main_get->modified
);
if ($anotherDate > $date)
{
$date = $anotherDate;
}
}
}
}
// check if ID was found
if (!isset($id))
{
$id = md5($date);
}
// now load the date
if (!isset($this->lastModifiedDate[$id]))
{
$this->lastModifiedDate[$id] = $date;
}
return JFactory::getDate($this->lastModifiedDate[$id])->format(
'jS F, Y'
);
}
/**
* Set the Static File & Folder
*
* @param array $target The main target and name
* @param string $type The type in the target
* @param string $fileName The custom file name
* @param array $cofig to add more data to the files info
*
* @return boolean
*
*/
public function buildDynamique($target, $type, $fileName = false,
$config = false
) {
// did we build the files (any number)
$build_status = false;
// check that we have the target values
if (ComponentbuilderHelper::checkArray($target))
{
// search the target
foreach ($target as $main => $name)
{
// make sure it is lower case
$name = ComponentbuilderHelper::safeString($name);
// setup the files
foreach (
$this->joomlaVersionData->move->dynamic->{$main} as $item =>
$details
)
{
if ($details->type === $type)
{
// set destination path
$path = '';
if (strpos($details->path, 'VIEW') !== false)
{
$path = str_replace('VIEW', $name, $details->path);
}
else
{
$path = $details->path;
}
// make sure we have component to replace
if (strpos($path, 'c0mp0n3nt') !== false)
{
$zipPath = str_replace('c0mp0n3nt/', '', $path);
$path = str_replace(
'c0mp0n3nt/', $this->componentPath . '/', $path
);
}
else
{
$this->app->enqueueMessage(
JText::sprintf(
'<hr /><h3>c0mp0n3nt issue found</h3><p>The path (%s) could not be used.</p>',
$path
), 'Error'
);
continue;
}
// setup the folder
if (!Folder::exists($path))
{
Folder::create($path);
$this->indexHTML($zipPath);
// count the folder created
$this->folderCount++;
}
// do the file renaming
if ($details->rename)
{
if ($fileName)
{
$new = str_replace(
$details->rename, $fileName, $item
);
$name = $name . '_' . $fileName;
}
elseif ($details->rename === 'new')
{
$new = $details->newName;
}
else
{
$new = str_replace(
$details->rename, $name, $item
);
}
}
else
{
$new = $item;
}
if (!File::exists($path . '/' . $new))
{
// move the file to its place
File::copy(
$this->templatePath . '/' . $item,
$path . '/' . $new
);
// count the file created
$this->fileCount++;
}
// setup array for new file
$newFIle = array('path' => $path . '/' . $new,
'name' => $new, 'view' => $name,
'zip' => $zipPath . '/' . $new);
if (ComponentbuilderHelper::checkArray($config))
{
$newFIle['config'] = $config;
}
// store the new files
$this->newFiles['dynamic'][$name][] = $newFIle;
// we have build atleast one
$build_status = true;
}
}
}
}
return $build_status;
}
/**
* set the Joomla Version Data
*
* @return object The version data
*
*/
private function setJoomlaVersionData()
{
// set the version data
$versionData = json_decode(
ComponentbuilderHelper::getFileContents(
$this->templatePath . '/settings.json'
)
);
// add custom folders
if ((isset($this->componentData->folders)
&& ComponentbuilderHelper::checkArray(
$this->componentData->folders
))
|| $this->addEximport
|| $this->uikit
|| $this->footable)
{
if ($this->addEximport)
{
// move the import view folder in place
$importView = array('folder' => 'importViews',
'path' => 'admin/views/import',
'rename' => 1);
$this->componentData->folders[] = $importView;
// move the phpspreadsheet Folder (TODO we must move this to a library package)
$PHPExcel
= array('folderpath' => 'JPATH_LIBRARIES/phpspreadsheet/vendor',
'path' => '/libraries/phpspreadsheet/',
'rename' => 0);
$this->componentData->folders[] = $PHPExcel;
}
if (2 == $this->uikit || 1 == $this->uikit)
{
// move the UIKIT Folder into place
$uikit = array('folder' => 'uikit-v2',
'path' => 'media',
'rename' => 0);
$this->componentData->folders[] = $uikit;
}
if (2 == $this->uikit || 3 == $this->uikit)
{
// move the UIKIT-3 Folder into place
$uikit = array('folder' => 'uikit-v3',
'path' => 'media',
'rename' => 0);
$this->componentData->folders[] = $uikit;
}
if ($this->footable
&& (!isset($this->footableVersion)
|| 2 == $this->footableVersion))
{
// move the footable folder into place
$footable = array('folder' => 'footable-v2',
'path' => 'media',
'rename' => 0);
$this->componentData->folders[] = $footable;
}
elseif ($this->footable && 3 == $this->footableVersion)
{
// move the footable folder into place
$footable = array('folder' => 'footable-v3',
'path' => 'media',
'rename' => 0);
$this->componentData->folders[] = $footable;
}
// pointer tracker
$pointer_tracker = 'h';
foreach ($this->componentData->folders as $custom)
{
// check type of target type
$_target_type = 'c0mp0n3nt';
if (isset($custom['target_type']))
{
$_target_type = $custom['target_type'];
}
// for good practice
ComponentbuilderHelper::fixPath(
$custom, array('path', 'folder', 'folderpath')
);
// fix custom path
if (isset($custom['path'])
&& ComponentbuilderHelper::checkString($custom['path']))
{
$custom['path'] = trim($custom['path'], '/');
}
// by default custom path is true
$customPath = 'custom';
// set full path if this is a full path folder
if (!isset($custom['folder']) && isset($custom['folderpath']))
{
// update the dynamic path
$custom['folderpath'] = $this->updateDynamicPath(
$custom['folderpath']
);
// set the folder path with / if does not have a drive/windows full path
$custom['folder'] = (preg_match(
'/^[a-z]:/i', $custom['folderpath']
))
? trim($custom['folderpath'], '/')
: '/' . trim($custom['folderpath'], '/');
// remove the file path
unset($custom['folderpath']);
// triget fullpath
$customPath = 'full';
}
// make sure we use the correct name
$pathArray = (array) explode('/', $custom['path']);
$firstFolder = array_values($pathArray)[0];
$lastFolder = end($pathArray);
// only rename folder if last has folder name
if (isset($custom['rename']) && $custom['rename'] == 1)
{
$custom['path'] = str_replace(
'/' . $lastFolder, '', $custom['path']
);
$rename = 'new';
$newname = $lastFolder;
}
elseif ('full' === $customPath)
{
// make sure we use the correct name
$folderArray = (array) explode('/', $custom['folder']);
$lastFolder = end($folderArray);
$rename = 'new';
$newname = $lastFolder;
}
else
{
$lastFolder = $custom['folder'];
$rename = false;
$newname = '';
}
// insure we have no duplicates
$key_pointer = ComponentbuilderHelper::safeString(
$custom['folder']
) . '_f' . $pointer_tracker;
$pointer_tracker++;
// fix custom path
$custom['path'] = ltrim($custom['path'], '/');
// set new folder to object
$versionData->move->static->{$key_pointer} = new stdClass(
);
$versionData->move->static->{$key_pointer}->naam
= str_replace(
'//', '/', $custom['folder']
);
$versionData->move->static->{$key_pointer}->path
= $_target_type
. '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = $rename;
$versionData->move->static->{$key_pointer}->newName = $newname;
$versionData->move->static->{$key_pointer}->type = 'folder';
$versionData->move->static->{$key_pointer}->custom
= $customPath;
// set the target if type and id is found
if (isset($custom['target_id'])
&& isset($custom['target_type']))
{
$versionData->move->static->{$key_pointer}->_target
= array('key' => $custom['target_id'] . '_'
. $custom['target_type'],
'type' => $custom['target_type']);
}
}
unset($this->componentData->folders);
unset($custom);
}
// add custom files
if ((isset($this->componentData->files)
&& ComponentbuilderHelper::checkArray(
$this->componentData->files
))
|| $this->googlechart)
{
if ($this->googlechart)
{
// move the google chart files
$googleChart = array('file' => 'google.jsapi.js',
'path' => 'media/js',
'rename' => 0);
$this->componentData->files[] = $googleChart;
$googleChart
= array('file' => 'chartbuilder.php',
'path' => 'admin/helpers',
'rename' => 0);
$this->componentData->files[] = $googleChart;
}
// pointer tracker
$pointer_tracker = 'h';
foreach ($this->componentData->files as $custom)
{
// check type of target type
$_target_type = 'c0mp0n3nt';
if (isset($custom['target_type']))
{
$_target_type = $custom['target_type'];
}
// for good practice
ComponentbuilderHelper::fixPath(
$custom, array('path', 'file', 'filepath')
);
// by default custom path is true
$customPath = 'custom';
// set full path if this is a full path file
if (!isset($custom['file']) && isset($custom['filepath']))
{
// update the dynamic path
$custom['filepath'] = $this->updateDynamicPath(
$custom['filepath']
);
// set the file path with / if does not have a drive/windows full path
$custom['file'] = (preg_match(
'/^[a-z]:/i', $custom['filepath']
))
? trim($custom['filepath'], '/')
: '/' . trim($custom['filepath'], '/');
// remove the file path
unset($custom['filepath']);
// triget fullpath
$customPath = 'full';
}
// make sure we have not duplicates
$key_pointer = ComponentbuilderHelper::safeString(
$custom['file']
) . '_g' . $pointer_tracker;
$pointer_tracker++;
// set new file to object
$versionData->move->static->{$key_pointer} = new stdClass(
);
$versionData->move->static->{$key_pointer}->naam = str_replace(
'//', '/', $custom['file']
);
// update the dynamic component name placholders in file names
$custom['path'] = $this->setPlaceholders(
$custom['path'], $this->placeholders
);
// get the path info
$pathInfo = pathinfo($custom['path']);
if (isset($pathInfo['extension']) && $pathInfo['extension'])
{
$pathInfo['dirname'] = trim($pathInfo['dirname'], '/');
// set the info
$versionData->move->static->{$key_pointer}->path
= $_target_type
. '/' . $pathInfo['dirname'];
$versionData->move->static->{$key_pointer}->rename = 'new';
$versionData->move->static->{$key_pointer}->newName
= $pathInfo['basename'];
}
elseif ('full' === $customPath)
{
// fix custom path
$custom['path'] = ltrim($custom['path'], '/');
// get file array
$fileArray = (array) explode('/', $custom['file']);
// set the info
$versionData->move->static->{$key_pointer}->path
= $_target_type
. '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = 'new';
$versionData->move->static->{$key_pointer}->newName = end(
$fileArray
);
}
else
{
// fix custom path
$custom['path'] = ltrim($custom['path'], '/');
// set the info
$versionData->move->static->{$key_pointer}->path
= $_target_type
. '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = false;
}
$versionData->move->static->{$key_pointer}->type = 'file';
$versionData->move->static->{$key_pointer}->custom
= $customPath;
// set the target if type and id is found
if (isset($custom['target_id'])
&& isset($custom['target_type']))
{
$versionData->move->static->{$key_pointer}->_target
= array('key' => $custom['target_id'] . '_'
. $custom['target_type'],
'type' => $custom['target_type']);
}
// check if file should be updated
if (!isset($custom['notnew']) || $custom['notnew'] == 0
|| $custom['notnew'] != 1)
{
$this->notNew[] = $key_pointer;
}
else
{
// update the file content
$this->updateFileContent[$key_pointer] = true;
}
}
unset($this->componentData->files);
unset($custom);
}
return $versionData;
}
/**
* set the index.html file in a folder path
*
* @param string $path The path to place the index.html file in
*
* @return void
*
*/
private function indexHTML($path, $root = 'component')
{
if ('component' === $root)
{
$root = $this->componentPath . '/';
}
// use path if exist
if (strlen($path) > 0)
{
File::copy(
$this->templatePath . '/index.html',
$root . $path . '/index.html'
);
// count the file created
$this->fileCount++;
}
else
{
File::copy(
$this->templatePath . '/index.html', $root . '/index.html'
);
// count the file created
$this->fileCount++;
}
}
/**
* Update paths with real value
*
* @param string $path The full path
*
* @return string The updated path
*
*/
protected function updateDynamicPath($path)
{
return $this->setPlaceholders(
$this->setPlaceholders(
$path, ComponentbuilderHelper::$constantPaths
), $this->placeholders
);
}
/**
* Remove folders with files
*
* @param string $dir The path to folder to remove
* @param boolean $ignore The files and folders to ignore
*
* @return boolean True if all is removed
*
*/
protected function removeFolder($dir, $ignore = false)
{
return ComponentbuilderHelper::removeFolder($dir, $ignore);
}
}