2023-03-21 22:52:57 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @package Joomla.Component.Builder
|
|
|
|
*
|
|
|
|
* @created 4th September, 2022
|
|
|
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
|
|
|
* @git Joomla Component Builder <https://git.vdm.dev/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
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace VDM\Joomla\Componentbuilder\Compiler\Utilities;
|
|
|
|
|
|
|
|
|
|
|
|
use Joomla\CMS\Factory;
|
|
|
|
use Joomla\CMS\Application\CMSApplication;
|
|
|
|
use Joomla\CMS\Language\Text;
|
|
|
|
use Joomla\CMS\Filesystem\File as JoomlaFile;
|
|
|
|
use Joomla\CMS\Filesystem\Folder;
|
2024-01-27 07:09:33 +00:00
|
|
|
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
|
|
|
|
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component\SettingsInterface as Settings;
|
2023-03-21 22:52:57 +00:00
|
|
|
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths;
|
|
|
|
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
|
|
|
|
use VDM\Joomla\Componentbuilder\Compiler\Utilities\File;
|
|
|
|
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files;
|
|
|
|
use VDM\Joomla\Utilities\ArrayHelper;
|
|
|
|
use VDM\Joomla\Utilities\StringHelper;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compiler Utilities To Build Structure
|
|
|
|
*
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
class Structure
|
|
|
|
{
|
|
|
|
/**
|
2024-01-27 07:09:33 +00:00
|
|
|
* The Placeholder Class.
|
2023-03-21 22:52:57 +00:00
|
|
|
*
|
2024-01-27 07:09:33 +00:00
|
|
|
* @var Placeholder
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
protected Placeholder $placeholder;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The SettingsInterface Class.
|
|
|
|
*
|
|
|
|
* @var Settings
|
2023-03-21 22:52:57 +00:00
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
protected Settings $settings;
|
|
|
|
|
|
|
|
/**
|
2024-01-27 07:09:33 +00:00
|
|
|
* The Paths Class.
|
2023-03-21 22:52:57 +00:00
|
|
|
*
|
2024-01-27 07:09:33 +00:00
|
|
|
* @var Paths
|
2023-03-21 22:52:57 +00:00
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
protected Paths $paths;
|
|
|
|
|
|
|
|
/**
|
2024-01-27 07:09:33 +00:00
|
|
|
* The Counter Class.
|
2023-03-21 22:52:57 +00:00
|
|
|
*
|
2024-01-27 07:09:33 +00:00
|
|
|
* @var Counter
|
2023-03-21 22:52:57 +00:00
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
protected Counter $counter;
|
|
|
|
|
|
|
|
/**
|
2024-01-27 07:09:33 +00:00
|
|
|
* The File Class.
|
2023-03-21 22:52:57 +00:00
|
|
|
*
|
2024-01-27 07:09:33 +00:00
|
|
|
* @var File
|
2023-03-21 22:52:57 +00:00
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
protected File $file;
|
|
|
|
|
|
|
|
/**
|
2024-01-27 07:09:33 +00:00
|
|
|
* The Files Class.
|
2023-03-21 22:52:57 +00:00
|
|
|
*
|
2024-01-27 07:09:33 +00:00
|
|
|
* @var Files
|
2023-03-21 22:52:57 +00:00
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
protected Files $files;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Database object to query local DB
|
|
|
|
*
|
|
|
|
* @var CMSApplication
|
|
|
|
* @since 3.2.0
|
|
|
|
**/
|
|
|
|
protected CMSApplication $app;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*
|
2024-01-27 07:09:33 +00:00
|
|
|
* @param Placeholder $placeholder The Placeholder Class.
|
|
|
|
* @param Settings $settings The SettingsInterface Class.
|
|
|
|
* @param Paths $paths The Paths Class.
|
|
|
|
* @param Counter $counter The Counter Class.
|
|
|
|
* @param File $file The File Class.
|
|
|
|
* @param Files $files The Files Class.
|
|
|
|
* @param CMSApplication|null $app The CMS Application object.
|
2023-03-21 22:52:57 +00:00
|
|
|
*
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
2024-01-27 07:09:33 +00:00
|
|
|
public function __construct(Placeholder $placeholder, Settings $settings, Paths $paths,
|
|
|
|
Counter $counter, File $file, Files $files, ?CMSApplication $app = null)
|
2023-03-21 22:52:57 +00:00
|
|
|
{
|
2024-01-27 07:09:33 +00:00
|
|
|
$this->placeholder = $placeholder;
|
|
|
|
$this->settings = $settings;
|
|
|
|
$this->paths = $paths;
|
|
|
|
$this->counter = $counter;
|
|
|
|
$this->file = $file;
|
|
|
|
$this->files = $files;
|
2023-03-21 22:52:57 +00:00
|
|
|
$this->app = $app ?: Factory::getApplication();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Build Structural Needed Files & Folders
|
|
|
|
*
|
|
|
|
* @param array $target The main target and name
|
|
|
|
* @param string $type The type in the target
|
|
|
|
* @param string|null $fileName The custom file name
|
|
|
|
* @param array|null $config To add more data to the files info
|
|
|
|
*
|
|
|
|
* @return bool true on success
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
public function build(array $target, string $type,
|
|
|
|
?string $fileName = null, ?array $config = null): bool
|
|
|
|
{
|
|
|
|
// did we build the files (any number)
|
|
|
|
$build_status = false;
|
|
|
|
|
|
|
|
// check that we have the target values
|
|
|
|
if (ArrayHelper::check($target))
|
|
|
|
{
|
|
|
|
// search the target
|
|
|
|
foreach ($target as $main => $name)
|
|
|
|
{
|
2024-01-27 07:09:33 +00:00
|
|
|
// get the key name (either file name or name)
|
|
|
|
$key = $fileName ?? $name;
|
|
|
|
|
|
|
|
// add to placeholders as Name and name
|
|
|
|
$this->placeholder->set('Name', StringHelper::safe($name, 'F'));
|
|
|
|
$this->placeholder->set('name', StringHelper::safe($name));
|
|
|
|
$this->placeholder->set('Key', StringHelper::safe($key, 'F'));
|
|
|
|
$this->placeholder->set('key', StringHelper::safe($key));
|
|
|
|
|
2023-03-21 22:52:57 +00:00
|
|
|
// make sure it is lower case
|
|
|
|
$name = StringHelper::safe($name);
|
|
|
|
|
|
|
|
// setup the files
|
|
|
|
foreach ($this->settings->multiple()->{$main} as $item => $details)
|
|
|
|
{
|
|
|
|
if ($details->type === $type)
|
|
|
|
{
|
|
|
|
$file_details = $this->getFileDetails(
|
|
|
|
$details,
|
|
|
|
(string) $item,
|
|
|
|
$name,
|
|
|
|
$fileName,
|
|
|
|
$config
|
|
|
|
);
|
|
|
|
|
|
|
|
if (is_array($file_details))
|
|
|
|
{
|
|
|
|
// store the new files
|
|
|
|
$this->files->appendArray('dynamic.' . $file_details['view'],
|
|
|
|
$file_details);
|
|
|
|
|
|
|
|
// we have build at least one
|
|
|
|
$build_status = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-01-27 07:09:33 +00:00
|
|
|
|
|
|
|
// remove the name from placeholders
|
|
|
|
$this->placeholder->remove('Name');
|
|
|
|
$this->placeholder->remove('name');
|
|
|
|
$this->placeholder->remove('Key');
|
|
|
|
$this->placeholder->remove('key');
|
2023-03-21 22:52:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $build_status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the details
|
|
|
|
*
|
|
|
|
* @param object $details The item details
|
|
|
|
* @param string $item The item name
|
|
|
|
* @param string $name The given name
|
|
|
|
* @param string|null $fileName The custom file name
|
|
|
|
* @param array|null $config To add more data to the files info
|
|
|
|
*
|
|
|
|
* @return array|null The details
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
private function getFileDetails(object $details, string $item,
|
|
|
|
string $name, ?string $fileName = null, ?array $config = null): ?array
|
|
|
|
{
|
|
|
|
$zip_path = '';
|
|
|
|
if (($path = $this->getPath($details, $zip_path, $name)) === null)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// setup the folder
|
|
|
|
if (!Folder::exists($path))
|
|
|
|
{
|
|
|
|
Folder::create($path);
|
|
|
|
$this->file->html($zip_path);
|
|
|
|
|
|
|
|
// count the folder created
|
|
|
|
$this->counter->folder++;
|
|
|
|
}
|
|
|
|
|
|
|
|
$new_name = $this->getNewName($details, $item, $name, $fileName);
|
|
|
|
|
|
|
|
if (!JoomlaFile::exists($path . '/' . $new_name))
|
|
|
|
{
|
|
|
|
// move the file to its place
|
|
|
|
JoomlaFile::copy(
|
|
|
|
$this->paths->template_path . '/' . $item,
|
|
|
|
$path . '/' . $new_name
|
|
|
|
);
|
|
|
|
|
|
|
|
// count the file created
|
|
|
|
$this->counter->file++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// we can't have dots in a view name
|
|
|
|
if (strpos($name, '.') !== false)
|
|
|
|
{
|
|
|
|
$name = preg_replace('/[\.]+/', '_', (string) $name);
|
|
|
|
}
|
|
|
|
|
|
|
|
// setup array for new file
|
|
|
|
$file = [
|
|
|
|
'path' => $path . '/' . $new_name,
|
|
|
|
'name' => $new_name,
|
|
|
|
'view' => $name,
|
|
|
|
'zip' => $zip_path . '/' . $new_name
|
|
|
|
];
|
|
|
|
|
|
|
|
if (ArrayHelper::check($config))
|
|
|
|
{
|
|
|
|
$file['config'] = $config;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $file;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the path
|
|
|
|
*
|
|
|
|
* @param object $details The item details
|
|
|
|
* @param string $zipPath The zip path
|
|
|
|
* @param string $name The name
|
|
|
|
*
|
|
|
|
* @return string|null The path
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
private function getPath(object $details, string &$zipPath, string $name): ?string
|
|
|
|
{
|
|
|
|
// set destination path
|
|
|
|
if (strpos((string) $details->path, 'VIEW') !== false)
|
|
|
|
{
|
|
|
|
$path = str_replace('VIEW', $name, (string) $details->path);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$path = $details->path;
|
|
|
|
}
|
2024-01-27 07:09:33 +00:00
|
|
|
|
|
|
|
$path = $this->placeholder->update_($path);
|
2023-03-21 22:52:57 +00:00
|
|
|
|
|
|
|
// make sure we have component to replace
|
|
|
|
if (strpos((string) $path, 'c0mp0n3nt') !== false)
|
|
|
|
{
|
|
|
|
$zipPath = str_replace('c0mp0n3nt/', '', (string) $path);
|
|
|
|
|
|
|
|
return str_replace(
|
|
|
|
'c0mp0n3nt/', $this->paths->component_path . '/', (string) $path
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->app->enqueueMessage(
|
|
|
|
Text::sprintf('COM_COMPONENTBUILDER_HR_HTHREECZEROMPZERONTHREENT_ISSUE_FOUNDHTHREEPTHE_PATH_S_COULD_NOT_BE_USEDP',
|
|
|
|
$path
|
|
|
|
), 'Error'
|
|
|
|
);
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the new name
|
|
|
|
*
|
|
|
|
* @param object $details The item details
|
|
|
|
* @param string $item The item name
|
|
|
|
* @param string $name The name
|
|
|
|
* @param string|null $fileName The custom file name
|
|
|
|
*
|
|
|
|
* @return string The new name
|
|
|
|
* @since 3.2.0
|
|
|
|
*/
|
|
|
|
private function getNewName(object $details, string $item,
|
|
|
|
string &$name, ?string $fileName = null): string
|
|
|
|
{
|
|
|
|
// do the file need renaming
|
|
|
|
if ($details->rename)
|
|
|
|
{
|
|
|
|
if (!empty($fileName))
|
|
|
|
{
|
|
|
|
$name = $name . '_' . $fileName;
|
2024-01-27 07:09:33 +00:00
|
|
|
}
|
2023-03-21 22:52:57 +00:00
|
|
|
|
2024-01-27 07:09:33 +00:00
|
|
|
if ($details->rename === 'new')
|
|
|
|
{
|
|
|
|
$item = $details->newName;
|
|
|
|
}
|
|
|
|
elseif (!empty($fileName))
|
|
|
|
{
|
|
|
|
$item = str_replace(
|
2023-03-21 22:52:57 +00:00
|
|
|
$details->rename, $fileName, $item
|
|
|
|
);
|
|
|
|
}
|
2024-01-27 07:09:33 +00:00
|
|
|
else
|
2023-03-21 22:52:57 +00:00
|
|
|
{
|
2024-01-27 07:09:33 +00:00
|
|
|
$item = str_replace(
|
|
|
|
$details->rename, $name, $item
|
|
|
|
);
|
2023-03-21 22:52:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-27 07:09:33 +00:00
|
|
|
return $this->placeholder->update_($item);
|
|
|
|
}
|
2023-03-21 22:52:57 +00:00
|
|
|
}
|
|
|
|
|