605 lines
14 KiB
Plaintext
605 lines
14 KiB
Plaintext
/**
|
|
* The new name
|
|
*
|
|
* @var string
|
|
* @since 3.2.0
|
|
*/
|
|
protected string $newName;
|
|
|
|
/**
|
|
* Current Full Path
|
|
*
|
|
* @var string
|
|
* @since 3.2.0
|
|
*/
|
|
protected string $currentFullPath;
|
|
|
|
/**
|
|
* Package Full Path
|
|
*
|
|
* @var string
|
|
* @since 3.2.0
|
|
*/
|
|
protected string $packageFullPath;
|
|
|
|
/**
|
|
* ZIP Full Path
|
|
*
|
|
* @var string
|
|
* @since 3.2.0
|
|
*/
|
|
protected string $zipFullPath;
|
|
|
|
/**
|
|
* The Config Class.
|
|
*
|
|
* @var Config
|
|
* @since 3.2.0
|
|
*/
|
|
protected Config $config;
|
|
|
|
/**
|
|
* The Registry Class.
|
|
*
|
|
* @var Registry
|
|
* @since 3.2.0
|
|
*/
|
|
protected Registry $registry;
|
|
|
|
/**
|
|
* The Placeholder Class.
|
|
*
|
|
* @var Placeholder
|
|
* @since 3.2.0
|
|
*/
|
|
protected Placeholder $placeholder;
|
|
|
|
/**
|
|
* The SettingsInterface Class.
|
|
*
|
|
* @var Settings
|
|
* @since 3.2.0
|
|
*/
|
|
protected Settings $settings;
|
|
|
|
/**
|
|
* The Component Class.
|
|
*
|
|
* @var Component
|
|
* @since 3.2.0
|
|
*/
|
|
protected Component $component;
|
|
|
|
/**
|
|
* The ContentOne Class.
|
|
*
|
|
* @var Content
|
|
* @since 3.2.0
|
|
*/
|
|
protected Content $content;
|
|
|
|
/**
|
|
* The Counter Class.
|
|
*
|
|
* @var Counter
|
|
* @since 3.2.0
|
|
*/
|
|
protected Counter $counter;
|
|
|
|
/**
|
|
* The Paths Class.
|
|
*
|
|
* @var Paths
|
|
* @since 3.2.0
|
|
*/
|
|
protected Paths $paths;
|
|
|
|
/**
|
|
* The Files Class.
|
|
*
|
|
* @var Files
|
|
* @since 3.2.0
|
|
*/
|
|
protected Files $files;
|
|
|
|
/**
|
|
* Application object.
|
|
*
|
|
* @var CMSApplication
|
|
* @since 3.2.0
|
|
**/
|
|
protected CMSApplication $app;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param Config $config The Config Class.
|
|
* @param Registry $registry The Registry Class.
|
|
* @param Placeholder $placeholder The Placeholder Class.
|
|
* @param Settings $settings The SettingsInterface Class.
|
|
* @param Component $component The Component Class.
|
|
* @param Content $content The ContentOne Class.
|
|
* @param Counter $counter The Counter Class.
|
|
* @param Paths $paths The Paths Class.
|
|
* @param Files $files The Files Class.
|
|
* @param CMSApplication|null $app The CMS Application object.
|
|
*
|
|
* @since 3.2.0
|
|
*/
|
|
public function __construct(Config $config, Registry $registry,
|
|
Placeholder $placeholder, Settings $settings,
|
|
Component $component, Content $content, Counter $counter,
|
|
Paths $paths, Files $files, ?CMSApplication $app = null)
|
|
{
|
|
$this->config = $config;
|
|
$this->registry = $registry;
|
|
$this->placeholder = $placeholder;
|
|
$this->settings = $settings;
|
|
$this->component = $component;
|
|
$this->content = $content;
|
|
$this->counter = $counter;
|
|
$this->paths = $paths;
|
|
$this->files = $files;
|
|
$this->app = $app ?: Factory::getApplication();
|
|
}
|
|
|
|
/**
|
|
* Build the Single Files & Folders
|
|
*
|
|
* @return bool
|
|
* @since 3.2.0
|
|
*/
|
|
public function build(): bool
|
|
{
|
|
if ($this->settings->exists())
|
|
{
|
|
// TODO needs more looking at this must be dynamic actually
|
|
$this->registry->appendArray('files.not.new', 'LICENSE.txt');
|
|
|
|
// do license check
|
|
$LICENSE = $this->doLicenseCheck();
|
|
|
|
// do README check
|
|
$README = $this->doReadmeCheck();
|
|
|
|
// do CHANGELOG check
|
|
$CHANGELOG = $this->doChangelogCheck();
|
|
|
|
// start moving
|
|
foreach ($this->settings->single() as $target => $details)
|
|
{
|
|
// if not gnu/gpl license dont add the LICENSE.txt file
|
|
if ($details->naam === 'LICENSE.txt' && !$LICENSE)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// if not needed do not add
|
|
if (($details->naam === 'README.md' || $details->naam === 'README.txt')
|
|
&& !$README)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// if not needed do not add
|
|
if ($details->naam === 'CHANGELOG.md' && !$CHANGELOG)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// set new name
|
|
$this->setNewName($details);
|
|
|
|
// set all paths
|
|
$this->setPaths($details);
|
|
|
|
// check if the path exists
|
|
if ($this->pathExist($details))
|
|
{
|
|
// set the target
|
|
$this->setTarget($target, $details);
|
|
}
|
|
|
|
// set dynamic target as needed
|
|
$this->setDynamicTarget($details);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if license must be added
|
|
*
|
|
* @return bool
|
|
* @since 3.2.0
|
|
*/
|
|
private function doLicenseCheck(): bool
|
|
{
|
|
$licenseChecker = strtolower((string) $this->component->get('license', ''));
|
|
|
|
if (strpos($licenseChecker, 'gnu') !== false
|
|
&& strpos(
|
|
$licenseChecker, '2'
|
|
) !== false
|
|
&& (strpos($licenseChecker, 'gpl') !== false
|
|
|| strpos(
|
|
$licenseChecker, 'general public license'
|
|
) !== false))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if readme must be added
|
|
*
|
|
* @return bool
|
|
* @since 3.2.0
|
|
*/
|
|
private function doReadmeCheck(): bool
|
|
{
|
|
return (bool) $this->component->get('addreadme', false);
|
|
}
|
|
|
|
/**
|
|
* Check if changelog must be added
|
|
*
|
|
* @return bool
|
|
* @since 3.2.0
|
|
*/
|
|
private function doChangelogCheck(): bool
|
|
{
|
|
return (bool) $this->component->get('changelog', false);
|
|
}
|
|
|
|
/**
|
|
* Set the new name
|
|
*
|
|
* @param object $details
|
|
*
|
|
* @return void
|
|
* @since 3.2.0
|
|
*/
|
|
private function setNewName(object $details)
|
|
{
|
|
// do the file renaming
|
|
if (isset($details->rename) && $details->rename)
|
|
{
|
|
if ($details->rename === 'new')
|
|
{
|
|
$newName = $details->newName;
|
|
}
|
|
else
|
|
{
|
|
$naam = $details->naam ?? 'error';
|
|
$newName = str_replace(
|
|
$details->rename,
|
|
$this->config->component_code_name,
|
|
(string) $naam
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$newName = $details->naam ?? 'error';
|
|
}
|
|
|
|
$this->newName = $this->placeholder->update_($newName);
|
|
}
|
|
|
|
/**
|
|
* Set all needed paths
|
|
*
|
|
* @param object $details
|
|
*
|
|
* @return void
|
|
* @since 3.2.0
|
|
*/
|
|
private function setPaths(object $details)
|
|
{
|
|
// check if we have a target value
|
|
if (isset($details->_target))
|
|
{
|
|
// set destination path
|
|
$zipPath = str_replace(
|
|
$details->_target['type'] . '/', '', (string) $details->path
|
|
);
|
|
$path = str_replace(
|
|
$details->_target['type'] . '/',
|
|
$this->registry->get('dynamic_paths.' . $details->_target['key'], '') . '/',
|
|
(string) $details->path
|
|
);
|
|
}
|
|
else
|
|
{
|
|
// set destination path
|
|
$zipPath = str_replace('c0mp0n3nt/', '', (string) $details->path);
|
|
$path = str_replace(
|
|
'c0mp0n3nt/', $this->paths->component_path . '/', (string) $details->path
|
|
);
|
|
}
|
|
|
|
// set the template folder path
|
|
$templatePath = (isset($details->custom) && $details->custom)
|
|
? (($details->custom !== 'full') ? $this->paths->template_path_custom
|
|
. '/' : '') : $this->paths->template_path . '/';
|
|
|
|
// set the final paths
|
|
$currentFullPath = (preg_match('/^[a-z]:/i', (string) $details->naam)) ? $details->naam
|
|
: $templatePath . '/' . $details->naam;
|
|
|
|
$this->currentFullPath = str_replace('//', '/', (string) $currentFullPath);
|
|
|
|
$this->packageFullPath = str_replace('//', '/', $path . '/' . $this->newName);
|
|
|
|
$this->zipFullPath = str_replace(
|
|
'//', '/', $zipPath . '/' . $this->newName
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if path exists
|
|
*
|
|
* @param object $details
|
|
*
|
|
* @return bool
|
|
* @since 3.2.0
|
|
*/
|
|
private function pathExist(object $details): bool
|
|
{
|
|
// check if this has a type
|
|
if (!isset($details->type))
|
|
{
|
|
return false;
|
|
}
|
|
// take action based on type
|
|
elseif ($details->type === 'file' && !File::exists($this->currentFullPath))
|
|
{
|
|
$this->app->enqueueMessage(
|
|
Text::_('<hr /><h3>File Path Error</h3>'), 'Error'
|
|
);
|
|
$this->app->enqueueMessage(
|
|
Text::sprintf('The file path: <b>%s</b> does not exist, and was not added!',
|
|
$this->currentFullPath
|
|
), 'Error'
|
|
);
|
|
|
|
return false;
|
|
}
|
|
elseif ($details->type === 'folder' && !Folder::exists($this->currentFullPath))
|
|
{
|
|
$this->app->enqueueMessage(
|
|
Text::_('<hr /><h3>Folder Path Error</h3>'),
|
|
'Error'
|
|
);
|
|
$this->app->enqueueMessage(
|
|
Text::sprintf('The folder path: <b>%s</b> does not exist, and was not added!',
|
|
$this->currentFullPath
|
|
), 'Error'
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set the target based on target type
|
|
*
|
|
* @param string $target
|
|
* @param object $details
|
|
*
|
|
* @return void
|
|
* @since 3.2.0
|
|
*/
|
|
private function setTarget(string $target, object $details)
|
|
{
|
|
// take action based on type
|
|
if ($details->type === 'file')
|
|
{
|
|
// move the file
|
|
$this->moveFile();
|
|
|
|
// register the file
|
|
$this->registerFile($target, $details);
|
|
}
|
|
elseif ($details->type === 'folder')
|
|
{
|
|
// move the folder to its place
|
|
Folder::copy(
|
|
$this->currentFullPath, $this->packageFullPath, '', true
|
|
);
|
|
|
|
// count the folder created
|
|
$this->counter->folder++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Move/Copy the file into place
|
|
*
|
|
* @return void
|
|
* @since 3.2.0
|
|
*/
|
|
private function moveFile()
|
|
{
|
|
// get base name && get the path only
|
|
$packageFullPath0nly = str_replace(
|
|
basename($this->packageFullPath), '', $this->packageFullPath
|
|
);
|
|
|
|
// check if path exist, if not creat it
|
|
if (!Folder::exists($packageFullPath0nly))
|
|
{
|
|
Folder::create($packageFullPath0nly);
|
|
}
|
|
|
|
// move the file to its place
|
|
File::copy($this->currentFullPath, $this->packageFullPath);
|
|
|
|
// count the file created
|
|
$this->counter->file++;
|
|
}
|
|
|
|
/**
|
|
* Register the file
|
|
*
|
|
* @param string $target
|
|
* @param object $details
|
|
*
|
|
* @return void
|
|
* @since 3.2.0
|
|
*/
|
|
private function registerFile(string $target, object $details)
|
|
{
|
|
// store the new files
|
|
if (!in_array($target, $this->registry->get('files.not.new', [])))
|
|
{
|
|
if (isset($details->_target))
|
|
{
|
|
$this->files->appendArray($details->_target['key'],
|
|
[
|
|
'path' => $this->packageFullPath,
|
|
'name' => $this->newName,
|
|
'zip' => $this->zipFullPath
|
|
]
|
|
);
|
|
}
|
|
else
|
|
{
|
|
$this->files->appendArray('static',
|
|
[
|
|
'path' => $this->packageFullPath,
|
|
'name' => $this->newName,
|
|
'zip' => $this->zipFullPath
|
|
]
|
|
);
|
|
}
|
|
}
|
|
|
|
// ensure we update this file if needed
|
|
if ($this->registry->exists('update.file.content.' . $target))
|
|
{
|
|
// remove the pointer
|
|
$this->registry->remove('update.file.content.' . $target);
|
|
|
|
// set the full path
|
|
$this->registry->set('update.file.content.' . $this->packageFullPath, $this->packageFullPath);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set Dynamic Target
|
|
*
|
|
* @param object $details
|
|
*
|
|
* @return void
|
|
* @since 3.2.0
|
|
*/
|
|
private function setDynamicTarget(object $details)
|
|
{
|
|
// 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('/', $this->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])
|
|
&& StringHelper::check($checker[0])
|
|
&& !$this->settings->standardFolder($checker[0]))
|
|
{
|
|
// activate dynamic folders
|
|
$this->setDynamicFolders();
|
|
}
|
|
elseif (count((array) $checker) == 2
|
|
&& StringHelper::check($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 ($this->settings->standardFolder($checker[0])
|
|
&& !$this->settings->standardRootFile($checker[1]))
|
|
{
|
|
$add_to_extra = true;
|
|
}
|
|
|
|
// add if valid folder/file
|
|
if ($add_to_extra)
|
|
{
|
|
// set the tab
|
|
$eTab = Indent::_(2);
|
|
if ('admin' === $checker[0])
|
|
{
|
|
$eTab = Indent::_(3);
|
|
}
|
|
|
|
// set the xml file
|
|
$key_ = 'EXSTRA_'
|
|
. StringHelper::safe(
|
|
$checker[0], 'U'
|
|
) . '_' . $eNAME;
|
|
$this->content->add($key_,
|
|
PHP_EOL . $eTab . "<" . $ename . ">"
|
|
. $checker[1] . "</" . $ename . ">");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add the dynamic folders
|
|
*
|
|
* @return void
|
|
* @since 3.2.0
|
|
*/
|
|
private function setDynamicFolders()
|
|
{
|
|
// check if we should add the dynamic folder moving script to the installer script
|
|
if (!$this->registry->get('set_move_folders_install_script'))
|
|
{
|
|
// add the setDynamicF0ld3rs() method to the install scipt.php file
|
|
$this->registry->set('set_move_folders_install_script', true);
|
|
|
|
$function = 'setDynamicF0ld3rs';
|
|
$script = 'script.php';
|
|
if ($this->config->get('joomla_version', 3) != 3)
|
|
{
|
|
$function = 'moveFolders';
|
|
$script = 'ComponentnameInstallerScript.php';
|
|
}
|
|
|
|
// set message that this was done (will still add a tutorial link later)
|
|
$this->app->enqueueMessage(
|
|
Text::_('<hr /><h3>Dynamic folder(s) were detected.</h3>'),
|
|
'Notice'
|
|
);
|
|
|
|
$this->app->enqueueMessage(
|
|
Text::sprintf('A method (%s) was added to the install <b>%s</b> of this package to insure that the folder(s) are copied into the correct place when this component is installed!',
|
|
$function, $script
|
|
),
|
|
'Notice'
|
|
);
|
|
}
|
|
} |