@my wife Roline van der Merwe @copyright Copyright (C) 2015. All Rights Reserved @license GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html Builds Complex Joomla Components /-----------------------------------------------------------------------------------------------------------------------------*/ // No direct access to this file defined('_JEXEC') or die('Restricted access'); /** * Get class as the main compilers class */ class Get { /** * The app * * @var object */ public $app; /** * The Params * * @var object */ public $params; /** * The placeholders * * @var array */ public $placeholders = array(); /** * The Compiler Path * * @var object */ public $compilerPath; /** * Switch to add custom code placeholders * * @var bool */ public $addPlaceholders = false; /** * The Component data * * @var object */ public $componentData; /*********************************************************************************************** * 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//x23x/ /xxx[/INSERTED$$$$]xxx/ * JCB Add Replaced Code = /xxx[REPLACED$$$$]xxx//x25x/ /xxx[/REPLACED$$$$]xxx/ * * /////////////////////////////// changeing existing custom code ///////////////////////// * Update Inserted Code = /xxx[INSERTED<>$$$$]xxx//x23x/ /xxx[/INSERTED<>$$$$]xxx/ * Update Replaced Code = /xxx[REPLACED<>$$$$]xxx//x25x/ /xxx[/REPLACED<>$$$$]xxx/ * * The custom script placeholders - we use the (==) to avoid detection it should be (--) * ###################################---> HTML <---##################################### * * New Insert Code = $$$$]==> $$$$]==> * New Replace Code = $$$$]==> $$$$]==> * * ///////////////////////////////// when JCB adds it back /////////////////////////////// * JCB Add Inserted Code = * JCB Add Replaced Code = * * //////////////////////////// changeing existing custom code /////////////////////////// * Update Inserted Code = $$$$]==> $$$$]==> * Update Replaced Code = $$$$]==> $$$$]==> * * ////////23 is the ID of the code in the system don't change it!!!!!!!!!!!!!!!!!!!!!!!!!! * * @var array ***********************************************************************************************/ protected $customCodePlaceholders = array( 1 => 'REPLACE<>$$$$]', 2 => 'INSERT<>$$$$]', 3 => 'REPLACED<>$$$$]', 4 => 'INSERTED<>$$$$]' ); /** * The custom code to be added * * @var array */ public $customCode; /** * The custom code to be added * * @var array */ protected $customCodeData = array(); /** * The function name memory ids * * @var array */ public $functionNameMemory = array(); /** * The custom code for local memory * * @var array */ public $customCodeMemory = array(); /** * The custom code in local files that aready exist in system * * @var array */ protected $existingCustomCode = array(); /** * The custom code in local files this are new * * @var array */ protected $newCustomCode = array(); /** * The index of code already loaded * * @var array */ protected $codeAreadyDone = array(); /* * The line numbers Switch * * @var boolean */ public $debugLinenr = false; /* * The percentage when a language should be added * * @var boolean */ public $percentageLanguageAdd = 0; /** * The Placholder Language prefix * * @var string */ public $langPrefix; /** * The Language content * * @var array */ public $langContent = array(); /** * The Languages bucket * * @var array */ public $languages = array('en-GB' => array()); /** * The Multi Languages bucket * * @var array */ public $multiLangString = array(); /** * The new lang to add * * @var array */ protected $newLangStrings = array(); /** * The existing lang to update * * @var array */ protected $existingLangStrings = array(); /** * The Component Code Name * * @var string */ public $componentCodeName; /** * The Component ID * * @var int */ public $componentID; /** * The current user * * @var array */ public $user; /** * The database object * * @var array */ public $db; /** * The Component version * * @var string */ public $component_version; /** * The UIKIT Switch * * @var boolean */ public $uikit = false; /** * The UIKIT component checker * * @var array */ public $uikitComp = array(); /** * The FOOTABLE Switch * * @var boolean */ public $footable = false; /** * The FOOTABLE Version * * @var int */ public $footableVersion; /** * The Google Chart Switch per view * * @var array */ public $googleChart = array(); /** * The Google Chart Switch * * @var boolean */ public $googlechart = false; /** * The Import & Export Switch * * @var boolean */ public $addEximport = false; /** * The Tag & History Switch * * @var boolean */ public $setTagHistory = false; /** * The site edit views * * @var array */ public $siteEditView = array(); /** * The Language target * * @var string */ public $lang = 'admin'; /** * The Build target Switch * * @var string */ public $target; /** * The unique codes * * @var array */ public $uniquecodes = array(); /** * The unique keys * * @var array */ public $uniquekeys = array(); /** * The Ad contributors Switch * * @var boolean */ public $addContributors = false; /** * The Custom Script Builder * * @var array */ public $customScriptBuilder = array(); /** * The Footable Script Builder * * @var array */ public $footableScripts = array(); /** * The pathe to the bom file to be used * * @var string */ public $bomPath; /** * The SQL Tweak of admin views * * @var array */ public $sqlTweak = array(); /** * The admin views data array * * @var array */ private $_adminViewData = array(); /** * The field data array * * @var array */ private $_fieldData = array(); /** * The linked admin view tabs * * @var array */ public $linkedAdminViews = array(); /** * The Add Ajax Switch * * @var boolean */ public $addAjax = false; /** * The Add Site Ajax Switch * * @var boolean */ public $addSiteAjax = false; /** * The get Module Script Switch * * @var array */ public $getModule = array(); /** * The template data * * @var array */ public $templateData = array(); /** * The layout data * * @var array */ public $layoutData = array(); /** * The Advanced Encryption Switch * * @var boolean */ public $advancedEncryption = false; /** * The Basic Encryption Switch * * @var boolean */ public $basicEncryption = false; /** * The Custom field Switch per view * * @var array */ public $customFieldScript = array(); /** * The site main get * * @var array */ public $siteMainGet = array(); /** * The site dynamic get * * @var array */ public $siteDynamicGet = array(); /** * The get AS lookup * * @var array */ public $getAsLookup = array(); /** * The site fields * * @var array */ public $siteFields = array(); /** * The add SQL * * @var array */ public $addSQL = array(); /** * The update SQL * * @var array */ public $updateSQL = array(); /*** * Constructor */ public function __construct($config = array ()) { if (isset($config) && count($config)) { // load application $this->app = JFactory::getApplication(); // Set the params $this->params = JComponentHelper::getParams('com_componentbuilder'); // 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']; // set this components code name if ($name_code = ComponentbuilderHelper::getVar('joomla_component', $this->componentID, 'id', 'name_code')) { // set lang prefix $this->langPrefix = 'COM_'.ComponentbuilderHelper::safeString($name_code,'U'); // set component code name $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); // 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); // set the current user $this->user = JFactory::getUser(); // Get a db connection. $this->db = JFactory::getDbo(); // check if this component is install on the current website if ($paths = $this->getLocalInstallPaths()) { // start Automatic import of custom code $today = JFactory::getDate()->toSql(); // get the custom code from installed files $this->customCodeFactory($paths, $today); } // get the component data $this->componentData = $this->getComponentData(); // make sure we have a version if (strpos($this->componentData->component_version, '.') === FALSE) { $this->componentData->component_version = '1.0.0'; } // update the version if (!isset($this->componentData->old_component_version) && (ComponentbuilderHelper::checkArray($this->addSQL) || ComponentbuilderHelper::checkArray($this->updateSQL))) { // set the new version $version = (array) explode('.', $this->componentData->component_version); // get last key end($version); $key = key($version); // just increment the last $version[$key]++; // set the old version $this->componentData->old_component_version = $this->componentData->component_version; // set the new version, and set update switch $this->componentData->component_version = implode('.', $version); } // set the percentage when a language can be added $this->percentageLanguageAdd = (int) $this->params->get('percentagelanguageadd', 50); return true; } } return false; } /** * Set the line number in comments * * @param int $nr The line number * * @return void * */ private function setLine($nr) { if ($this->debugLinenr) { return ' [Get '.$nr.']'; } return ''; } /** * get all Component Data * * @param int $id The component ID * * @return oject The component data * */ public function getComponentData() { // Create a new query object. $query = $this->db->getQuery(true); $query->select('a.*'); $query->select( $this->db->quoteName( array( 'b.addadmin_views', 'b.id', 'h.addconfig', 'd.addcustom_admin_views', 'g.addcustommenus', 'j.addfiles', 'j.addfolders', 'c.addsite_views', 'i.dashboard_tab', 'i.php_dashboard_methods', 'f.sql_tweak', 'e.version_update' ), array( 'addadmin_views', 'addadmin_views_id', 'addconfig', 'addcustom_admin_views', 'addcustommenus', 'addfiles', 'addfolders', 'addsite_views', 'dashboard_tab', 'php_dashboard_methods', 'sql_tweak', 'version_update' ) ) ); // from these tables $query->from('#__componentbuilder_joomla_component AS a'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_admin_views', 'b') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('b.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_site_views', 'c') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('c.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_custom_admin_views', 'd') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('d.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_updates', 'e') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('e.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_mysql_tweaks', 'f') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('f.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_custom_admin_menus', 'g') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('g.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_config', 'h') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('h.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_dashboard', 'i') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('i.joomla_component') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_component_files_folders', 'j') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('j.joomla_component') . ')'); $query->where($this->db->quoteName('a.id') . ' = '. (int) $this->componentID); // Reset the query using our newly populated query object. $this->db->setQuery($query); // Load the results as a list of stdClass objects $component = $this->db->loadObject(); // set upater $updater = array( 'unique' => array( 'addadmin_views' => array('table' => 'component_admin_views', 'val' => (int) $component->addadmin_views_id, 'key' => 'id'), 'addconfig' => array('table' => 'component_config', 'val' => (int) $this->componentID, 'key' => 'joomla_component'), 'addcustom_admin_views' => array('table' => 'component_custom_admin_views', 'val' => (int) $this->componentID, 'key' => 'joomla_component'), 'addcustommenus' => array('table' => 'component_custom_admin_menus', 'val' => (int) $this->componentID, 'key' => 'joomla_component'), 'addfiles' => array('table' => 'component_files_folders', 'val' => (int) $this->componentID, 'key' => 'joomla_component'), 'addfolders' => array('table' => 'component_files_folders', 'val' => (int) $this->componentID, 'key' => 'joomla_component'), 'addsite_views' => array('table' => 'component_site_views', 'val' => (int) $this->componentID, 'key' => 'joomla_component'), 'dashboard_tab' => array('table' => 'component_dashboard', 'val' => (int) $this->componentID, 'key' => 'joomla_component'), 'sql_tweak' => array('table' => 'component_mysql_tweaks', 'val' => (int) $this->componentID, 'key' => 'joomla_component'), 'version_update' => array('table' => 'component_updates', 'val' => (int) $this->componentID, 'key' => 'joomla_component') ), 'table' => 'joomla_component', 'key' => 'id', 'val' => (int) $this->componentID ); // repeatable fields to update $searchRepeatables = array( // repeatablefield => checker 'addadmin_views' => 'adminview', 'addconfig' => 'field', 'addcontributors' => 'name', 'addcustom_admin_views' => 'customadminview', 'addcustommenus' => 'name', 'addfiles' => 'file', 'addfolders' => 'folder', 'addsite_views' => 'siteview', 'dashboard_tab' => 'name', 'sql_tweak' => 'adminview', 'version_update' => 'version' ); // update the repeatable fields $component = ComponentbuilderHelper::convertRepeatableFields($component, $searchRepeatables, $updater); // set component place holders $this->placeholders['###component###'] = ComponentbuilderHelper::safeString($component->name_code); $this->placeholders['###Component###'] = ComponentbuilderHelper::safeString($component->name_code, 'F'); $this->placeholders['###COMPONENT###'] = ComponentbuilderHelper::safeString($component->name_code, 'U'); $this->placeholders['[[[component]]]'] = $this->placeholders['###component###']; $this->placeholders['[[[Component]]]'] = $this->placeholders['###Component###']; $this->placeholders['[[[COMPONENT]]]'] = $this->placeholders['###COMPONENT###']; // set component sales name $component->sales_name = ComponentbuilderHelper::safeString($component->system_name); // ensure version naming is correct $this->component_version = preg_replace('/[^0-9.]+/', '', $component->component_version); // set the addfolders data (isset($component->addfolders)) ? $component->addfolders = json_decode($component->addfolders,true):null; if (isset($component->addfolders) && ComponentbuilderHelper::checkArray($component->addfolders)) { $component->folders = array_values($component->addfolders); } unset($component->addfolders); // set the addfiles data (isset($component->addfiles)) ? $component->addfiles = json_decode($component->addfiles,true):null; if (isset($component->addfiles) && ComponentbuilderHelper::checkArray($component->addfiles)) { $component->files = array_values($component->addfiles); } unset($component->addfiles); // set the uikit switch if ($component->adduikit) { $this->uikit = true; } // set the footable switch if ($component->addfootable) { $this->footable = true; // add the version $this->footableVersion = (1 == $component->addfootable || 2 == $component->addfootable) ? 2 : $component->addfootable; } // set the addcustommenus data (isset($component->addcustommenus)) ? $component->addcustommenus = json_decode($component->addcustommenus,true):null; if (isset($component->addcustommenus) && ComponentbuilderHelper::checkArray($component->addcustommenus)) { $component->custommenus = array_values($component->addcustommenus); } unset($component->addcustommenus); // set the sql_tweak data (isset($component->sql_tweak)) ? $component->sql_tweak = json_decode($component->sql_tweak,true):null; if (isset($component->sql_tweak) && ComponentbuilderHelper::checkArray($component->sql_tweak)) { // build the tweak settings $this->setSqlTweaking(array_map(function($array) { return array_map(function($value) { if (!ComponentbuilderHelper::checkArray($value) && !ComponentbuilderHelper::checkObject($value) && strval($value) === strval(intval($value))) { return (int) $value; } return $value; }, $array); }, array_values($component->sql_tweak))); } unset($component->sql_tweak); // set the admin_view data (isset($component->addadmin_views)) ? $component->addadmin_views = json_decode($component->addadmin_views,true):null; if (isset($component->addadmin_views) && ComponentbuilderHelper::checkArray($component->addadmin_views)) { // sort the views acording to order usort($component->addadmin_views, function($a, $b) { if ($a['order'] != 0 && $b['order'] != 0) { return $a['order'] - $b['order']; } elseif ($b['order'] != 0 && $a['order'] == 0) { return 1; } elseif ($a['order'] != 0 && $b['order'] == 0) { return 0; } return 1; }); // build the admin_views settings $component->admin_views = array_map(function($array) { $array = array_map(function($value) { if (!ComponentbuilderHelper::checkArray($value) && !ComponentbuilderHelper::checkObject($value) && strval($value) === strval(intval($value))) { return (int) $value; } return $value; }, $array); // has become a lacacy issue, can't remove this $array['view'] = $array['adminview']; $array['settings'] = $this->getAdminViewData($array['view']); if ($array['port'] && !$this->addEximport) { $this->addEximport = true; } if ($array['history'] && !$this->setTagHistory) { $this->setTagHistory = true; } if ($array['edit_create_site_view']) { $this->siteEditView[$array['adminview']] = true; } return $array; }, array_values($component->addadmin_views)); } // set the site_view data (isset($component->addsite_views)) ? $component->addsite_views = json_decode($component->addsite_views,true):null; if (isset($component->addsite_views) && ComponentbuilderHelper::checkArray($component->addsite_views)) { $this->lang = 'site'; $this->target = 'site'; // build the site_views settings $component->site_views = array_map(function($array) { // has become a lacacy issue, can't remove this $array['view'] = $array['siteview']; $array['settings'] = $this->getCustomViewData($array['view']); return array_map(function($value) { if (!ComponentbuilderHelper::checkArray($value) && !ComponentbuilderHelper::checkObject($value) && strval($value) === strval(intval($value))) { return (int) $value; } return $value; }, $array); }, array_values($component->addsite_views)); // unset original value unset($component->addsite_views); } // set the custom_admin_views data (isset($component->addcustom_admin_views)) ? $component->addcustom_admin_views = json_decode($component->addcustom_admin_views,true):null; if (isset($component->addcustom_admin_views) && ComponentbuilderHelper::checkArray($component->addcustom_admin_views)) { $this->lang = 'admin'; $this->target = 'custom_admin'; // build the custom_admin_views settings $component->custom_admin_views = array_map(function($array) { // has become a lacacy issue, can't remove this $array['view'] = $array['customadminview']; $array['settings'] = $this->getCustomViewData($array['view'], 'custom_admin_view'); return array_map(function($value) { if (!ComponentbuilderHelper::checkArray($value) && !ComponentbuilderHelper::checkObject($value) && strval($value) === strval(intval($value))) { return (int) $value; } return $value; }, $array); }, array_values($component->addcustom_admin_views)); // unset original value unset($component->addcustom_admin_views); } // ser the config data (isset($component->addconfig)) ? $component->addconfig = json_decode($component->addconfig,true):null; if (isset($component->addconfig) && ComponentbuilderHelper::checkArray($component->addconfig)) { $component->config = array_map(function($array) { $array['alias'] = 0; $array['title'] = 0; $array['settings'] = $this->getFieldData($array['field']); return $array; }, array_values($component->addconfig)); // unset original value unset($component->addconfig); } // set the addcustommenus data (isset($component->addcontributors)) ? $component->addcontributors = json_decode($component->addcontributors,true):null; if (isset($component->addcontributors) && ComponentbuilderHelper::checkArray($component->addcontributors)) { $this->addContributors = true; $component->contributors = array_values($component->addcontributors); } unset($component->addcontributors); // set the addcustommenus data (isset($component->version_update)) ? $component->version_update = json_decode($component->version_update,true):null; if (isset($component->version_update) && ComponentbuilderHelper::checkArray($component->version_update)) { $component->version_update = array_values($component->version_update); } // build update SQL if ($old_component = $this->getHistoryWatch('joomla_component', $this->componentID) && $old_admin_views = $this->getHistoryWatch('component_admin_views', $component->addadmin_views_id)) { // add new views if found if (isset($old_admin_views->addadmin_views) && ComponentbuilderHelper::checkJson($old_admin_views->addadmin_views)) { $this->setUpdateSQL(json_decode($old_admin_views->addadmin_views, true), $component->addadmin_views, 'adminview'); } // check if a new version was manualy set $old_component_version = preg_replace('/[^0-9.]+/', '', $old_component->component_version); if ($old_component_version != $this->component_version) { // yes, this is a new version, this mean there may be manual sql and must be checked and updated $component->old_component_version = $old_component_version; } // clear this data unset($old_component); } // unset original value unset($component->addadmin_views); // add_javascript if ($component->add_javascript == 1) { $this->customScriptBuilder['component_js'] = base64_decode($component->javascript); } else { $this->customScriptBuilder['component_js'] = ''; } unset($component->javascript); // add_css if ($component->add_css == 1) { $this->customScriptBuilder['component_css'] = base64_decode($component->css); } else { $this->customScriptBuilder['component_css'] = ''; } unset($component->css); // set the lang target $this->lang = 'admin'; // add PHP in ADMIN $addScriptMethods = array('php_preflight','php_postflight','php_method'); $addScriptTypes = array('install','update','uninstall'); foreach ($addScriptMethods as $scriptMethod) { foreach ($addScriptTypes as $scriptType) { if (isset($component->{'add_'.$scriptMethod.'_'.$scriptType}) && $component->{'add_'.$scriptMethod.'_'.$scriptType} == 1 && ComponentbuilderHelper::checkString($component->{$scriptMethod.'_'.$scriptType})) { $this->customScriptBuilder[$scriptMethod][$scriptType] = $this->setDynamicValues(base64_decode($component->{$scriptMethod.'_'.$scriptType})); } else { $this->customScriptBuilder[$scriptMethod][$scriptType] = ''; } unset($component->{$scriptMethod.'_'.$scriptType}); } } // add_php_helper if ($component->add_php_helper_admin == 1 && ComponentbuilderHelper::checkString($component->php_helper_admin)) { $this->lang = 'admin'; $this->customScriptBuilder['component_php_helper_admin'] = PHP_EOL.PHP_EOL.$this->setDynamicValues(base64_decode($component->php_helper_admin)); } else { $this->customScriptBuilder['component_php_helper_admin'] = ''; } unset($component->php_helper); // add_admin_event if ($component->add_admin_event == 1 && ComponentbuilderHelper::checkString($component->php_admin_event)) { $this->lang = 'admin'; $this->customScriptBuilder['component_php_admin_event'] = $this->setDynamicValues(base64_decode($component->php_admin_event)); } else { $this->customScriptBuilder['component_php_admin_event'] = ''; } unset($component->php_admin_event); // add_php_helper_both if ($component->add_php_helper_both == 1 && ComponentbuilderHelper::checkString($component->php_helper_both)) { $this->lang = 'both'; $this->customScriptBuilder['component_php_helper_both'] = PHP_EOL.PHP_EOL.$this->setDynamicValues(base64_decode($component->php_helper_both)); } else { $this->customScriptBuilder['component_php_helper_both'] = ''; } // add_php_helper_site if ($component->add_php_helper_site == 1 && ComponentbuilderHelper::checkString($component->php_helper_site)) { $this->lang = 'site'; $this->customScriptBuilder['component_php_helper_site'] = PHP_EOL.PHP_EOL.$this->setDynamicValues(base64_decode($component->php_helper_site)); } else { $this->customScriptBuilder['component_php_helper_site'] = ''; } unset($component->php_helper); // add_site_event if ($component->add_site_event == 1 && ComponentbuilderHelper::checkString($component->php_site_event)) { $this->lang = 'site'; $this->customScriptBuilder['component_php_site_event'] = $this->setDynamicValues(base64_decode($component->php_site_event)); } else { $this->customScriptBuilder['component_php_site_event'] = ''; } unset($component->php_site_event); // add_sql if ($component->add_sql == 1) { $this->customScriptBuilder['sql']['component_sql'] = base64_decode($component->sql); } unset($component->sql); // bom if (ComponentbuilderHelper::checkString($component->bom)) { $this->bomPath = $this->compilerPath.'/'.$component->bom; } else { $this->bomPath = $this->compilerPath.'/default.txt'; } unset($component->bom); // README if ($component->addreadme) { $component->readme = base64_decode($component->readme); } else { $component->readme = ''; } // dashboard methods (isset($component->dashboard_tab)) ? $component->dashboard_tab = json_decode($component->dashboard_tab,true):null; if (isset($component->dashboard_tab) && ComponentbuilderHelper::checkArray($component->dashboard_tab)) { $nowLang = $this->lang; $this->lang = 'admin'; $component->dashboard_tab = array_map( function($array) { $array['html'] = $this->setDynamicValues($array['html']); return $array; }, array_values($component->dashboard_tab)); } else { $component->dashboard_tab = ''; } // add the php of the dashboard if set if (ComponentbuilderHelper::checkString($component->php_dashboard_methods)) { // load the php for the dashboard model $component->php_dashboard_methods = $this->setDynamicValues(base64_decode($component->php_dashboard_methods)); // reset back to nowlang $this->lang = $nowLang; } else { $component->php_dashboard_methods = ''; } // add the update FTP server sig if ($component->add_update_server == 1 && is_numeric($component->update_server_ftp) && $component->update_server_ftp > 0) { $component->update_server_ftp = ComponentbuilderHelper::getVar('ftp', (int) $component->update_server_ftp, 'id', 'signature'); } else { $component->update_server_ftp = 0; } // add the sales FTP server sig if ($component->add_sales_server == 1 && is_numeric($component->sales_server_ftp) && $component->sales_server_ftp > 0) { $component->sales_server_ftp = ComponentbuilderHelper::getVar('ftp', (int) $component->sales_server_ftp, 'id', 'signature'); } else { $component->sales_server_ftp = 0; $component->add_sales_server = 0; } // set the ignore folders for repo if found if (isset($component->toignore) && ComponentbuilderHelper::checkString($component->toignore)) { if (strpos($component->toignore, ',') !== false) { $component->toignore = array_map('trim', (array) explode(',', $component->toignore)); } else { $component->toignore = array(trim($component->toignore)); } } else { // the default is to ignore the repo folder $component->toignore = array('.git'); } // return the found component data return $component; } /** * Get all Admin View Data * * @param int $id The view ID * * @return oject The view data * */ public function getAdminViewData($id) { if (!isset($this->_adminViewData[$id])) { // Create a new query object. $query = $this->db->getQuery(true); $query->select('a.*'); $query->select( $this->db->quoteName( array( 'b.addfields', 'b.id', 'c.addconditions', 'c.id' ), array( 'addfields', 'addfields_id', 'addconditions', 'addconditions_id' ) ) ); $query->from('#__componentbuilder_admin_view AS a'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_admin_fields', 'b') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('b.admin_view') . ')'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_admin_fields_conditions', 'c') . ' ON (' . $this->db->quoteName('a.id') . ' = ' . $this->db->quoteName('c.admin_view') . ')'); $query->where($this->db->quoteName('a.id') . ' = '. (int) $id); // Reset the query using our newly populated query object. $this->db->setQuery($query); // Load the results as a list of stdClass objects (see later for more options on retrieving data). $view = $this->db->loadObject(); // setup view name to use in storing the data $name_single = ComponentbuilderHelper::safeString($view->name_single); $name_list = ComponentbuilderHelper::safeString($view->name_list); // set upater $updater = array( 'unique' => array( 'addfields' => array('table' => 'admin_fields', 'val' => (int) $view->addfields_id, 'key' => 'id'), 'addconditions' => array('table' => 'admin_fields_conditions', 'val' => (int) $view->addconditions_id, 'key' => 'id') ), 'table' => 'admin_view', 'key' => 'id', 'val' => (int) $id ); // repeatable fields to update $searchRepeatables = array( // repeatablefield => checker 'addfields' => 'field', 'addconditions' => 'target_field', 'ajax_input' => 'value_name', 'custom_button' => 'name', 'addlinked_views' => 'adminview', 'addtables' => 'table', 'addtabs' => 'name', 'addpermissions' => 'action' ); // update the repeatable fields $view = ComponentbuilderHelper::convertRepeatableFields($view, $searchRepeatables, $updater); // setup token check if (!isset($this->customScriptBuilder['token'])) { $this->customScriptBuilder['token'] = array(); } $this->customScriptBuilder['token'][$name_single] = false; $this->customScriptBuilder['token'][$name_list] = false; // set some placeholders $this->placeholders['###view###'] = ComponentbuilderHelper::safeString($name_single); $this->placeholders['###views###'] = ComponentbuilderHelper::safeString($name_list); $this->placeholders['###View###'] = ComponentbuilderHelper::safeString($name_single, 'F'); $this->placeholders['###Views###'] = ComponentbuilderHelper::safeString($name_list, 'F'); $this->placeholders['###VIEW###'] = ComponentbuilderHelper::safeString($name_single, 'U'); $this->placeholders['###VIEWS###'] = ComponentbuilderHelper::safeString($name_list, 'U'); $this->placeholders['[[[view]]]'] = $this->placeholders['###view###']; $this->placeholders['[[[views]]]'] = $this->placeholders['###views###']; $this->placeholders['[[[View]]]'] = $this->placeholders['###View###']; $this->placeholders['[[[Views]]]'] = $this->placeholders['###Views###']; $this->placeholders['[[[VIEW]]]'] = $this->placeholders['###VIEW###']; $this->placeholders['[[[VIEWS]]]'] = $this->placeholders['###VIEWS###']; // add the tables (isset($view->addtables)) ? $view->addtables = json_decode($view->addtables,true):null; if (isset($view->addtables) && ComponentbuilderHelper::checkArray($view->addtables)) { $view->tables = array_values($view->addtables); } unset($view->addtables); // add the tabs (isset($view->addtabs)) ? $view->addtabs = json_decode($view->addtabs,true):null; if (isset($view->addtabs) && ComponentbuilderHelper::checkArray($view->addtabs)) { $nr = 1; foreach ($view->addtabs as $tab) { $view->tabs[$nr] = trim($tab['name']); $nr++; } } // if Details tab is not set, then set it here if (!isset($view->tabs[1])) { $view->tabs[1] = 'Details'; } // always make sure that publishing is lowercase if (($removeKey = array_search('publishing', array_map('strtolower', $view->tabs))) !== false) { $view->tabs[$removeKey] = 'publishing'; } // make sure to set the publishing tab (just incase we need it) $view->tabs[15] = 'publishing'; unset($view->addtabs); // add permissions (isset($view->addpermissions)) ? $view->addpermissions = json_decode($view->addpermissions,true):null; if (isset($view->addpermissions) && ComponentbuilderHelper::checkArray($view->addpermissions)) { $view->permissions = array_values($view->addpermissions); } unset($view->addpermissions); // reset fields $view->fields = array(); // set fields (isset($view->addfields)) ? $view->addfields = json_decode($view->addfields,true):null; if (isset($view->addfields) && ComponentbuilderHelper::checkArray($view->addfields)) { // build update SQL if ($old_view = $this->getHistoryWatch('admin_fields', $view->addfields_id)) { // add new fields were added if (isset($old_view->addfields) && ComponentbuilderHelper::checkJson($old_view->addfields)) { $this->setUpdateSQL(json_decode($old_view->addfields, true), $view->addfields, 'field', $name_single); } // clear this data unset($old_view); } if (ComponentbuilderHelper::checkArray($view->addfields)) { // load the field data $view->fields = array_map( function($array) use($name_single, $name_list){ $array['settings'] = $this->getFieldData($array['field'], $name_single, $name_list); return $array; }, array_values($view->addfields)); // sort the fields acording to order usort($view->fields, function($a, $b) { if (isset($a['order_list']) && isset($b['order_list'])) { if ($a['order_list'] != 0 && $b['order_list'] != 0) { return $a['order_list'] - $b['order_list']; } elseif ($b['order_list'] != 0 && $a['order_list'] == 0) { return 1; } elseif ($a['order_list'] != 0 && $b['order_list'] == 0) { return 0; } return 1; } return 0; }); } } unset($view->addfields); // build update SQL if ($old_view = $this->getHistoryWatch('admin_view', $id)) { // check if the view name changed if (ComponentbuilderHelper::checkString($old_view->name_single)) { $this->setUpdateSQL(ComponentbuilderHelper::safeString($old_view->name_single), $name_single, 'table_name', $name_single); } // clear this data unset($old_view); } // set the conditions (isset($view->addconditions)) ? $view->addconditions = json_decode($view->addconditions,true):null; if (isset($view->addconditions) && ComponentbuilderHelper::checkArray($view->addconditions)) { $view->conditions = array(); $ne = 0; foreach ($view->addconditions as $nr => $conditionValue) { if (ComponentbuilderHelper::checkArray($conditionValue['target_field']) && ComponentbuilderHelper::checkArray($view->fields)) { foreach ($conditionValue['target_field'] as $fieldKey => $fieldId) { foreach ($view->fields as $fieldValues) { if ((int) $fieldValues['field'] == (int) $fieldId) { // load the field details $required = ComponentbuilderHelper::getBetween($fieldValues['settings']->xml,'required="','"'); $required = ($required == true) ? 'yes' : 'no'; $filter = ComponentbuilderHelper::getBetween($fieldValues['settings']->xml,'filter="','"'); $filter = ComponentbuilderHelper::checkString($filter) ? $filter : 'none'; // get name $name = ComponentbuilderHelper::getBetween($fieldValues['settings']->xml,'name="','"'); $name = ComponentbuilderHelper::checkString($name) ? $name : $fieldValues['settings']->name; // get type $type = ComponentbuilderHelper::getBetween($fieldValues['settings']->xml,'type="','"'); $type = ComponentbuilderHelper::checkString($type) ? $type : $fieldValues['settings']->type_name; // set the field name $conditionValue['target_field'][$fieldKey] = array( 'name' => ComponentbuilderHelper::safeString($name), 'type' => ComponentbuilderHelper::safeString($type), 'required' => $required, 'filter' => $filter ); break; } } } } // load match field if (ComponentbuilderHelper::checkArray($view->fields) && isset($conditionValue['match_field'])) { foreach ($view->fields as $fieldValue) { if ((int) $fieldValue['field'] == (int) $conditionValue['match_field']) { // get name $name = ComponentbuilderHelper::getBetween($fieldValue['settings']->xml,'name="','"'); $name = ComponentbuilderHelper::checkString($name) ? $name : $fieldValue['settings']->name; // get type $type = ComponentbuilderHelper::getBetween($fieldValue['settings']->xml,'type="','"'); $type = ComponentbuilderHelper::checkString($type) ? $type : $fieldValue['settings']->type_name; // set the field details $conditionValue['match_name'] = ComponentbuilderHelper::safeString($name); $conditionValue['match_type'] = ComponentbuilderHelper::safeString($type); $conditionValue['match_xml'] = $fieldValue['settings']->xml; // if custom field load field being extended if (!ComponentbuilderHelper::typeField($type)) { $conditionValue['match_extends'] = ComponentbuilderHelper::getBetween($fieldValue['settings']->xml,'extends="','"'); } else { $conditionValue['match_extends'] = ''; } break; } } } // set condition values $view->conditions[$ne] = $conditionValue; $ne++; } } unset($view->addconditions); // set linked views $this->linkedAdminViews[$name_single] = null; (isset($view->addlinked_views)) ? $view->addlinked_views = json_decode($view->addlinked_views,true):null; if (isset($view->addlinked_views) && ComponentbuilderHelper::checkArray($view->addlinked_views)) { // setup linked views to global data sets $this->linkedAdminViews[$name_single] = array_values($view->addlinked_views); } unset($view->addlinked_views); // set the lang target $this->lang = 'admin'; // add_javascript $addArrayJ = array('javascript_view_file','javascript_view_footer','javascript_views_file','javascript_views_footer'); foreach ($addArrayJ as $scripter) { if (isset($view->{'add_'.$scripter}) && $view->{'add_'.$scripter} == 1 && ComponentbuilderHelper::checkString($view->$scripter)) { $view->$scripter = $this->setDynamicValues(base64_decode($view->$scripter)); $scripter_target = str_replace('javascript_', '', $scripter); if (!isset($this->customScriptBuilder[$scripter_target][$name_single])) { if (!isset($this->customScriptBuilder[$scripter_target])) { $this->customScriptBuilder[$scripter_target] = array(); } $this->customScriptBuilder[$scripter_target][$name_single] = ''; } $this->customScriptBuilder[$scripter_target][$name_single] .= $view->$scripter; if (strpos($view->$scripter,"token") !== false || strpos($view->$scripter,"task=ajax") !== false) { if (!$this->customScriptBuilder['token'][$name_single]) { $this->customScriptBuilder['token'][$name_single] = true; } } unset($view->$scripter); } } // add_css $addArrayC = array('css_view', 'css_views'); foreach ($addArrayC as $scripter) { if (isset($view->{'add_'.$scripter}) && $view->{'add_'.$scripter} == 1) { if (!isset($this->customScriptBuilder[$scripter][$name_single])) { $this->customScriptBuilder[$scripter][$name_single] = ''; } $this->customScriptBuilder[$scripter][$name_single] .= base64_decode($view->$scripter); unset($view->$scripter); } } // add_php $addArrayP = array('php_getitem','php_before_save','php_save','php_postsavehook','php_getitems','php_getitems_after_all','php_getlistquery','php_allowedit','php_before_delete','php_after_delete','php_before_publish','php_after_publish','php_batchcopy','php_batchmove','php_document'); foreach ($addArrayP as $scripter) { if (isset($view->{'add_'.$scripter}) && $view->{'add_'.$scripter} == 1) { $this->customScriptBuilder[$scripter][$name_single] = $this->setDynamicValues(base64_decode($view->$scripter)); unset($view->$scripter); } } // add the custom buttons if (isset($view->add_custom_button) && $view->add_custom_button == 1) { // set for the edit views if (ComponentbuilderHelper::checkString($view->php_model)) { $view->php_model = $this->setDynamicValues(base64_decode($view->php_model)); } if (ComponentbuilderHelper::checkString($view->php_controller)) { $view->php_controller = $this->setDynamicValues(base64_decode($view->php_controller)); } // set for the list views if (isset($view->php_model_list) && ComponentbuilderHelper::checkString($view->php_model_list)) { $view->php_model_list = $this->setDynamicValues(base64_decode($view->php_model_list)); } if (isset($view->php_controller_list) && ComponentbuilderHelper::checkString($view->php_controller_list)) { $view->php_controller_list = $this->setDynamicValues(base64_decode($view->php_controller_list)); } // set the button array (isset($view->custom_button)) ? $view->custom_button = json_decode($view->custom_button,true):null; if (isset($view->custom_button) && ComponentbuilderHelper::checkArray($view->custom_button)) { $view->custom_buttons = array_values($view->custom_button); } unset($view->custom_button); } // set custom import scripts if (isset($view->add_custom_import) && $view->add_custom_import == 1) { $addImportArray = array('php_import_ext','php_import_display','php_import','php_import_setdata','php_import_save','html_import_view'); foreach ($addImportArray as $importScripter) { if (isset($view->$importScripter) && strlen($view->$importScripter) > 0) { $this->customScriptBuilder[$importScripter]['import_'.$name_list] = $this->setDynamicValues(base64_decode($view->$importScripter)); unset($view->$importScripter); } else { // load the default $this->customScriptBuilder[$importScripter]['import_'.$name_list] = ComponentbuilderHelper::getImportScripts($importScripter, true); } } } // add_Ajax for this view if (isset($view->add_php_ajax) && $view->add_php_ajax == 1) { // insure the token is added to edit view atleast $this->customScriptBuilder['token'][$name_single] = true; $addAjaxSite = false; if (isset($this->siteEditView[$id]) && $this->siteEditView[$id]) { // we should add this site ajax to front ajax $addAjaxSite = true; if (!isset($this->addSiteAjax) || !$this->addSiteAjax) { $this->addSiteAjax = true; } } // check if controller input as been set (isset($view->ajax_input)) ? $view->ajax_input = json_decode($view->ajax_input,true):null; if (isset($view->ajax_input) && ComponentbuilderHelper::checkArray($view->ajax_input)) { if ($addAjaxSite) { $this->customScriptBuilder['site']['ajax_controller'][$name_single] = array_values($view->ajax_input); } $this->customScriptBuilder['admin']['ajax_controller'][$name_single] = array_values($view->ajax_input); $this->addAjax = true; unset($view->ajax_input); } if (ComponentbuilderHelper::checkString($view->php_ajaxmethod)) { $this->customScriptBuilder['admin']['ajax_model'][$name_single] = $this->setDynamicValues(base64_decode($view->php_ajaxmethod)); if ($addAjaxSite) { $this->customScriptBuilder['site']['ajax_model'][$name_single] = $this->customScriptBuilder['admin']['ajax_model'][$name_single]; } // unset anyway unset($view->php_ajaxmethod); $this->addAjax = true; } } // add_sql if ($view->add_sql == 1) { if ($view->source == 1 && isset($view->tables)) { // build and add the SQL dump $this->customScriptBuilder['sql'][$name_single] = $this->buildSqlDump($view->tables, $name_single, $id); unset($view->tables); } elseif ($view->source == 2 && isset($view->sql)) { // add the SQL dump string $this->customScriptBuilder['sql'][$name_single] = base64_decode($view->sql); unset($view->sql); } } // clear placeholders unset($this->placeholders['###view###']); unset($this->placeholders['###views###']); unset($this->placeholders['###View###']); unset($this->placeholders['###Views###']); unset($this->placeholders['###VIEW###']); unset($this->placeholders['###VIEWS###']); unset($this->placeholders['[[[view]]]']); unset($this->placeholders['[[[views]]]']); unset($this->placeholders['[[[View]]]']); unset($this->placeholders['[[[Views]]]']); unset($this->placeholders['[[[VIEW]]]']); unset($this->placeholders['[[[VIEWS]]]']); // store this view to class object $this->_adminViewData[$id] = $view; } // return the found view data return $this->_adminViewData[$id]; } /** * Get all Custom View Data * * @param int $id The view ID * @param string $table The view table * * @return oject The view data * */ public function getCustomViewData($id, $table = 'site_view') { // Create a new query object. $query = $this->db->getQuery(true); $query->select('a.*'); $query->from('#__componentbuilder_'.$table.' AS a'); $query->where($this->db->quoteName('a.id') . ' = '. (int) $id); // Reset the query using our newly populated query object. $this->db->setQuery($query); // Load the results as a list of stdClass objects (see later for more options on retrieving data). $view = $this->db->loadObject(); if ($table === 'site_view') { $this->lang = 'site'; // repeatable fields to update $searchRepeatables = array( // repeatablefield => checker 'ajax_input' => 'value_name', 'custom_button' => 'name' ); } else { $this->lang = 'admin'; // repeatable fields to update $searchRepeatables = array( // repeatablefield => checker 'custom_button' => 'name' ); } // set upater $updater = array( 'table' => $table, 'key' => 'id', 'val' => (int) $id ); // update the repeatable fields $view = ComponentbuilderHelper::convertRepeatableFields($view, $searchRepeatables, $updater); // set the default data $view->default = $this->setDynamicValues(base64_decode($view->default)); // fix alias to use in code $view->code = $this->uniqueCode(ComponentbuilderHelper::safeString($view->codename)); $view->Code = ComponentbuilderHelper::safeString($view->code, 'F'); $view->CODE = ComponentbuilderHelper::safeString($view->code, 'U'); // insure the uikit components are loaded if (!isset($this->uikitComp[$view->code])) { $this->uikitComp[$view->code] = array(); } $this->uikitComp[$view->code] = ComponentbuilderHelper::getUikitComp($view->default,$this->uikitComp[$view->code]); // check for footable if (!isset($this->footableScripts[$this->target][$view->code]) || !$this->footableScripts[$this->target][$view->code]) { $foundFoo = $this->getFootableScripts($view->default); if ($foundFoo) { $this->footableScripts[$this->target][$view->code] = true; } if ($foundFoo && !$this->footableScripts) { $this->footable = true; } } // check for get module if (!isset($this->getModule[$this->target][$view->code]) || !$this->getModule[$this->target][$view->code]) { $found = $this->getGetModule($view->default); if ($found) { $this->getModule[$this->target][$view->code] = true; } } // setup template array $this->templateData[$this->target][$view->code] = array(); // setup template and layout data $this->setTemplateAndLayoutData($view->default,$view->code); // set the main get data $main_get = $this->setGetData(array($view->main_get),$view->code); $view->main_get = $main_get[0]; // set the custom_get data $view->custom_get = $this->setGetData(json_decode($view->custom_get, true),$view->code); // set array adding array of scripts $addArray = array('php_view','php_jview','php_jview_display','php_document','js_document','css_document','css'); foreach ($addArray as $scripter) { if (isset($view->{'add_'.$scripter}) && $view->{'add_'.$scripter} == 1 && ComponentbuilderHelper::checkString($view->$scripter)) { $view->$scripter = $this->setDynamicValues(base64_decode($view->$scripter)); // set uikit to views $this->uikitComp[$view->code] = ComponentbuilderHelper::getUikitComp($view->$scripter,$this->uikitComp[$view->code]); $this->setTemplateAndLayoutData($view->$scripter,$view->code); // check for footable if (!isset($this->footableScripts[$this->target][$view->code]) || !$this->footableScripts[$this->target][$view->code]) { $foundFoo = $this->getFootableScripts($view->$scripter); if ($foundFoo) { $this->footableScripts[$this->target][$view->code] = true; } if ($foundFoo && !$this->footable) { $this->footable = true; } } // check for google chart if (!isset($this->googleChart[$this->target][$view->code]) || !$this->googleChart[$this->target][$view->code]) { $found = $this->getGoogleChart($view->$scripter); if ($found) { $this->googleChart[$this->target][$view->code] = true; } if ($found && !$this->googlechart) { $this->googlechart = true; } } // check for get module if (!isset($this->getModule[$this->target][$view->code]) || !$this->getModule[$this->target][$view->code]) { $found = $this->getGetModule($view->$scripter); if ($found) { $this->getModule[$this->target][$view->code] = true; } } // (TODO) we may want to automate this .... lets see if someone asks // if (strpos($view->$scripter,"token") !== false || strpos($view->$scripter,"task=ajax") !== false) // { // if(!isset($this->customScriptBuilder['token'])) // { // $this->customScriptBuilder['token'] = array(); // } // if (!isset($this->customScriptBuilder['token'][$this->target.$view->code]) || !$this->customScriptBuilder['token'][$this->target.$view->code]) // { // $this->customScriptBuilder['token'][$this->target.$view->code] = true; // } // } } } // add_Ajax for this view if (isset($view->add_php_ajax) && $view->add_php_ajax == 1) { // check if controller input as been set (isset($view->ajax_input)) ? $view->ajax_input = json_decode($view->ajax_input,true):null; if (isset($view->ajax_input) && ComponentbuilderHelper::checkArray($view->ajax_input)) { $this->customScriptBuilder[$this->target]['ajax_controller'][$view->code] = array_values($view->ajax_input); $this->addSiteAjax = true; } unset($view->ajax_input); // load the ajax class mathods (if set) if (ComponentbuilderHelper::checkString($view->php_ajaxmethod)) { $this->customScriptBuilder[$this->target]['ajax_model'][$view->code] = $this->setDynamicValues(base64_decode($view->php_ajaxmethod)); $this->addSiteAjax = true; } // unset anyway unset($view->php_ajaxmethod); } // add the custom buttons if (isset($view->add_custom_button) && $view->add_custom_button == 1) { if (ComponentbuilderHelper::checkString($view->php_model)) { $view->php_model = base64_decode($view->php_model); $view->php_model = $this->setDynamicValues($view->php_model); } $view->php_controller = base64_decode($view->php_controller); $view->php_controller = $this->setDynamicValues($view->php_controller); // set the button array (isset($view->custom_button)) ? $view->custom_button = json_decode($view->custom_button,true):null; if (isset($view->custom_button) && ComponentbuilderHelper::checkArray($view->custom_button)) { $view->custom_buttons = array_values($view->custom_button); } unset($view->custom_button); } // return the found view data return $view; } /** * Get all Field Data * * @param int $id The field ID * @param string $name_single The view edit or single name * @param string $name_list The view list name * * @return oject The field data * */ public function getFieldData($id, $name_single = null, $name_list = null) { if ($id > 0 && !isset($this->_fieldData[$id])) { // Create a new query object. $query = $this->db->getQuery(true); // Order it by the ordering field. $query->select('a.*'); $query->select($this->db->quoteName(array('c.name', 'c.properties'), array('type_name', 'properties'))); $query->from('#__componentbuilder_field AS a'); $query->join('LEFT', $this->db->quoteName('#__componentbuilder_fieldtype', 'c') . ' ON (' . $this->db->quoteName('a.fieldtype') . ' = ' . $this->db->quoteName('c.id') . ')'); $query->where($this->db->quoteName('a.id') . ' = '. $this->db->quote($id)); // Reset the query using our newly populated query object. $this->db->setQuery($query); $this->db->execute(); if ($this->db->getNumRows()) { // Load the results as a list of stdClass objects (see later for more options on retrieving data). $field = $this->db->loadObject(); // adding a fix for the changed name of type to fieldtype $field->type = $field->fieldtype; // repeatable fields to update $searchRepeatables = array( // repeatablefield => checker 'properties' => 'name' ); // set upater $updater = array( 'table' => 'fieldtype', 'key' => 'id', 'val' => (int) $id ); // update the repeatable fields $field = ComponentbuilderHelper::convertRepeatableFields($field, $searchRepeatables, $updater); // load the values form params $field->xml = $this->setDynamicValues(json_decode($field->xml)); // load the type values form type params (isset($field->properties)) ? $field->properties = json_decode($field->properties, true):null; if (isset($field->properties) && ComponentbuilderHelper::checkArray($field->properties)) { $field->properties = array_values($field->properties); } // check if we have advanced encryption if (4 == $field->store && (!isset($this->advancedEncryption) || !$this->advancedEncryption)) { $this->advancedEncryption = true; } // check if we have basic encryption elseif (3 == $field->store && (!isset($this->basicEncryption) || !$this->basicEncryption)) { $this->basicEncryption = true; } // get the last used version $field->history = $this->getHistoryWatch('field', $id); $this->_fieldData[$id] = $field; } else { return false; } } // check if the script should be added to the view each time this field is called if ($id > 0 && isset($this->_fieldData[$id])) { // check if we should load scripts for single view if (ComponentbuilderHelper::checkString($name_single) && !isset($this->customFieldScript[$name_single][$id])) { // add_javascript_view_footer if ($this->_fieldData[$id]->add_javascript_view_footer == 1 && ComponentbuilderHelper::checkString($this->_fieldData[$id]->javascript_view_footer)) { if(!isset($this->customScriptBuilder['view_footer'])) { $this->customScriptBuilder['view_footer'] = array(); } if (!isset($this->customScriptBuilder['view_footer'][$name_single])) { $this->customScriptBuilder['view_footer'][$name_single] = ''; } if (!isset($this->_fieldData[$id]->javascript_view_footer_decoded)) { $this->_fieldData[$id]->javascript_view_footer = $this->setDynamicValues(base64_decode($this->_fieldData[$id]->javascript_view_footer)); $this->_fieldData[$id]->javascript_view_footer_decoded = true; } $this->customScriptBuilder['view_footer'][$name_single] .= PHP_EOL.$this->_fieldData[$id]->javascript_view_footer; if ( strpos($this->_fieldData[$id]->javascript_view_footer,"token") !== false || strpos($this->_fieldData[$id]->javascript_view_footer,"task=ajax") !== false) { if(!isset($this->customScriptBuilder['token'])) { $this->customScriptBuilder['token'] = array(); } if (!isset($this->customScriptBuilder['token'][$name_single]) || !$this->customScriptBuilder['token'][$name_single]) { $this->customScriptBuilder['token'][$name_single] = true; } } } // add_css_view if ($this->_fieldData[$id]->add_css_view == 1) { if (!isset($this->customScriptBuilder['css_view'])) { $this->customScriptBuilder['css_view'] = array(); } if (!isset($this->customScriptBuilder['css_view'][$name_single])) { $this->customScriptBuilder['css_view'][$name_single] = ''; } if (!isset($this->_fieldData[$id]->css_view_decoded)) { $this->_fieldData[$id]->css_view = base64_decode($this->_fieldData[$id]->css_view); // check for custom code $this->setCustomCodeData($this->_fieldData[$id]->css_view); $this->_fieldData[$id]->css_view_decoded = true; } $this->customScriptBuilder['css_view'][$name_single] .= PHP_EOL.$this->_fieldData[$id]->css_view; } // add this only once to view. $this->customFieldScript[$name_single][$id] = true; } // check if we should load scripts for list views if (ComponentbuilderHelper::checkString($name_list) && !isset($this->customFieldScript[$name_list][$id])) { // add_javascript_views_footer if ($this->_fieldData[$id]->add_javascript_views_footer == 1 && ComponentbuilderHelper::checkString($this->_fieldData[$id]->javascript_views_footer)) { if(!isset($this->customScriptBuilder['views_footer'])) { $this->customScriptBuilder['views_footer'] = array(); } if (!isset($this->customScriptBuilder['views_footer'][$name_list])) { $this->customScriptBuilder['views_footer'][$name_list] = ''; } if (!isset($this->_fieldData[$id]->javascript_views_footer_decoded)) { $this->_fieldData[$id]->javascript_views_footer = $this->setDynamicValues(base64_decode($this->_fieldData[$id]->javascript_views_footer)); $this->_fieldData[$id]->javascript_views_footer_decoded = true; } $this->customScriptBuilder['views_footer'][$name_list] .= $this->_fieldData[$id]->javascript_views_footer; if ( strpos($this->_fieldData[$id]->javascript_views_footer,"token") !== false || strpos($this->_fieldData[$id]->javascript_views_footer,"task=ajax") !== false) { if(!isset($this->customScriptBuilder['token'])) { $this->customScriptBuilder['token'] = array(); } if (!isset($this->customScriptBuilder['token'][$name_list]) || !$this->customScriptBuilder['token'][$name_list]) { $this->customScriptBuilder['token'][$name_list] = true; } } } // add_css_views if ($this->_fieldData[$id]->add_css_views == 1) { if (!isset($this->customScriptBuilder['css_views'])) { $this->customScriptBuilder['css_views'] = array(); } if (!isset($this->customScriptBuilder['css_views'][$name_list])) { $this->customScriptBuilder['css_views'][$name_list] = ''; } if (!isset($this->_fieldData[$id]->css_views_decoded)) { $this->_fieldData[$id]->css_views = base64_decode($this->_fieldData[$id]->css_views); // check for custom code $this->setCustomCodeData($this->_fieldData[$id]->css_views); $this->_fieldData[$id]->css_views_decoded = true; } $this->customScriptBuilder['css_views'][$name_list] .= $this->_fieldData[$id]->css_views; } // add this only once to view. $this->customFieldScript[$name_list][$id] = true; } } if ($id > 0 && isset($this->_fieldData[$id])) { // return the found field data return $this->_fieldData[$id]; } return false; } /** * Set get Data * * @param array $ids The ids of the dynamic get * @param string $view_code The view code name * * @return oject the get dynamicGet data * */ public function setGetData($ids, $view_code) { if (ComponentbuilderHelper::checkArray($ids)) { $ids = implode(',', $ids); if (ComponentbuilderHelper::checkString($ids)) { // Create a new query object. $query = $this->db->getQuery(true); $query->select('a.*'); $query->from('#__componentbuilder_dynamic_get AS a'); $query->where('a.id IN (' . $ids . ')'); $this->db->setQuery($query); $this->db->execute(); if ($this->db->getNumRows()) { $results = $this->db->loadObjectList(); $typeArray = array(1 => 'LEFT', 2 => 'LEFT OUTER', 3 => 'INNER', 4 => 'RIGHT', 5 => 'RIGHT OUTER'); $operatorArray = array(1 => '=', 2 => '!=', 3 => '<>', 4 => '>', 5 => '<', 6 => '>=', 7 => '<=', 8 => '!<', 9 => '!>', 10 => 'IN', 11 => 'NOT IN'); foreach ($results as $_nr => &$result) { // add calculations if set if($result->addcalculation == 1 && ComponentbuilderHelper::checkString($result->php_calculation)) { $result->php_calculation = $this->setDynamicValues(base64_decode($result->php_calculation)); } // add php custom scripting (php_before_getitem) if($result->add_php_before_getitem == 1 && ComponentbuilderHelper::checkString($result->php_before_getitem)) { if (!isset($this->customScriptBuilder[$this->target.'_php_before_getitem'][$view_code])) { $this->customScriptBuilder[$this->target.'_php_before_getitem'][$view_code] = ''; } $this->customScriptBuilder[$this->target.'_php_before_getitem'][$view_code] .= $this->setDynamicValues(PHP_EOL.PHP_EOL.base64_decode($result->php_before_getitem)); unset($result->php_before_getitem); } // add php custom scripting (php_after_getitem) if($result->add_php_after_getitem == 1 && ComponentbuilderHelper::checkString($result->php_after_getitem)) { if (!isset($this->customScriptBuilder[$this->target.'_php_after_getitem'][$view_code])) { $this->customScriptBuilder[$this->target.'_php_after_getitem'][$view_code] = ''; } $this->customScriptBuilder[$this->target.'_php_after_getitem'][$view_code] .= $this->setDynamicValues(PHP_EOL.PHP_EOL.base64_decode($result->php_after_getitem)); unset($result->php_after_getitem); } // add php custom scripting (php_before_getitems) if($result->add_php_before_getitems == 1 && ComponentbuilderHelper::checkString($result->php_before_getitems)) { if (!isset($this->customScriptBuilder[$this->target.'_php_before_getitems'][$view_code])) { $this->customScriptBuilder[$this->target.'_php_before_getitems'][$view_code] = ''; } $this->customScriptBuilder[$this->target.'_php_before_getitems'][$view_code] .= $this->setDynamicValues(PHP_EOL.PHP_EOL.base64_decode($result->php_before_getitems)); unset($result->php_before_getitems); } // add php custom scripting (php_after_getitems) if($result->add_php_after_getitems == 1 && ComponentbuilderHelper::checkString($result->php_after_getitems)) { if (!isset($this->customScriptBuilder[$this->target.'_php_after_getitems'][$view_code])) { $this->customScriptBuilder[$this->target.'_php_after_getitems'][$view_code] = ''; } $this->customScriptBuilder[$this->target.'_php_after_getitems'][$view_code] .= $this->setDynamicValues(PHP_EOL.PHP_EOL.base64_decode($result->php_after_getitems)); unset($result->php_after_getitems); } // add php custom scripting (php_getlistquery) if($result->add_php_getlistquery == 1 && ComponentbuilderHelper::checkString($result->php_getlistquery)) { if (!isset($this->customScriptBuilder[$this->target.'_php_getlistquery'][$view_code])) { $this->customScriptBuilder[$this->target.'_php_getlistquery'][$view_code] = ''; } $this->customScriptBuilder[$this->target.'_php_getlistquery'][$view_code] .= $this->setDynamicValues(PHP_EOL.base64_decode($result->php_getlistquery)); unset($result->php_getlistquery); } // set the getmethod code name $result->key = ComponentbuilderHelper::safeString($view_code. ' ' .$result->name . ' ' .$result->id); // reset buckets $result->main_get = array(); $result->custom_get = array(); // set source data switch ($result->main_source) { case 1: // set the view data $result->main_get[0]['selection'] = $this->setDataSelection($result->key, $view_code, $result->view_selection, $result->view_table_main, 'a', '', 'view'); $result->main_get[0]['as'] = 'a'; $result->main_get[0]['key'] = $result->key; unset($result->view_selection); break; case 2: // set the database data $result->main_get[0]['selection'] = $this->setDataSelection($result->key, $view_code, $result->db_selection, $result->db_table_main, 'a', '', 'db'); $result->main_get[0]['as'] = 'a'; $result->main_get[0]['key'] = $result->key; unset($result->db_selection); break; case 3: // set custom script $result->main_get[0]['selection'] = array( 'select' => base64_decode($result->php_custom_get), 'from' => '', 'table' => '', 'type' => ''); break; } // set join_view_table details $result->join_view_table = json_decode($result->join_view_table, true); if (ComponentbuilderHelper::checkArray($result->join_view_table)) { foreach ($result->join_view_table as $nr => &$option) { if (ComponentbuilderHelper::checkString($option['selection'])) { // convert the type $option['type'] = $typeArray[$option['type']]; // convert the operator $option['operator'] = $operatorArray[$option['operator']]; // get the on field values $on_field = array(); // array(on_field_as, on_field) $on_field = array_map('trim', explode('.',$option['on_field'])); // get the join field values $join_field = array(); // array(join_field_as, join_field) $join_field = array_map('trim', explode('.',$option['join_field'])); $option['selection'] = $this->setDataSelection($result->key, $view_code, $option['selection'], $option['view_table'], $option['as'], $option['row_type'], 'view'); $option['key'] = $result->key; // load to the getters if ($option['row_type'] == 1) { $result->main_get[] = $option; if ($on_field[0] === 'a') { $this->siteMainGet[$this->target][$view_code][$option['as']] = $option['as']; } else { $this->siteDynamicGet[$this->target][$view_code][$option['as']][$join_field[1]] = $on_field[0]; } } elseif ($option['row_type'] == 2) { $result->custom_get[] = $option; if ($on_field[0] != 'a') { $this->siteDynamicGet[$this->target][$view_code][$option['as']][$join_field[1]] = $on_field[0]; } } } unset($result->join_view_table[$nr]); } } unset($result->join_view_table); // set join_db_table details $result->join_db_table = json_decode($result->join_db_table, true); if (ComponentbuilderHelper::checkArray($result->join_db_table)) { foreach ($result->join_db_table as $nr => &$option1) { if (ComponentbuilderHelper::checkString($option1['selection'])) { // convert the type $option1['type'] = $typeArray[$option1['type']]; // convert the operator $option1['operator'] = $operatorArray[$option1['operator']]; // get the on field values $on_field = array(); // array(on_field_as, on_field) $on_field = array_map('trim', explode('.',$option1['on_field'])); // get the join field values $join_field = array(); // array(join_field_as, join_field) $join_field = array_map('trim', explode('.',$option1['join_field'])); $option1['selection'] = $this->setDataSelection($result->key, $view_code, $option1['selection'], $option1['db_table'], $option1['as'], $option1['row_type'], 'db'); $option1['key'] = $result->key; // load to the getters if ($option1['row_type'] == 1) { $result->main_get[] = $option1; if ($on_field[0] === 'a') { $this->siteMainGet[$this->target][$view_code][$option1['as']] = $option1['as']; } else { $this->siteDynamicGet[$this->target][$view_code][$option1['as']][$join_field[1]] = $on_field[0]; } } elseif ($option1['row_type'] == 2) { $result->custom_get[] = $option1; if ($on_field[0] != 'a') { $this->siteDynamicGet[$this->target][$view_code][$option1['as']][$join_field[1]] = $on_field[0]; } } } unset($result->join_db_table[$nr]); } } unset($result->join_db_table); // set filter details $result->filter = json_decode($result->filter, true); if (ComponentbuilderHelper::checkArray($result->filter)) { foreach ($result->filter as $nr => &$option2) { if (isset($option2['operator'])) { $option2['operator'] = $operatorArray[$option2['operator']]; $option2['key'] = $result->key; } else { unset($result->filter[$nr]); } } } // set where details $result->where = json_decode($result->where, true); if (ComponentbuilderHelper::checkArray($result->where)) { foreach ($result->where as $nr => &$option3) { if (isset($option3['operator'])) { $option3['operator'] = $operatorArray[$option3['operator']]; } else { unset($result->where[$nr]); } } } else { unset($result->where); } // set order details $result->order = json_decode($result->order, true); if (!ComponentbuilderHelper::checkArray($result->order)) { unset($result->order); } // set global details $result->global = json_decode($result->global, true); if (!ComponentbuilderHelper::checkArray($result->global)) { unset($result->global); } } return $results; } } } return false; } /** * To limit the SQL Demo date build in the views * * @param array $settings Tweaking array. * * @return void * */ public function setSqlTweaking($settings) { if (ComponentbuilderHelper::checkArray($settings)) { foreach($settings as $setting) { // should sql dump be added if (1 == $setting['add_sql']) { // add sql (by option) if (2 == $setting['add_sql_options']) { // rest always $id_array = array(); // by id (first remove backups) $ids = $setting['ids']; // now get the ids if (strpos($ids, ',') !== false) { $id_array = (array) array_map('trim',explode(',', $ids)); } else { $id_array[] = trim($ids); } $id_array_new = array(); // check for ranges foreach ($id_array as $key => $id) { if (strpos($id, '=>') !== false) { $id_range = (array) array_map('trim', explode('=>', $id)); unset($id_array[$key]); // build range if (count($id_range) == 2) { $range = range($id_range[0],$id_range[1]); $id_array_new = array_merge($id_array_new,$range); } } } if (ComponentbuilderHelper::checkArray($id_array_new)) { $id_array = array_merge($id_array_new, $id_array); } // final fixing to array if (ComponentbuilderHelper::checkArray($id_array)) { // uniqe $id_array = array_unique($id_array, SORT_NUMERIC); // sort sort($id_array, SORT_NUMERIC); // now set it to global $this->sqlTweak[ (int) $setting['adminview']]['where'] = implode(',', $id_array); } } } else { // remove all sql dump options $this->sqlTweak[ (int) $setting['adminview']]['remove'] = true; } } } } /** * check if an update SQL is needed * * @param mix $old The old values * @param mix $new The new values * @param string $type The type of values * @param int $key The id/key where values changed * * @return void * */ protected function setUpdateSQL($old, $new, $type, $key = null) { // check if there were new items added if (ComponentbuilderHelper::checkArray($new) && ComponentbuilderHelper::checkArray($old)) { // check if this is old repeatable field if (isset($new[$type])) { foreach ($new[$type] as $item) { $newItem = true; // check if this is old repeatable field if (isset($old[$type]) && ComponentbuilderHelper::checkArray($old[$type])) { if (!in_array($item, $old[$type])) { // we have a new item, lets add to SQL $this->setAddSQL($type, $item, $key); } // add only once $newItem = false; } elseif (!isset($old[$type])) { // we have new values foreach($old as $oldItem) { if (isset($oldItem[$type])) { if ($oldItem[$type] == $item[$type]) { $newItem = false; break; } } else { $newItem = false; break; } } } else { $newItem = false; } // add if new if ($newItem) { // we have a new item, lets add to SQL $this->setAddSQL($type, $item[$type], $key); } } } else { foreach ($new as $item) { // search to see if this is a new value $newItem = true; if (isset($item[$type])) { // check if this is old repeatable field if (isset($old[$type]) && ComponentbuilderHelper::checkArray($old[$type])) { if (in_array($item[$type], $old[$type])) { $newItem = false; } } elseif (!isset($old[$type])) { // we have new values foreach($old as $oldItem) { if (isset($oldItem[$type])) { if ($oldItem[$type] == $item[$type]) { $newItem = false; break; } } else { $newItem = false; break; } } } else { $newItem = false; } } else { break; } // add if new if ($newItem) { // we have a new item, lets add to SQL $this->setAddSQL($type, $item[$type], $key); } } } } elseif ($key && ComponentbuilderHelper::checkString($new) && ComponentbuilderHelper::checkString($old) && $new !== $old) { // the string changed, lets add to SQL update if (!isset($this->updateSQL[$type]) || !ComponentbuilderHelper::checkArray($this->updateSQL[$type])) { $this->updateSQL[$type] = array(); } // set at key $this->updateSQL[$type][$key] = array('old' => $old, 'new' => $new); } } /** * Set the add sql * * @param string $type The type of values * @param int $item The item id to add * @param int $key The id/key where values changed * * @return void */ protected function setAddSQL($type, $item, $key) { // we have a new item, lets add to SQL if (!isset($this->addSQL[$type]) || !ComponentbuilderHelper::checkArray($this->addSQL[$type])) { $this->addSQL[$type] = array(); } // add key if found if ($key) { if (!isset($this->addSQL[$type][$key]) || !ComponentbuilderHelper::checkArray($this->addSQL[$type][$key])) { $this->addSQL[$type][$key] = array(); } $this->addSQL[$type][$key][] = (int) $item; } else { // convert adminview id to name if ('adminview' === $type) { $this->addSQL[$type][] = ComponentbuilderHelper::safeString($this->getAdminViewData($item)->name_single); } else { $this->addSQL[$type][] = (int) $item; } } } /** * Get Item History values * * @param string $type The type of item * @param int $id The item ID * * @return oject The history * */ protected function getHistoryWatch($type, $id) { // quick class object to store old history object $this->tmpHistory = null; // Create a new query object. $query = $this->db->getQuery(true); $query->select('h.*'); $query->from('#__ucm_history AS h'); $query->where($this->db->quoteName('h.ucm_item_id') . ' = '. (int) $id); // Join over the content type for the type id $query->join('LEFT', '#__content_types AS ct ON ct.type_id = h.ucm_type_id'); $query->where('ct.type_alias = ' . $this->db->quote('com_componentbuilder.'.$type)); $query->order('h.save_date DESC'); $this->db->setQuery($query, 0, 1); $this->db->execute(); if ($this->db->getNumRows()) { // new version of this item found // so we need to mark it as the last compiled version $newActive = $this->db->loadObject(); // set the new version watch $this->setHistoryWatch($newActive, 1); } // Get last compiled verion $query = $this->db->getQuery(true); $query->select('h.*'); $query->from('#__ucm_history AS h'); $query->where($this->db->quoteName('h.ucm_item_id') . ' = ' . (int) $id); $query->where('h.keep_forever = 1'); $query->where('h.version_note LIKE ' . $this->db->quote('%component%')); // make sure it does not return the active version if (isset($newActive) && isset($newActive->version_id)) { $query->where('h.version_id != ' . (int) $newActive->version_id); } // Join over the content type for the type id $query->join('LEFT', '#__content_types AS ct ON ct.type_id = h.ucm_type_id'); $query->where('ct.type_alias = ' . $this->db->quote('com_componentbuilder.'.$type)); $query->order('h.save_date DESC'); $this->db->setQuery($query); $this->db->execute(); if ($this->db->getNumRows()) { // the old active version was found // so we may need to do an SQL update // and unmark the old compiled version $oldActives = $this->db->loadObjectList(); foreach ($oldActives as $oldActive) { // remove old version watch $this->setHistoryWatch($oldActive, 0); } } // return the last used history record or null. return $this->tmpHistory; } /** * Set Item History Watch * * @param Object $object The history object * @param int $action The action to take * 0 = remove watch * 1 = add watch * @param string $type The type of item * * @return bool * */ protected function setHistoryWatch($object, $action) { // check the note if (ComponentbuilderHelper::checkJson($object->version_note)) { $version_note = json_decode($object->version_note, true); } else { $version_note = array('component' => array()); } // set watch switch ($action) { case 0: // remove watch if(isset($version_note['component']) && ($key = array_search($this->componentID, $version_note['component'])) !== false) { // last version that was used to build/compile $this->tmpHistory = json_decode($object->version_data); // remove it from this component unset($version_note['component'][$key]); } else { // since it was not found, no need to update anything return true; } break; case 1: // add watch if (!in_array($this->componentID, $version_note['component'])) { $version_note['component'][] = $this->componentID; } else { // since it is there already, no need to update anything return true; } break; } // check if we need to still keep this locked if (isset($version_note['component']) && ComponentbuilderHelper::checkArray($version_note['component'])) { // insure component ids are only added once per item $version_note['component'] = array_unique($version_note['component']); // we may change this, little risky (but since JCB does not have history notes it should be okay for now) $object->version_note = json_encode($version_note); $object->keep_forever = '1'; } else { $object->version_note = ''; $object->keep_forever = '0'; } // run the update return $this->db->updateObject('#__ucm_history', $object, 'version_id'); } /** * Set Template and Layout Data * * @param string $default The content to check * @param string $view The view code name * * @return void * */ public function setTemplateAndLayoutData($default,$view) { // set the Tempale date $temp1 = ComponentbuilderHelper::getAllBetween($default, "\$this->loadTemplate('","')"); $temp2 = ComponentbuilderHelper::getAllBetween($default, '$this->loadTemplate("','")'); $templates = array(); $again = array(); if (ComponentbuilderHelper::checkArray($temp1) && ComponentbuilderHelper::checkArray($temp2)) { $templates = array_merge($temp1,$temp2); } else { if (ComponentbuilderHelper::checkArray($temp1)) { $templates = $temp1; } elseif (ComponentbuilderHelper::checkArray($temp2)) { $templates = $temp2; } } if (ComponentbuilderHelper::checkArray($templates)) { foreach ($templates as $template) { if (!isset($this->templateData[$this->target][$view]) || !array_key_exists($template,$this->templateData[$this->target][$view])) { $data = $this->getDataWithAlias($template,'template',$view); if (ComponentbuilderHelper::checkArray($data)) { $this->templateData[$this->target][$view][$template] = $data; // call self to get child data $again[] = array($data['html'],$view); $again[] = array($data['php_view'],$view); } } } } // set the layout data $lay1 = ComponentbuilderHelper::getAllBetween($default, "JLayoutHelper::render('","',"); $lay2 = ComponentbuilderHelper::getAllBetween($default, 'JLayoutHelper::render("','",');; if (ComponentbuilderHelper::checkArray($lay1) && ComponentbuilderHelper::checkArray($lay2)) { $layouts = array_merge($lay1,$lay2); } else { if (ComponentbuilderHelper::checkArray($lay1)) { $layouts = $lay1; } elseif (ComponentbuilderHelper::checkArray($lay2)) { $layouts = $lay2; } } if (isset($layouts) && ComponentbuilderHelper::checkArray($layouts)) { foreach ($layouts as $layout) { if (!isset($this->layoutData[$this->target]) || !ComponentbuilderHelper::checkArray($this->layoutData[$this->target]) || !array_key_exists($layout,$this->layoutData[$this->target])) { $data = $this->getDataWithAlias($layout,'layout',$view); if (ComponentbuilderHelper::checkArray($data)) { $this->layoutData[$this->target][$layout] = $data; // call self to get child data $again[] = array($data['html'],$view); $again[] = array($data['php_view'],$view); } } } } if (ComponentbuilderHelper::checkArray($again)) { foreach ($again as $go) { $this->setTemplateAndLayoutData($go[0],$go[1]); } } } /** * Get Data With Alias * * @param string $n_ame The alias name * @param string $table The table where to find the alias * @param string $view The view code name * * @return array The data found with the alias * */ public function getDataWithAlias($n_ame,$table,$view) { // Create a new query object. $query = $this->db->getQuery(true); $query->select('a.*'); $query->from('#__componentbuilder_'.$table.' AS a'); $this->db->setQuery($query); $rows = $this->db->loadObjectList(); foreach ($rows as $row) { $k_ey = ComponentbuilderHelper::safeString($row->alias); $key = preg_replace("/[^A-Za-z]/", '', $k_ey); $name = preg_replace("/[^A-Za-z]/", '', $n_ame); if ($k_ey == $n_ame || $key == $name) { $php_view = ''; if ($row->add_php_view == 1 && ComponentbuilderHelper::checkString($row->php_view)) { $php_view = $this->setDynamicValues(base64_decode($row->php_view)); } $contnent = $this->setDynamicValues(base64_decode($row->{$table})); // set uikit to views $this->uikitComp[$view] = ComponentbuilderHelper::getUikitComp($contnent,$this->uikitComp[$view]); // set footable to views and turn it on if (!isset($this->footableScripts[$this->target][$view]) || !$this->footableScripts[$this->target][$view]) { $foundFoo = $this->getFootableScripts($contnent); if ($foundFoo) { $this->footableScripts[$this->target][$view] = true; } if ($foundFoo && !$this->footable) { $this->footable = true; } } // set google charts to views and turn it on if (!isset($this->googleChart[$this->target][$view]) || !$this->googleChart[$this->target][$view]) { $foundA = $this->getGoogleChart($php_view); $foundB = $this->getGoogleChart($contnent); if ($foundA || $foundB) { $this->googleChart[$this->target][$view] = true; } if ($foundA || $foundB && !$this->googlechart) { $this->googlechart = true; } } // check for get module if (!isset($this->getModule[$this->target][$view]) || !$this->getModule[$this->target][$view]) { $foundA = $this->getGetModule($php_view); $foundB = $this->getGetModule($contnent); if ($foundA || $foundB) { $this->getModule[$this->target][$view] = true; } } return array('id' => $row->id, 'html' => $contnent, 'php_view' => $php_view); } } return false; } /** * Set Language Place Holders * * @param string $content The content * * @return string The content with the updated Language place holder * */ public function setLangStrings($content) { // first check if we should continue if (strpos($content, 'JText::_(') !== false || strpos($content, 'JText::sprintf(') !== false) { // insure string is not broken $content = str_replace('COM_###COMPONENT###',$this->langPrefix,$content); // set language data $langCheck[] = ComponentbuilderHelper::getAllBetween($content, "JText::_('","'"); $langCheck[] = ComponentbuilderHelper::getAllBetween($content, 'JText::_("','"'); $langCheck[] = ComponentbuilderHelper::getAllBetween($content, "JText::sprintf('","'"); $langCheck[] = ComponentbuilderHelper::getAllBetween($content, 'JText::sprintf("','"'); $langArray = ComponentbuilderHelper::mergeArrays($langCheck); if (ComponentbuilderHelper::checkArray($langArray)) { foreach ($langArray as $string) { // this is there to insure we dont break already added Language strings if (ComponentbuilderHelper::safeString($string,'U') === $string) { continue; } // only load if string is not already set $keyLang = $this->langPrefix.'_'.ComponentbuilderHelper::safeString($string,'U'); if (!isset($this->langContent[$this->lang][$keyLang])) { $this->langContent[$this->lang][$keyLang] = trim($string); } $langHolders["JText::_('".$string."')"] = "JText::_('".$keyLang."')"; $langHolders['JText::_("'.$string.'")'] = 'JText::_("'.$keyLang.'")'; $langHolders["JText::sprintf('".$string."',"] = "JText::sprintf('".$keyLang."',"; $langHolders['JText::sprintf("'.$string.'",'] = 'JText::sprintf("'.$keyLang.'",'; } // only continue if we have value to replace if (isset($langHolders) && ComponentbuilderHelper::checkArray($langHolders)) { $content = $this->setPlaceholders($content, $langHolders); } } } return $content; } /** * Set Data Selection of the dynamic get * * @param string $method_key The method unique key * @param string $view_code The code name of the view * @param string $string The data string * @param string || INT $asset The asset in question * @param string $as The as string * @param int $row_type The row type * @param string $type The target type (db||view) * * @return array the select query * */ public function setDataSelection($method_key, $view_code, $string, $asset, $as, $row_type, $type) { if (ComponentbuilderHelper::checkString($string)) { $lines = explode(PHP_EOL,$string); if (ComponentbuilderHelper::checkArray($lines)) { if ('db' === $type) { $table = '#__'.$asset; $queryName = $asset; $view = ''; } elseif ('view' === $type) { $view = $this->getViewTableName($asset); $table = '#__'.$this->componentCodeName.'_'.$view; $queryName = $view; } $gets = array(); $keys = array(); foreach ($lines as $line) { if (strpos($line,'AS') !== false) { list($get,$key) = explode("AS",$line); } elseif (strpos($line,'as') !== false) { list($get,$key) = explode("as",$line); } else { $get = $line; $key = null; } $get = trim($get); $key = trim($key); // only add the view if ('a' != $as && 1 == $row_type && 'view' === $type && strpos('#'.$key,'#'.$view.'_') === false) { $key = $view.'_'.trim($key); } if (ComponentbuilderHelper::checkString($get)) { $gets[] = $this->db->quote($get); if (ComponentbuilderHelper::checkString($key)) { $this->getAsLookup[$method_key][$get] = $key; $keys[] = $this->db->quote($key); } else { $key = str_replace($as.'.','',$get); $this->getAsLookup[$method_key][$get] = $key; $keys[] = $this->db->quote($key); } if (ComponentbuilderHelper::checkString($view)) { $field = str_replace($as.'.','',$get); $this->siteFields[$view][$field][$method_key] = array('site' => $view_code, 'get' => $get, 'as' => $as, 'key' => $key); } } } if (ComponentbuilderHelper::checkArray($gets) && ComponentbuilderHelper::checkArray($keys)) { $querySelect = '$query->select($db->quoteName('.PHP_EOL."\t\t\t".'array('.implode(',',$gets).'),'.PHP_EOL."\t\t\t".'array('.implode(',',$keys).')));'; $queryFrom = '$db->quoteName('.$this->db->quote($table).', '.$this->db->quote($as).')'; // return the select query return array('select' => $querySelect, 'from' => $queryFrom, 'name' => $queryName, 'table' => $table, 'type' => $type, 'select_gets' => $gets, 'select_keys' => $keys); } } } return false; } /** * Get the View Table Name * * @param int $id The admin view in * * @return string view code name * */ public function getViewTableName($id) { // Create a new query object. $query = $this->db->getQuery(true); $query->select($this->db->quoteName(array('a.name_single'))); $query->from($this->db->quoteName('#__componentbuilder_admin_view','a')); $query->where($this->db->quoteName('a.id') . ' = '. (int) $id); $this->db->setQuery($query); return ComponentbuilderHelper::safeString($this->db->loadResult()); } /** * Build the SQL dump String for a view * * @param string $tables The tables to use in build * @param string $view The target view/table to dump in * @param int $view_id The id of the target view * * @return string on success with the Dump SQL * */ public function buildSqlDump($tables, $view, $view_id) { // first build a query statment to get all the data (insure it must be added - check the tweaking) if (ComponentbuilderHelper::checkArray($tables) && (!isset($this->sqlTweak[$view_id]['remove']) || !$this->sqlTweak[$view_id]['remove'])) { $counter = 'a'; // Create a new query object. $query = $this->db->getQuery(true); foreach ($tables as $table) { if ($counter === 'a') { // the main table fields if (strpos($table['sourcemap'],PHP_EOL) !== false) { $fields = explode(PHP_EOL,$table['sourcemap']); if (ComponentbuilderHelper::checkArray($fields)) { // reset array buckets $sourceArray = array(); $targetArray = array(); foreach ($fields as $field) { if (strpos($field,"=>") !== false) { list($source,$target) = explode("=>",$field); $sourceArray[] = $counter.'.'.trim($source); $targetArray[] = trim($target); } } if (ComponentbuilderHelper::checkArray($sourceArray) && ComponentbuilderHelper::checkArray($targetArray)) { // add to query $query->select($this->db->quoteName($sourceArray,$targetArray)); $query->from('#__'.$table['table'].' AS a'); } // we may need to filter the selection if (isset($this->sqlTweak[$view_id]['where'])) { // add to query the where filter $query->where('a.id IN (' . $this->sqlTweak[$view_id]['where'] . ')'); } } } } else { // the other tables if (strpos($table['sourcemap'],PHP_EOL) !== false) { $fields = explode(PHP_EOL,$table['sourcemap']); if (ComponentbuilderHelper::checkArray($fields)) { // reset array buckets $sourceArray = array(); $targetArray = array(); foreach ($fields as $field) { if (strpos($field,"=>") !== false) { list($source,$target) = explode("=>",$field); $sourceArray[] = $counter.'.'.trim($source); $targetArray[] = trim($target); } if (strpos($field,"==") !== false) { list($aKey,$bKey) = explode("==",$field); // add to query $query->join('LEFT', $this->db->quoteName('#__'.$table['table'], $counter) . ' ON (' . $this->db->quoteName('a.'.trim($aKey)) . ' = ' . $this->db->quoteName($counter.'.'.trim($bKey)) . ')'); } } if (ComponentbuilderHelper::checkArray($sourceArray) && ComponentbuilderHelper::checkArray($targetArray)) { // add to query $query->select($this->db->quoteName($sourceArray,$targetArray)); } } } } $counter++; } // now get the data $this->db->setQuery($query); $this->db->execute(); if ($this->db->getNumRows()) { // get the data $data = $this->db->loadObjectList(); // start building the MySql dump $dump = "--"; $dump .= PHP_EOL."-- Dumping data for table `#__[[[component]]]_".$view."`"; $dump .= PHP_EOL."--"; $dump .= PHP_EOL.PHP_EOL."INSERT INTO `#__[[[component]]]_".$view."` ("; foreach ($data as $line) { $comaSet = 0; foreach($line as $fieldName => $fieldValue) { if ($comaSet == 0) { $dump .= $this->db->quoteName($fieldName); } else { $dump .= ", ".$this->db->quoteName($fieldName); } $comaSet++; } break; } $dump .= ") VALUES"; $coma = 0; foreach ($data as $line) { if ($coma == 0) { $dump .= PHP_EOL."("; } else { $dump .= ",".PHP_EOL."("; } $comaSet = 0; foreach($line as $fieldName => $fieldValue) { if ($comaSet == 0) { $dump .= $this->mysql_escape($fieldValue); } else { $dump .= ", ". $this->mysql_escape($fieldValue); } $comaSet++; } $dump .= ")"; $coma++; } $dump .= ";"; // return build dump query return $dump; } } return false; } /** * Escape the values for a SQL dump * * @param string $value the value to escape * * @return string on success with escaped string * */ public function mysql_escape($value) { // if array then return maped if(ComponentbuilderHelper::checkArray($value)) { return array_map(__METHOD__, $value); } // if string make sure it is correctly escaped if(ComponentbuilderHelper::checkString($value) && !is_numeric($value)) { return $this->db->quote($value); } // if empty value return place holder if(empty($value)) { return "''"; } // if not array or string then return number return $value; } /** * Creating an uniqueCode * * @param string $code The planed code * * @return string The unique code * */ public function uniqueCode($code) { if (!isset($this->uniquecodes[$this->target]) || !in_array($code,$this->uniquecodes[$this->target])) { $this->uniquecodes[$this->target][] = $code; return $code; } // make sure it is unique return $this->uniqueCode($code.$this->uniquekey(1)); } /** * Creating an unique local key * * @param int $size The key size * * @return string The unique localkey * */ public function uniquekey($size, $random = false, $newBag = "vvvvvvvvvvvvvvvvvvv") { if ($random) { $bag = "abcefghijknopqrstuwxyzABCDDEFGHIJKLLMMNOPQRSTUVVWXYZabcddefghijkllmmnopqrstuvvwxyzABCEFGHIJKNOPQRSTUWXYZ"; } else { $bag = $newBag; } $key = array(); $bagsize = strlen($bag) - 1; for ($i = 0; $i < $size; $i++) { $get = rand(0, $bagsize); $key[] = $bag[$get]; } $key = implode($key); while (in_array($key, $this->uniquekeys)) { $key++; } $this->uniquekeys[] = $key; return $key; } /** * Check for footable scripts * * @param string $content The content to check * * @return boolean True if found * */ public function getFootableScripts($content) { if (strpos($content,'footable') !== false) { return true; } return false; } /** * Check for getModules script * * @param string $content The content to check * * @return boolean True if found * */ public function getGetModule($content) { if (strpos($content,'this->getModules(') !== false) { return true; } return false; } /** * Check for getModules script * * @param string $content The content to check * * @return boolean True if found * */ public function getGoogleChart($content) { if (strpos($content,'Chartbuilder(') !== false) { return true; } return false; } /** * Set the dynamic values in strings here * * @param string $string The content to check * * @return string * */ public function setDynamicValues($string) { if (ComponentbuilderHelper::checkString($string)) { return $this->setLangStrings($this->setCustomCodeData($string)); } return $string; } /** * We start set the custom code data & can load it in to string * * @param string $string The content to check * @param bool $insert Should we insert the code into the content * @param bool $bool Should we return bool on success * * @return string|bool based on sig * */ public function setCustomCodeData($string) { // insure the code is loaded $loaded = false; // check if content has custom code place holder if (strpos($string, '[CUSTO'.'MCODE=') !== false) { // the ids found in this content $bucket = array(); $found = ComponentbuilderHelper::getAllBetween($string, '[CUSTO'.'MCODE=', ']'); if (ComponentbuilderHelper::checkArray($found)) { foreach ($found as $key) { // check if we have args if (is_numeric($key)) { $id = (int) $key; } elseif (ComponentbuilderHelper::checkString($key) && strpos($key, '+') === false) { $getFuncName = trim($key); if (!isset($this->functionNameMemory[$getFuncName])) { if (!$found = ComponentbuilderHelper::getVar('custom_code', $getFuncName, 'function_name', 'id')) { continue; } $this->functionNameMemory[$getFuncName] = $found; } $id = (int) $this->functionNameMemory[$getFuncName]; } elseif (ComponentbuilderHelper::checkString($key) && strpos($key, '+') !== false) { $array = explode('+', $key); // set ID if (is_numeric($array[0])) { $id = (int) $array[0]; } elseif (ComponentbuilderHelper::checkString($array[0])) { $getFuncName = trim($array[0]); if (!isset($this->functionNameMemory[$getFuncName])) { if (!$found = ComponentbuilderHelper::getVar('custom_code', $getFuncName, 'function_name', 'id')) { continue; } $this->functionNameMemory[$getFuncName] = $found; } $id = (int) $this->functionNameMemory[$getFuncName]; } else { continue; } // load args for this ID if (isset($array[1])) { if (!isset($this->customCodeData[$id]['args'])) { $this->customCodeData[$id]['args'] = array(); } // only load if not already loaded if (!isset($this->customCodeData[$id]['args'][$key])) { if (strpos($array[1], ',') !== false) { $this->customCodeData[$id]['args'][$key] = explode(',', $array[1]); } elseif (ComponentbuilderHelper::checkString($array[1])) { $this->customCodeData[$id]['args'][$key] = array(); $this->customCodeData[$id]['args'][$key][] = $array[1]; } } } } else { continue; } $bucket[$id] = $id; } } // check if any custom code placeholders where found if (ComponentbuilderHelper::checkArray($bucket)) { $_tmpLang = $this->lang; // insure we add the langs to both site and admin $this->lang = 'both'; // now load the code to memory $loaded = $this->getCustomCode($bucket, false); // revert lang to current setting $this->lang = $_tmpLang; } // when the custom code is loaded if ($loaded === true) { $string = $this->insertCustomCode($string); } } return $string; } /** * Insert the custom code into the string * * @param string $string The content to check * * @return string on success * */ protected function insertCustomCode($string) { $code = array(); foreach($this->customCode as $item) { $this->buildCustomCodePlaceholders($item, $code); } // now update the string return $this->setPlaceholders($string, $code); } /** * Insert the custom code into the string * * @param string $string The content to check * * @return string on success * */ protected function buildCustomCodePlaceholders($item, &$code) { // check if there is args for this code if (isset($this->customCodeData[$item['id']]['args']) && ComponentbuilderHelper::checkArray($this->customCodeData[$item['id']]['args'])) { // since we have args we cant update this code via IDE (TODO) $placeholder = $this->getPlaceHolder(3, null); // we have args and so need to load each foreach ($this->customCodeData[$item['id']]['args'] as $key => $args) { $this->setThesePlaceHolders('arg', $args); $code['[CUSTOM'.'CODE='.$key.']'] = $placeholder['start'] . PHP_EOL . $this->setPlaceholders($item['code'], $this->placeholders). $placeholder['end']; } // always clear the args $this->clearFromPlaceHolders('arg'); } else { if (($keyPlaceholder = array_search($item['id'], $this->functionNameMemory)) === false) { $keyPlaceholder = $item['id']; } // check what type of place holders we should load here $placeholderType = (int) $item['comment_type'].'2'; if (stripos($item['code'], '[[[view') !== false || stripos($item['code'], '[[[sview') !== false || stripos($item['code'], '[[[arg') !== false) { // if view is being set dynamicly then we can't update this code via IDE (TODO) $placeholderType = 3; } // if now ars were found, clear it $this->clearFromPlaceHolders('arg'); // load args for this code $placeholder = $this->getPlaceHolder($placeholderType, $item['id']); $code['[CUSTOM'.'CODE='.$keyPlaceholder.']'] = $placeholder['start'] . PHP_EOL . $this->setPlaceholders($item['code'], $this->placeholders). $placeholder['end']; } } /** * Set a type of placeholder with set of values * * @param string $key The main string for placeholder key * @param array $values The values to add * * @return void */ public function setThesePlaceHolders($key, $values) { // aways fist reset these $this->clearFromPlaceHolders($key); if (ComponentbuilderHelper::checkArray($values)) { $number = 0; foreach ($values as $value) { $this->placeholders['[[['.$key.$number.']]]'] = $value; $number++; } } } /** * Remove a type of placeholder by main string * * @param string $like The main string for placeholder key * * @return void */ public function clearFromPlaceHolders($like) { foreach ($this->placeholders as $something => $value) { if (stripos($something, $like) !== false) { unset($this->placeholders[$something]); } } } /** * to unset stuff that are private or protected * */ public function unsetNow($remove) { unset($this->$remove); } /** * Get the other languages * * @param array $values The lang strings to get * * * @return void * */ public function getMultiLangStrings($values) { // Create a new query object. $query = $this->db->getQuery(true); $query->from($this->db->quoteName('#__componentbuilder_language_translation','a')); if (ComponentbuilderHelper::checkArray($values)) { $query->select($this->db->quoteName(array('a.id','a.translation','a.entranslation','a.components','a.published'))); $query->where($this->db->quoteName('a.entranslation') . ' IN (' . implode(',',array_map(function($a){ return $this->db->quote($a); }, $values)) . ')'); $this->db->setQuery($query); $this->db->execute(); if ($this->db->getNumRows()) { return $this->db->loadAssocList('entranslation'); } } return false; } /** * Set the Current language values to DB * * * @return void * */ public function setLangPlaceholders($strings) { $counterInsert = 0; $counterUpdate = 0; $today = JFactory::getDate()->toSql(); foreach ($this->languages['en-GB'] as $area => $placeholders) { foreach ($placeholders as $placeholder => $string) { // to keep or remove $remove = false; // build the tranlations if (ComponentbuilderHelper::checkString($string) && isset($this->multiLangString[$string])) { // make sure we have converted the string to array if (isset($this->multiLangString[$string]['translation']) && ComponentbuilderHelper::checkJson($this->multiLangString[$string]['translation'])) { $this->multiLangString[$string]['translation'] = json_decode($this->multiLangString[$string]['translation'], true); } // if we have an array continue if (isset($this->multiLangString[$string]['translation']) && ComponentbuilderHelper::checkArray($this->multiLangString[$string]['translation'])) { // great lets build the multi languages strings foreach ($this->multiLangString[$string]['translation'] as $translations) { if (isset($translations['language']) && isset($translations['translation'])) { // build arrays if (!isset($this->languages[$translations['language']])) { $this->languages[$translations['language']] = array(); } if (!isset($this->languages[$translations['language']][$area])) { $this->languages[$translations['language']][$area] = array(); } $this->languages[$translations['language']][$area][$placeholder] = $translations['translation']; } } } else { // remove this string not to be checked again $remove = true; } } // do the database managment if(ComponentbuilderHelper::checkString($string) && ($key = array_search($string, $strings)) !== false) { if (isset($this->multiLangString[$string])) { // update the existing placeholder in db $id = $this->multiLangString[$string]['id']; if (ComponentbuilderHelper::checkJson($this->multiLangString[$string]['components'])) { $components = (array) json_decode($this->multiLangString[$string]['components'], true); // check if we should add the component ID if (in_array($this->componentID, $components)) { // only skip the update if the string is published and has the component ID if ($this->multiLangString[$string]['published'] == 1) { continue; } } else { $components[] = $this->componentID; } } else { $components = array($this->componentID); } // start the bucket for this lang $this->setUpdateExistingLangStrings($id, $components, 1, $today, $counterUpdate); $counterUpdate++; // load to db $this->setExistingLangStrings(50); // remove string if needed if ($remove) { unset($this->multiLangString[$string]); } } else { // add the new lang placeholder to the db $this->newLangStrings[$counterInsert] = array(); $this->newLangStrings[$counterInsert][] = $this->db->quote(json_encode(array($this->componentID))); // 'components' $this->newLangStrings[$counterInsert][] = $this->db->quote($string); // 'entranslation' $this->newLangStrings[$counterInsert][] = $this->db->quote(1); // 'published' $this->newLangStrings[$counterInsert][] = $this->db->quote($today); // 'created' $this->newLangStrings[$counterInsert][] = $this->db->quote((int) $this->user->id); // 'created_by' $this->newLangStrings[$counterInsert][] = $this->db->quote(1); // 'version' $this->newLangStrings[$counterInsert][] = $this->db->quote(1); // 'access' $counterInsert++; // load to db $this->setNewLangStrings(100); } // only set the string once unset($strings[$key]); } } } // just to make sure all is done $this->setExistingLangStrings(); $this->setNewLangStrings(); } /** * store the language placeholders * * @param int $when To set when to update * * @return void * */ protected function setNewLangStrings($when = 1) { if (count($this->newLangStrings) >= $when) { // Create a new query object. $query = $this->db->getQuery(true); $continue = false; // Insert columns. $columns = array('components','entranslation','published','created','created_by','version','access'); // Prepare the insert query. $query->insert($this->db->quoteName('#__componentbuilder_language_translation')); $query->columns($this->db->quoteName($columns)); foreach($this->newLangStrings as $values) { if (count($values) == 7) { $query->values(implode(',', $values)); $continue = true; } else { // TODO line mismatch... should not happen } } // clear the values array $this->newLangStrings = array(); if (!$continue) { return false; // insure we dont 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 language placeholders * * @param int $when To set when to update * * @return void * */ protected function setExistingLangStrings($when = 1) { if (count($this->existingLangStrings) >= $when) { foreach($this->existingLangStrings as $values) { // Create a new query object. $query = $this->db->getQuery(true); // Prepare the update query. $query->update($this->db->quoteName('#__componentbuilder_language_translation'))->set($values['fields'])->where($values['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->existingLangStrings = array(); } } /** * Remove exiting language translation stings * * @param int $id To string ID to remove * * @return void * */ protected function removeExitingLangString($id) { // Create a new query object. $query = $this->db->getQuery(true); // delete all custom keys for user 1001. $conditions = array( $this->db->quoteName('id') . ' = ' . (int) $id ); $query->delete($this->db->quoteName('#__componentbuilder_language_translation')); $query->where($conditions); $this->db->setQuery($query); $this->db->execute(); } /** * Function to purge the unused languge strings * * @param string $values the active strings * * @return void * */ public function purgeLanuageStrings($values) { // Create a new query object. $query = $this->db->getQuery(true); $query->from($this->db->quoteName('#__componentbuilder_language_translation','a')); $query->select($this->db->quoteName(array('a.id','a.translation','a.components'))); // get all string that are not linked to this component $query->where($this->db->quoteName('a.entranslation') . ' NOT IN (' . implode(',',array_map(function($a){ return $this->db->quote($a); }, $values)) . ')'); $query->where($this->db->quoteName('a.published') . ' = 1'); $this->db->setQuery($query); $this->db->execute(); if ($this->db->getNumRows()) { $counterUpdate = 0; $otherStrings = $this->db->loadAssocList(); $today = JFactory::getDate()->toSql(); foreach ($otherStrings as $item) { if (ComponentbuilderHelper::checkJson($item['components'])) { $components = (array) json_decode($item['components'], true); // if component is not found ignore this string, and do nothing if (($key = array_search($this->componentID, $components)) !== false) { // first remove the component from the string unset($components[$key]); // check if there are more components if (ComponentbuilderHelper::checkArray($components)) { // just update the string to unlink the current component $this->setUpdateExistingLangStrings($item['id'], $components, 1, $today, $counterUpdate); $counterUpdate++; // load to db $this->setExistingLangStrings(50); } // check if this string has been worked on elseif (ComponentbuilderHelper::checkJson($item['translation'])) { $translation = json_decode($item['translation'], true); if (ComponentbuilderHelper::checkArray($translation)) { // only archive the item and update the string to unlink the current component $this->setUpdateExistingLangStrings($item['id'], $components, 2, $today, $counterUpdate); $counterUpdate++; // load to db $this->setExistingLangStrings(50); } else { // remove the string since no translation found and not linked to any other component $this->removeExitingLangString($item['id']); } } else { // remove the string since no translation found and not linked to any other component $this->removeExitingLangString($item['id']); } } } } // load to db $this->setExistingLangStrings(); } } /** * just to add lang string to the existing Lang Strings array * * @return void * */ protected function setUpdateExistingLangStrings($id, $components, $published, $today, $counterUpdate) { // start the bucket for this lang $this->existingLangStrings[$counterUpdate] = array(); $this->existingLangStrings[$counterUpdate]['id'] = (int) $id; $this->existingLangStrings[$counterUpdate]['conditions'] = array(); $this->existingLangStrings[$counterUpdate]['conditions'][] = $this->db->quoteName('id') . ' = ' . $this->db->quote($id); $this->existingLangStrings[$counterUpdate]['fields'] = array(); $this->existingLangStrings[$counterUpdate]['fields'][] = $this->db->quoteName('components') . ' = ' . $this->db->quote(json_encode($components)); $this->existingLangStrings[$counterUpdate]['fields'][] = $this->db->quoteName('published') . ' = ' . $this->db->quote($published); $this->existingLangStrings[$counterUpdate]['fields'][] = $this->db->quoteName('modified') . ' = ' . $this->db->quote($today); $this->existingLangStrings[$counterUpdate]['fields'][] = $this->db->quoteName('modified_by') . ' = ' . $this->db->quote((int) $this->user->id); } /** * get the custom code from the system * * @return void * */ public function getCustomCode($ids = null, $setLang = true) { // should the result be stored in memory $loadInMemory = false; // Create a new query object. $query = $this->db->getQuery(true); $query->from($this->db->quoteName('#__componentbuilder_custom_code','a')); if (ComponentbuilderHelper::checkArray($ids)) { if ($idArray = $this->customCodeMemory($ids)) { $query->select($this->db->quoteName(array('a.id','a.code','a.comment_type'))); $query->where($this->db->quoteName('a.id') . ' IN (' . implode(',',$idArray) . ')'); $query->where($this->db->quoteName('a.target') . ' = 2'); // <--- to load the correct target $loadInMemory = true; } else { // all values are already in memory continue return true; } } else { $query->select($this->db->quoteName(array('a.id','a.code','a.comment_type','a.component','a.from_line','a.hashtarget','a.hashendtarget','a.path','a.to_line','a.type'))); $query->where($this->db->quoteName('a.component') . ' = '. (int) $this->componentData->id); $query->where($this->db->quoteName('a.target') . ' = 1'); // <--- to load the correct target $query->order($this->db->quoteName('a.from_line') . ' ASC'); // <--- insrue we always add code from top of file // reset custom code $this->customCode = array(); } $query->where($this->db->quoteName('a.published') . ' >= 1'); $this->db->setQuery($query); $this->db->execute(); if ($this->db->getNumRows()) { $bucket = $this->db->loadAssocList('id'); // open the code foreach($bucket as $nr => &$customCode) { $customCode['code'] = base64_decode($customCode['code']); if ($setLang) { $customCode['code'] = $this->setLangStrings($customCode['code']); } if (isset($customCode['hashtarget'])) { $customCode['hashtarget'] = explode("__", $customCode['hashtarget']); if ($customCode['type'] == 1 && strpos($customCode['hashendtarget'], '__') !== false) { $customCode['hashendtarget'] = explode("__", $customCode['hashendtarget']); } } } // load this code into memory if needed if ($loadInMemory === true) { $this->customCodeMemory = $this->customCodeMemory + $bucket; } $this->customCode = array_merge($this->customCode, $bucket); return true; } return false; } /** * check if we already have these ids in local memory * * @return void * */ protected function customCodeMemory($ids) { // reset custom code $this->customCode = array(); foreach ($ids as $pointer => $id) { if (isset($this->customCodeMemory[$id])) { $this->customCode[] = $this->customCodeMemory[$id]; unset($ids[$pointer]); } } // check if any ids left to fetch if (ComponentbuilderHelper::checkArray($ids)) { return $ids; } return false; } /** * store the code * * @param int $when To set when to update * * @return void * */ protected function setNewCustomCode($when = 1) { if (count($this->newCustomCode) >= $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->newCustomCode as $values) { if (count($values) == 15) { $query->values(implode(',', $values)); $continue = true; } else { // TODO line mismatch... should not happen } } // clear the values array $this->newCustomCode = array(); if (!$continue) { return false; // insure we dont 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(); } } /** * store the code * * @param int $when To set when to update * * @return void * */ protected function setExistingCustomCode($when = 1) { if (count($this->existingCustomCode) >= $when) { foreach($this->existingCustomCode 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->existingCustomCode = array(); } } /** * get the custom code from the local files * * @param array $paths The local paths to parse * @param string $today The date for today * * @return void * */ protected function customCodeFactory(&$paths, &$today) { // we must first store the current woking directory $joomla = getcwd(); $counter = array(1 => 0, 2 => 0); // file types to get $fileTypes = array('\.php', '\.js'); // set some local placeholders $placeholders = array(); $placeholders[ComponentbuilderHelper::safeString($this->componentCodeName, 'F').'Helper::'] = '[[[Component]]]Helper::'; $placeholders['COM_'.ComponentbuilderHelper::safeString($this->componentCodeName, 'U')] = 'COM_[[[COMPONENT]]]'; $placeholders['com_'.$this->componentCodeName] = 'com_[[[component]]]'; foreach ($paths as $target => $path) { // we are changing the working directory to the componet path chdir($path); foreach ($fileTypes as $type) { // get a list of files in the current directory tree (only PHP and JS for now) $files = JFolder::files('.', $type, true, true); foreach ($files as $file) { $this->searchFileContent($counter, $file, $target, $this->customCodePlaceholders, $placeholders, $today); // insert new code if (ComponentbuilderHelper::checkArray($this->newCustomCode)) { $this->setNewCustomCode(100); } // update existing custom code if (ComponentbuilderHelper::checkArray($this->existingCustomCode)) { $this->setExistingCustomCode(30); } } } } // change back to Joomla working directory chdir($joomla); // make sure all code is stored if (ComponentbuilderHelper::checkArray($this->newCustomCode)) { $this->setNewCustomCode(); } // update existing custom code if (ComponentbuilderHelper::checkArray($this->existingCustomCode)) { $this->setExistingCustomCode(); } } /** * search a file for placeholders and store result * * @param array $counter The counter for the arrays * @param string $file The file path to search * @param array $searchArray The values to search for * @param array $placeholders The values to replace in the code being stored * @param string $today The date for today * * @return array on success * */ protected function searchFileContent(&$counter, &$file, &$target, &$searchArray, &$placeholders, &$today) { // reset each time per file $loadEndFingerPrint = false; $endFingerPrint = array(); $fingerPrint = array(); $codeBucket = array(); $pointer = array(); $reading = array(); $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); if ($file !== 'script.php') { $path = $target . '/' . $file; } else { $path = $file; } foreach (new SplFileObject($file) as $lineNumber => $lineContent) { // we musk 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 ($searchArray 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 = ''; $endHTML = ''; // check if the ending place holder 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 ($_line = $this->addLineChecker($endReplace, 2, $lineContent)) { $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->newCustomCode[$pointer[$targetKey]][] = $this->db->quote((int) $lineNumber); // 'toline' // first reverse engineer this code block $c0de = $this->reversePlaceholders(implode('', $codeBucket[$pointer[$targetKey]]), $placeholders); $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote(base64_encode($c0de)); // 'code' if ($_type == 2) { // load the last value $this->newCustomCode[$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->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('to_line') . ' = ' . $this->db->quote($lineNumber); // first reverse engineer this code block $c0de = $this->reversePlaceholders(implode('', $codeBucket[$pointer[$targetKey]]), $placeholders, $this->existingCustomCode[$pointer[$targetKey]]['id']); $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('code') . ' = ' . $this->db->quote(base64_encode($c0de)); if ($_type == 2) { // load the last value $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('hashendtarget') . ' = ' . $this->db->quote(0); } } } // check if the endfingerprint is ready to save if (count($endFingerPrint) === 3) { $hashendtarget = '3__'.md5(implode('',$endFingerPrint)); // all new records we can do a bulk insert if ($i === 1) { // load the last value $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote($hashendtarget); // 'hashendtarget' } // the record already exist so we must use module to update elseif ($i === 2) { $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('hashendtarget') . ' = ' . $this->db->quote($hashendtarget); } // reset the needed values $endFingerPrint = array(); $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; 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->codeAreadyDone[$id])) { // reset found comment type $commentType = 0; continue; } // store the id to avoid duplication $this->codeAreadyDone[$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] = $counter[$i]; // activate the reader $reading[$targetKey] = true; // start code bucket $codeBucket[$pointer[$targetKey]] = array(); // 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)); // all new records we can do a buldk insert if ($i === 1 || !$id) { // start the bucket for this code $this->newCustomCode[$pointer[$targetKey]] = array(); $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote($path); // 'path' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote((int) $_type); // 'type' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote(1); // 'target' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote($commentType); // 'comment_type' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote((int) $this->componentID); // 'component' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote(1); // 'published' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote($today); // 'created' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote((int) $this->user->id); // 'created_by' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote(1); // 'version' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote(1); // 'access' $this->newCustomCode[$pointer[$targetKey]][] = $this->db->quote($hashtarget); // 'hashtarget' $this->newCustomCode[$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->existingCustomCode[$pointer[$targetKey]] = array(); $this->existingCustomCode[$pointer[$targetKey]]['id'] = (int) $id; $this->existingCustomCode[$pointer[$targetKey]]['conditions'] = array(); $this->existingCustomCode[$pointer[$targetKey]]['conditions'][] = $this->db->quoteName('id') . ' = ' . $this->db->quote($id); $this->existingCustomCode[$pointer[$targetKey]]['fields'] = array(); $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('path') . ' = ' . $this->db->quote($path); $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('type') . ' = ' . $this->db->quote($_type); $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('comment_type') . ' = ' . $this->db->quote($commentType); $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('component') . ' = ' . $this->db->quote($this->componentID); $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('from_line') . ' = ' . $this->db->quote($lineNumber); $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('modified') . ' = ' . $this->db->quote($today); $this->existingCustomCode[$pointer[$targetKey]]['fields'][] = $this->db->quoteName('modified_by') . ' = ' . $this->db->quote($this->user->id); $this->existingCustomCode[$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 $counter[$i]++; } } } // make sure only a few lines is kept at a time if (count($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($endFingerPrint) > 0 || $loadEndFingerPrint) { if (count($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->newCustomCode[$pointer[$backupTargetKey]][] = $this->db->quote($hashendtarget); // 'hashendtarget' } // the record already exist so we must use module to update elseif ($backupI === 2) { $this->existingCustomCode[$pointer[$backupTargetKey]]['fields'][] = $this->db->quoteName('hashendtarget') . ' = ' . $this->db->quote($hashendtarget); } } } /** * Check if this line should be added * * @param strin $replaceKey The key to remove from line * @param int $type The line type * @param string $lineContent The line to check * * @return bool true on success * */ protected function addLineChecker($replaceKey, $type, $lineContent) { $check = explode($replaceKey, $lineContent); switch($type) { case 1: // beginning of code $i = trim($check[1]); if (ComponentbuilderHelper::checkString($i)) { return $check[1]; } break; case 2: // end of code $i = trim($check[0]); if (ComponentbuilderHelper::checkString($i)) { return $check[0]; } break; } return false; } /** * search for the system id in the line given * * @param int $id The comment id * @param int $commentType The comment type * @param string $startReplace The main replace string * * @return array on success * */ protected function setStartReplace($id, $commentType, $startReplace) { if ($id > 0) { switch($commentType) { case 1: $startReplace .= '/*'.$id.'*/'; break; case 2: $startReplace .= ''; break; } } return $startReplace; } /** * search for the system id in the line given * * @param string $lineContent The file path to search * @param string $placeholders The values to search for * * @return array on success * */ protected function getSystemID(&$lineContent, $placeholders, $commentType) { $trim = '/'; if ($commentType == 2) { $trim = ' if ($this->addPlaceholders === true) { return array( 'start' => '', 'end' => ''); } else { return array( 'start' => "\t\t\t", 'end' => "\t\t\t"); } break; case 22: // if ($this->addPlaceholders === true) { return array( 'start' => '', 'end' => ''); } else { return array( 'start' => "\t\t\t", 'end' => "\t\t\t"); } break; case 3: return array( 'start' => "\t\t\t", 'end' => "\t\t\t"); break; } return false; } /** * get the local installed path of this component * * @return array of paths on success * */ protected function getLocalInstallPaths() { // set the local paths to search $localPaths = array(); // admin path $localPaths['admin'] = JPATH_ADMINISTRATOR . '/components/com_'. $this->componentCodeName; // site path $localPaths['site'] = JPATH_ROOT . '/components/com_'. $this->componentCodeName; // TODO later to include the JS and CSS $localPaths['media'] = JPATH_ROOT . '/media/com_'. $this->componentCodeName; // check if the local install is found foreach ($localPaths as $key => $localPath) { if (!JFolder::exists($localPath)) { unset($localPaths[$key]); } } if (ComponentbuilderHelper::checkArray($localPaths)) { return $localPaths; } return false; } }