forked from joomla/Component-Builder
Adds the customcode extractor class
This commit is contained in:
parent
abe9b5d227
commit
0512af0f33
@ -140,14 +140,14 @@ TODO
|
||||
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
|
||||
+ *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
+ *First Build*: 30th April, 2015
|
||||
+ *Last Build*: 31st August, 2022
|
||||
+ *Last Build*: 2nd September, 2022
|
||||
+ *Version*: 3.1.5
|
||||
+ *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
|
||||
+ *Line count*: **319873**
|
||||
+ *Line count*: **321348**
|
||||
+ *Field count*: **2002**
|
||||
+ *File count*: **2090**
|
||||
+ *Folder count*: **359**
|
||||
+ *File count*: **2094**
|
||||
+ *Folder count*: **360**
|
||||
|
||||
> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com).
|
||||
> Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)
|
||||
|
@ -140,14 +140,14 @@ TODO
|
||||
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
|
||||
+ *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
+ *First Build*: 30th April, 2015
|
||||
+ *Last Build*: 31st August, 2022
|
||||
+ *Last Build*: 2nd September, 2022
|
||||
+ *Version*: 3.1.5
|
||||
+ *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
|
||||
+ *Line count*: **319873**
|
||||
+ *Line count*: **321348**
|
||||
+ *Field count*: **2002**
|
||||
+ *File count*: **2090**
|
||||
+ *Folder count*: **359**
|
||||
+ *File count*: **2094**
|
||||
+ *Folder count*: **360**
|
||||
|
||||
> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com).
|
||||
> Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3679,8 +3679,10 @@ abstract class ComponentbuilderHelper
|
||||
|
||||
|
||||
/**
|
||||
* prepare base64 string for url
|
||||
**/
|
||||
* prepare base64 string for url
|
||||
*
|
||||
* @deprecate Use urlencode();
|
||||
*/
|
||||
public static function base64_urlencode($string, $encode = false)
|
||||
{
|
||||
if ($encode)
|
||||
@ -3691,8 +3693,10 @@ abstract class ComponentbuilderHelper
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare base64 string form url
|
||||
**/
|
||||
* prepare base64 string form url
|
||||
*
|
||||
* @deprecate
|
||||
*/
|
||||
public static function base64_urldecode($string, $decode = false)
|
||||
{
|
||||
$string = str_replace(array('-', '_'), array('+', '/'), $string);
|
||||
|
@ -5597,6 +5597,7 @@ COM_COMPONENTBUILDER_HI="Hi"
|
||||
COM_COMPONENTBUILDER_HIDE_ONLY="Hide Only"
|
||||
COM_COMPONENTBUILDER_HIDE_TOGGLE="Hide Toggle"
|
||||
COM_COMPONENTBUILDER_HOW_TO_GET_A_S_FREE_KEYSA_FROM_VDM="How to get <a %s >free keys</a> from VDM."
|
||||
COM_COMPONENTBUILDER_HR_HTHREECUSTOM_CODES_WARNINGHTHREE="<hr /><h3>Custom Codes Warning</h3>"
|
||||
COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_ERRORHTHREE="<hr /><h3>External Code Error</h3>"
|
||||
COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_NOTICEHTHREE="<hr /><h3>External Code Notice</h3>"
|
||||
COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_WARNINGHTHREE="<hr /><h3>External Code Warning</h3>"
|
||||
@ -9361,6 +9362,7 @@ COM_COMPONENTBUILDER_WEBSITE_OF_S="Website of %s"
|
||||
COM_COMPONENTBUILDER_WEBSITE_S="Website: %s"
|
||||
COM_COMPONENTBUILDER_WE_DID_NOT_CHECK_THE_SNIPPET_IT_SELF_TO_SEE_IF_IT_CHANGED_WE_ONLY_WORK_ON_DATES="We did not check the snippet it self, to see if it changed. We only work on dates."
|
||||
COM_COMPONENTBUILDER_WE_FAILED_TO_MOVE_BSB="We failed to move <b>%s</b>!"
|
||||
COM_COMPONENTBUILDER_WE_FOUND_DYNAMIC_CODE_BALL_IN_ONE_LINEB_AND_IGNORED_IT_PLEASE_REVIEW_S_FOR_MORE_DETAILS="We found dynamic code <b>all in one line</b>, and ignored it! Please review (%s) for more details!"
|
||||
COM_COMPONENTBUILDER_WE_SUCCESSFULLY_MOVED_BSB="We successfully moved <b>%s</b>!"
|
||||
COM_COMPONENTBUILDER_WHILE_WE_DOWNLOAD_ALL_TWENTY_SIX_COMPILER_GIF_ANIMATIONS_RANDOMLY_USED_IN_THE_COMPILER_GUI_DURING_COMPILATION="While we download all 26 compiler GIF animations randomly used in the compiler GUI during compilation"
|
||||
COM_COMPONENTBUILDER_WIKI="Wiki"
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<extension type="component" version="4" method="upgrade">
|
||||
<name>COM_COMPONENTBUILDER</name>
|
||||
<creationDate>31st August, 2022</creationDate>
|
||||
<creationDate>2nd September, 2022</creationDate>
|
||||
<author>Llewellyn van der Merwe</author>
|
||||
<authorEmail>joomla@vdm.io</authorEmail>
|
||||
<authorUrl>https://dev.vdm.io</authorUrl>
|
||||
|
@ -36,14 +36,6 @@ class Dispenser
|
||||
**/
|
||||
public array $hub;
|
||||
|
||||
/**
|
||||
* Compiler Customcode
|
||||
*
|
||||
* @var Customcode
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Customcode $customcode;
|
||||
|
||||
/**
|
||||
* Compiler Placeholder
|
||||
*
|
||||
@ -52,6 +44,14 @@ class Dispenser
|
||||
**/
|
||||
protected Placeholder $placeholder;
|
||||
|
||||
/**
|
||||
* Compiler Customcode
|
||||
*
|
||||
* @var Customcode
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Customcode $customcode;
|
||||
|
||||
/**
|
||||
* Compiler Customcode in Gui
|
||||
*
|
||||
@ -79,8 +79,8 @@ class Dispenser
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Customcode|null $customcode The compiler customcode object.
|
||||
* @param Placeholder|null $placeholder The compiler placeholder object.
|
||||
* @param Customcode|null $customcode The compiler customcode object.
|
||||
* @param Gui|null $gui The compiler customcode gui object.
|
||||
* @param Hash|null $hash The compiler customcode hash object.
|
||||
* @param LockBase|null $base64 The compiler customcode lock base64 object.
|
||||
|
@ -0,0 +1,927 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Component.Builder
|
||||
*
|
||||
* @created 30th April, 2015
|
||||
* @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\Customcode;
|
||||
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\User\User;
|
||||
use Joomla\CMS\Filesystem\Folder;
|
||||
use Joomla\CMS\Application\CMSApplication;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use VDM\Joomla\Utilities\ArrayHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Config;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Extractor\Paths;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Placeholder\Reverse;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Path;
|
||||
|
||||
|
||||
/**
|
||||
* Compiler Custom Code Extractor
|
||||
*
|
||||
* The custom script placeholders - we use the (xxx) to avoid detection it should be (***)
|
||||
* ##################################---> PHP/JS ---####################################
|
||||
*
|
||||
* New Insert Code = /xxx[INSERT>$$$$]xxx/ /xxx[/INSERT>$$$$]xxx/
|
||||
* New Replace Code = /xxx[REPLACE>$$$$]xxx/ /xxx[/REPLACE>$$$$]xxx/
|
||||
*
|
||||
* //////////////////////////////// when JCB adds it back //////////////////////////////////
|
||||
* JCB Add Inserted Code = /xxx[INSERTED$$$$]xxx//xx23xx/ /xxx[/INSERTED$$$$]xxx/
|
||||
* JCB Add Replaced Code = /xxx[REPLACED$$$$]xxx//xx25xx/ /xxx[/REPLACED$$$$]xxx/
|
||||
*
|
||||
* /////////////////////////////// changeing existing custom code /////////////////////////
|
||||
* Update Inserted Code = /xxx[INSERTED>$$$$]xxx//xx23xx/ /xxx[/INSERTED>$$$$]xxx/
|
||||
* Update Replaced Code = /xxx[REPLACED>$$$$]xxx//xx25xx/ /xxx[/REPLACED>$$$$]xxx/
|
||||
*
|
||||
* The custom script placeholders - we use the (==) to avoid detection it should be (--)
|
||||
* ###################################---> HTML ---#####################################
|
||||
*
|
||||
* New Insert Code = !==[INSERT>$$$$]==> !==[/INSERT>$$$$]==>
|
||||
* New Replace Code = !==[REPLACE>$$$$]==> !==[/REPLACE>$$$$]==>
|
||||
*
|
||||
* ///////////////////////////////// when JCB adds it back ///////////////////////////////
|
||||
* JCB Add Inserted Code =
|
||||
* JCB Add Replaced Code =
|
||||
*
|
||||
* //////////////////////////// changeing existing custom code ///////////////////////////
|
||||
* Update Inserted Code = !==[INSERTED>$$$$]==> !==[/INSERTED>$$$$]==>
|
||||
* Update Replaced Code = !==[REPLACED>$$$$]==> !==[/REPLACED>$$$$]==>
|
||||
*
|
||||
* ////////23 is the ID of the code in the system don't change it!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*
|
||||
* More info read: https://git.vdm.dev/joomla/Component-Builder/wiki/TIPS:-Custom-Code
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Extractor
|
||||
{
|
||||
/**
|
||||
* The placeholder keys
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected array $PKeys
|
||||
= [
|
||||
1 => 'REPLACE<>$$$$]',
|
||||
2 => 'INSERT<>$$$$]',
|
||||
3 => 'REPLACED<>$$$$]',
|
||||
4 => 'INSERTED<>$$$$]'
|
||||
];
|
||||
|
||||
/**
|
||||
* The custom code in local files that already exist in system
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected array $existing = [];
|
||||
|
||||
/**
|
||||
* The custom code in local files that are new
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected array $new = [];
|
||||
|
||||
/**
|
||||
* The index of code already loaded
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected array $done = [];
|
||||
|
||||
/**
|
||||
* The search counter
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected array $counter = [1 => 0, 2 => 0];
|
||||
|
||||
/**
|
||||
* The file types to search
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected array $fileTypes = ['\.php', '\.js', '\.xml'];
|
||||
|
||||
/**
|
||||
* The local placeholders
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected array $placeholders;
|
||||
|
||||
/**
|
||||
* Today's date in SQL format
|
||||
*
|
||||
* @var string
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected string $today;
|
||||
|
||||
/**
|
||||
* Compiler Config
|
||||
*
|
||||
* @var Config
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Config $config;
|
||||
|
||||
/**
|
||||
* Compiler Customcode Gui
|
||||
*
|
||||
* @var Gui
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Gui $gui;
|
||||
|
||||
/**
|
||||
* Compiler Customcode Extractor Paths
|
||||
*
|
||||
* @var Paths
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Paths $paths;
|
||||
|
||||
/**
|
||||
* Compiler Placeholder Reverse
|
||||
*
|
||||
* @var Reverse
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Reverse $reverse;
|
||||
|
||||
/**
|
||||
* Compiler Component Placeholder
|
||||
*
|
||||
* @var Placeholder
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Placeholder $componentPlaceholder;
|
||||
|
||||
/**
|
||||
* Current User Object
|
||||
*
|
||||
* @var User
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected User $user;
|
||||
|
||||
/**
|
||||
* Database object to query local DB
|
||||
*
|
||||
* @var \JDatabaseDriver
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected \JDatabaseDriver $db;
|
||||
|
||||
/**
|
||||
* Database object to query local DB
|
||||
*
|
||||
* @var CMSApplication
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected CMSApplication $app;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Config|null $config The compiler config object.
|
||||
* @param Gui|null $gui The compiler customcode gui object.
|
||||
* @param Paths|null $paths The compiler customcode extractor paths object.
|
||||
* @param Reverse|null $reverse The compiler placeholder reverse object.
|
||||
* @param Placeholder|null $placeholder The compiler component placeholder object.
|
||||
* @param User|null $user The current User object.
|
||||
* @param \JDatabaseDriver|null $db The Database Driver object.
|
||||
* @param CMSApplication|null $app The CMS Application object.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function __construct(?Config $config = null, ?Gui $gui = null, ?Paths $paths = null,
|
||||
?Reverse $reverse = null, ?Placeholder $placeholder = null,
|
||||
?User $user = null, ?\JDatabaseDriver $db = null, ?CMSApplication $app = null)
|
||||
{
|
||||
$this->config = $config ?: Compiler::_('Config');
|
||||
$this->gui = $gui ?: Compiler::_('Customcode.Gui');
|
||||
$this->paths = $paths ?: Compiler::_('Customcode.Extractor.Paths');
|
||||
$this->reverse = $reverse ?: Compiler::_('Placeholder.Reverse');
|
||||
$this->componentPlaceholder = $placeholder ?: Compiler::_('Component.Placeholder');
|
||||
$this->user = $user ?: Factory::getUser();
|
||||
$this->db = $db ?: Factory::getDbo();
|
||||
$this->app = $app ?: Factory::getApplication();
|
||||
|
||||
// set today's date
|
||||
$this->today = Factory::getDate()->toSql();
|
||||
|
||||
// set some local placeholders
|
||||
$placeholders = array_flip(
|
||||
$this->componentPlaceholder->get()
|
||||
);
|
||||
|
||||
$placeholders[StringHelper::safe(
|
||||
$this->config->component_code_name, 'F'
|
||||
) . 'Helper::'] = Placefix::_('Component') . 'Helper::';
|
||||
|
||||
$placeholders['COM_' . StringHelper::safe(
|
||||
$this->config->component_code_name, 'U'
|
||||
)] = 'COM_' . Placefix::_('COMPONENT');
|
||||
|
||||
$placeholders['com_' . $this->config->component_code_name] = 'com_' . Placefix::_('component');
|
||||
|
||||
// set the local placeholders
|
||||
$this->placeholders = array_reverse($placeholders, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the custom code from the local files
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// we must first store the current working directory
|
||||
$joomla = getcwd();
|
||||
|
||||
foreach ($this->paths->active as $target => $path)
|
||||
{
|
||||
// we are changing the working directory to the component path
|
||||
chdir($path);
|
||||
foreach ($this->fileTypes as $type)
|
||||
{
|
||||
// get a list of files in the current directory tree (only PHP, JS and XML for now)
|
||||
$files = Folder::files('.', $type, true, true);
|
||||
|
||||
// check if files found
|
||||
if (ArrayHelper::check($files))
|
||||
{
|
||||
foreach ($files as $file)
|
||||
{
|
||||
// search the file
|
||||
$this->searchFileContent($file, $target);
|
||||
|
||||
// insert new code
|
||||
$this->insert(100);
|
||||
|
||||
// update existing custom code
|
||||
$this->update(30);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// change back to Joomla working directory
|
||||
chdir($joomla);
|
||||
|
||||
// make sure all code is stored
|
||||
$this->insert();
|
||||
// update existing custom code
|
||||
$this->update();
|
||||
}
|
||||
|
||||
/**
|
||||
* search a file for placeholders and store result
|
||||
*
|
||||
* @param string $file The file path to search
|
||||
*
|
||||
* @return array on success
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function searchFileContent(&$file, &$target)
|
||||
{
|
||||
// we add a new search for the GUI CODE Blocks
|
||||
$this->gui->search($file, $this->placeholders, $this->today, $target);
|
||||
|
||||
// reset each time per file
|
||||
$loadEndFingerPrint = false;
|
||||
$endFingerPrint = [];
|
||||
$fingerPrint = [];
|
||||
$codeBucket = [];
|
||||
$pointer = [];
|
||||
$reading = [];
|
||||
$reader = 0;
|
||||
|
||||
// reset found Start type
|
||||
$commentType = 0;
|
||||
|
||||
// make sure we have the path correct (the script file is not in admin path for example)
|
||||
// there may be more... will nead to keep our eye on this... since files could be moved during install
|
||||
$file = str_replace('./', '', $file); # TODO (windows path issues)
|
||||
|
||||
if ($file !== 'script.php')
|
||||
{
|
||||
$path = $target . '/' . $file;
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = $file;
|
||||
}
|
||||
|
||||
// now we go line by line
|
||||
foreach (new \SplFileObject($file) as $lineNumber => $lineContent)
|
||||
{
|
||||
// we must keep last few lines to dynamic find target entry later
|
||||
$fingerPrint[$lineNumber] = trim($lineContent);
|
||||
|
||||
// load the end fingerprint
|
||||
if ($loadEndFingerPrint)
|
||||
{
|
||||
$endFingerPrint[$lineNumber] = trim($lineContent);
|
||||
}
|
||||
|
||||
foreach ($this->PKeys as $type => $search)
|
||||
{
|
||||
$i = (int) ($type == 3 || $type == 4) ? 2 : 1;
|
||||
$_type = (int) ($type == 1 || $type == 3) ? 1 : 2;
|
||||
|
||||
if ($reader === 0 || $reader === $i)
|
||||
{
|
||||
$targetKey = $type;
|
||||
|
||||
$start = '/***[' . $search . '***/';
|
||||
$end = '/***[/' . $search . '***/';
|
||||
$startHTML = '<!--[' . $search . '-->';
|
||||
$endHTML = '<!--[/' . $search . '-->';
|
||||
|
||||
// check if the ending placeholder was found
|
||||
if (isset($reading[$targetKey]) && $reading[$targetKey]
|
||||
&& ((trim($lineContent) === $end
|
||||
|| strpos($lineContent, $end) !== false)
|
||||
|| (trim($lineContent) === $endHTML
|
||||
|| strpos($lineContent, $endHTML) !== false)))
|
||||
{
|
||||
// trim the placeholder and if there is still data then load it
|
||||
if (isset($endReplace)
|
||||
&& ($_line = $this->addLineChecker($endReplace, 2, $lineContent)) !== false)
|
||||
{
|
||||
$codeBucket[$pointer[$targetKey]][] = $_line;
|
||||
}
|
||||
|
||||
// deactivate the reader
|
||||
$reading[$targetKey] = false;
|
||||
|
||||
if ($_type == 2)
|
||||
{
|
||||
// deactivate search
|
||||
$reader = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// activate fingerPrint for replacement end target
|
||||
$loadEndFingerPrint = true;
|
||||
$backupTargetKey = $targetKey;
|
||||
$backupI = $i;
|
||||
}
|
||||
|
||||
// all new records we can do a bulk insert
|
||||
if ($i === 1)
|
||||
{
|
||||
// end the bucket info for this code block
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
(int) $lineNumber
|
||||
); // 'toline'
|
||||
|
||||
// first reverse engineer this code block
|
||||
$c0de = $this->reverse->engine(
|
||||
implode('', $codeBucket[$pointer[$targetKey]]),
|
||||
$this->placeholders, $target
|
||||
);
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
base64_encode($c0de)
|
||||
); // 'code'
|
||||
|
||||
if ($_type == 2)
|
||||
{
|
||||
// load the last value
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(0); // 'hashendtarget'
|
||||
}
|
||||
}
|
||||
// the record already exist so we must update instead
|
||||
elseif ($i === 2)
|
||||
{
|
||||
// end the bucket info for this code block
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('to_line') . ' = '
|
||||
. $this->db->quote($lineNumber);
|
||||
|
||||
// first reverse engineer this code block
|
||||
$c0de = $this->reverse->engine(
|
||||
implode('', $codeBucket[$pointer[$targetKey]]),
|
||||
$this->placeholders, $target,
|
||||
$this->existing[$pointer[$targetKey]]['id']
|
||||
);
|
||||
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('code') . ' = '
|
||||
. $this->db->quote(base64_encode($c0de));
|
||||
|
||||
if ($_type == 2)
|
||||
{
|
||||
// load the last value
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('hashendtarget')
|
||||
. ' = ' . $this->db->quote(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if the endfingerprint is ready to save
|
||||
if (count((array) $endFingerPrint) === 3)
|
||||
{
|
||||
$hashendtarget = '3__' . md5(
|
||||
implode('', $endFingerPrint)
|
||||
);
|
||||
|
||||
// all new records we can do a bulk insert
|
||||
if ($i === 1)
|
||||
{
|
||||
// load the last value
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
$hashendtarget
|
||||
); // 'hashendtarget'
|
||||
}
|
||||
// the record already exist so we must update
|
||||
elseif ($i === 2)
|
||||
{
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('hashendtarget') . ' = '
|
||||
. $this->db->quote($hashendtarget);
|
||||
}
|
||||
|
||||
// reset the needed values
|
||||
$endFingerPrint = [];
|
||||
$loadEndFingerPrint = false;
|
||||
|
||||
// deactivate reader (to allow other search)
|
||||
$reader = 0;
|
||||
}
|
||||
|
||||
// then read in the code
|
||||
if (isset($reading[$targetKey]) && $reading[$targetKey])
|
||||
{
|
||||
$codeBucket[$pointer[$targetKey]][] = $lineContent;
|
||||
}
|
||||
|
||||
// see if the custom code line starts now with PHP/JS comment type
|
||||
if ((!isset($reading[$targetKey]) || !$reading[$targetKey])
|
||||
&& (($i === 1 && trim($lineContent) === $start)
|
||||
|| strpos($lineContent, $start) !== false))
|
||||
{
|
||||
$commentType = 1; // PHP/JS type
|
||||
$startReplace = $start;
|
||||
$endReplace = $end;
|
||||
}
|
||||
// see if the custom code line starts now with HTML comment type
|
||||
elseif ((!isset($reading[$targetKey])
|
||||
|| !$reading[$targetKey])
|
||||
&& (($i === 1 && trim($lineContent) === $startHTML)
|
||||
|| strpos($lineContent, $startHTML) !== false))
|
||||
{
|
||||
$commentType = 2; // HTML type
|
||||
$startReplace = $startHTML;
|
||||
$endReplace = $endHTML;
|
||||
}
|
||||
|
||||
// check if the starting place holder was found
|
||||
if ($commentType > 0)
|
||||
{
|
||||
// if we have all on one line we have a problem (don't load it TODO)
|
||||
if (strpos($lineContent, $endReplace) !== false)
|
||||
{
|
||||
// reset found comment type
|
||||
$commentType = 0;
|
||||
$this->app->enqueueMessage(
|
||||
Text::_('COM_COMPONENTBUILDER_HR_HTHREECUSTOM_CODES_WARNINGHTHREE'),
|
||||
'Warning'
|
||||
);
|
||||
$this->app->enqueueMessage(
|
||||
Text::sprintf('COM_COMPONENTBUILDER_WE_FOUND_DYNAMIC_CODE_BALL_IN_ONE_LINEB_AND_IGNORED_IT_PLEASE_REVIEW_S_FOR_MORE_DETAILS',
|
||||
$path
|
||||
), 'Warning'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// do a quick check to insure we have an id
|
||||
$id = false;
|
||||
if ($i === 2)
|
||||
{
|
||||
$id = $this->getSystemID(
|
||||
$lineContent,
|
||||
array(1 => $start, 2 => $startHTML),
|
||||
$commentType
|
||||
);
|
||||
}
|
||||
|
||||
if ($i === 2 && $id > 0)
|
||||
{
|
||||
// make sure we update it only once even if found again.
|
||||
if (isset($this->done[$id]))
|
||||
{
|
||||
// reset found comment type
|
||||
$commentType = 0;
|
||||
continue;
|
||||
}
|
||||
// store the id to avoid duplication
|
||||
$this->done[$id] = (int) $id;
|
||||
}
|
||||
|
||||
// start replace
|
||||
$startReplace = $this->setStartReplace(
|
||||
$id, $commentType, $startReplace
|
||||
);
|
||||
|
||||
// set active reader (to lock out other search)
|
||||
$reader = $i;
|
||||
|
||||
// set pointer
|
||||
$pointer[$targetKey] = $this->counter[$i];
|
||||
|
||||
// activate the reader
|
||||
$reading[$targetKey] = true;
|
||||
|
||||
// start code bucket
|
||||
$codeBucket[$pointer[$targetKey]] = [];
|
||||
|
||||
// trim the placeholder and if there is still data then load it
|
||||
if ($_line = $this->addLineChecker(
|
||||
$startReplace, 1, $lineContent
|
||||
))
|
||||
{
|
||||
$codeBucket[$pointer[$targetKey]][] = $_line;
|
||||
}
|
||||
|
||||
// get the finger print around the custom code
|
||||
$inFinger = count($fingerPrint);
|
||||
$getFinger = $inFinger - 1;
|
||||
$hasharray = array_slice(
|
||||
$fingerPrint, -$inFinger, $getFinger, true
|
||||
);
|
||||
$hasleng = count($hasharray);
|
||||
$hashtarget = $hasleng . '__' . md5(
|
||||
implode('', $hasharray)
|
||||
);
|
||||
|
||||
// for good practice
|
||||
Path::fix($path);
|
||||
|
||||
// all new records we can do a bulk insert
|
||||
if ($i === 1 || !$id)
|
||||
{
|
||||
// start the bucket for this code
|
||||
$this->new[$pointer[$targetKey]] = [];
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
$path
|
||||
); // 'path'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
(int) $_type
|
||||
); // 'type'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
1
|
||||
); // 'target'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
$commentType
|
||||
); // 'comment_type'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
(int) $this->config->component_id
|
||||
); // 'component'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
1
|
||||
); // 'published'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
$this->today
|
||||
); // 'created'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
(int) $this->user->id
|
||||
); // 'created_by'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
1
|
||||
); // 'version'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
1
|
||||
); // 'access'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
$hashtarget
|
||||
); // 'hashtarget'
|
||||
|
||||
$this->new[$pointer[$targetKey]][]
|
||||
= $this->db->quote(
|
||||
(int) $lineNumber
|
||||
); // 'fromline'
|
||||
|
||||
}
|
||||
// the record already exist so we must update instead
|
||||
elseif ($i === 2 && $id > 0)
|
||||
{
|
||||
// start the bucket for this code
|
||||
$this->existing[$pointer[$targetKey]] = [];
|
||||
$this->existing[$pointer[$targetKey]]['id']
|
||||
= (int) $id;
|
||||
$this->existing[$pointer[$targetKey]]['conditions'] = [];
|
||||
$this->existing[$pointer[$targetKey]]['conditions'][]
|
||||
= $this->db->quoteName('id') . ' = '
|
||||
. $this->db->quote($id);
|
||||
$this->existing[$pointer[$targetKey]]['fields'] = [];
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('path') . ' = '
|
||||
. $this->db->quote($path);
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('type') . ' = '
|
||||
. $this->db->quote($_type);
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('comment_type') . ' = '
|
||||
. $this->db->quote($commentType);
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('component') . ' = '
|
||||
. $this->db->quote($this->config->component_id);
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('from_line') . ' = '
|
||||
. $this->db->quote($lineNumber);
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('modified') . ' = '
|
||||
. $this->db->quote($this->today);
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('modified_by') . ' = '
|
||||
. $this->db->quote($this->user->id);
|
||||
$this->existing[$pointer[$targetKey]]['fields'][]
|
||||
= $this->db->quoteName('hashtarget') . ' = '
|
||||
. $this->db->quote($hashtarget);
|
||||
}
|
||||
else // this should actualy never happen
|
||||
{
|
||||
// de activate the reader
|
||||
$reading[$targetKey] = false;
|
||||
$reader = 0;
|
||||
}
|
||||
|
||||
// reset found comment type
|
||||
$commentType = 0;
|
||||
// update the counter
|
||||
$this->counter[$i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure only a few lines is kept at a time
|
||||
if (count((array) $fingerPrint) > 10)
|
||||
{
|
||||
$fingerPrint = array_slice($fingerPrint, -6, 6, true);
|
||||
}
|
||||
}
|
||||
|
||||
// if the code is at the end of the page and there were not three more lines
|
||||
if (count((array) $endFingerPrint) > 0 || $loadEndFingerPrint)
|
||||
{
|
||||
if (count((array) $endFingerPrint) > 0)
|
||||
{
|
||||
$leng = count($endFingerPrint);
|
||||
$hashendtarget = $leng . '__' . md5(
|
||||
implode('', $endFingerPrint)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$hashendtarget = 0;
|
||||
}
|
||||
|
||||
// all new records we can do a buldk insert
|
||||
if ($backupI === 1)
|
||||
{
|
||||
// load the last value
|
||||
$this->new[$pointer[$backupTargetKey]][]
|
||||
= $this->db->quote($hashendtarget); // 'hashendtarget'
|
||||
}
|
||||
// the record already exist so we must use module to update
|
||||
elseif ($backupI === 2)
|
||||
{
|
||||
$this->existing[$pointer[$backupTargetKey]]['fields'][]
|
||||
= $this->db->quoteName('hashendtarget') . ' = '
|
||||
. $this->db->quote($hashendtarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the code
|
||||
*
|
||||
* @param int $when To set when to update
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function insert(int $when = 1)
|
||||
{
|
||||
if (ArrayHelper::check($this->new) >= $when)
|
||||
{
|
||||
// Create a new query object.
|
||||
$query = $this->db->getQuery(true);
|
||||
$continue = false;
|
||||
// Insert columns.
|
||||
$columns = array('path', 'type', 'target', 'comment_type',
|
||||
'component', 'published', 'created', 'created_by',
|
||||
'version', 'access', 'hashtarget', 'from_line',
|
||||
'to_line', 'code', 'hashendtarget');
|
||||
// Prepare the insert query.
|
||||
$query->insert(
|
||||
$this->db->quoteName('#__componentbuilder_custom_code')
|
||||
);
|
||||
$query->columns($this->db->quoteName($columns));
|
||||
foreach ($this->new as $values)
|
||||
{
|
||||
if (count((array) $values) == 15)
|
||||
{
|
||||
$query->values(implode(',', $values));
|
||||
$continue = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO line mismatch... should not happen
|
||||
}
|
||||
}
|
||||
// clear the values array
|
||||
$this->new = [];
|
||||
if (!$continue)
|
||||
{
|
||||
return; // insure we don't continue if no values were loaded
|
||||
}
|
||||
// Set the query using our newly populated query object and execute it.
|
||||
$this->db->setQuery($query);
|
||||
$this->db->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the code
|
||||
*
|
||||
* @param int $when To set when to update
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function update(int $when = 1)
|
||||
{
|
||||
if (ArrayHelper::check($this->existing) >= $when)
|
||||
{
|
||||
foreach ($this->existing as $code)
|
||||
{
|
||||
// Create a new query object.
|
||||
$query = $this->db->getQuery(true);
|
||||
// Prepare the update query.
|
||||
$query->update(
|
||||
$this->db->quoteName('#__componentbuilder_custom_code')
|
||||
)->set($code['fields'])->where($code['conditions']);
|
||||
// Set the query using our newly populated query object and execute it.
|
||||
$this->db->setQuery($query);
|
||||
$this->db->execute();
|
||||
}
|
||||
// clear the values array
|
||||
$this->existing = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set the start replace placeholder
|
||||
*
|
||||
* @param int $id The comment id
|
||||
* @param int $commentType The comment type
|
||||
* @param string $startReplace The main replace string
|
||||
*
|
||||
* @return string on success
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function setStartReplace(int $id, int $commentType, string $startReplace): string
|
||||
{
|
||||
if ($id > 0)
|
||||
{
|
||||
switch ($commentType)
|
||||
{
|
||||
case 1: // the PHP & JS type
|
||||
$startReplace .= '/*' . $id . '*/';
|
||||
break;
|
||||
case 2: // the HTML type
|
||||
$startReplace .= '<!--' . $id . '-->';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $startReplace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this line should be added
|
||||
*
|
||||
* @param string $replaceKey The key to remove from line
|
||||
* @param int $type The line type
|
||||
* @param string $lineContent The line to check
|
||||
*
|
||||
* @return bool|int true on success
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function addLineChecker(string $replaceKey, int $type, string $lineContent)
|
||||
{
|
||||
$check = explode($replaceKey, $lineContent);
|
||||
switch ($type)
|
||||
{
|
||||
case 1:
|
||||
// beginning of code
|
||||
if (isset($check[1]) && StringHelper::check($check[1]))
|
||||
{
|
||||
return trim($check[1]);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// end of code
|
||||
if (isset($check[0]) && StringHelper::check($check[0]))
|
||||
{
|
||||
return trim($check[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* search for the system id in the line given
|
||||
*
|
||||
* @param string $lineContent The file path to search
|
||||
* @param array $placeholders The values to search for
|
||||
* @param int $commentType The comment type
|
||||
*
|
||||
* @return mixed on success
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function getSystemID(string &$lineContent, array $placeholders, int $commentType)
|
||||
{
|
||||
$trim = '/';
|
||||
if ($commentType == 2)
|
||||
{
|
||||
$trim = '<!--';
|
||||
}
|
||||
// remove place holder from content
|
||||
$string = trim(
|
||||
str_replace($placeholders[$commentType] . $trim, '', $lineContent)
|
||||
);
|
||||
// now get all numbers
|
||||
$numbers = [];
|
||||
preg_match_all('!\d+!', $string, $numbers);
|
||||
// return the first number
|
||||
if (isset($numbers[0])
|
||||
&& ArrayHelper::check(
|
||||
$numbers[0]
|
||||
))
|
||||
{
|
||||
return reset($numbers[0]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,429 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Component.Builder
|
||||
*
|
||||
* @created 30th April, 2015
|
||||
* @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\Customcode\Extractor;
|
||||
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Filesystem\Folder;
|
||||
use VDM\Joomla\Utilities\ArrayHelper;
|
||||
use VDM\Joomla\Utilities\JsonHelper;
|
||||
use VDM\Joomla\Utilities\GetHelper;
|
||||
use VDM\Joomla\Utilities\String\ClassfunctionHelper;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Config;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder as ComponentPlaceholder;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Customcode;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Language\Extractor;
|
||||
|
||||
|
||||
/**
|
||||
* Compiler Custom Code Paths
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Paths
|
||||
{
|
||||
/**
|
||||
* The local paths
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
**/
|
||||
public array $active = [];
|
||||
|
||||
/**
|
||||
* Compiler Component Placeholder
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected array $componentPlaceholder;
|
||||
|
||||
/**
|
||||
* Compiler Config
|
||||
*
|
||||
* @var Config
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Config $config;
|
||||
|
||||
/**
|
||||
* Compiler Placeholder
|
||||
*
|
||||
* @var Placeholder
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Placeholder $placeholder;
|
||||
|
||||
/**
|
||||
* Compiler Customcode
|
||||
*
|
||||
* @var Customcode
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Customcode $customcode;
|
||||
|
||||
/**
|
||||
* Compiler Language Extractor
|
||||
*
|
||||
* @var Extractor
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected Extractor $extractor;
|
||||
|
||||
/**
|
||||
* Database object to query local DB
|
||||
*
|
||||
* @var \JDatabaseDriver
|
||||
* @since 3.2.0
|
||||
**/
|
||||
protected \JDatabaseDriver $db;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Config|null $config The compiler config object.
|
||||
* @param Placeholder|null $placeholder The compiler placeholder object.
|
||||
* @param ComponentPlaceholder|null $componentPlaceholder The compiler component placeholder object.
|
||||
* @param Customcode|null $customcode The compiler customcode object.
|
||||
* @param Extractor|null $extractor The compiler language extractor object.
|
||||
* @param \JDatabaseDriver|null $db The Database Driver object.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function __construct(?Config $config = null, ?Placeholder $placeholder = null,
|
||||
?ComponentPlaceholder $componentPlaceholder = null, ?Customcode $customcode = null,
|
||||
?Extractor $extractor = null, ?\JDatabaseDriver $db = null)
|
||||
{
|
||||
$this->config = $config ?: Compiler::_('Config');
|
||||
$this->placeholder = $placeholder ?: Compiler::_('Placeholder');
|
||||
/** @var ComponentPlaceholder $componentPlaceholder */
|
||||
$componentPlaceholder = $componentPlaceholder ?: Compiler::_('Component.Placeholder');
|
||||
$this->customcode = $customcode ?: Compiler::_('Customcode');
|
||||
$this->extractor = $extractor ?: Compiler::_('Language.Extractor');
|
||||
$this->db = $db ?: Factory::getDbo();
|
||||
|
||||
// load the placeholders to local array
|
||||
$this->componentPlaceholder = $componentPlaceholder->get();
|
||||
|
||||
// load the paths on initialization
|
||||
$this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the local installed path of this component
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function load()
|
||||
{
|
||||
// set the local paths to search
|
||||
$local_paths = array();
|
||||
|
||||
// admin path
|
||||
$local_paths['admin'] = JPATH_ADMINISTRATOR . '/components/com_'
|
||||
. $this->config->component_code_name;
|
||||
|
||||
// site path
|
||||
$local_paths['site'] = JPATH_ROOT . '/components/com_'
|
||||
. $this->config->component_code_name;
|
||||
|
||||
// media path
|
||||
$local_paths['media'] = JPATH_ROOT . '/media/com_'
|
||||
. $this->config->component_code_name;
|
||||
|
||||
// power path
|
||||
$local_paths['power'] = JPATH_ROOT . '/' . $this->config->get('jcb_powers_path', 'libraries/jcb_powers');
|
||||
|
||||
// lets also go over the REPOS - TODO
|
||||
|
||||
// Painful but we need to folder paths for the linked modules
|
||||
if (($module_ids = $this->getModuleIDs()) !== false)
|
||||
{
|
||||
foreach ($module_ids as $module_id)
|
||||
{
|
||||
// get the module folder path
|
||||
if (($path = $this->getModulePath($module_id)) !== false)
|
||||
{
|
||||
// set the path
|
||||
$local_paths['module_' . str_replace('/', '_', $path)] = $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Painful but we need to folder paths for the linked plugins
|
||||
if (($plugin_ids = $this->getPluginIDs()) !== false)
|
||||
{
|
||||
foreach ($plugin_ids as $plugin_id)
|
||||
{
|
||||
// get the plugin group and folder name
|
||||
if (($path = $this->getPluginPath($plugin_id)) !== false)
|
||||
{
|
||||
// set the path
|
||||
$local_paths['plugin_' . str_replace('/', '_', $path)] = JPATH_ROOT . '/plugins/' . $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if the local install is found
|
||||
foreach ($local_paths as $key => $localPath)
|
||||
{
|
||||
if (!Folder::exists($localPath))
|
||||
{
|
||||
unset($local_paths[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (ArrayHelper::check($local_paths))
|
||||
{
|
||||
$this->active = $local_paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the Joomla Modules IDs
|
||||
*
|
||||
* @return mixed of IDs on success
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function getModuleIDs()
|
||||
{
|
||||
if (($addjoomla_modules = GetHelper::var(
|
||||
'component_modules', $this->config->component_id, 'joomla_component',
|
||||
'addjoomla_modules'
|
||||
)) !== false)
|
||||
{
|
||||
$addjoomla_modules = (JsonHelper::check(
|
||||
$addjoomla_modules
|
||||
)) ? json_decode($addjoomla_modules, true) : null;
|
||||
if (ArrayHelper::check($addjoomla_modules))
|
||||
{
|
||||
$joomla_modules = array_filter(
|
||||
array_values($addjoomla_modules),
|
||||
function ($array) {
|
||||
// only load the modules whose target association call for it
|
||||
if (!isset($array['target']) || $array['target'] != 2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
// if we have values we return IDs
|
||||
if (ArrayHelper::check($joomla_modules))
|
||||
{
|
||||
return array_map(
|
||||
function ($array) {
|
||||
return (int) $array['module'];
|
||||
}, $joomla_modules
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the Joomla module path
|
||||
*
|
||||
* @return mixed of module path and target site area on success
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function getModulePath($id)
|
||||
{
|
||||
if (is_numeric($id) && $id > 0)
|
||||
{
|
||||
// Create a new query object.
|
||||
$query = $this->db->getQuery(true);
|
||||
|
||||
$query->select('a.*');
|
||||
$query->select(
|
||||
$this->db->quoteName(
|
||||
array(
|
||||
'a.name',
|
||||
'a.target'
|
||||
), array(
|
||||
'name',
|
||||
'target'
|
||||
)
|
||||
)
|
||||
);
|
||||
// from these tables
|
||||
$query->from('#__componentbuilder_joomla_module AS a');
|
||||
$query->where($this->db->quoteName('a.id') . ' = ' . (int) $id);
|
||||
$this->db->setQuery($query);
|
||||
$this->db->execute();
|
||||
if ($this->db->getNumRows())
|
||||
{
|
||||
// get the module data
|
||||
$module = $this->db->loadObject();
|
||||
// update the name if it has dynamic values
|
||||
$module->name = $this->placeholder->update(
|
||||
$this->customcode->add($module->name),
|
||||
$this->componentPlaceholder
|
||||
);
|
||||
|
||||
// set safe class function name
|
||||
$module->code_name
|
||||
= ClassfunctionHelper::safe(
|
||||
$module->name
|
||||
);
|
||||
// set module folder name
|
||||
$module->folder_name = 'mod_' . strtolower($module->code_name);
|
||||
|
||||
// set the lang key
|
||||
$this->extractor->langKeys[strtoupper($module->folder_name)] =
|
||||
$module->id . '_M0dU|3';
|
||||
|
||||
// return the path
|
||||
if ($module->target == 2)
|
||||
{
|
||||
// administrator client area
|
||||
return JPATH_ADMINISTRATOR . '/modules/'
|
||||
. $module->folder_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
// default is the site client area
|
||||
return JPATH_ROOT . '/modules/' . $module->folder_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the Joomla plugins IDs
|
||||
*
|
||||
* @return mixed of IDs on success
|
||||
* @since 3.2.0
|
||||
*/
|
||||
protected function getPluginIDs()
|
||||
{
|
||||
if (($addjoomla_plugins = GetHelper::var(
|
||||
'component_plugins', $this->config->component_id, 'joomla_component',
|
||||
'addjoomla_plugins'
|
||||
)) !== false)
|
||||
{
|
||||
$addjoomla_plugins = (JsonHelper::check(
|
||||
$addjoomla_plugins
|
||||
)) ? json_decode($addjoomla_plugins, true) : null;
|
||||
if (ArrayHelper::check($addjoomla_plugins))
|
||||
{
|
||||
$joomla_plugins = array_filter(
|
||||
array_values($addjoomla_plugins),
|
||||
function ($array) {
|
||||
// only load the plugins whose target association call for it
|
||||
if (!isset($array['target']) || $array['target'] != 2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
// if we have values we return IDs
|
||||
if (ArrayHelper::check($joomla_plugins))
|
||||
{
|
||||
return array_map(
|
||||
function ($array) {
|
||||
return (int) $array['plugin'];
|
||||
}, $joomla_plugins
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the Joomla plugin path
|
||||
*
|
||||
* @return mixed of plugin path on success
|
||||
* @deprecated 3.3
|
||||
*/
|
||||
protected function getPluginPath($id)
|
||||
{
|
||||
if (is_numeric($id) && $id > 0)
|
||||
{
|
||||
// Create a new query object.
|
||||
$query = $this->db->getQuery(true);
|
||||
|
||||
$query->select('a.*');
|
||||
$query->select(
|
||||
$this->db->quoteName(
|
||||
array(
|
||||
'a.name',
|
||||
'g.name'
|
||||
), array(
|
||||
'name',
|
||||
'group'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// from these tables
|
||||
$query->from('#__componentbuilder_joomla_plugin AS a');
|
||||
$query->join(
|
||||
'LEFT', $this->db->quoteName(
|
||||
'#__componentbuilder_joomla_plugin_group', 'g'
|
||||
) . ' ON (' . $this->db->quoteName('a.joomla_plugin_group')
|
||||
. ' = ' . $this->db->quoteName('g.id') . ')'
|
||||
);
|
||||
$query->where($this->db->quoteName('a.id') . ' = ' . (int) $id);
|
||||
$this->db->setQuery($query);
|
||||
$this->db->execute();
|
||||
|
||||
if ($this->db->getNumRows())
|
||||
{
|
||||
// get the plugin data
|
||||
$plugin = $this->db->loadObject();
|
||||
|
||||
// update the name if it has dynamic values
|
||||
$plugin->name = $this->placeholder->update(
|
||||
$this->customcode->add($plugin->name),
|
||||
$this->componentPlaceholder
|
||||
);
|
||||
|
||||
// update the name if it has dynamic values
|
||||
$plugin->code_name
|
||||
= ClassfunctionHelper::safe(
|
||||
$plugin->name
|
||||
);
|
||||
|
||||
// set plugin folder name
|
||||
$plugin->group = strtolower($plugin->group);
|
||||
// set plugin file name
|
||||
$plugin->file_name = strtolower($plugin->code_name);
|
||||
|
||||
// set the lang key
|
||||
$this->extractor->langKeys['PLG_' . strtoupper(
|
||||
$plugin->group . '_' . $plugin->file_name
|
||||
)] = $plugin->id . '_P|uG!n';
|
||||
|
||||
// return the path
|
||||
return $plugin->group . '/' . $plugin->file_name;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
<html><body bgcolor="#FFFFFF"></body></html>
|
@ -84,18 +84,18 @@ class Reverse
|
||||
/**
|
||||
* Reverse Engineer the dynamic placeholders (TODO hmmmm this is not ideal)
|
||||
*
|
||||
* @param string $string The string to revers
|
||||
* @param array $placeholders The values to search for
|
||||
* @param string $target The target path type
|
||||
* @param int|null $id The custom code id
|
||||
* @param string $field The field name
|
||||
* @param string $table The table name
|
||||
* @param string $string The string to revers
|
||||
* @param array $placeholders The values to search for
|
||||
* @param string $target The target path type
|
||||
* @param int|null $id The custom code id
|
||||
* @param string $field The field name
|
||||
* @param string $table The table name
|
||||
*
|
||||
* @return string
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function engine(string $string, array &$placeholders,
|
||||
string $target, ?int $id = null, $field = 'code', $table = 'custom_code'): string
|
||||
string $target, ?int $id = null, string $field = 'code', string $table = 'custom_code'): string
|
||||
{
|
||||
// get local code if set
|
||||
if ($id > 0 && $code = base64_decode(
|
||||
@ -222,7 +222,7 @@ class Reverse
|
||||
}
|
||||
}
|
||||
// return the found placeholders
|
||||
$updateString = $this->placeholder->replace(
|
||||
$updateString = $this->placeholder->update(
|
||||
$updateString, $lang_holders
|
||||
);
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Hash;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Customcode\LockBase;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Extractor;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Extractor\Paths;
|
||||
|
||||
|
||||
/**
|
||||
@ -56,6 +58,12 @@ class Customcode implements ServiceProviderInterface
|
||||
|
||||
$container->alias(Dispenser::class, 'Customcode.Dispenser')
|
||||
->share('Customcode.Dispenser', [$this, 'getDispenser'], true);
|
||||
|
||||
$container->alias(Paths::class, 'Customcode.Extractor.Paths')
|
||||
->share('Customcode.Extractor.Paths', [$this, 'getPaths'], true);
|
||||
|
||||
$container->alias(Extractor::class, 'Customcode.Extractor')
|
||||
->share('Customcode.Extractor', [$this, 'getExtractor'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -156,5 +164,43 @@ class Customcode implements ServiceProviderInterface
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Customcode Extractor Paths
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Paths
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getPaths(Container $container): Paths
|
||||
{
|
||||
return new Paths(
|
||||
$container->get('Config'),
|
||||
$container->get('Placeholder'),
|
||||
$container->get('Component.Placeholder'),
|
||||
$container->get('Customcode'),
|
||||
$container->get('Language.Extractor')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Customcode Extractor
|
||||
*
|
||||
* @param Container $container The DI container.
|
||||
*
|
||||
* @return Extractor
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public function getExtractor(Container $container): Extractor
|
||||
{
|
||||
return new Extractor(
|
||||
$container->get('Config'),
|
||||
$container->get('Customcode.Gui'),
|
||||
$container->get('Customcode.Extractor.Paths'),
|
||||
$container->get('Placeholder.Reverse'),
|
||||
$container->get('Component.Placeholder')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Joomla.Component.Builder
|
||||
*
|
||||
* @created 30th April, 2015
|
||||
* @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 VDM\Joomla\Utilities\ArrayHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
|
||||
|
||||
/**
|
||||
* Compiler Path Fix
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
abstract class Path
|
||||
{
|
||||
/**
|
||||
* Fix the path to work in the JCB script <-- (main issue here)
|
||||
* Since we need / slash in all paths, for the JCB script even if it is Windows
|
||||
* and since MS works with both forward and back slashes
|
||||
* we just convert all slashes to forward slashes
|
||||
*
|
||||
* THIS is just my hack (fix) if you know a better way! speak-up!
|
||||
*
|
||||
* @param mixed $values the array of paths or the path as a string
|
||||
* @param array $targets paths to target
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function fix(&$values, $targets = array())
|
||||
{
|
||||
// if multiple to gets searched and fixed
|
||||
if (ArrayHelper::check($values) && ArrayHelper::check($targets))
|
||||
{
|
||||
foreach ($targets as $target)
|
||||
{
|
||||
if (isset($values[$target]) && strpos($values[$target], '\\') !== false)
|
||||
{
|
||||
$values[$target] = str_replace('\\', '/', $values[$target]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if just a string
|
||||
elseif (StringHelper::check($values) && strpos($values, '\\') !== false)
|
||||
{
|
||||
$values = str_replace('\\', '/', $values);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3676,8 +3676,10 @@ abstract class ComponentbuilderHelper
|
||||
|
||||
|
||||
/**
|
||||
* prepare base64 string for url
|
||||
**/
|
||||
* prepare base64 string for url
|
||||
*
|
||||
* @deprecate Use urlencode();
|
||||
*/
|
||||
public static function base64_urlencode($string, $encode = false)
|
||||
{
|
||||
if ($encode)
|
||||
@ -3688,8 +3690,10 @@ abstract class ComponentbuilderHelper
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare base64 string form url
|
||||
**/
|
||||
* prepare base64 string form url
|
||||
*
|
||||
* @deprecate
|
||||
*/
|
||||
public static function base64_urldecode($string, $decode = false)
|
||||
{
|
||||
$string = str_replace(array('-', '_'), array('+', '/'), $string);
|
||||
|
@ -41,6 +41,7 @@ COM_COMPONENTBUILDER_FREEOPEN="Free/Open"
|
||||
COM_COMPONENTBUILDER_GREAT_THIS_PLACEHOLDER_WILL_WORK="Great, this placeholder will work!"
|
||||
COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP="<h4 class="nav-header">Copyright</h4><p>%s</p>"
|
||||
COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP="<h4 class="nav-header">License</h4><p>%s</p>"
|
||||
COM_COMPONENTBUILDER_HR_HTHREECUSTOM_CODES_WARNINGHTHREE="<hr /><h3>Custom Codes Warning</h3>"
|
||||
COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_ERRORHTHREE="<hr /><h3>External Code Error</h3>"
|
||||
COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_NOTICEHTHREE="<hr /><h3>External Code Notice</h3>"
|
||||
COM_COMPONENTBUILDER_HR_HTHREEEXTERNAL_CODE_WARNINGHTHREE="<hr /><h3>External Code Warning</h3>"
|
||||
@ -116,6 +117,7 @@ COM_COMPONENTBUILDER_TO_CHANGE_THE_PACKAGE_OWNER_DEFAULTS_OPEN_THE_BJCB_GLOBAL_O
|
||||
COM_COMPONENTBUILDER_TO_CHANGE_THE_PACKAGE_OWNER_DEFAULTS_OPEN_THE_JCB_GLOBAL_OPTIONS_GO_TO_THE_COMPANY_TAB_AND_ADD_THE_CORRECT_COMPANY_DETAILS_THERE="To change the package owner defaults. Open the JCB Global Options, go to the Company tab and add the correct company details there."
|
||||
COM_COMPONENTBUILDER_TRANSLATOR_MODULE_NOT_READYBR_THIS_AREA_IS_STILL_UNDER_PRODUCTION_HOPEFULLY_WITH_NEXT_UPDATE="Translator Module not ready!<br />This area is still under production, hopefully with next update."
|
||||
COM_COMPONENTBUILDER_WEBSITE_S="Website: %s"
|
||||
COM_COMPONENTBUILDER_WE_FOUND_DYNAMIC_CODE_BALL_IN_ONE_LINEB_AND_IGNORED_IT_PLEASE_REVIEW_S_FOR_MORE_DETAILS="We found dynamic code <b>all in one line</b>, and ignored it! Please review (%s) for more details!"
|
||||
COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EIGHT_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEY_WITHOUT_THIS_KEY_IT_WILL_TAKE_THE_CURRENT_TECHNOLOGY_WITH_A_BRUTE_FORCE_ATTACK_METHOD_MORE_THEN_A_HREFHTTPRANDOMIZECOMHOWLONGTOHACKPASS_TARGET_BLANK_TITLEHOW_LONG_TO_HACK_PASSSEVEN_HUNDRED_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZEROA_YEARS_TO_CRACK_THEORETICALLY_UNLESS_THEY_HAVE_THIS_KEY_ABOVE_SO_DO_KEEP_IT_SAFE="Your data is encrypted with a AES 128 bit encryption using the above 32 character key. Without this key it will take the current technology with a brute force attack method more then <a href="http://random-ize.com/how-long-to-hack-pass/" target="_blank" title="How long to hack pass">700 000 000 000 000 000 000 000 000 000 000</a> years to crack theoretically. Unless they have this key above, so do keep it safe."
|
||||
COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_ACCESS_THE_SERVER_DETAILS_BS_DENIEDB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="You do not have permission to access the server details (<b>%s - denied</b>), please contact your system administrator for more info."
|
||||
COM_COMPONENTBUILDER_YOU_SHOULD_ADD_THE_CORRECT_OWNER_DETAILS="You should add the correct owner details."
|
||||
|
Loading…
Reference in New Issue
Block a user