Added the feature that allows you to setup the behaviour of a selected set of components that will be auto build and installed. So you do not need to manually compile and install those components any more, the system does all that automatically for you. We have called the feature Expansion Development Method, and it can be set in the global settings of JCB under the Development Method tab.

This commit is contained in:
Llewellyn van der Merwe 2018-04-25 00:36:05 +02:00
parent 909a91844f
commit 47d1a6c155
No known key found for this signature in database
GPG Key ID: CAD7B16D27AF28C5
18 changed files with 1525 additions and 82 deletions

View File

@ -126,12 +126,12 @@ Component Builder is mapped as a component in itself on my local development env
+ *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)
+ *Name*: [Component Builder](http://joomlacomponentbuilder.com)
+ *First Build*: 30th April, 2015
+ *Last Build*: 23rd April, 2018
+ *Last Build*: 24th April, 2018
+ *Version*: 2.7.6
+ *Copyright*: Copyright (C) 2015. All Rights Reserved
+ *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
+ *Line count*: **184709**
+ *Field count*: **1025**
+ *Line count*: **193223**
+ *Field count*: **1026**
+ *File count*: **1201**
+ *Folder count*: **193**

View File

@ -126,12 +126,12 @@ Component Builder is mapped as a component in itself on my local development env
+ *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)
+ *Name*: [Component Builder](http://joomlacomponentbuilder.com)
+ *First Build*: 30th April, 2015
+ *Last Build*: 23rd April, 2018
+ *Last Build*: 24th April, 2018
+ *Version*: 2.7.6
+ *Copyright*: Copyright (C) 2015. All Rights Reserved
+ *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
+ *Line count*: **184709**
+ *Field count*: **1025**
+ *Line count*: **193223**
+ *Field count*: **1026**
+ *File count*: **1201**
+ *Folder count*: **193**

View File

@ -653,33 +653,24 @@
description="COM_COMPONENTBUILDER_CONFIG_REPOSITORY_DESCRIPTION"
class="inputbox"
/>
<!-- Event Field. Type: List. (joomla) -->
<!-- Placeholders Field. Type: Checkbox. (joomla) -->
<field
type="list"
name="event"
label="COM_COMPONENTBUILDER_CONFIG_EVENT_LABEL"
class="list_class"
multiple="false"
type="checkbox"
name="placeholders"
label="COM_COMPONENTBUILDER_CONFIG_PLACEHOLDERS_LABEL"
value="1"
required="false"
default="1">
<!-- Option Set. -->
<option value="1">
COM_COMPONENTBUILDER_CONFIG_PERCHANGE</option>
<option value="2">
COM_COMPONENTBUILDER_CONFIG_PERJCB_PACKAGE_IMPORT</option>
<option value="3">
COM_COMPONENTBUILDER_CONFIG_PERCOMPONENT_EVENT</option>
<option value="4">
COM_COMPONENTBUILDER_CONFIG_PERHOUR</option>
<option value="5">
COM_COMPONENTBUILDER_CONFIG_PERDAY</option>
</field>
description="COM_COMPONENTBUILDER_CONFIG_PLACEHOLDERS_DESCRIPTION"
class="inputbox"
/>
</form>
</field>
<!-- Expansioncronjob_note Field. Type: Note. A None Database Field. (joomla) -->
<field type="note" name="expansioncronjob_note" label="COM_COMPONENTBUILDER_CONFIG_EXPANSIONCRONJOB_NOTE_LABEL" description="COM_COMPONENTBUILDER_CONFIG_EXPANSIONCRONJOB_NOTE_DESCRIPTION" heading="h4" class="expansioncronjob_note" showon="development_method:2" />
</fieldset>
<fieldset
name="cronjob_custom_config"
label="COM_COMPONENTBUILDER_CONFIG_CRONJOB">
name="auto_backup_custom_config"
label="COM_COMPONENTBUILDER_CONFIG_AUTO_BACKUP">
<!-- Backupcronjob_note Field. Type: Note. A None Database Field. (joomla) -->
<field type="note" name="backupcronjob_note" label="COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_LABEL" description="COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_DESCRIPTION" heading="h4" class="backupcronjob_note" />

View File

@ -194,7 +194,7 @@ class ComponentbuilderControllerCompiler extends JControllerAdmin
$lang->load($extension, $base_dir, $language_tag, $reload);
$message = '('.$fileName.'.zip) file was also removed from tmp!';
$this->setRedirect($redirect_url,$message,'message');
return $model->install($fileName.'.zip');;
return $model->install($fileName.'.zip');
}
}
$this->setRedirect($redirect_url,$message,'error');

View File

@ -72,12 +72,12 @@ class Compiler extends Infusion
$comConfig = JFactory::getConfig();
$this->tempPath = $comConfig->get('tmp_path');
// set some folder paths in relation to distribution
if ($config['addBackup'])
if ($config['backup'])
{
$this->backupPath = $this->params->get('backup_folder_path', $this->tempPath) . '/' . $this->componentBackupName . '.zip';
$this->dynamicIntegration = true;
}
if ($config['addRepo'])
if ($config['repository'])
{
$this->repoPath = $this->params->get('git_folder_path', null);
}

View File

@ -668,7 +668,7 @@ class Get
// load the compiler path
$this->compilerPath = $this->params->get('compiler_folder_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler');
// set the component ID
$this->componentID = (int) $config['componentId'];
$this->componentID = (int) $config['component'];
// set this components code name
if ($name_code = ComponentbuilderHelper::getVar('joomla_component', $this->componentID, 'id', 'name_code'))
{
@ -678,10 +678,10 @@ class Get
$this->componentCodeName = ComponentbuilderHelper::safeString($name_code);
// set if placeholders should be added to customcode
$global = ((int) ComponentbuilderHelper::getVar('joomla_component', $this->componentID, 'id', 'add_placeholders') == 1) ? true : false;
$this->addPlaceholders = ((int) $config['addPlaceholders'] == 0) ? false : (((int) $config['addPlaceholders'] == 1) ? true : $global);
$this->addPlaceholders = ((int) $config['placeholders'] == 0) ? false : (((int) $config['placeholders'] == 1) ? true : $global);
// set if line numbers should be added to comments
$global = ((int) ComponentbuilderHelper::getVar('joomla_component', $this->componentID, 'id', 'debug_linenr') == 1) ? true : false;
$this->debugLinenr = ((int) $config['debugLinenr'] == 0) ? false : (((int) $config['debugLinenr'] == 1) ? true : $global);
$this->debugLinenr = ((int) $config['debuglinenr'] == 0) ? false : (((int) $config['debuglinenr'] == 1) ? true : $global);
// set the current user
$this->user = JFactory::getUser();
// Get a db connection.

View File

@ -338,9 +338,9 @@ class Structure extends Get
// run global updater
ComponentbuilderHelper::runGlobalUpdater();
// set the Joomla version
$this->joomlaVersion = $config['joomlaVersion'];
$this->joomlaVersion = $config['version'];
// set the template path
$this->templatePath = $this->compilerPath . '/joomla_' . $config['joomlaVersion'];
$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;

View File

@ -13048,12 +13048,6 @@ class Interpretation extends Fields
$tabCode = ComponentbuilderHelper::safeString($tab) . '_custom_config';
$tabUpper = ComponentbuilderHelper::safeString($tab, 'U');
$tabLower = ComponentbuilderHelper::safeString($tab);
// setup lang
$this->langContent[$this->lang][$lang . '_' . $tabUpper] = $tab;
// start field set
$this->configFieldSets[] = "\t<fieldset";
$this->configFieldSets[] = "\t\t" . 'name="' . $tabCode . '"';
$this->configFieldSets[] = "\t\t" . 'label="' . $lang . '_' . $tabUpper . '">';
// remove display targeted fields
$bucket = array();
foreach ($tabFields as $tabField)
@ -13065,10 +13059,20 @@ class Interpretation extends Fields
$bucket[] = str_replace('display="config"', '', $tabField);
}
}
// set the fields
$this->configFieldSets[] = implode("", $bucket);
// close field set
$this->configFieldSets[] = "\t</fieldset>";
// only add the tab if it has values
if (ComponentbuilderHelper::checkArray($bucket))
{
// setup lang
$this->langContent[$this->lang][$lang . '_' . $tabUpper] = $tab;
// start field set
$this->configFieldSets[] = "\t<fieldset";
$this->configFieldSets[] = "\t\t" . 'name="' . $tabCode . '"';
$this->configFieldSets[] = "\t\t" . 'label="' . $lang . '_' . $tabUpper . '">';
// set the fields
$this->configFieldSets[] = implode("", $bucket);
// close field set
$this->configFieldSets[] = "\t</fieldset>";
}
// remove after loading
unset($this->configFieldSetsCustomField[$tab]);
}

