Added #31 feature to build fields and views dynamically via a sql dump. Fixed #29 to insure that a redirect loop does not occur easily. Made many other compiler improvements.

This commit is contained in:
2016-12-30 12:47:19 +02:00
parent 829384a56b
commit 0ae4e4f80d
388 changed files with 5052 additions and 3714 deletions

View File

@ -0,0 +1,389 @@
<?php
/*--------------------------------------------------------------------------------------------------------| www.vdm.io |------/
__ __ _ _____ _ _ __ __ _ _ _
\ \ / / | | | __ \ | | | | | \/ | | | | | | |
\ \ / /_ _ ___| |_ | | | | _____ _____| | ___ _ __ _ __ ___ ___ _ __ | |_ | \ / | ___| |_| |__ ___ __| |
\ \/ / _` / __| __| | | | |/ _ \ \ / / _ \ |/ _ \| '_ \| '_ ` _ \ / _ \ '_ \| __| | |\/| |/ _ \ __| '_ \ / _ \ / _` |
\ / (_| \__ \ |_ | |__| | __/\ V / __/ | (_) | |_) | | | | | | __/ | | | |_ | | | | __/ |_| | | | (_) | (_| |
\/ \__,_|___/\__| |_____/ \___| \_/ \___|_|\___/| .__/|_| |_| |_|\___|_| |_|\__| |_| |_|\___|\__|_| |_|\___/ \__,_|
| |
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 1.0.0
@created 26th December, 2016
@package Component Builder
@subpackage mapping.php
@author Llewellyn van der Merwe <http://www.vdm.io>
@my wife Roline van der Merwe <http://www.vdm.io/>
@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');
/**
* Mapping class
*/
class Mapping
{
/**
* Some default fields
*/
protected $buildcompsql;
public $id;
public $name_code;
public $addadmin_views;
public $addSql = array();
public $source = array();
public $sql = array();
/**
* The map of the needed fields and views
*/
public $map;
/**
* The app to load messages mostly
*/
public $app;
/**
* The needed set of keys needed to set
*/
protected $setting = array('id' => 'default', 'buildcompsql' => 'base64', 'addadmin_views' => 'json', 'name_code' => 'safeString');
/**
* The needed set of keys needed to set
*/
protected $notRequiered = array('id', 'asset_id', 'published',
'created_by', 'modified_by', 'created', 'modified', 'checked_out','checked_out_time',
'version', 'hits', 'access', 'ordering',
'metakey', 'metadesc', 'metadata', 'params');
/**
* The datatypes and it linked field types (basic)
* (TODO) We may need to set this dynamicly
*/
protected $dataTypes = array( 'CHAR' => 'Text', 'VARCHAR' => 'Text',
'TEXT' => 'Textarea', 'MEDIUMTEXT' => 'Textarea',
'LONGTEXT' => 'Textarea', 'DATE' => 'Text', 'TIME' => 'Text',
'DATETIME' => 'Calendar', 'INT' => 'Text', 'TINYINT' => 'Text',
'BIGINT' => 'Text', 'FLOAT' => 'Text', 'DECIMAL' => 'Text',
'DOUBLE' => 'Text');
/**
* The datasize identifiers
*/
protected $dataSize = array( 'CHAR', 'VARCHAR', 'INT', 'TINYINT',
'BIGINT', 'FLOAT', 'DECIMAL', 'DOUBLE');
/**
* The default identifiers
*/
protected $defaults = array(0, 1, "CURRENT_TIMESTAMP", "DATETIME"); // Other
/**
* The sizes identifiers
*/
protected $sizes = array("1", "7", "10", "11", "50", "64", "100", "255", "1024", "2048"); // Other
/**
* Constructor
*/
public function __construct($data = false)
{
// set the app to insure messages can be set
$this->app = JFactory::getApplication();
if ($data)
{
if (isset($data['buildcomp']) && 1 == $data['buildcomp'] && isset($data['buildcompsql']))
{
foreach ($data as $key => $value)
{
if (isset($this->setting[$key]))
{
switch($this->setting[$key])
{
case 'base64':
// set needed value
$this->$key = base64_decode($value);
break;
case 'json':
// set needed value
$this->$key = json_decode($value, true);
break;
case 'safeString':
// set needed value
$this->$key = ComponentbuilderHelper::safeString($value);
break;
default :
$this->$key = $value;
break;
}
}
}
// set the map of the views needed
if ($this->setMap())
{
return true;
}
$this->app->enqueueMessage(
JText::_('No "CREATE TABLE.." were found, please check your sql.'),
'Error'
);
return false;
}
return false; // not set so just return without any error
}
$this->app->enqueueMessage(
JText::_('Could not find the data needed to continue.'),
'Error'
);
return false;
}
/**
* The mapping function
* To Map the views and fields that are needed
*/
protected function setMap()
{
// start parsing the sql dump data
$queries = JDatabaseDriver::splitSql($this->buildcompsql);
if (ComponentbuilderHelper::checkArray($queries))
{
foreach ($queries as $query)
{
// only use create table queries
if (strpos($query, 'CREATE TABLE IF NOT EXISTS `') !== false)
{
if ($tableName = $this->getTableName($query))
{
// now get the fields/columns of this view/table
if ($fields = $this->getFields($query))
{
// make sure it is all lower case from here on
$tableName = strtolower($tableName);
$this->map[$tableName] = $fields;
}
}
else
{
continue;
}
}
// get the insert data if set
if (strpos($query, 'INSERT INTO `') !== false)
{
if ($tableName = $this->getTableName($query))
{
$this->addSql[$tableName] = 1;
$this->source[$tableName] = 2;
$this->sql[$tableName] = $query;
}
}
}
// check if the mapping was done
if (ComponentbuilderHelper::checkArray($this->map))
{
return true;
}
}
return false;
}
/**
* Get the table name
*/
protected function getTableName(&$query)
{
$tableName = ComponentbuilderHelper::getBetween($query, '`#__', "`");
// if it still was not found
if (!ComponentbuilderHelper::checkString($tableName))
{
// skip this query
return false;
}
// clean the table name (so only view name remain)
if (strpos($tableName, $this->name_code) !== false)
{
$tableName = trim(str_replace($this->name_code, '', $tableName), '_');
}
// if found
if (ComponentbuilderHelper::checkString($tableName))
{
return $tableName;
}
// skip this query
return false;
}
/**
* Get the field details
*/
protected function getFields(&$query)
{
$rows = array_map('trim', explode("\n", $query));
$fields = array();
foreach ($rows as $row)
{
// make sure we have a lower case string
$row = strtoupper($row);
$field = array();
$name = '';
if (0 === strpos($row, '`'))
{
// get field name
$name = ComponentbuilderHelper::getBetween($row, '`', '`');
}
if (0 === strpos($row, "'"))
{
// get field name
$name = ComponentbuilderHelper::getBetween($row, "'", "'");
}
// check if the name was found
if (ComponentbuilderHelper::checkString($name))
{
// insure we have the name in lower case from here on
$name = strtolower($name);
// only continue if field is requered
if (in_array($name, $this->notRequiered))
{
continue;
}
// check if the field type is found
if ($fieldType = $this->getType($row, $field, $name))
{
$field['row'] = $row;
$field['name'] = $name;
$field['label'] = ComponentbuilderHelper::safeString($name, 'W');
$field['fieldType'] = $fieldType;
$field['size'] = $this->getSize($row, $field);
$field['sizeOther'] = '';
if (!in_array($field['size'], $this->sizes))
{
if (ComponentbuilderHelper::checkString($field['size']))
{
$field['sizeOther'] = $field['size'];
$field['size'] = 'Other';
}
}
$field['default'] = $this->getDefault($row);
$field['defaultOther'] = '';
if (!in_array($field['default'], $this->defaults))
{
if (ComponentbuilderHelper::checkString($field['default']))
{
$field['defaultOther'] = $field['default'];
$field['default'] = 'Other';
}
}
$field['null'] = $this->getNullValue($row, $field);
// check if field is a key
$field['key'] = $this->getKeyStatus($rows, $name);
// load to fields
$fields[] = $field;
}
}
}
if (ComponentbuilderHelper::checkArray($fields))
{
return $fields;
}
return false;
}
/**
* Get the field types
*/
protected function getType($row, &$field, &$name)
{
// first remove field name
$row = str_replace($name, '', $row);
// get the data type first
foreach ($this->dataTypes as $type => $fieldType)
{
if (strpos($row, $type) !== false)
{
$field['dataType'] = $type;
return $fieldType;
}
}
return false;
}
/**
* Get the field size
*/
protected function getSize(&$row, $field)
{
if (in_array($field['dataType'], $this->dataSize))
{
return ComponentbuilderHelper::getBetween($row, $field['dataType'].'(', ')');
}
return '';
}
/**
* Get the field default
*/
protected function getDefault(&$row)
{
// get default value
if (strpos($row, 'DEFAULT "') !== false) // to sure it this is correct...
{
return ComponentbuilderHelper::getBetween($row, 'DEFAULT "', '"');
}
// get default value
if (strpos($row, "DEFAULT '") !== false)
{
return ComponentbuilderHelper::getBetween($row, "DEFAULT '", "'");
}
return '';
}
/**
* Get the field Null Value
*/
protected function getNullValue(&$row, &$field)
{
// get the result of null
if (strpos($row, 'NOT NULL') !== false)
{
return 'NOT NULL';
}
if (strpos($row, 'DEFAULT NULL') !== false)
{
$field['default'] = 'NULL';
return '';
}
return 'NULL';
}
/**
* Get the field key status
*/
protected function getKeyStatus(&$rows, &$name)
{
// get the data type first
foreach ($rows as $row)
{
if (strpos($row, 'UNIQUE KEY ') !== false && stripos($row, $name) !== false)
{
return 1;
}
if ((strpos($row, 'PRIMARY KEY ') !== false && stripos($row, $name) !== false) || (strpos($row, 'KEY ') !== false && stripos($row, $name) !== false))
{
return 2;
}
}
return 0;
}
}