View File

@ -1175,7 +1175,7 @@ class Infusion extends Interpretation
// add to language file
$this->writeFile($path . '/' . $fileName, implode(PHP_EOL, $lang));
// set the line counter
$this->lineCount = $this->lineCount + substr_count($lang, PHP_EOL);
$this->lineCount = $this->lineCount + count((array)$lang);
// build xml strings
if (!isset($langXML[$p]))
{

View File

@ -2290,6 +2290,607 @@ abstract class ComponentbuilderHelper
}
}
/**
* the locker
*
* @var array
**/
protected static $locker = array();
/**
* the dynamic replacement salt
*
* @var array
**/
protected static $globalSalt = array();
/**
* the timer
*
* @var object
**/
protected static $keytimer;
/**
* To Lock string
*
* @param string $string The string/array to lock
* @param string $key The custom key to use
* @param int $salt The switch to add salt and type of salt
* @param int $dynamic The dynamic replacement array of salt build string
* @param int $urlencode The switch to control url encoding
**/
public static function lock($string, $key = null, $salt = 2, $dynamic = null, $urlencode = true)
{
// get the global settings
if (!$key || !self::checkString($key))
{
// set temp timer
$timer = 2;
// if we have a timer use it
if ($salt > 0)
{
$timer = $salt;
}
if (method_exists(get_called_class(), "getCryptKey"))
{
$key = self::getCryptKey('basic', self::salt($timer, $dynamic));
}
else
{
$key = self::salt($timer, $dynamic);
}
}
// check if we have a salt timer
if ($salt > 0)
{
$key .= self::salt($salt, $dynamic);
}
// get the locker settings
if (!isset(self::$locker[$key]) || !self::checkObject(self::$locker[$key]))
{
self::$locker[$key] = new FOFEncryptAes($key, 128);
}
// convert array or object to string
if (self::checkArray($string) || self::checkObject($string))
{
$string = serialize($string);
}
// prep for url
if ($urlencode)
{
return self::base64_urlencode(self::$locker[$key]->encryptString($string));
}
return self::$locker[$key]->encryptString($string);
}
/**
* To un-Lock string
*
* @param string $string The string to unlock
* @param string $key The custom key to use
* @param int $salt The switch to add salt and type of salt
* @param int $dynamic The dynamic replacement array of salt build string
* @param int $urlencode The switch to control url decoding
**/
public static function unlock($string, $key = null, $salt = 2, $dynamic = null, $urlencode = true)
{
// get the global settings
if (!$key || !self::checkString($key))
{
// set temp timer
$timer = 2;
// if we have a timer use it
if ($salt > 0)
{
$timer = $salt;
}
// get secure key
if (method_exists(get_called_class(), "getCryptKey"))
{
$key = self::getCryptKey('basic', self::salt($timer, $dynamic));
}
else
{
$key = self::salt($timer, $dynamic);
}
}
// check if we have a salt timer
if ($salt > 0)
{
$key .= self::salt($salt, $dynamic);
}
// get the locker settings
if (!isset(self::$locker[$key]) || !self::checkObject(self::$locker[$key]))
{
self::$locker[$key] = new FOFEncryptAes($key, 128);
}
// make sure we have real base64
if ($urlencode)
{
$string = self::base64_urldecode($string);
}
// basic decrypt string.
if (!empty($string) && !is_numeric($string) && $string === base64_encode(base64_decode($string, true)))
{
$string = rtrim(self::$locker[$key]->decryptString($string), "\0");
// convert serial string to array
if (self::is_serial($string))
{
$string = unserialize($string);
}
}
return $string;
}
/**
* The Salt
*
* @param int $type The type of length the salt should be valid
* @param int $dynamic The dynamic replacement array of salt build string
**/
public static function salt($type = 1, $dynamic = null)
{
// get dynamic replacement salt
$dynamic = self::getDynamicSalt($dynamic);
// get the key timer
if (!self::checkObject(self::$keytimer))
{
// load the date time object
self::$keytimer = new DateTime;
// set the correct time stamp
$vdmLocalTime = new DateTimeZone('Africa/Windhoek');
self::$keytimer->setTimezone($vdmLocalTime);
}
// set type
if ($type == 2)
{
// hour
$format = 'Y-m-d \o\n ' . self::periodFix(self::$keytimer->format('H'));
}
elseif ($type == 3)
{
// day
$format = 'Y-m-' . self::periodFix(self::$keytimer->format('d'));
}
elseif ($type == 4)
{
// month
$format = 'Y-' . self::periodFix(self::$keytimer->format('m'));
}
else
{
// minute
$format = 'Y-m-d \o\n H:' . self::periodFix(self::$keytimer->format('i'));
}
// get key
if (self::checkArray($dynamic))
{
return md5(str_replace(array_keys($dynamic), array_values($dynamic), self::$keytimer->format($format) . ' @ VDM.I0'));
}
return md5(self::$keytimer->format($format) . ' @ VDM.I0');
}
/**
* The function to insure the salt is valid within the given period (third try)
*
* @param int $main The main number
*/
protected static function periodFix($main)
{
return round($main / 3) * 3;
}
/**
* Check if a string is serialized
* @param string $string
*/
public static function is_serial($string)
{
return (@unserialize($string) !== false);
}
/**
* Get dynamic replacement salt
*/
public static function getDynamicSalt($dynamic = null)
{
// load global if not manually set
if (!self::checkArray($dynamic))
{
return self::getGlobalSalt();
}
// return manual values if set
else
{
return $dynamic;
}
}
/**
* The random or dynamic secret salt
*/
public static function getSecretSalt($string = null, $size = 9)
{
// set the string
if (!$string)
{
// get random string
$string = self::randomkey($size);
}
// convert string to array
$string = self::safeString($string);
// convert string to array
$array = str_split($string);
// insure only unique values are used
$array = array_unique($array);
// set the size
$size = ($size <= count($array)) ? $size : count($array);
// down size the
return array_slice($array, 0, $size);
}
/**
* Get global replacement salt
*/
public static function getGlobalSalt()
{
// load from memory if found
if (!self::checkArray(self::$globalSalt))
{
// get the global settings
if (!self::checkObject(self::$params))
{
self::$params = JComponentHelper::getParams('com_componentbuilder');
}
// check if we have a global dynamic replacement array available (format --> ' 1->!,3->E,4->A')
$tmp = self::$params->get('dynamic_salt', null);
if (self::checkString($tmp) && strpos($tmp, ',') !== false && strpos($tmp, '->') !== false)
{
$salt = array_map('trim', (array) explode(',', $tmp));
if (self::checkArray($salt ))
{
foreach($salt as $replace)
{
$dynamic = array_map('trim', (array) explode('->', $replace));
if (isset($dynamic[0]) && isset($dynamic[1]))
{
self::$globalSalt[$dynamic[0]] = $dynamic[1];
}
}
}
}
}
// return global if found
if (self::checkArray(self::$globalSalt))
{
return self::$globalSalt;
}
// return default as fail safe
return array('1' => '!', '3' => 'E', '4' => 'A');
}
/**
* Close public protocol
*/
public static function closePublicProtocol($id, $public)
{
// get secret salt
$secretSalt = self::getSecretSalt(self::salt(1,array('4' => 'R','1' => 'E','2' => 'G','7' => 'J','8' => 'A')));
// get the key
$key = self::salt(1, $secretSalt);
// get secret salt
$secret = self::getSecretSalt();
// set the secret
$close['SECRET'] = self::lock($secret, $key, 1, array('1' => 's', '3' => 'R', '4' => 'D'));
// get the key
$key = self::salt(1, $secret);
// get the public key
$close['PUBLIC'] = self::lock($public, $key, 1, array('1' => '!', '3' => 'E', '4' => 'A'));
// get secret salt
$secretSalt = self::getSecretSalt($public);
// get the key
$key = self::salt(1, $secretSalt);
// get the ID
$close['ID'] = self::unlock($id, $key, 1, array('1' => 'i', '3' => 'e', '4' => 'B'));
// return closed values
return $close;
}
/**
* Open public protocol
*/
public static function openPublicProtocol($SECRET, $ID, $PUBLIC)
{
// get secret salt
$secretSalt = self::getSecretSalt(self::salt(1,array('4' => 'R','1' => 'E','2' => 'G','7' => 'J','8' => 'A')));
// get the key
$key = self::salt(1, $secretSalt);
// get the $SECRET
$SECRET = self::unlock($SECRET, $key, 1, array('1' => 's', '3' => 'R', '4' => 'D'));
// get the key
$key = self::salt(1, $SECRET);
// get the public key
$open['public'] = self::unlock($PUBLIC, $key, 1, array('1' => '!', '3' => 'E', '4' => 'A'));
// get secret salt
$secretSalt = self::getSecretSalt($open['public']);
// get the key
$key = self::salt(1, $secretSalt);
// get the ID
$open['id'] = self::unlock($ID, $key, 1, array('1' => 'i', '3' => 'e', '4' => 'B'));
// return opened values
return $open;
}
/**
* Workers to load tasks
*
* @var array
*/
protected static $worker = array();
/**
* Set a worker dynamic URLs
*
* @var array
*/
protected static $workerURL = array();
/**
* Set a worker dynamic HEADERs
*
* @var array
*/
protected static $workerHEADER = array();
/**
* Curl Error Notice
*
* @var bool
*/
protected static $curlErrorLoaded = false;
/**
* Set a worker url
*
* @param string $function The function to target to perform the task
* @param string $url The url of where the task is to be performed
*
* @return void
*
*/
public static function setWorkerUrl(&$function, &$url)
{
// set the URL if found
if (self::checkString($url))
{
// make sure task function url is up
self::$workerURL[$function] = $url;
}
}
/**
* Set a worker headers
*
* @param string $function The function to target to perform the task
* @param array $headers The headers needed for these workers/function
*
* @return void
*
*/
public static function setWorkerHeaders(&$function, &$headers)
{
// set the Headers if found
if (self::checkArray($headers))
{
// make sure task function headers are set
self::$workerHEADER[$function] = $headers;
}
}
/**
* Set a worker that needs to perform a task
*
* @param mixed $data The data to pass to the task
* @param string $function The function to target to perform the task
* @param string $url The url of where the task is to be performed
* @param array $headers The headers needed for these workers/function
*
* @return void
*
*/
public static function setWorker($data, $function, $url = null, $headers = null)
{
// make sure task function is up
if (!isset(self::$worker[$function]))
{
self::$worker[$function] = array();
}
// load the task
self::$worker[$function][] = self::lock($data);
// set the Headers if found
if ($headers && !isset(self::$workerHEADER[$function]))
{
self::setWorkerHeaders($function, $headers);
}
// set the URL if found
if ($url && !isset(self::$workerURL[$function]))
{
self::setWorkerUrl($function, $url);
}
}
/**
* Run set Workers
*
* @param string $function The function to target to perform the task
* @param string $perTask The amount of task per worker
* @param function $callback The option to do a call back when task is completed
* @param int $threadSize The size of the thread
*
* @return bool true On success
*
*/
public static function runWorker($function, $perTask = 50, $callback = null, $threadSize = 20)
{
// set task
$task = self::lock($function);
// build headers
$headers = array('VDM-TASK: ' .$task);
// build dynamic headers
if (isset(self::$workerHEADER[$function]) && self::checkArray(self::$workerHEADER[$function]))
{
foreach (self::$workerHEADER[$function] as $header)
{
$headers[] = $header;
}
}
// build worker options
$options = array();
// make sure worker is up
if (isset(self::$worker[$function]) && self::checkArray(self::$worker[$function]))
{
// this load method is for each
if (1 == $perTask)
{
// working with a string = 1
$headers[] = 'VDM-VALUE-TYPE: ' .self::lock(1);
// now load the options
foreach (self::$worker[$function] as $data)
{
$options[] = array(CURLOPT_HTTPHEADER => $headers, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => 'VDM_DATA='. $data);
}
}
// this load method is for bundles
else
{
// working with an array = 2
$headers[] = 'VDM-VALUE-TYPE: ' .self::lock(2);
// now load the options
$work = array_chunk(self::$worker[$function], $perTask);
foreach ($work as $data)
{
$options[] = array(CURLOPT_HTTPHEADER => $headers, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => 'VDM_DATA='. implode('___VDM___', $data));
}
}
// relieve worker of task/function
self::$worker[$function] = array();
}
// do the execution
if (self::checkArray($options))
{
if (isset(self::$workerURL[$function]))
{
$url = self::$workerURL[$function];
}
else
{
$url = JURI::root() . '/index.php?option=com_componentbuilder&task=api.worker';
}
return self::curlMultiExec($url, $options, $callback, $threadSize);
}
return false;
}
/**
* Do a multi curl execution of tasks
*
* @param string $url The url of where the task is to be performed
* @param array $_options The array of curl options/headers to set
* @param function $callback The option to do a call back when task is completed
* @param int $threadSize The size of the thread
*
* @return bool true On success
*
*/
public static function curlMultiExec(&$url, &$_options, $callback = null, $threadSize = 20)
{
// make sure we have curl available
if (!function_exists('curl_version'))
{
if (!self::$curlErrorLoaded)
{
// set the notice
JFactory::getApplication()->enqueueMessage(JText::_('COM_COMPONENTBUILDER_HTWOCURL_NOT_FOUNDHTWOPPLEASE_SETUP_CURL_ON_YOUR_SYSTEM_OR_BCOMPONENTBUILDERB_WILL_NOT_FUNCTION_CORRECTLYP'), 'Error');
// load the notice only once
self::$curlErrorLoaded = true;
}
return false;
}
// make sure we have an url
if (self::checkString($url))
{
// make sure the thread size isn't greater than the # of _options
$threadSize = (count($_options) < $threadSize) ? count($_options) : $threadSize;
// set the options
$options = array();
$options[CURLOPT_URL] = $url;
$options[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$options[CURLOPT_RETURNTRANSFER] = TRUE;
$options[CURLOPT_SSL_VERIFYPEER] = FALSE;
// start multi threading :)
$handle = curl_multi_init();
// start the first batch of requests
for ($i = 0; $i < $threadSize; $i++)
{
if (isset($_options[$i]))
{
$ch = curl_init();
foreach ($_options[$i] as $curlopt => $string)
{
$options[$curlopt] = $string;
}
curl_setopt_array($ch, $options);
curl_multi_add_handle($handle, $ch);
}
}
// we wait for all the calls to finish (should not take long)
do {
while(($execrun = curl_multi_exec($handle, $working)) == CURLM_CALL_MULTI_PERFORM);
if($execrun != CURLM_OK)
break;
// a request was just completed -- find out which one
while($done = curl_multi_info_read($handle))
{
if (is_callable($callback))
{
// $info = curl_getinfo($done['handle']);
// request successful. process output using the callback function.
$output = curl_multi_getcontent($done['handle']);
$callback($output);
}
$key = $i + 1;
if(isset($_options[$key]))
{
// start a new request (it's important to do this before removing the old one)
$ch = curl_init(); $i++;
// add options
foreach ($_options[$key] as $curlopt => $string)
{
$options[$curlopt] = $string;
}
curl_setopt_array($ch, $options);
curl_multi_add_handle($handle, $ch);
// remove options again
foreach ($_options[$key] as $curlopt => $string)
{
unset($options[$curlopt]);
}
}
// remove the curl handle that just completed
curl_multi_remove_handle($handle, $done['handle']);
}
// stop wasting CPU cycles and rest for a couple ms
usleep(10000);
} while ($working);
// close the curl multi thread
curl_multi_close($handle);
// okay done
return true;
}
return false;
}
/**
* Move File to Server
*

View File

@ -2041,12 +2041,12 @@ COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_CONSTANT_PATHS_DESCRIPTION="<p
<b>JPATH_BASE</b><br />
// The path to the cache folder.<br />
<b>JPATH_CACHE</b><br />
// The path to the administration folder of the current component being executed.<br />
<b>JPATH_COMPONENT_ADMINISTRATOR</b><br />
// The path to the site folder of the current component being executed.<br />
<b>JPATH_COMPONENT_SITE</b><br />
// The path to the current component being executed.<br />
<b>JPATH_COMPONENT</b><br />
// The path to the administration folder of JCB component.<br />
<b>JPATH_COMPONENT_ADMINISTRATOR</b> <small>no ideal to use</small><br />
// The path to the site folder of JCB component.<br />
<b>JPATH_COMPONENT_SITE</b> <small>no ideal to use</small><br />
// The path to the JCB component.<br />
<b>JPATH_COMPONENT</b> <small>no ideal to use</small><br />
// The path to folder containing the configuration.php file.<br />
<b>JPATH_CONFIGURATION</b><br />
// The path to the installation folder.<br />
@ -2218,6 +2218,7 @@ COM_COMPONENTBUILDER_CONFIG_AUTHOR_EMAIL_DESC="The email address of the author o
COM_COMPONENTBUILDER_CONFIG_AUTHOR_EMAIL_LABEL="Author Email"
COM_COMPONENTBUILDER_CONFIG_AUTHOR_NAME_DESC="The name of the author of this component."
COM_COMPONENTBUILDER_CONFIG_AUTHOR_NAME_LABEL="Author Name"
COM_COMPONENTBUILDER_CONFIG_AUTO_BACKUP="Auto Backup"
COM_COMPONENTBUILDER_CONFIG_AUTO_LOAD="Auto"
COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_DESCRIPTION="You can run a cronjob that will backup all your components as they are mapped in JCB.<br /><br /><b>USE THE FOLLOWING:</b> <span id='cronjob-backup'>loading...<span class='loading-dots' ></span></span><br /><br />Please note that if your Joomla website has a Firewall installed, it will not allow cronjob via direct URL (most of the time), you will then need to adapt the cornjob request to look like a browser. For more info please read https://stackoverflow.com/a/31597823/1429677
<script type='text/javascript'>
@ -2268,7 +2269,7 @@ function getCronPath(getType, token){
} else {
jQuery('#cronjob-'+getType).html('<span style=\'color: red;\'>Error loading path!</span>');
}
})
});
}
</script>"
COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_LABEL="Backup JCB Mapped Components"
@ -2307,7 +2308,6 @@ COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_LABEL="Compiler Folder Path"
COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_MESSAGE="Error! Please add some text here."
COM_COMPONENTBUILDER_CONFIG_COMPONENT="Component"
COM_COMPONENTBUILDER_CONFIG_COMPONENT_LABEL="Component"
COM_COMPONENTBUILDER_CONFIG_CRONJOB="CronJob"
COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_FOLDER_PATH_DESCRIPTION="Here you can set the path to where all components are backed up to."
COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_FOLDER_PATH_HINT="/home/user/fullbackup"
COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_FOLDER_PATH_LABEL="Cronjob Backup Folder Path"
@ -2357,7 +2357,6 @@ COM_COMPONENTBUILDER_CONFIG_EMAILREPLY_HINT="Email Address Here"
COM_COMPONENTBUILDER_CONFIG_EMAILREPLY_LABEL=" Reply to Email"
COM_COMPONENTBUILDER_CONFIG_ENCRYPTION_DESC="The encryption key for the field encryption is set here."
COM_COMPONENTBUILDER_CONFIG_ENCRYPTION_LABEL="Encryption Settings"
COM_COMPONENTBUILDER_CONFIG_EVENT_LABEL="Trigger Event"
COM_COMPONENTBUILDER_CONFIG_EVERY_DAY="Every Day"
COM_COMPONENTBUILDER_CONFIG_EVERY_FIFTEEN_MINUTES="Every 15 Minutes"
COM_COMPONENTBUILDER_CONFIG_EVERY_FIVE_HOURS="Every 5 Hours"
@ -2370,6 +2369,35 @@ COM_COMPONENTBUILDER_CONFIG_EVERY_THIRTY_MINUTES="Every 30 Minutes"
COM_COMPONENTBUILDER_CONFIG_EVERY_THIRTY_SECONDS="Every 30 Seconds"
COM_COMPONENTBUILDER_CONFIG_EVERY_WEEK="Every Week"
COM_COMPONENTBUILDER_CONFIG_EXPANSION="Expansion"
COM_COMPONENTBUILDER_CONFIG_EXPANSIONCRONJOB_NOTE_DESCRIPTION="You must run a cronjob that will trigger the expansion events for JCB.<br /><br /><b>USE THE FOLLOWING:</b> <span id='cronjob-expand'>loading...<span class='loading-dots' ></span></span><br /><br />Please note that if your Joomla website has a Firewall installed, it will not allow cronjob via direct URL (most of the time), you will then need to adapt the cornjob request to look like a browser. For more info please read https://stackoverflow.com/a/31597823/1429677
<script type='text/javascript'>
jQuery(document).ready(function($) {
// get token from the form
$('form :input').each(function(index, elm){
if (elm.name.length == 32 && elm.type == 'hidden')
{
value = $(elm).val();
if (1 == value)
{
token = elm.name;
}
}
});
// nice little dot trick :)
var x=0;
setInterval(function() {
var dots = '';
x++;
for (var y=0; y < x%11; y++) {
dots+='.';
}
jQuery('.loading-dots').text(dots);
} , 500);
// now get the Cron Path
getCronPath('expand', token);
});
</script>"
COM_COMPONENTBUILDER_CONFIG_EXPANSIONCRONJOB_NOTE_LABEL="Expansion Cronjob"
COM_COMPONENTBUILDER_CONFIG_EXPANSION_DESCRIPTION="Properties for this field"
COM_COMPONENTBUILDER_CONFIG_EXPANSION_LABEL="Expansion"
COM_COMPONENTBUILDER_CONFIG_EXPORT_BUY_LINK_DESCRIPTION="Enter link where your JCB package key can be bought."
@ -2433,7 +2461,7 @@ COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_FOLDER_PATH_DESCRIPTION="The custom fold
COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_FOLDER_PATH_LABEL="Moving The Custom Folder"
COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_DEFAULT_DESCRIPTION="<p>This method is basically the way JCB has always worked by default.</p><p>You have a compiler area, once you have made changes you go to the compiler view and compile your component. Then you have the option to install and/or distribute the Joomla install package.</p><p>This can also be called the manual development method.</p>"
COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_DEFAULT_LABEL="Default Development Method"
COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_DESCRIPTION="<p>This method adds auto expansion to the current Joomla automatically.</p><p>Below you setup events that trigger <b>auto build and install</b> of a selected set of components. So you do not need to manually compile and install those components any more, the system does all that automatically for you.</p><p>So your experience is that you change the field, view or something else in JCB and then the component in Joomla moments later, based on your events and the size of your component, reflect those changed automatically.</p><p>This can also be called the automatic development method.</p>"
COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_DESCRIPTION="<p>This method adds auto expansion to the current Joomla automatically.</p><p>Below you setup the behaviour of a selected set of components that will be <b>auto build and installed</b>. So you do not need to manually compile and install those components any more, the system does all that automatically for you.</p><p>So your experience is that you change the field, view or something else in JCB and then the component in Joomla moments later reflect those changed automatically. The latency of the workflow is based on your <b>cronjob frequency</b> and the <b>size</b> of your component. You can pause the build in a few ways, one by actually <b>checking out/opening</b> the Joomla Component view of the component in JCB, or changing the state to unpublish, archive or trashed, or simply remove if from the list below.</p><p>This can also be called the automatic development method.</p>"
COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_LABEL="Expansion Development Method"
COM_COMPONENTBUILDER_CONFIG_NOTE_DKIM_USE_DESCRIPTION="<p>Using the below details, you need to configure your DNS by adding a TXT record on your domain: <b><span id='a_dkim_domain'></span></b></p>
<script>
@ -2474,12 +2502,9 @@ COM_COMPONENTBUILDER_CONFIG_PACKAGE_NAME_PLAEHOLDERS_DESCRIPTION="<code>[YEAR]</
COM_COMPONENTBUILDER_CONFIG_PACKAGE_NAME_PLAEHOLDERS_LABEL="Package Name Placeholders"
COM_COMPONENTBUILDER_CONFIG_PERCENTAGELANGUAGEADD_DESCRIPTION="Select percentage any language should be translated before the system should add the language to the component during compilation."
COM_COMPONENTBUILDER_CONFIG_PERCENTAGELANGUAGEADD_LABEL="Add Language if %? ready."
COM_COMPONENTBUILDER_CONFIG_PERCHANGE="Per/change"
COM_COMPONENTBUILDER_CONFIG_PERCOMPONENT_EVENT="Per/Component event"
COM_COMPONENTBUILDER_CONFIG_PERDAY="Per/Day"
COM_COMPONENTBUILDER_CONFIG_PERHOUR="Per/hour"
COM_COMPONENTBUILDER_CONFIG_PERJCB_PACKAGE_IMPORT="Per/JCB package import"
COM_COMPONENTBUILDER_CONFIG_PHP_MAIL="PHP Mail"
COM_COMPONENTBUILDER_CONFIG_PLACEHOLDERS_DESCRIPTION="Should JCB insert the custom code placeholders? This is only applicable if this component has custom code."
COM_COMPONENTBUILDER_CONFIG_PLACEHOLDERS_LABEL="Add Custom Code Placeholders"
COM_COMPONENTBUILDER_CONFIG_REMOTE_SERVER="Remote Server"
COM_COMPONENTBUILDER_CONFIG_REPLYNAME_DESCRIPTION="Text displayed in the header &quot;Reply To:&quot; field when replying to the site email. Usually the the person that receives the response. (leave blank for none)"
COM_COMPONENTBUILDER_CONFIG_REPLYNAME_HINT="Reply Name Here"
@ -3262,7 +3287,7 @@ COM_COMPONENTBUILDER_DEFAULT_LINK="Default (link)"
COM_COMPONENTBUILDER_DEFAULT_VIEW="Default View"
COM_COMPONENTBUILDER_DESCRIPTION="Description"
COM_COMPONENTBUILDER_DETAILS="Details"
COM_COMPONENTBUILDER_DISPLAY_SWITCH_FOR_DYNAMIC_PLACEMENT_IN_RELATION_TO_THE_USE_OF_THE_FIELD_IN_MENU_AND_GLOBAL_CONFIGURATION_OPTIONS="Display switch for dynamic placement in relation to the use of the field in menu and global configuration options."
COM_COMPONENTBUILDER_DISPLAY_SWITCH_FOR_DYNAMIC_PLACEMENT_IN_RELATION_TO_THE_USE_OF_THE_FIELD_IN_MENU_AND_GLOBAL_CONFIGURATION_OPTIONS_SO_THE_CONFIG_OPTION_WILL_ONLY_ADD_THE_FIELD_TO_THE_GLOBAL_CONFIGURATION_AREA_MENU_WILL_ADD_THE_FIELD_ONLY_TO_THE_MENU_AREA="Display switch for dynamic placement in relation to the use of the field in menu and global configuration options. So the (config) option will only add the field to the global configuration area, (menu) will add the field only to the menu area."
COM_COMPONENTBUILDER_DIVERGED="Diverged"
COM_COMPONENTBUILDER_DIVERGED_MEANS_YOUR_BLOCAL_SNIPPETB_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_HAS_A_BDIVERGEDB_FROM_THE_COMMUNITY_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_IN_THAT_IT_DOES_NOT_HAVE_THE_SAME_BCREATIONB_OR_BMODIFIED_DATEB="Diverged means your <b>local snippet</b> (with the same name, library and type) has a <b>diverged</b> from the community snippet (with the same name, library and type) in that it does not have the same <b>creation</b> or <b>modified date</b>."
COM_COMPONENTBUILDER_DOES_THIS_PACKAGE_REQUIRE_A_KEY_TO_INSTALL="Does this package require a key to install."
@ -5210,12 +5235,12 @@ COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION=
<b>JPATH_BASE</b><br />
// The path to the cache folder.<br />
<b>JPATH_CACHE</b><br />
// The path to the administration folder of the current component being executed.<br />
<b>JPATH_COMPONENT_ADMINISTRATOR</b><br />
// The path to the site folder of the current component being executed.<br />
<b>JPATH_COMPONENT_SITE</b><br />
// The path to the current component being executed.<br />
<b>JPATH_COMPONENT</b><br />
// The path to the administration folder of JCB component.<br />
<b>JPATH_COMPONENT_ADMINISTRATOR</b> <small>no ideal to use</small><br />
// The path to the site folder of JCB component.<br />
<b>JPATH_COMPONENT_SITE</b> <small>no ideal to use</small><br />
// The path to the JCB component.<br />
<b>JPATH_COMPONENT</b> <small>no ideal to use</small><br />
// The path to folder containing the configuration.php file.<br />
<b>JPATH_CONFIGURATION</b><br />
// The path to the installation folder.<br />

View File

@ -168,6 +168,19 @@ class ComponentbuilderModelAjax extends JModelList
}
$result['path'] = '<code>' . $path . '</code>';
}
elseif ('expand' === $type)
{
$result['error'] = '<span style="color: red;">' . JText::sprintf('COM_COMPONENTBUILDER_NO_CRONJOB_PATH_FOUND_FOR_S', $type) . '</span>';
if ($this->hasCurl())
{
$path = '* * * * * curl -s "' .JURI::root() . 'index.php?option=com_componentbuilder&task=api.expand" >/dev/null 2>&1';
}
else
{
$path = '* * * * * wget "' .JURI::root() . 'index.php?option=com_componentbuilder&task=api.expand" >/dev/null 2>&1';
}
$result['path'] = '<code>' . $path . '</code>';
}
return $result;
}
@ -2243,7 +2256,7 @@ class ComponentbuilderModelAjax extends JModelList
protected $extraFieldProperties = array(
'listclass' => 'COM_COMPONENTBUILDER_SET_A_CLASS_VALUE_FOR_THE_LIST_VIEW_OF_THIS_FIELD',
'escape' => 'COM_COMPONENTBUILDER_SHOULD_THIS_FIELD_BE_ESCAPED_IN_THE_LIST_VIEW',
'display' => 'COM_COMPONENTBUILDER_DISPLAY_SWITCH_FOR_DYNAMIC_PLACEMENT_IN_RELATION_TO_THE_USE_OF_THE_FIELD_IN_MENU_AND_GLOBAL_CONFIGURATION_OPTIONS',
'display' => 'COM_COMPONENTBUILDER_DISPLAY_SWITCH_FOR_DYNAMIC_PLACEMENT_IN_RELATION_TO_THE_USE_OF_THE_FIELD_IN_MENU_AND_GLOBAL_CONFIGURATION_OPTIONS_SO_THE_CONFIG_OPTION_WILL_ONLY_ADD_THE_FIELD_TO_THE_GLOBAL_CONFIGURATION_AREA_MENU_WILL_ADD_THE_FIELD_ONLY_TO_THE_MENU_AREA',
'validate' => 'COM_COMPONENTBUILDER_TO_ADD_VALIDATION_TO_A_FIELD_IF_VALIDATION_IS_NOT_PART_OF_FIELD_TYPE_PROPERTIES_LOADED_ABOVE_SO_IF_YOU_HAVE_VALIDATION_SET_AS_A_FIELD_PROPERTY_THIS_EXTRA_PROPERTY_WILL_NOT_BE_NEEDED');
public function getFieldOptions($fieldtype)

View File

@ -151,7 +151,7 @@ class ComponentbuilderModelCompiler extends JModelList
}
public $compiler;
public function getComponents()
{
// Get a db connection.
@ -169,18 +169,18 @@ class ComponentbuilderModelCompiler extends JModelList
// return the result
return $db->loadObjectList();
}
public function builder($version, $id, $backup, $repo, $addPlaceholders, $debugLinenr, $minify)
{
$set['joomlaVersion'] = $version;
$set['componentId'] = $id;
$set['addBackup'] = $backup;
$set['addRepo'] = $repo;
$set['addPlaceholders'] = $addPlaceholders;
$set['debugLinenr'] = $debugLinenr;
$set['minify'] = $minify;
{
$set['version'] = $version;
$set['component'] = $id;
$set['backup'] = $backup;
$set['repository'] = $repo;
$set['placeholders'] = $addPlaceholders;
$set['debuglinenr'] = $debugLinenr;
$set['minify'] = $minify;
// start up Compiler
$this->compiler = new Compiler($set);
$this->compiler = new Compiler($set);
if($this->compiler)
{
return true;

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="3.2" method="upgrade">
<name>COM_COMPONENTBUILDER</name>
<creationDate>23rd April, 2018</creationDate>
<creationDate>24th April, 2018</creationDate>
<author>Llewellyn van der Merwe</author>
<authorEmail>llewellyn@joomlacomponentbuilder.com</authorEmail>
<authorUrl>http://joomlacomponentbuilder.com</authorUrl>

View File

@ -210,12 +210,146 @@ class ComponentbuilderControllerApi extends JControllerForm
return;
}
public function expand()
{
// get params first
if (!isset($this->params) || !ComponentbuilderHelper::checkObject($this->params))
{
$this->params = JComponentHelper::getParams('com_componentbuilder');
}
// check if expansion is enabled
$method = $this->params->get('development_method', 1);
if (2 == $method)
{
// get expansion components
$expansion = $this->params->get('expansion', null);
// check if they are set
if (ComponentbuilderHelper::checkObject($expansion))
{
// check if user has the right
$user = $this->getApiUser();
if ($user->authorise('core.admin', 'com_componentbuilder'))
{
// we have two options, doing them one at a time, use using curl to do tome somewhat asynchronously
if (count ( (array) $expansion) > 1 && function_exists('curl_version'))
{
// set workers
foreach ($expansion as $component)
{
ComponentbuilderHelper::setWorker($component, 'compileInstall');
}
// get messages function
$callback = function($messages) {
$messages = ComponentbuilderHelper::unlock($messages);
// check if we have any messages
if (ComponentbuilderHelper::checkArray($messages))
{
// echo "<br />\n".implode("<br />\n", $messages); // (TODO) adding a switch to show messages
} else {
var_dump($messages); // error debug message
}
};
// run workers
ComponentbuilderHelper::runWorker('compileInstall', 1, $callback);
}
else
{
// get model
$model = $this->getModel('api');
// load the compiler
$this->_autoloader();
// set workers
foreach ($expansion as $component)
{
// compile and install
$model->compileInstall($component);
}
// check if we have any messages
if (ComponentbuilderHelper::checkArray($model->messages))
{
// echo the messages
// echo "<br />\n".implode("<br />\n", $model->messages); // (TODO) adding a switch to show messages
} else {
var_dump($messages); // error debug message
}
}
// clear session
JFactory::getApplication()->getSession()->destroy();
jexit();
}
// clear session
JFactory::getApplication()->getSession()->destroy();
jexit('Access Denied!');
}
}
// clear session
JFactory::getApplication()->getSession()->destroy();
jexit('Expansion Disabled!');
}
protected function getApiUser()
{
// return user object
return JFactory::getUser($this->params->get('api', 0, 'INT'));
}
public function worker()
{
// get input values
$input = JFactory::getApplication()->input;
// get DATA
$DATA = $input->post->get('VDM_DATA', null, 'STRING');
// get TASK
$TASK = $input->server->get('HTTP_VDM_TASK', null, 'STRING');
// get TYPE
$TYPE = $input->server->get('HTTP_VDM_VALUE_TYPE', null, 'STRING');
// check if correct value is given
if (ComponentbuilderHelper::checkString($DATA) && ComponentbuilderHelper::checkString($TASK) && ComponentbuilderHelper::checkString($TYPE))
{
// get the type of values we are working with ( 2 = array; 1 = string)
$type = ComponentbuilderHelper::unlock($TYPE);
// get data value
$dataValues = ComponentbuilderHelper::unlock($DATA);
// get the task
$task = ComponentbuilderHelper::unlock($TASK);
// check the for a string
if (1 == $type && ComponentbuilderHelper::checkObject($dataValues) && ComponentbuilderHelper::checkString($task))
{
// get params first
if (!isset($this->params) || !ComponentbuilderHelper::checkObject($this->params))
{
$this->params = JComponentHelper::getParams('com_componentbuilder');
}
// get model
$model = $this->getModel('api');
// open the compile Install function
if ('compileInstall' === $task)
{
// load the compiler
$this->_autoloader();
// compile and install
$model->compileInstall($dataValues);
// return locked values
echo ComponentbuilderHelper::lock($model->messages);
// clear session
JFactory::getApplication()->getSession()->destroy();
jexit();
}
}
}
// not success
echo 0;
// clear session
JFactory::getApplication()->getSession()->destroy();
jexit();
}
protected function _autoloader()
{
// include component compiler
require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/compiler.php';
}
/**
* Method to check if you can edit an existing record.
*

View File

@ -2290,6 +2290,607 @@ abstract class ComponentbuilderHelper
}
}
/**
* the locker
*
* @var array
**/
protected static $locker = array();
/**
* the dynamic replacement salt
*
* @var array
**/
protected static $globalSalt = array();
/**
* the timer
*
* @var object
**/
protected static $keytimer;
/**
* To Lock string
*
* @param string $string The string/array to lock
* @param string $key The custom key to use
* @param int $salt The switch to add salt and type of salt
* @param int $dynamic The dynamic replacement array of salt build string
* @param int $urlencode The switch to control url encoding
**/
public static function lock($string, $key = null, $salt = 2, $dynamic = null, $urlencode = true)
{
// get the global settings
if (!$key || !self::checkString($key))
{
// set temp timer
$timer = 2;
// if we have a timer use it
if ($salt > 0)
{
$timer = $salt;
}
if (method_exists(get_called_class(), "getCryptKey"))
{
$key = self::getCryptKey('basic', self::salt($timer, $dynamic));
}
else
{
$key = self::salt($timer, $dynamic);
}
}
// check if we have a salt timer
if ($salt > 0)
{
$key .= self::salt($salt, $dynamic);
}
// get the locker settings
if (!isset(self::$locker[$key]) || !self::checkObject(self::$locker[$key]))
{
self::$locker[$key] = new FOFEncryptAes($key, 128);
}
// convert array or object to string
if (self::checkArray($string) || self::checkObject($string))
{
$string = serialize($string);
}
// prep for url
if ($urlencode)
{
return self::base64_urlencode(self::$locker[$key]->encryptString($string));
}
return self::$locker[$key]->encryptString($string);
}
/**
* To un-Lock string
*
* @param string $string The string to unlock
* @param string $key The custom key to use
* @param int $salt The switch to add salt and type of salt
* @param int $dynamic The dynamic replacement array of salt build string
* @param int $urlencode The switch to control url decoding
**/
public static function unlock($string, $key = null, $salt = 2, $dynamic = null, $urlencode = true)
{
// get the global settings
if (!$key || !self::checkString($key))
{
// set temp timer
$timer = 2;
// if we have a timer use it
if ($salt > 0)
{
$timer = $salt;
}
// get secure key
if (method_exists(get_called_class(), "getCryptKey"))
{
$key = self::getCryptKey('basic', self::salt($timer, $dynamic));
}
else
{
$key = self::salt($timer, $dynamic);
}
}
// check if we have a salt timer
if ($salt > 0)
{
$key .= self::salt($salt, $dynamic);
}
// get the locker settings
if (!isset(self::$locker[$key]) || !self::checkObject(self::$locker[$key]))
{
self::$locker[$key] = new FOFEncryptAes($key, 128);
}
// make sure we have real base64
if ($urlencode)
{
$string = self::base64_urldecode($string);
}
// basic decrypt string.
if (!empty($string) && !is_numeric($string) && $string === base64_encode(base64_decode($string, true)))
{
$string = rtrim(self::$locker[$key]->decryptString($string), "\0");
// convert serial string to array
if (self::is_serial($string))
{
$string = unserialize($string);
}
}
return $string;
}
/**
* The Salt
*
* @param int $type The type of length the salt should be valid
* @param int $dynamic The dynamic replacement array of salt build string
**/
public static function salt($type = 1, $dynamic = null)
{
// get dynamic replacement salt
$dynamic = self::getDynamicSalt($dynamic);
// get the key timer
if (!self::checkObject(self::$keytimer))
{
// load the date time object
self::$keytimer = new DateTime;
// set the correct time stamp
$vdmLocalTime = new DateTimeZone('Africa/Windhoek');
self::$keytimer->setTimezone($vdmLocalTime);
}
// set type
if ($type == 2)
{
// hour
$format = 'Y-m-d \o\n ' . self::periodFix(self::$keytimer->format('H'));
}
elseif ($type == 3)
{
// day
$format = 'Y-m-' . self::periodFix(self::$keytimer->format('d'));
}
elseif ($type == 4)
{
// month
$format = 'Y-' . self::periodFix(self::$keytimer->format('m'));
}
else
{
// minute
$format = 'Y-m-d \o\n H:' . self::periodFix(self::$keytimer->format('i'));
}
// get key
if (self::checkArray($dynamic))
{
return md5(str_replace(array_keys($dynamic), array_values($dynamic), self::$keytimer->format($format) . ' @ VDM.I0'));
}
return md5(self::$keytimer->format($format) . ' @ VDM.I0');
}
/**
* The function to insure the salt is valid within the given period (third try)
*
* @param int $main The main number
*/
protected static function periodFix($main)
{
return round($main / 3) * 3;
}
/**
* Check if a string is serialized
* @param string $string
*/
public static function is_serial($string)
{
return (@unserialize($string) !== false);
}
/**
* Get dynamic replacement salt
*/
public static function getDynamicSalt($dynamic = null)
{
// load global if not manually set
if (!self::checkArray($dynamic))
{
return self::getGlobalSalt();
}
// return manual values if set
else
{
return $dynamic;
}
}
/**
* The random or dynamic secret salt
*/
public static function getSecretSalt($string = null, $size = 9)
{
// set the string
if (!$string)
{
// get random string
$string = self::randomkey($size);
}
// convert string to array
$string = self::safeString($string);
// convert string to array
$array = str_split($string);
// insure only unique values are used
$array = array_unique($array);
// set the size
$size = ($size <= count($array)) ? $size : count($array);
// down size the
return array_slice($array, 0, $size);
}
/**
* Get global replacement salt
*/
public static function getGlobalSalt()
{
// load from memory if found
if (!self::checkArray(self::$globalSalt))
{
// get the global settings
if (!self::checkObject(self::$params))
{
self::$params = JComponentHelper::getParams('com_componentbuilder');
}
// check if we have a global dynamic replacement array available (format --> ' 1->!,3->E,4->A')
$tmp = self::$params->get('dynamic_salt', null);
if (self::checkString($tmp) && strpos($tmp, ',') !== false && strpos($tmp, '->') !== false)
{
$salt = array_map('trim', (array) explode(',', $tmp));
if (self::checkArray($salt ))
{
foreach($salt as $replace)
{
$dynamic = array_map('trim', (array) explode('->', $replace));
if (isset($dynamic[0]) && isset($dynamic[1]))
{
self::$globalSalt[$dynamic[0]] = $dynamic[1];
}
}
}
}
}
// return global if found
if (self::checkArray(self::$globalSalt))
{
return self::$globalSalt;
}
// return default as fail safe
return array('1' => '!', '3' => 'E', '4' => 'A');
}
/**
* Close public protocol
*/
public static function closePublicProtocol($id, $public)
{
// get secret salt
$secretSalt = self::getSecretSalt(self::salt(1,array('4' => 'R','1' => 'E','2' => 'G','7' => 'J','8' => 'A')));
// get the key
$key = self::salt(1, $secretSalt);
// get secret salt
$secret = self::getSecretSalt();
// set the secret
$close['SECRET'] = self::lock($secret, $key, 1, array('1' => 's', '3' => 'R', '4' => 'D'));
// get the key
$key = self::salt(1, $secret);
// get the public key
$close['PUBLIC'] = self::lock($public, $key, 1, array('1' => '!', '3' => 'E', '4' => 'A'));
// get secret salt
$secretSalt = self::getSecretSalt($public);
// get the key
$key = self::salt(1, $secretSalt);
// get the ID
$close['ID'] = self::unlock($id, $key, 1, array('1' => 'i', '3' => 'e', '4' => 'B'));
// return closed values
return $close;
}
/**
* Open public protocol
*/
public static function openPublicProtocol($SECRET, $ID, $PUBLIC)
{
// get secret salt
$secretSalt = self::getSecretSalt(self::salt(1,array('4' => 'R','1' => 'E','2' => 'G','7' => 'J','8' => 'A')));
// get the key
$key = self::salt(1, $secretSalt);
// get the $SECRET
$SECRET = self::unlock($SECRET, $key, 1, array('1' => 's', '3' => 'R', '4' => 'D'));
// get the key
$key = self::salt(1, $SECRET);
// get the public key
$open['public'] = self::unlock($PUBLIC, $key, 1, array('1' => '!', '3' => 'E', '4' => 'A'));
// get secret salt
$secretSalt = self::getSecretSalt($open['public']);
// get the key
$key = self::salt(1, $secretSalt);
// get the ID
$open['id'] = self::unlock($ID, $key, 1, array('1' => 'i', '3' => 'e', '4' => 'B'));
// return opened values
return $open;
}
/**
* Workers to load tasks
*
* @var array
*/
protected static $worker = array();
/**
* Set a worker dynamic URLs
*
* @var array
*/
protected static $workerURL = array();
/**
* Set a worker dynamic HEADERs
*
* @var array
*/
protected static $workerHEADER = array();
/**
* Curl Error Notice
*
* @var bool
*/
protected static $curlErrorLoaded = false;
/**
* Set a worker url
*
* @param string $function The function to target to perform the task
* @param string $url The url of where the task is to be performed
*
* @return void
*
*/
public static function setWorkerUrl(&$function, &$url)
{
// set the URL if found
if (self::checkString($url))
{
// make sure task function url is up
self::$workerURL[$function] = $url;
}
}
/**
* Set a worker headers
*
* @param string $function The function to target to perform the task
* @param array $headers The headers needed for these workers/function
*
* @return void
*
*/
public static function setWorkerHeaders(&$function, &$headers)
{
// set the Headers if found
if (self::checkArray($headers))
{
// make sure task function headers are set
self::$workerHEADER[$function] = $headers;
}
}
/**
* Set a worker that needs to perform a task
*
* @param mixed $data The data to pass to the task
* @param string $function The function to target to perform the task
* @param string $url The url of where the task is to be performed
* @param array $headers The headers needed for these workers/function
*
* @return void
*
*/
public static function setWorker($data, $function, $url = null, $headers = null)
{
// make sure task function is up
if (!isset(self::$worker[$function]))
{
self::$worker[$function] = array();
}
// load the task
self::$worker[$function][] = self::lock($data);
// set the Headers if found
if ($headers && !isset(self::$workerHEADER[$function]))
{
self::setWorkerHeaders($function, $headers);
}
// set the URL if found
if ($url && !isset(self::$workerURL[$function]))
{
self::setWorkerUrl($function, $url);
}
}
/**
* Run set Workers
*
* @param string $function The function to target to perform the task
* @param string $perTask The amount of task per worker
* @param function $callback The option to do a call back when task is completed
* @param int $threadSize The size of the thread
*
* @return bool true On success
*
*/
public static function runWorker($function, $perTask = 50, $callback = null, $threadSize = 20)
{
// set task
$task = self::lock($function);
// build headers
$headers = array('VDM-TASK: ' .$task);
// build dynamic headers
if (isset(self::$workerHEADER[$function]) && self::checkArray(self::$workerHEADER[$function]))
{
foreach (self::$workerHEADER[$function] as $header)
{
$headers[] = $header;
}
}
// build worker options
$options = array();
// make sure worker is up
if (isset(self::$worker[$function]) && self::checkArray(self::$worker[$function]))
{
// this load method is for each
if (1 == $perTask)
{
// working with a string = 1
$headers[] = 'VDM-VALUE-TYPE: ' .self::lock(1);
// now load the options
foreach (self::$worker[$function] as $data)
{
$options[] = array(CURLOPT_HTTPHEADER => $headers, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => 'VDM_DATA='. $data);
}
}
// this load method is for bundles
else
{
// working with an array = 2
$headers[] = 'VDM-VALUE-TYPE: ' .self::lock(2);
// now load the options
$work = array_chunk(self::$worker[$function], $perTask);
foreach ($work as $data)
{
$options[] = array(CURLOPT_HTTPHEADER => $headers, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => 'VDM_DATA='. implode('___VDM___', $data));
}
}
// relieve worker of task/function
self::$worker[$function] = array();
}
// do the execution
if (self::checkArray($options))
{
if (isset(self::$workerURL[$function]))
{
$url = self::$workerURL[$function];
}
else
{
$url = JURI::root() . '/index.php?option=com_componentbuilder&task=api.worker';
}
return self::curlMultiExec($url, $options, $callback, $threadSize);
}
return false;
}
/**
* Do a multi curl execution of tasks
*
* @param string $url The url of where the task is to be performed
* @param array $_options The array of curl options/headers to set
* @param function $callback The option to do a call back when task is completed
* @param int $threadSize The size of the thread
*
* @return bool true On success
*
*/
public static function curlMultiExec(&$url, &$_options, $callback = null, $threadSize = 20)
{
// make sure we have curl available
if (!function_exists('curl_version'))
{
if (!self::$curlErrorLoaded)
{
// set the notice
JFactory::getApplication()->enqueueMessage(JText::_('COM_COMPONENTBUILDER_HTWOCURL_NOT_FOUNDHTWOPPLEASE_SETUP_CURL_ON_YOUR_SYSTEM_OR_BCOMPONENTBUILDERB_WILL_NOT_FUNCTION_CORRECTLYP'), 'Error');
// load the notice only once
self::$curlErrorLoaded = true;
}
return false;
}
// make sure we have an url
if (self::checkString($url))
{
// make sure the thread size isn't greater than the # of _options
$threadSize = (count($_options) < $threadSize) ? count($_options) : $threadSize;
// set the options
$options = array();
$options[CURLOPT_URL] = $url;
$options[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12';
$options[CURLOPT_RETURNTRANSFER] = TRUE;
$options[CURLOPT_SSL_VERIFYPEER] = FALSE;
// start multi threading :)
$handle = curl_multi_init();
// start the first batch of requests
for ($i = 0; $i < $threadSize; $i++)
{
if (isset($_options[$i]))
{
$ch = curl_init();
foreach ($_options[$i] as $curlopt => $string)
{
$options[$curlopt] = $string;
}
curl_setopt_array($ch, $options);
curl_multi_add_handle($handle, $ch);
}
}
// we wait for all the calls to finish (should not take long)
do {
while(($execrun = curl_multi_exec($handle, $working)) == CURLM_CALL_MULTI_PERFORM);
if($execrun != CURLM_OK)
break;
// a request was just completed -- find out which one
while($done = curl_multi_info_read($handle))
{
if (is_callable($callback))
{
// $info = curl_getinfo($done['handle']);
// request successful. process output using the callback function.
$output = curl_multi_getcontent($done['handle']);
$callback($output);
}
$key = $i + 1;
if(isset($_options[$key]))
{
// start a new request (it's important to do this before removing the old one)
$ch = curl_init(); $i++;
// add options
foreach ($_options[$key] as $curlopt => $string)
{
$options[$curlopt] = $string;
}
curl_setopt_array($ch, $options);
curl_multi_add_handle($handle, $ch);
// remove options again
foreach ($_options[$key] as $curlopt => $string)
{
unset($options[$curlopt]);
}
}
// remove the curl handle that just completed
curl_multi_remove_handle($handle, $done['handle']);
}
// stop wasting CPU cycles and rest for a couple ms
usleep(10000);
} while ($working);
// close the curl multi thread
curl_multi_close($handle);
// okay done
return true;
}
return false;
}
/**
* Move File to Server
*

View File

@ -6,6 +6,9 @@ COM_COMPONENTBUILDER_BACKUP_FAILED_PLEASE_TRY_AGAIN_IF_THE_ERROR_CONTINUE_PLEASE
COM_COMPONENTBUILDER_BACKUP_WAS_DONE_SUCCESSFULLY="Backup was done successfully"
COM_COMPONENTBUILDER_CHECK_YOUR_OWNER_DETAILS_IT_HAS_NOT_BEEN_SET_OPEN_THE_JCB_GLOBAL_OPTIONS_GO_TO_THE_COMPANY_TAB_AND_ADD_THE_CORRECT_COMPANY_DETAILS_THERE="Check your owner details, it has not been set. Open the JCB Global Options, go to the Company tab and add the correct company details there."
COM_COMPONENTBUILDER_COMPANY_S="Company: %s"
COM_COMPONENTBUILDER_COMPONENT_DID_NOT_COMPILE="Component did not compile!"
COM_COMPONENTBUILDER_COMPONENT_IS_NOT_PUBLISHED_OR_IS_CHECKED_OUT="Component is not published, or is checked out!"
COM_COMPONENTBUILDER_COMPONENT_WAS_NOT_FOUND="Component was not found!"
COM_COMPONENTBUILDER_COPYRIGHT_S="Copyright: %s"
COM_COMPONENTBUILDER_CREATE_NEW_S="Create New %s"
COM_COMPONENTBUILDER_DESCRIPTION="Description"
@ -54,6 +57,9 @@ COM_COMPONENTBUILDER_THE_PACKAGE_KEY_IS_S="The package key is: %s"
COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FIELD_COULD_NOT_BE_LOADED_FOR_BSB_SERVER="The private key field could not be loaded for <b>%s</b> server!"
COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER="The private key file could not be loaded/found for <b>%s</b> server!"
COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BID_SB_COULD_NOT_BE_RETRIEVED="The server details for <b>(ID: %s)</b> could not be retrieved!"
COM_COMPONENTBUILDER_THE_S_WAS_NOT_INSTALLED_AND_IS_STILL_IN_THE_TEMP_FOLDER="The %s was not Installed and is still in the temp folder."
COM_COMPONENTBUILDER_THE_S_WAS_SUCCESSFULLY_COMPILED="The %s was successfully compiled."
COM_COMPONENTBUILDER_THE_S_WAS_SUCCESSFULLY_INSTALLED_AND_REMOVED_FROM_TEMP_FOLDER="The %s was successfully Installed and removed from temp folder."
COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST="The url (%s) set to retrieve the packages does not exist!"
COM_COMPONENTBUILDER_THIS_PACKAGE_HAS_NO_KEY="This package has no key."
COM_COMPONENTBUILDER_TO_CHANGE_THE_PACKAGE_OWNER_DEFAULTS_OPEN_THE_BJCB_GLOBAL_OPTIONSB_GO_TO_THE_BCOMPANYB_TAB_AND_ADD_THE_CORRECT_COMPANY_DETAILS_THERE="To change the package owner defaults. Open the <b>JCB Global Options</b>, go to the <b>Company</b> tab and add the correct company details there."

View File

@ -175,5 +175,73 @@ class ComponentbuilderModelApi extends JModelItem
return $this->uikitComp;
}
return false;
}
}
public $messages = array();
public $model;
protected $compiler;
public function compileInstall($component)
{
$values = array(
'version' => 3,
'component' => 0,
'backup' => 0,
'repository' => 0,
'placeholders' => 2,
'debuglinenr' => 2,
'minify' => 2
);
// set the values
foreach ($values as $key => $val)
{
if (isset($component->{$key}))
{
$values[$key] = $component->{$key};
}
}
// make sure we have a component
if (isset($values['component']) && $values['component'] > 1)
{
// make sure the component is published
$published = ComponentbuilderHelper::getVar('joomla_component', (int) $values['component'], 'id', 'published');
// make sure the component is checked in
$checked_out = ComponentbuilderHelper::getVar('joomla_component', (int) $values['component'], 'id', 'checked_out');
if (1 == $published && $checked_out == 0)
{
// start up Compiler
$this->compiler = new Compiler($values);
if($this->compiler)
{
// component was compiled
$this->messages[] = JText::sprintf('COM_COMPONENTBUILDER_THE_S_WAS_SUCCESSFULLY_COMPILED', $this->compiler->componentFolderName);
// get compiler model to run the installer
$model = ComponentbuilderHelper::getModel('compiler', JPATH_COMPONENT_ADMINISTRATOR);
// now install components
if ($model->install($this->compiler->componentFolderName.'.zip'))
{
// component was installed
$this->messages[] = JText::sprintf('COM_COMPONENTBUILDER_THE_S_WAS_SUCCESSFULLY_INSTALLED_AND_REMOVED_FROM_TEMP_FOLDER', $this->compiler->componentFolderName);
}
else
{
// component was not installed
$this->messages[] = JText::sprintf('COM_COMPONENTBUILDER_THE_S_WAS_NOT_INSTALLED_AND_IS_STILL_IN_THE_TEMP_FOLDER', $this->compiler->componentFolderName);
}
// get all the messages from application (TODO)
return true;
}
// set that the component was not found
$this->messages[] = JText::_('COM_COMPONENTBUILDER_COMPONENT_DID_NOT_COMPILE');
return false;
}
// set that the component was not found
$this->messages[] = JText::_('COM_COMPONENTBUILDER_COMPONENT_IS_NOT_PUBLISHED_OR_IS_CHECKED_OUT');
return false;
}
// set that the component was not found
$this->messages[] = JText::_('COM_COMPONENTBUILDER_COMPONENT_WAS_NOT_FOUND');
return false;
}
}