View File

@ -0,0 +1,294 @@
<?php
/*--------------------------------------------------------------------------------------------------------| www.vdm.io |------/
__ __ _ _____ _ _ __ __ _ _ _
\ \ / / | | | __ \ | | | | | \/ | | | | | | |
\ \ / /_ _ ___| |_ | | | | _____ _____| | ___ _ __ _ __ ___ ___ _ __ | |_ | \ / | ___| |_| |__ ___ __| |
\ \/ / _` / __| __| | | | |/ _ \ \ / / _ \ |/ _ \| '_ \| '_ ` _ \ / _ \ '_ \| __| | |\/| |/ _ \ __| '_ \ / _ \ / _` |
\ / (_| \__ \ |_ | |__| | __/\ V / __/ | (_) | |_) | | | | | | __/ | | | |_ | | | | __/ |_| | | | (_) | (_| |
\/ \__,_|___/\__| |_____/ \___| \_/ \___|_|\___/| .__/|_| |_| |_|\___|_| |_|\__| |_| |_|\___|\__|_| |_|\___/ \__,_|
| |
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 1.0.0
@created 26th December, 2016
@package Component Builder
@subpackage builder.php
@author Llewellyn van der Merwe <http://www.vdm.io>
@my wife Roline van der Merwe <http://www.vdm.io/>
@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');
/**
* Builder class
*/
class Builder extends Mapping
{
/**
* Some default fields
*/
public $user;
public $today;
public $db;
public $views = array();
protected $fields = array();
protected $title = array();
protected $description = array();
protected $alias = array();
protected $list = array();
/**
* Field that should not be used in name, alias, disc, and list view
* (TODO) We may need to set this dynamicly
*/
protected $avoidList = array('not_required');
/***
* Constructor
*/
public function __construct(&$data)
{
// first we run the perent constructor
if (parent::__construct($data))
{
// always reset the building values if found
$data['buildcomp'] = 0;
$data['buildcompsql'] = '';
// set some globals
$this->db = JFactory::getDbo();
$this->user = JFactory::getUser();
$this->today = JFactory::getDate()->toSql();
// no start the building of the views and fields
if ($this->setBuild())
{
return true;
}
}
return false;
}
/**
* The building function
* To build the views and fields that are needed
*/
protected function setBuild()
{
foreach ($this->map as $view => $fields)
{
// set this field with all its needed data
foreach ($fields as $field)
{
$this->setField($view, $field);
}
// set this view with all its needed data
$this->setView($view);
}
return true;
}
/**
* The building function for views
*/
protected function setView(&$name)
{
// set the view object
$object = new stdClass();
$object->system_name = ComponentbuilderHelper::safeString($name, 'W') . ' (dynamic build)';
$object->name_single = $name;
$object->name_list = $name. 's';
$object->short_description = $name. ' view (dynamic build)';
$object->type = 1;
$object->description = $name. ' view (dynamic build)';
$object->add_fadein = 1;
$object->add_sql = (isset($this->addSql[$name])) ? $this->addSql[$name]: 0;
$object->source = (isset($this->source[$name])) ? $this->source[$name]: 0;
$object->sql = (isset($this->sql[$name])) ? base64_encode($this->sql[$name]): '';
$object->addpermissions = '{"action":["view.edit","view.edit.own","view.edit.state","view.create","view.delete","view.access"],"implementation":["3","3","3","3","3","3"]}';
$object->addfields = $this->addFields($name);
$object->created = $this->today;
$object->created_by = $this->user->id;
$object->published = 1;
// add to data base
if ($this->db->insertObject('#__componentbuilder_admin_view', $object))
{
// make sure the access of asset is set
$id = $this->db->insertid();
ComponentbuilderHelper::setAsset($id, 'admin_view');
// load the views
$this->views[] = $id;
return true;
}
return false;
}
/**
* Add the fields to the view
*/
protected function addFields(&$view)
{
if (isset($this->fields[$view]))
{
// set some defaults
$addField = array (
'field' => array(),
'list' => array(),
'order_list' => array(),
'title' => array(),
'alias' => array(),
'sort' => array(),
'search' => array(),
'filter' => array(),
'link' => array(),
'tab' => array(),
'alignment' => array(),
'order_edit' => array(),
'permission' => array()
);
$fixLink = (isset($this->title[$view])) ? 0 : 1;
// build the field data... hmmm
foreach ($this->fields[$view] as $nr => $id)
{
$alignment = 1;
if ($nr % 2 == 0)
{
$alignment = 2;
}
// some defaults
$isTitle = (isset($this->title[$view]) && $this->title[$view] == $id) ? 1 : 0;
$isAlias = (isset($this->alias[$view]) && $this->alias[$view] == $id) ? 1 : 0;
$isList = ($key = array_search($id, $this->list[$view])) ? 1 : 0;
$isLink = ($isTitle) ? 1 : (($isList && $fixLink) ? 1 : 0);
if ($isLink)
{
$fixLink = 0;
}
// load the field values
$addField['field'][] = $id;
$addField['list'][] = $isList;
$addField['order_list'][] = ($key) ? $key : 0;
$addField['title'][] = $isTitle;
$addField['alias'][] = $isAlias;
$addField['sort'][] = $isList;
$addField['search'][] = $isList;
$addField['filter'][] = $isList;
$addField['link'][] = $isLink;
$addField['tab'][] = 1;
$addField['alignment'][] = ($isTitle || $isAlias) ? 4 : $alignment;
$addField['order_edit'][] = $nr;
$addField['permission'][] = 0;
}
return json_encode($addField);
}
return '';
}
/**
* The building function for fields
*/
protected function setField(&$view, &$field)
{
if ($fieldType = $this->getFieldType($field['fieldType']))
{
// set the field object
$object = new stdClass();
$object->name = $field['label'] . ' (dynamic build)';
$object->fieldtype = $fieldType;
$object->datatype = $field['dataType'];
$object->indexes = $field['key'];
$object->null_switch = $field['null'];
$object->datalenght = $field['size'];
$object->datalenght_other = $field['sizeOther'];
$object->datadefault = $field['default'];
$object->datadefault_other = $field['defaultOther'];
$object->created = $this->today;
$object->created_by = $this->user->id;
$object->published = 1;
$object->store = 0;
$object->xml = $this->setFieldXML($field, $fieldType);
// add to data base
if ($this->db->insertObject('#__componentbuilder_field', $object))
{
// make sure the access of asset is set
$id = $this->db->insertid();
ComponentbuilderHelper::setAsset($id, 'field');
// check if any field for this field was already set, if not set array
if (!isset($this->fields[$view]))
{
$this->fields[$view] = array();
}
// load the field
$this->fields[$view][] = $id;
if (!isset($this->list[$view]))
{
$this->list[$view] = array();
}
// insure that some fields are avoided
if (!in_array($field['name'], $this->avoidList))
{
// set the name/title field if found
if (!isset($this->title[$view]) && (stripos($field['name'], 'name') !== false || stripos($field['name'], 'title') !== false))
{
$this->title[$view] = $id;
$this->list[$view][] = $id;
}
// set the alias field if found
elseif (!isset($this->alias[$id]) && stripos($field['name'], 'alias') !== false)
{
$this->alias[$view] = $id;
}
// set the alias field if found
elseif (!isset($this->description[$id]) && stripos($field['name'], 'desc') !== false)
{
$this->description[$view] = $id;
$this->list[$view][] = $id;
}
elseif ('Text' == $field['fieldType'] && count($this->list[$view]) < 5)
{
$this->list[$view][] = $id;
}
}
return true;
}
}
return false;
}
/**
* get the field type id from system
*/
protected function getFieldType($fieldName)
{
// load the field settings
return ComponentbuilderHelper::getVar('fieldtype', $fieldName, 'name', 'id');
}
/**
* The building function for field xml
*/
protected function setFieldXML(&$field, $fieldId)
{
// load the field settings
$settings = array();
$settings['name'] = $field['name'];
$settings['description'] = 'The '.strtolower($field['label']) . ' is set here.';
$settings['message'] = "Error! Please add some ".strtolower($field['label'])." here.";
$settings['label'] = $field['label'];
$settings['default'] = ($field['default'] == 'Other') ? $field['defaultOther'] : $field['default'];
$settings['hint'] = $field['label'] .' Here!';
// okay set the xml field values
if ($fieldOptions = ComponentbuilderHelper::getFieldOptions($fieldId, 'id', $settings))
{
return json_encode($fieldOptions['values']);
}
return '';
}
}

View File

@ -0,0 +1,141 @@
<?php
/*--------------------------------------------------------------------------------------------------------| www.vdm.io |------/
__ __ _ _____ _ _ __ __ _ _ _
\ \ / / | | | __ \ | | | | | \/ | | | | | | |
\ \ / /_ _ ___| |_ | | | | _____ _____| | ___ _ __ _ __ ___ ___ _ __ | |_ | \ / | ___| |_| |__ ___ __| |
\ \/ / _` / __| __| | | | |/ _ \ \ / / _ \ |/ _ \| '_ \| '_ ` _ \ / _ \ '_ \| __| | |\/| |/ _ \ __| '_ \ / _ \ / _` |
\ / (_| \__ \ |_ | |__| | __/\ V / __/ | (_) | |_) | | | | | | __/ | | | |_ | | | | __/ |_| | | | (_) | (_| |
\/ \__,_|___/\__| |_____/ \___| \_/ \___|_|\___/| .__/|_| |_| |_|\___|_| |_|\__| |_| |_|\___|\__|_| |_|\___/ \__,_|
| |
|_|
/-------------------------------------------------------------------------------------------------------------------------------/
@version 1.0.0
@created 26th December, 2016
@package Component Builder
@subpackage extrusion.php
@author Llewellyn van der Merwe <http://www.vdm.io>
@my wife Roline van der Merwe <http://www.vdm.io/>
@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');
/**
* Extrusion class
*/
class Extrusion extends Builder
{
/***
* Constructor
*/
public function __construct(&$data)
{
// first we run the perent constructor
if (parent::__construct($data))
{
// link the view data to the component
$data['addadmin_views'] = $this->linkAdminViews();
if (ComponentbuilderHelper::checkJson($data['addadmin_views']))
{
$this->app->enqueueMessage(
JText::_('All the fields and views from your sql dump has been created and linked to this component.'),
'Success'
);
return true;
}
}
return false;
}
/**
* link the build views to the component
*/
protected function linkAdminViews()
{
// check if views were set
if (ComponentbuilderHelper::checkArray($this->views))
{
// insure arrays are set
if (!isset($this->addadmin_views['adminview']))
{
$this->addadmin_views['adminview'] = array();
}
if (!isset($this->addadmin_views['icomoon']))
{
$this->addadmin_views['icomoon'] = array();
}
if (!isset($this->addadmin_views['mainmenu']))
{
$this->addadmin_views['mainmenu'] = array();
}
if (!isset($this->addadmin_views['dashboard_add']))
{
$this->addadmin_views['dashboard_add'] = array();
}
if (!isset($this->addadmin_views['dashboard_list']))
{
$this->addadmin_views['dashboard_list'] = array();
}
if (!isset($this->addadmin_views['submenu']))
{
$this->addadmin_views['submenu'] = array();
}
if (!isset($this->addadmin_views['checkin']))
{
$this->addadmin_views['checkin'] = array();
}
if (!isset($this->addadmin_views['history']))
{
$this->addadmin_views['history'] = array();
}
if (!isset($this->addadmin_views['metadata']))
{
$this->addadmin_views['metadata'] = array();
}
if (!isset($this->addadmin_views['access']))
{
$this->addadmin_views['access'] = array();
}
if (!isset($this->addadmin_views['port']))
{
$this->addadmin_views['port'] = array();
}
if (!isset($this->addadmin_views['edit_create_site_view']))
{
$this->addadmin_views['edit_create_site_view'] = array();
}
if (!isset($this->addadmin_views['order']))
{
$this->addadmin_views['order'] = array();
}
// set the admin view data linking
foreach ($this->views as $id)
{
$this->addadmin_views['adminview'][] = $id;
$this->addadmin_views['icomoon'][] = 'joomla';
$this->addadmin_views['mainmenu'][] = 1;
$this->addadmin_views['dashboard_add'][] = 1;
$this->addadmin_views['dashboard_list'][] = 1;
$this->addadmin_views['submenu'][] = 1;
$this->addadmin_views['checkin'][] = 1;
$this->addadmin_views['history'][] = 1;
$this->addadmin_views['metadata'][] = 1;
$this->addadmin_views['access'][] = 1;
$this->addadmin_views['port'][] = 1;
$this->addadmin_views['edit_create_site_view'][] = 0;
$this->addadmin_views['order'][] = count($this->addadmin_views['order']) + 1;
}
}
if (isset($this->addadmin_views) && ComponentbuilderHelper::checkArray($this->addadmin_views))
{
return json_encode($this->addadmin_views);
}
return '';
}
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>