protected function _generate() { $className = $this->_getClassName(); $tableName = DevHelper_Generator_Db::getTableName($this->_config, $this->_dataClass['name']); $tableFields = $this->_dataClass['fields']; foreach ($tableFields as &$field) { unset($field['name']); if (!empty($field['length'])) { $field['maxLength'] = $field['length']; unset($field['length']); } $field['type'] = DevHelper_Generator_File::varExportConstantFromArray($field['type'], array('XenForo_DataWriter::TYPE_BOOLEAN', 'XenForo_DataWriter::TYPE_STRING', 'XenForo_DataWriter::TYPE_BINARY', 'XenForo_DataWriter::TYPE_INT', 'XenForo_DataWriter::TYPE_UINT', 'XenForo_DataWriter::TYPE_UINT_FORCED', 'XenForo_DataWriter::TYPE_FLOAT', 'XenForo_DataWriter::TYPE_SERIALIZED', 'XenForo_DataWriter::TYPE_JSON', 'XenForo_DataWriter::TYPE_UNKNOWN')); } $tableFields = DevHelper_Generator_File::varExport($tableFields, 1); $primaryKey = DevHelper_Generator_File::varExport($this->_dataClass['primaryKey']); $modelClassName = DevHelper_Generator_Code_Model::getClassName($this->_addOn, $this->_config, $this->_dataClass); $this->_setClassName($className); $this->_setBaseClass('XenForo_DataWriter'); $this->_addMethod('_getFields', 'protected', array(), "\n\nreturn array(\n '{$tableName}' => {$tableFields}\n);\n\n "); if (count($this->_dataClass['primaryKey']) == 1) { $idField = reset($this->_dataClass['primaryKey']); $this->_addMethod('_getExistingData', 'protected', array('$data'), "\n\nif (!\$id = \$this->_getExistingPrimaryKey(\$data, '{$idField}')) {\n return false;\n}\n\nreturn array('{$tableName}' => \$this->_get{$this->_dataClass['camelCase']}Model()->get{$this->_dataClass['camelCase']}ById(\$id));\n\n "); } else { $this->_addMethod('_getExistingData', 'protected', array('$data'), "\n\nthrow new XenForo_Exception('{$className} does not support _getExistingData()');\n\n "); } $this->_addMethod('_getUpdateCondition', 'protected', array('$tableName'), "\n\n\$conditions = array();\n\nforeach ({$primaryKey} as \$field) {\n \$conditions[] = \$field . ' = ' . \$this->_db->quote(\$this->getExisting(\$field));\n}\n\nreturn implode(' AND ', \$conditions);\n\n "); $this->_addMethod("_get{$this->_dataClass['camelCase']}Model", 'protected', array(), "\n\nreturn \$this->getModelFromCache('{$modelClassName}');\n\n "); $this->_generateImageCode(); $this->_generatePhrasesCode(); $this->_generateParentCode(); return parent::_generate(); }
public static function generate(array $addOn, DevHelper_Config_Base $config, array $dataClass) { $className = self::getClassName($addOn, $config, $dataClass); $tableName = DevHelper_Generator_Db::getTableName($config, $dataClass['name']); $tableFields = $dataClass['fields']; foreach ($tableFields as &$field) { unset($field['name']); if (!empty($field['length'])) { $field['maxLength'] = $field['length']; unset($field['length']); } } $tableFields = DevHelper_Generator_File::varExport($tableFields, 3); $primaryKey = DevHelper_Generator_File::varExport($dataClass['primaryKey']); $modelClassName = DevHelper_Generator_Code_Model::getClassName($addOn, $config, $dataClass); $commentAutoGeneratedStart = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_START; $commentAutoGeneratedEnd = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_END; $contents = <<<EOF <?php class {$className} extends XenForo_DataWriter { \t{$commentAutoGeneratedStart} \t \tprotected function _getFields() { \t\treturn array( \t\t\t'{$tableName}' => {$tableFields} \t\t); \t} \tprotected function _getExistingData(\$data) { \t\tif (!\$id = \$this->_getExistingPrimaryKey(\$data, '{$dataClass['id_field']}')) { \t\t\treturn false; \t\t} \t\treturn array('{$tableName}' => \$this->_get{$dataClass['camelCase']}Model()->get{$dataClass['camelCase']}ById(\$id)); \t} \tprotected function _getUpdateCondition(\$tableName) { \t\t\$conditions = array(); \t\t \t\tforeach ({$primaryKey} as \$field) { \t\t\t\$conditions[] = \$field . ' = ' . \$this->_db->quote(\$this->getExisting(\$field)); \t\t} \t\t \t\treturn implode(' AND ', \$conditions); \t} \t \tprotected function _get{$dataClass['camelCase']}Model() { \t\treturn \$this->getModelFromCache('{$modelClassName}'); \t} \t \t{$commentAutoGeneratedEnd} } EOF; return array($className, $contents); }
protected function _generate() { $className = $this->_getClassName(); $tableName = DevHelper_Generator_Db::getTableName($this->_config, $this->_dataClass['name']); $idField = ''; if (count($this->_dataClass['primaryKey']) == 1) { $idField = reset($this->_dataClass['primaryKey']); } $getFunctionName = self::generateGetDataFunctionName($this->_addOn, $this->_config, $this->_dataClass); $countFunctionName = self::generateCountDataFunctionName($this->_addOn, $this->_config, $this->_dataClass); $tableAlias = $this->_dataClass['name']; if (in_array($tableAlias, array('group', 'join', 'order'))) { $tableAlias = '_' . $tableAlias; } $variableName = self::getVariableName($this->_addOn, $this->_config, $this->_dataClass); $variableNamePlural = self::getVariableNamePlural($this->_addOn, $this->_config, $this->_dataClass); $conditionFields = DevHelper_Generator_Db::getConditionFields($this->_dataClass['fields']); $this->_setClassName($className); $this->_setBaseClass('XenForo_Model'); $this->_addCustomizableMethod("_{$getFunctionName}Customized", 'protected', array('array &$data', 'array $fetchOptions')); $this->_addCustomizableMethod("_prepare{$this->_dataClass['camelCase']}ConditionsCustomized", 'protected', array('array &$sqlConditions', 'array $conditions', 'array $fetchOptions')); $this->_addCustomizableMethod("_prepare{$this->_dataClass['camelCase']}FetchOptionsCustomized", 'protected', array('&$selectFields', '&$joinTables', 'array $fetchOptions')); $this->_addCustomizableMethod("_prepare{$this->_dataClass['camelCase']}OrderOptionsCustomized", 'protected', array('array &$choices', 'array &$fetchOptions')); if (!empty($idField)) { $this->_addMethod('getList', 'public', array('$conditions' => 'array $conditions = array()', '$fetchOptions' => 'array $fetchOptions = array()'), "\n\n\${$variableNamePlural} = \$this->{$getFunctionName}(\$conditions, \$fetchOptions);\n\$list = array();\n\nforeach (\${$variableNamePlural} as \$id => \${$variableName}) {\n \$list[\$id] = \${$variableName}" . (empty($this->_dataClass['title_field']) ? "['{$idField}']" : (is_array($this->_dataClass['title_field']) ? "['{$this->_dataClass['title_field'][0]}']['{$this->_dataClass['title_field'][1]}']" : "['{$this->_dataClass['title_field']}']")) . ";\n}\n\nreturn \$list;\n\n "); $this->_addMethod("get{$this->_dataClass['camelCase']}ById", 'public', array('$id', '$fetchOptions' => 'array $fetchOptions = array()'), "\n\n\${$variableNamePlural} = \$this->{$getFunctionName}(array('{$idField}' => \$id), \$fetchOptions);\n\nreturn reset(\${$variableNamePlural});\n\n "); $this->_addMethod("get{$this->_dataClass['camelCase']}IdsInRange", 'public', array('$start', '$limit'), "\n\n\$db = \$this->_getDb();\n\nreturn \$db->fetchCol(\$db->limit('\n SELECT {$idField}\n FROM {$tableName}\n WHERE {$idField} > ?\n ORDER BY {$idField}\n', \$limit), \$start);\n\n "); } $this->_addMethod($getFunctionName, 'public', array('$conditions' => 'array $conditions = array()', '$fetchOptions' => 'array $fetchOptions = array()'), "\n\n\$whereConditions = \$this->prepare{$this->_dataClass['camelCase']}Conditions(\$conditions, \$fetchOptions);\n\n\$orderClause = \$this->prepare{$this->_dataClass['camelCase']}OrderOptions(\$fetchOptions);\n\$joinOptions = \$this->prepare{$this->_dataClass['camelCase']}FetchOptions(\$fetchOptions);\n\$limitOptions = \$this->prepareLimitFetchOptions(\$fetchOptions);\n\n\${$variableNamePlural} = \$this->" . (!empty($idField) ? "fetchAllKeyed" : "_getDb()->fetchAll") . "(\$this->limitQueryResults(\"\n SELECT {$tableAlias}.*\n \$joinOptions[selectFields]\n FROM `{$tableName}` AS {$tableAlias}\n \$joinOptions[joinTables]\n WHERE \$whereConditions\n \$orderClause\n \", \$limitOptions['limit'], \$limitOptions['offset']\n)" . (!empty($idField) ? ", '{$idField}'" : "") . ");\n\n ", '001'); $this->_addMethod($getFunctionName, 'public', array('$conditions' => 'array $conditions = array()', '$fetchOptions' => 'array $fetchOptions = array()'), "\n\n\$this->_{$getFunctionName}Customized(\${$variableNamePlural}, \$fetchOptions);\n\nreturn \${$variableNamePlural};\n\n ", '999'); $this->_addMethod($countFunctionName, 'public', array('$conditions' => 'array $conditions = array()', '$fetchOptions' => 'array $fetchOptions = array()'), "\n\n\$whereConditions = \$this->prepare{$this->_dataClass['camelCase']}Conditions(\$conditions, \$fetchOptions);\n\n\$orderClause = \$this->prepare{$this->_dataClass['camelCase']}OrderOptions(\$fetchOptions);\n\$joinOptions = \$this->prepare{$this->_dataClass['camelCase']}FetchOptions(\$fetchOptions);\n\$limitOptions = \$this->prepareLimitFetchOptions(\$fetchOptions);\n\nreturn \$this->_getDb()->fetchOne(\"\n SELECT COUNT(*)\n FROM `{$tableName}` AS {$tableAlias}\n \$joinOptions[joinTables]\n WHERE \$whereConditions\n\");\n\n "); $this->_addMethod("prepare{$this->_dataClass['camelCase']}Conditions", 'public', array('$conditions' => 'array $conditions = array()', '$fetchOptions' => 'array $fetchOptions = array()'), "\n\n\$sqlConditions = array();\n\$db = \$this->_getDb();\n\n "); foreach ($conditionFields as $conditionField) { $this->_addMethod("prepare{$this->_dataClass['camelCase']}Conditions", '', array(), "\n\nif (isset(\$conditions['{$conditionField}'])) {\n if (is_array(\$conditions['{$conditionField}'])) {\n if (!empty(\$conditions['{$conditionField}'])) {\n // only use IN condition if the array is not empty (nasty!)\n \$sqlConditions[] = \"{$tableAlias}.{$conditionField} IN (\" . \$db->quote(\$conditions['{$conditionField}']) . \")\";\n }\n } else {\n \$sqlConditions[] = \"{$tableAlias}.{$conditionField} = \" . \$db->quote(\$conditions['{$conditionField}']);\n }\n}\n\n "); } $this->_addMethod("prepare{$this->_dataClass['camelCase']}Conditions", '', array(), "\n\n\$this->_prepare{$this->_dataClass['camelCase']}ConditionsCustomized(\$sqlConditions, \$conditions, \$fetchOptions);\n\nreturn \$this->getConditionsForClause(\$sqlConditions);\n\n "); $this->_addMethod("prepare{$this->_dataClass['camelCase']}FetchOptions", 'public', array('$fetchOptions' => 'array $fetchOptions = array()'), "\n\n\$selectFields = '';\n\$joinTables = '';\n\n\$this->_prepare{$this->_dataClass['camelCase']}FetchOptionsCustomized(\$selectFields, \$joinTables, \$fetchOptions);\n\nreturn array(\n 'selectFields' => \$selectFields,\n 'joinTables' => \$joinTables\n);\n\n "); $orderChoices = array(); if (isset($this->_dataClass['fields']['display_order'])) { if (isset($this->_dataClass['fields']['lft'])) { $orderChoices['display_order'] = sprintf('%s.lft', $tableAlias); } else { $orderChoices['display_order'] = sprintf('%s.display_order', $tableAlias); } } $orderChoices = DevHelper_Generator_File::varExport($orderChoices); $this->_addMethod("prepare{$this->_dataClass['camelCase']}OrderOptions", 'public', array('$fetchOptions' => 'array $fetchOptions = array()', '$defaultOrderSql' => '$defaultOrderSql = \'\''), "\n\n\$choices = {$orderChoices};\n\n\$this->_prepare{$this->_dataClass['camelCase']}OrderOptionsCustomized(\$choices, \$fetchOptions);\n\nreturn \$this->getOrderByClause(\$choices, \$fetchOptions, \$defaultOrderSql);\n\n "); $this->_generateImageCode(); $this->_generatePhrasesCode(); $this->_generateOptionsCode(); $this->_generateParentCode(); return parent::_generate(); }
public function outputSelf() { $className = get_class($this); $dataClasses = DevHelper_Generator_File::varExport($this->_dataClasses); $dataPatches = DevHelper_Generator_File::varExport($this->_dataPatches); $exportPath = DevHelper_Generator_File::varExport($this->_exportPath); $exportIncludes = DevHelper_Generator_File::varExport($this->_exportIncludes); $exportExcludes = DevHelper_Generator_File::varExport($this->_exportExcludes); $exportAddOns = DevHelper_Generator_File::varExport($this->_exportAddOns); $exportStyles = DevHelper_Generator_File::varExport($this->_exportStyles); $options = DevHelper_Generator_File::varExport($this->_options); $contents = <<<EOF <?php class {$className} extends DevHelper_Config_Base { protected \$_dataClasses = {$dataClasses}; protected \$_dataPatches = {$dataPatches}; protected \$_exportPath = {$exportPath}; protected \$_exportIncludes = {$exportIncludes}; protected \$_exportExcludes = {$exportExcludes}; protected \$_exportAddOns = {$exportAddOns}; protected \$_exportStyles = {$exportStyles}; protected \$_options = {$options}; /** * Return false to trigger the upgrade! **/ protected function _upgrade() { return true; // remove this line to trigger update /* \$this->addDataClass( 'name_here', array( // fields 'field_here' => array( 'type' => 'type_here', // 'length' => 'length_here', // 'required' => true, // 'allowedValues' => array('value_1', 'value_2'), // 'default' => 0, // 'autoIncrement' => true, ), // other fields go here ), array('primary_key_1', 'primary_key_2'), // or 'primary_key', both are okie array( // indeces array( 'fields' => array('field_1', 'field_2'), 'type' => 'NORMAL', // UNIQUE or FULLTEXT ), ), ); */ } } EOF; return $contents; }
public static function generate(array $addOn, DevHelper_Config_Base $config, array $dataClass, array $info) { $className = self::getClassName($addOn, $config, $dataClass); $variableName = strtolower(substr($dataClass['camelCase'], 0, 1)) . substr($dataClass['camelCase'], 1); $modelClassName = DevHelper_Generator_Code_Model::getClassName($addOn, $config, $dataClass); $commentAutoGeneratedStart = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_START; $commentAutoGeneratedEnd = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_END; $dataWriterClassName = DevHelper_Generator_Code_DataWriter::getClassName($addOn, $config, $dataClass); $otherDataClassStuff = ''; $filterParams = array(); foreach ($dataClass['fields'] as $field) { if ($field['name'] != $dataClass['id_field']) { $filterParams[$field['name']] = $field['type']; } } $filterParams = DevHelper_Generator_File::varExport($filterParams, 2); $templateList = DevHelper_Generator_Template::getTemplateTitle($addOn, $config, $dataClass, $dataClass['name'] . '_list'); $templateEdit = DevHelper_Generator_Template::getTemplateTitle($addOn, $config, $dataClass, $dataClass['name'] . '_edit'); $templateDelete = DevHelper_Generator_Template::getTemplateTitle($addOn, $config, $dataClass, $dataClass['name'] . '_delete'); $viewListClassName = self::getViewClassName($addOn, $config, $dataClass, 'list'); $viewEditClassName = self::getViewClassName($addOn, $config, $dataClass, 'edit'); $viewDeleteClassName = self::getViewClassName($addOn, $config, $dataClass, 'delete'); // create the phrases $phraseClassName = DevHelper_Generator_Phrase::getPhraseName($addOn, $config, $dataClass, $dataClass['name']); $phraseAdd = DevHelper_Generator_Phrase::getPhraseName($addOn, $config, $dataClass, $dataClass['name'] . '_add'); $phraseEdit = DevHelper_Generator_Phrase::getPhraseName($addOn, $config, $dataClass, $dataClass['name'] . '_edit'); $phraseDelete = DevHelper_Generator_Phrase::getPhraseName($addOn, $config, $dataClass, $dataClass['name'] . '_delete'); $phraseSave = DevHelper_Generator_Phrase::getPhraseName($addOn, $config, $dataClass, $dataClass['name'] . '_save'); $phraseConfirmDeletion = DevHelper_Generator_Phrase::getPhraseName($addOn, $config, $dataClass, $dataClass['name'] . '_confirm_deletion'); $phrasePleaseConfirm = DevHelper_Generator_Phrase::getPhraseName($addOn, $config, $dataClass, $dataClass['name'] . '_please_confirm'); $phraseNotFound = DevHelper_Generator_Phrase::getPhraseName($addOn, $config, $dataClass, $dataClass['name'] . '_not_found'); $phraseNoResults = DevHelper_Generator_Phrase::getPhraseName($addOn, $config, $dataClass, $dataClass['name'] . '_no_results'); DevHelper_Generator_Phrase::generatePhrase($addOn, $phraseClassName, $dataClass['camelCaseWSpace']); DevHelper_Generator_Phrase::generatePhrase($addOn, $phraseAdd, 'Add New ' . $dataClass['camelCaseWSpace']); DevHelper_Generator_Phrase::generatePhrase($addOn, $phraseEdit, 'Edit ' . $dataClass['camelCaseWSpace']); DevHelper_Generator_Phrase::generatePhrase($addOn, $phraseDelete, 'Delete ' . $dataClass['camelCaseWSpace']); DevHelper_Generator_Phrase::generatePhrase($addOn, $phraseSave, 'Save ' . $dataClass['camelCaseWSpace']); DevHelper_Generator_Phrase::generatePhrase($addOn, $phraseConfirmDeletion, 'Confirm Deletion of ' . $dataClass['camelCaseWSpace']); DevHelper_Generator_Phrase::generatePhrase($addOn, $phrasePleaseConfirm, 'Please confirm that you want to delete the following ' . $dataClass['camelCaseWSpace']); DevHelper_Generator_Phrase::generatePhrase($addOn, $phraseNotFound, 'The requested ' . $dataClass['camelCaseWSpace'] . ' could not be found'); DevHelper_Generator_Phrase::generatePhrase($addOn, $phraseNoResults, 'No clues of ' . $dataClass['camelCaseWSpace'] . ' at this moment...'); // finished creating pharses // create the templates $templateListTemplate = <<<EOF <xen:title>{xen:phrase {$phraseClassName}}</xen:title> <xen:topctrl> \t<a href="{xen:adminlink '{$info['routePrefix']}/add'}" class="button" accesskey="a">+ {xen:phrase {$phraseAdd}}</a> </xen:topctrl> <xen:require css="filter_list.css" /> <xen:require js="js/xenforo/filter_list.js" /> <xen:form action="{xen:adminlink '{$info['routePrefix']}'}" class="section"> \t<xen:if is="{\$all{$dataClass['camelCase']}}"> \t\t<h2 class="subHeading"> \t\t\t<link rel="xenforo_template" type="text/html" href="filter_list_controls.html" /> \t\t\t{xen:phrase {$phraseClassName}} \t\t</h2> \t \t\t<ol class="FilterList Scrollable"> \t\t\t<xen:foreach loop="\$all{$dataClass['camelCase']}" value="\${$variableName}"> \t\t\t\t<xen:listitem \t\t\t\t\tid="{\${$variableName}.{$dataClass['id_field']}}" \t\t\t\t\thref="{xen:adminlink '{$info['routePrefix']}/edit', \${$variableName}}" \t\t\t\t\tlabel="{\${$variableName}.{$dataClass['title_field']}}" \t\t\t\t\tdelete="{xen:adminlink '{$info['routePrefix']}/delete', \${$variableName}}" /> \t\t\t</xen:foreach> \t\t</ol> \t \t\t<p class="sectionFooter">{xen:phrase showing_x_of_y_items, 'count=<span class="FilterListCount">{xen:count \$all{$dataClass['camelCase']}}</span>', 'total={xen:count \$all{$dataClass['camelCase']}}'}</p> \t<xen:else /> \t\t<div class="noResults">{xen:phrase {$phraseNoResults}}</div> \t</xen:if> </xen:form> EOF; DevHelper_Generator_Template::generateAdminTemplate($addOn, $templateList, $templateListTemplate); // finished template_list $templateEditFields = ''; foreach ($dataClass['fields'] as $field) { if ($field['name'] == $dataClass['id_field']) { continue; } if ($field['name'] == $dataClass['title_field']) { $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($addOn, $config, $dataClass, $field['name']); $templateEditFields .= <<<EOF \t<xen:textboxunit label="{xen:phrase {$fieldPhraseName}}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}" data-liveTitleTemplate="{xen:if {\${$variableName}.{$dataClass['id_field']}}, \t\t'{xen:phrase {$phraseEdit}}: <em>%s</em>', \t\t'{xen:phrase {$phraseAdd}}: <em>%s</em>'}" /> EOF; continue; } if (substr($field['name'], -3) == '_id') { // link to another dataClass? $other = substr($field['name'], 0, -3); if ($config->checkDataClassExists($other)) { // yeah! $otherDataClass = $config->getDataClass($other); $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($addOn, $config, $otherDataClass, $otherDataClass['name']); $templateEditFields .= <<<EOF \t<xen:selectunit label="{xen:phrase {$fieldPhraseName}}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}"> \t\t<xen:option value=""> </xen:option> \t\t<xen:options source="\$all{$otherDataClass['camelCase']}" /> \t</xen:selectunit> EOF; $otherDataClassModelClassName = DevHelper_Generator_Code_Model::getClassName($addOn, $config, $otherDataClass); $otherDataClassStuff .= <<<EOF 'all{$otherDataClass['camelCase']}' => \$this->getModelFromCache('{$otherDataClassModelClassName}')->getList(), EOF; continue; } } // special case with display_order if ($field['name'] == 'display_order') { $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($addOn, $config, $dataClass, $field['name']); $templateEditFields .= <<<EOF \t<xen:spinboxunit label="{xen:phrase {$fieldPhraseName}}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}" /> EOF; continue; } $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($addOn, $config, $dataClass, $field['name']); $extra = ''; if ($field['type'] == XenForo_DataWriter::TYPE_STRING and (empty($field['length']) or $field['length'] > 255)) { $extra .= ' rows="5"'; } $templateEditFields .= <<<EOF \t<xen:textboxunit label="{xen:phrase {$fieldPhraseName}}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}" {$extra}/> EOF; } $templateEditTemplate = <<<EOF <xen:title>{xen:if '{\${$variableName}.{$dataClass['id_field']}}', '{xen:phrase {$phraseEdit}}', '{xen:phrase {$phraseAdd}}'}</xen:title> <xen:form action="{xen:adminlink '{$info['routePrefix']}/save'}" class="AutoValidator" data-redirect="yes"> \t{$templateEditFields} \t<xen:submitunit save="{xen:phrase {$phraseSave}}"> \t\t<input type="button" name="delete" value="{xen:phrase {$phraseDelete}}" \t\t\taccesskey="d" class="button OverlayTrigger" \t\t\tdata-href="{xen:adminlink '{$info['routePrefix']}/delete', \${$variableName}}" \t\t\t{xen:if '!{\${$variableName}.{$dataClass['id_field']}}', 'style="display: none"'} \t\t/> \t</xen:submitunit> \t \t<input type="hidden" name="{$dataClass['id_field']}" value="{\${$variableName}.{$dataClass['id_field']}}" /> </xen:form> EOF; DevHelper_Generator_Template::generateAdminTemplate($addOn, $templateEdit, $templateEditTemplate); // finished template_edit $templateDeleteTemplate = <<<EOF <xen:title>{xen:phrase {$phraseConfirmDeletion}}: {\${$variableName}.{$dataClass['title_field']}}</xen:title> <xen:h1>{xen:phrase {$phraseConfirmDeletion}}</xen:h1> <xen:navigation> \t<xen:breadcrumb href="{xen:adminlink '{$info['routePrefix']}/edit', \${$variableName}}">{\${$variableName}.{$dataClass['title_field']}}</xen:breadcrumb> </xen:navigation> <xen:require css="delete_confirmation.css" /> <xen:form action="{xen:adminlink '{$info['routePrefix']}/delete', \${$variableName}}" class="deleteConfirmForm formOverlay"> \t<p>{xen:phrase {$phrasePleaseConfirm}}:</p> \t<strong><a href="{xen:adminlink '{$info['routePrefix']}/edit', \${$variableName}}">{\${$variableName}.{$dataClass['title_field']}}</a></strong> \t<xen:submitunit save="{xen:phrase {$phraseDelete}}" /> \t \t<input type="hidden" name="_xfConfirm" value="1" /> </xen:form> EOF; DevHelper_Generator_Template::generateAdminTemplate($addOn, $templateDelete, $templateDeleteTemplate); // finished creating our templates $contents = <<<EOF <?php class {$info['controller']} extends XenForo_ControllerAdmin_Abstract { \t{$commentAutoGeneratedStart} \tpublic function actionIndex() { \t\t\$model = \$this->_get{$dataClass['camelCase']}Model(); \t\t\$all{$dataClass['camelCase']} = \$model->getAll{$dataClass['camelCase']}(); \t\t \t\t\$viewParams = array( \t\t\t'all{$dataClass['camelCase']}' => \$all{$dataClass['camelCase']} \t\t); \t\t \t\treturn \$this->responseView('{$viewListClassName}', '{$templateList}', \$viewParams); \t} \t \tpublic function actionAdd() { \t\t\$viewParams = array( \t\t\t'{$variableName}' => array(), \t\t\t{$otherDataClassStuff} \t\t); \t\t \t\treturn \$this->responseView('{$viewEditClassName}', '{$templateEdit}', \$viewParams); \t} \t \tpublic function actionEdit() { \t\t\$id = \$this->_input->filterSingle('{$dataClass['id_field']}', XenForo_Input::UINT); \t\t\${$variableName} = \$this->_get{$dataClass['camelCase']}OrError(\$id); \t\t \t\t\$viewParams = array( \t\t\t'{$variableName}' => \${$variableName}, \t\t\t{$otherDataClassStuff} \t\t); \t\t \t\treturn \$this->responseView('{$viewEditClassName}', '{$templateEdit}', \$viewParams); \t} \t \tpublic function actionSave() { \t\t\$this->_assertPostOnly(); \t\t \t\t\$id = \$this->_input->filterSingle('{$dataClass['id_field']}', XenForo_Input::UINT); \t\t\$dwInput = \$this->_input->filter({$filterParams}); \t\t \t\t\$dw = \$this->_get{$dataClass['camelCase']}DataWriter(); \t\tif (\$id) { \t\t\t\$dw->setExistingData(\$id); \t\t} \t\t\$dw->bulkSet(\$dwInput); \t\t\$dw->save(); \t\treturn \$this->responseRedirect( \t\t\tXenForo_ControllerResponse_Redirect::SUCCESS, \t\t\tXenForo_Link::buildAdminLink('{$info['routePrefix']}') \t\t); \t} \t \tpublic function actionDelete() { \t\t\$id = \$this->_input->filterSingle('{$dataClass['id_field']}', XenForo_Input::UINT); \t\t\${$variableName} = \$this->_get{$dataClass['camelCase']}OrError(\$id); \t\t \t\tif (\$this->isConfirmedPost()) { \t\t\t\$dw = \$this->_get{$dataClass['camelCase']}DataWriter(); \t\t\t\$dw->setExistingData(\$id); \t\t\t\$dw->delete(); \t\t\treturn \$this->responseRedirect( \t\t\t\tXenForo_ControllerResponse_Redirect::SUCCESS, \t\t\t\tXenForo_Link::buildAdminLink('{$info['routePrefix']}') \t\t\t); \t\t} else { \t\t\t\$viewParams = array( \t\t\t\t'{$variableName}' => \${$variableName} \t\t\t); \t\t\treturn \$this->responseView('{$viewDeleteClassName}', '{$templateDelete}', \$viewParams); \t\t} \t} \t \t \tprotected function _get{$dataClass['camelCase']}OrError(\$id, array \$fetchOptions = array()) { \t\t\$info = \$this->_get{$dataClass['camelCase']}Model()->get{$dataClass['camelCase']}ById(\$id, \$fetchOptions); \t\t \t\tif (empty(\$info)) { \t\t\tthrow \$this->responseException(\$this->responseError(new XenForo_Phrase('{$phraseNotFound}'), 404)); \t\t} \t\t \t\treturn \$info; \t} \t \tprotected function _get{$dataClass['camelCase']}Model() { \t\treturn \$this->getModelFromCache('{$modelClassName}'); \t} \t \tprotected function _get{$dataClass['camelCase']}DataWriter() { \t\treturn XenForo_DataWriter::create('{$dataWriterClassName}'); \t} \t{$commentAutoGeneratedEnd} } EOF; return array($className, $contents); }
protected function _generateTemplates($variableName, $variableNamePlural, $imageField) { if (count($this->_dataClass['primaryKey']) > 1) { throw new XenForo_Exception(sprintf('Cannot generate %s: too many fields in primary key', $this->_info['controller'])); } $idField = reset($this->_dataClass['primaryKey']); $dataTitle = "\${$variableName}" . (empty($this->_dataClass['title_field']) ? ".{$idField}" : (is_array($this->_dataClass['title_field']) ? ".{$this->_dataClass['title_field'][0]}.{$this->_dataClass['title_field'][1]}" : ".{$this->_dataClass['title_field']}")); // create the phrases $phraseClassName = $this->_getPhraseName(''); $phrasePlural = $this->_getPhrasePluralName(); $phraseAdd = $this->_getPhraseName('_add'); $phraseEdit = $this->_getPhraseName('_edit'); $phraseDelete = $this->_getPhraseName('_delete'); $phraseSave = $this->_getPhraseName('_save'); $phraseConfirmDeletion = $this->_getPhraseName('_confirm_deletion'); $phrasePleaseConfirm = $this->_getPhraseName('_please_confirm'); $phraseNotFound = $this->_getPhraseName('_not_found'); $phraseNoResults = $this->_getPhraseName('_no_results'); $this->_generatePhrase($phraseClassName, $this->_dataClass['camelCaseWSpace']); if (!empty($this->_dataClass['camelCasePluralWSpace'])) { $this->_generatePhrase($phrasePlural, $this->_dataClass['camelCasePluralWSpace']); } else { $this->_generatePhrase($phrasePlural, $this->_dataClass['camelCaseWSpace'] . ' (Plural)'); } $this->_generatePhrase($phraseAdd, 'Add New ' . $this->_dataClass['camelCaseWSpace']); $this->_generatePhrase($phraseEdit, 'Edit ' . $this->_dataClass['camelCaseWSpace']); $this->_generatePhrase($phraseDelete, 'Delete ' . $this->_dataClass['camelCaseWSpace']); $this->_generatePhrase($phraseSave, 'Save ' . $this->_dataClass['camelCaseWSpace']); $this->_generatePhrase($phraseConfirmDeletion, 'Confirm Deletion of ' . $this->_dataClass['camelCaseWSpace']); $this->_generatePhrase($phrasePleaseConfirm, 'Please confirm that you want to delete the following ' . strtolower($this->_dataClass['camelCaseWSpace'])); $this->_generatePhrase($phraseNotFound, 'The requested ' . strtolower($this->_dataClass['camelCaseWSpace']) . ' could not be found'); $this->_generatePhrase($phraseNoResults, 'No ' . strtolower($this->_dataClass['camelCaseWSpace']) . ' could be found...'); // finished creating pharses $templateList = $this->_getTemplateTitle('_list'); $templateListItems = $this->_getTemplateTitle('_list_items'); $templateEdit = $this->_getTemplateTitle('_edit'); $templateDelete = $this->_getTemplateTitle('_delete'); // create the templates $listItemExtras = ''; if ($imageField !== false) { $listItemExtras .= <<<EOF \t\t<xen:beforelabel> \t\t\t{xen:if '{\${$variableName}.images.s}', '<img src="{\${$variableName}.images.s}" style="float: left; height: 30px;" />'} \t\t</xen:beforelabel> EOF; } $templateListItemsTemplate = <<<EOF <xen:foreach loop="\${$variableNamePlural}" value="\${$variableName}"> \t<xen:listitem \t\tid="{\${$variableName}.{$idField}}" \t\thref="{xen:adminlink '{$this->_info['routePrefix']}/edit', \${$variableName}}" \t\tdelete="{xen:adminlink '{$this->_info['routePrefix']}/delete', \${$variableName}}"> \t\t<xen:label>{{$dataTitle}}</xen:label>{$listItemExtras} \t</xen:listitem> </xen:foreach> EOF; $this->_generateAdminTemplate($templateListItems, $templateListItemsTemplate); // finished template_list_items $templateListTemplate = <<<EOF <xen:title>{xen:phrase {$phrasePlural}}</xen:title> <xen:topctrl> \t<a href="{xen:adminlink '{$this->_info['routePrefix']}/add'}" class="button" accesskey="a">+ {xen:phrase {$phraseAdd}}</a> </xen:topctrl> <xen:require css="filter_list.css" /> <xen:require js="js/xenforo/filter_list.js" /> <xen:form action="{xen:adminlink '{$this->_info['routePrefix']}'}" class="section"> \t<xen:if is="{\${$variableNamePlural}}"> \t\t<h2 class="subHeading"> \t\t\t<xen:include template="filter_list_controls" /> \t\t\t{xen:phrase {$phrasePlural}} \t\t</h2> \t\t<ol class="FilterList Scrollable"> \t\t\t<xen:include template="{$templateListItems}" /> \t\t</ol> \t\t<p class="sectionFooter">{xen:phrase showing_x_of_y_items, 'count=<span class="FilterListCount">{xen:count \${$variableNamePlural}}</span>', 'total={xen:count \${$variableNamePlural}}'}</p> \t<xen:else /> \t\t<div class="noResults">{xen:phrase {$phraseNoResults}}</div> \t</xen:if> </xen:form> EOF; $this->_generateAdminTemplate($templateList, $templateListTemplate); // finished template_list $templateEditFormExtra = 'class="AutoValidator" data-redirect="yes"'; $templateEditFields = ''; $extraViewParamsForTemplateEdit = array(); $filterParams = array(); if (!empty($this->_dataClass['phrases'])) { foreach ($this->_dataClass['phrases'] as $phraseType) { $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($this->_addOn, $this->_config, $this->_dataClass, $this->_dataClass['name'] . '_' . $phraseType); $templateEditFields .= <<<EOF \t<xen:textboxunit label="{xen:phrase {$fieldPhraseName}}:" name="_phrases[{$phraseType}]" value="{\${$variableName}.phrases.{$phraseType}}" /> EOF; } } foreach ($this->_dataClass['fields'] as $field) { if ($field['name'] == $idField) { continue; } if (empty($field['required'])) { // ignore non-required fields continue; } if ($field['name'] == $imageField) { // ignore image field continue; } // queue this field for validation $filterParams[$field['name']] = $field['type']; if ($field['name'] == $this->_dataClass['title_field']) { $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($this->_addOn, $this->_config, $this->_dataClass, $field['name']); $templateEditFields .= <<<EOF \t<xen:textboxunit label="{xen:phrase {$fieldPhraseName}}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}" data-liveTitleTemplate="{xen:if {\${$variableName}.{$idField}}, \t\t'{xen:phrase {$phraseEdit}}: <em>%s</em>', \t\t'{xen:phrase {$phraseAdd}}: <em>%s</em>'}" /> EOF; continue; } if (substr($field['name'], -3) == '_id') { // link to another dataClass? $other = substr($field['name'], 0, -3); if ($this->_config->checkDataClassExists($other)) { // yeah! $otherDataClass = $this->_config->getDataClass($other); $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($this->_addOn, $this->_config, $otherDataClass, $otherDataClass['name']); $templateEditFields .= <<<EOF \t<xen:selectunit label="{xen:phrase {$fieldPhraseName}}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}"> \t\t<xen:option value=""> </xen:option> \t\t<xen:options source="\$list{$otherDataClass['camelCase']}" /> \t</xen:selectunit> EOF; $otherDataClassModelClassName = DevHelper_Generator_Code_Model::getClassName($this->_addOn, $this->_config, $otherDataClass); $extraViewParamsForTemplateEdit["list{$otherDataClass['camelCase']}"] = "\$viewParams['list{$otherDataClass['camelCase']}'] = \$this->getModelFromCache('{$otherDataClassModelClassName}')->getList();"; continue; } elseif ($other === $this->_dataClass['name'] . '_parent') { // just a parent of this same class $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($this->_addOn, $this->_config, $this->_dataClass, $other); $templateEditFields .= <<<EOF \t<xen:selectunit label="{xen:phrase {$fieldPhraseName}}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}"> \t\t<xen:option value=""> </xen:option> \t\t<xen:options source="\$list{$this->_dataClass['camelCase']}" /> \t</xen:selectunit> EOF; $thisDataClassModelClassName = DevHelper_Generator_Code_Model::getClassName($this->_addOn, $this->_config, $this->_dataClass); $extraViewParamsForTemplateEdit["list{$this->_dataClass['camelCase']}"] = "\$viewParams['list{$this->_dataClass['camelCase']}'] = \$this->getModelFromCache('{$thisDataClassModelClassName}')->getList();"; continue; } } if ($field['name'] == 'display_order') { // special case with display_order $templateEditFields .= <<<EOF \t<xen:spinboxunit label="{xen:phrase display_order}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}" /> EOF; continue; } if ($field['type'] == 'string' && !empty($field['allowedValues'])) { // render field with enum type as a list of selections $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($this->_addOn, $this->_config, $this->_dataClass, $field['name']); $templateEditFields .= <<<EOF \t<xen:selectunit label="{xen:phrase {$fieldPhraseName}}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}"> \t\t<xen:option value=""> </xen:option> EOF; foreach ($field['allowedValues'] as $allowedValue) { $allowedValuePhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($this->_addOn, $this->_config, $this->_dataClass, $field['name'] . '_' . $allowedValue); $templateEditFields .= <<<EOF \t\t<xen:option value="{$allowedValue}">{xen:phrase {$allowedValuePhraseName}}</xen:option> EOF; } $templateEditFields .= <<<EOF \t</xen:selectunit> EOF; continue; } if ($field['type'] == 'uint' and substr($field['name'], 0, 3) === 'is_') { // special case with boolean fields $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($this->_addOn, $this->_config, $this->_dataClass, $field['name']); $templateEditFields .= <<<EOF \t<xen:checkboxunit label=""> \t\t<xen:option name="{$field['name']}" value="1" label="{xen:phrase {$fieldPhraseName}}" selected="{\${$variableName}.{$field['name']}}" /> \t</xen:checkboxunit> EOF; continue; } $fieldPhraseName = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($this->_addOn, $this->_config, $this->_dataClass, $field['name']); $extra = ''; if ($field['type'] == XenForo_DataWriter::TYPE_STRING and (empty($field['length']) or $field['length'] > 255)) { $extra .= ' rows="5"'; } $templateEditFields .= <<<EOF \t<xen:textboxunit label="{xen:phrase {$fieldPhraseName}}:" name="{$field['name']}" value="{\${$variableName}.{$field['name']}}" {$extra}/> EOF; } if ($imageField !== false) { $fieldPhraseImage = DevHelper_Generator_Phrase::generatePhraseAutoCamelCaseStyle($this->_addOn, $this->_config, $this->_dataClass, 'image'); $templateEditFormExtra = 'enctype="multipart/form-data"'; $templateEditFields .= <<<EOF \t<xen:uploadunit label="{xen:phrase {$fieldPhraseImage}}:" name="image" value=""> \t\t<div id="imageHtml"> \t\t\t<xen:if is="{\${$variableName}.images}"> \t\t\t\t<xen:foreach loop="\${$variableName}.images" key="\$imageSizeCode" value="\$image"> \t\t\t\t\t<img src="{\$image}" alt="{\$imageSizeCode}" title="{\$imageSizeCode}" /> \t\t\t\t</xen:foreach> \t\t\t</xen:if> \t\t</div> \t</xen:uploadunit> EOF; } $templateEditTemplate = <<<EOF <xen:title>{xen:if '{\${$variableName}.{$idField}}', '{xen:phrase {$phraseEdit}}', '{xen:phrase {$phraseAdd}}'}</xen:title> <xen:form action="{xen:adminlink '{$this->_info['routePrefix']}/save'}" {$templateEditFormExtra}> \t{$templateEditFields} \t<xen:submitunit save="{xen:phrase {$phraseSave}}"> \t\t<input type="button" name="delete" value="{xen:phrase {$phraseDelete}}" \t\t\taccesskey="d" class="button OverlayTrigger" \t\t\tdata-href="{xen:adminlink '{$this->_info['routePrefix']}/delete', \${$variableName}}" \t\t\t{xen:if '!{\${$variableName}.{$idField}}', 'style="display: none"'} \t\t/> \t</xen:submitunit> \t<input type="hidden" name="{$idField}" value="{\${$variableName}.{$idField}}" /> </xen:form> EOF; $this->_generateAdminTemplate($templateEdit, $templateEditTemplate); // add extra code for add, edit actions if (!empty($extraViewParamsForTemplateEdit)) { $this->_addMethod('actionAdd', 'public', array(), implode("\n", $extraViewParamsForTemplateEdit), '100'); $this->_addMethod('actionEdit', 'public', array(), implode("\n", $extraViewParamsForTemplateEdit), '100'); } // add input fields to action save if (!empty($this->_dataClass['phrases'])) { $phraseCode = "\$phrases = \$this->_input->filterSingle('_phrases', XenForo_Input::ARRAY_SIMPLE);\n"; foreach ($this->_dataClass['phrases'] as $phraseType) { $dataWriterClassName = DevHelper_Generator_Code_DataWriter::getClassName($this->_addOn, $this->_config, $this->_dataClass); $dataPhraseConstantName = DevHelper_Generator_Code_DataWriter::generateDataPhraseConstant($this->_addOn, $this->_config, $this->_dataClass, $phraseType); $phraseCode .= "if (isset(\$phrases['{$phraseType}']))\n{\n"; $phraseCode .= " \$dw->setExtraData({$dataWriterClassName}::{$dataPhraseConstantName}, \$phrases['{$phraseType}']);\n"; $phraseCode .= "}\n"; } $this->_addMethod('actionSave', 'public', array(), "\n\n// get phrases from input data\n{$phraseCode}\n\n ", '100'); } if (!empty($filterParams)) { $filterParamsExported = DevHelper_Generator_File::varExport($filterParams, 1); $this->_addMethod('actionSave', 'public', array(), "\n\n// get regular fields from input data\n\$dwInput = \$this->_input->filter({$filterParamsExported});\n\$dw->bulkSet(\$dwInput);\n\n ", '200'); } if ($imageField !== false) { // add image to action save $this->_addMethod('actionSave', 'public', array(), "\n\n// try to save the uploaded image if any\n\$image = XenForo_Upload::getUploadedFile('image');\nif (!empty(\$image)) {\n \$dw->setImage(\$image);\n}\n\n ", '300'); } // finished template_edit $templateDeleteTemplate = <<<EOF <xen:title>{xen:phrase {$phraseConfirmDeletion}}: {{$dataTitle}}</xen:title> <xen:h1>{xen:phrase {$phraseConfirmDeletion}}</xen:h1> <xen:navigation> \t<xen:breadcrumb href="{xen:adminlink '{$this->_info['routePrefix']}/edit', \${$variableName}}">{{$dataTitle}}</xen:breadcrumb> </xen:navigation> <xen:require css="delete_confirmation.css" /> <xen:form action="{xen:adminlink '{$this->_info['routePrefix']}/delete', \${$variableName}}" class="deleteConfirmForm formOverlay"> \t<p>{xen:phrase {$phrasePleaseConfirm}}:</p> \t<strong><a href="{xen:adminlink '{$this->_info['routePrefix']}/edit', \${$variableName}}">{{$dataTitle}}</a></strong> \t<xen:submitunit save="{xen:phrase {$phraseDelete}}" /> \t<input type="hidden" name="_xfConfirm" value="1" /> </xen:form> EOF; $this->_generateAdminTemplate($templateDelete, $templateDeleteTemplate); // finished creating our templates return array($templateList, $templateEdit, $templateDelete); }
public static function generate(array $addOn, DevHelper_Config_Base $config) { $className = self::getClassName($addOn, $config); $tables = array(); $dataClasses = $config->getDataClasses(); foreach ($dataClasses as $dataClass) { $table = array(); $table['createQuery'] = DevHelper_Generator_Db::createTable($config, $dataClass); $table['dropQuery'] = false; $tables[$dataClass['name']] = $table; } $tables = DevHelper_Generator_File::varExport($tables); $patches = array(); $dataPatches = $config->getDataPatches(); foreach ($dataPatches as $table => $tablePatches) { foreach ($tablePatches as $dataPatch) { $patch = array(); $patch['table'] = $table; $patch['field'] = $dataPatch['name']; $patch['showColumnsQuery'] = DevHelper_Generator_Db::showColumns($config, $table, $dataPatch); $patch['alterTableAddColumnQuery'] = DevHelper_Generator_Db::alterTableAddColumn($config, $table, $dataPatch); $patch['alterTableDropColumnQuery'] = false; $patches[] = $patch; } } $patches = DevHelper_Generator_File::varExport($patches); $commentAutoGeneratedStart = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_START; $commentAutoGeneratedEnd = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_END; $contents = <<<EOF <?php class {$className} { \t{$commentAutoGeneratedStart} \tprotected static \$_tables = {$tables}; \tprotected static \$_patches = {$patches}; \tpublic static function install() { \t\t\$db = XenForo_Application::get('db'); \t\tforeach (self::\$_tables as \$table) { \t\t\t\$db->query(\$table['createQuery']); \t\t} \t\t \t\tforeach (self::\$_patches as \$patch) { \t\t\t\$existed = \$db->fetchOne(\$patch['showColumnsQuery']); \t\t\tif (empty(\$existed)) { \t\t\t\t\$db->query(\$patch['alterTableAddColumnQuery']); \t\t\t} \t\t} \t} \t \tpublic static function uninstall() { \t\t// TODO \t} \t{$commentAutoGeneratedStart} \t } EOF; return array($className, $contents); }
public function outputSelf() { $className = get_class($this); foreach ($this->_dataClasses as $dataClass) { if (empty($dataClass['id_field'])) { throw new XenForo_Exception("{$dataClass['name']} does not have an id_field.", true); } } $dataClasses = DevHelper_Generator_File::varExport($this->_dataClasses); $dataPatches = DevHelper_Generator_File::varExport($this->_dataPatches); $exportPath = DevHelper_Generator_File::varExport($this->_exportPath); $contents = <<<EOF <?php class {$className} extends DevHelper_Config_Base { \tprotected \$_dataClasses = {$dataClasses}; \tprotected \$_dataPatches = {$dataPatches}; \tprotected \$_exportPath = {$exportPath}; \t \t/** \t * Return false to trigger the upgrade! \t * common use methods: \t * \tpublic function addDataClass(\$name, \$fields = array(), \$primaryKey = false, \$indeces = array()) \t *\tpublic function addDataPatch(\$table, array \$field) \t *\tpublic function setExportPath(\$path) \t**/ \tprotected function _upgrade() { \t\treturn true; // remove this line to trigger update \t\t \t\t/* \t\t\$this->addDataClass( \t\t\t'name_here', \t\t\tarray( // fields \t\t\t\t'field_here' => array( \t\t\t\t\t'type' => 'type_here', \t\t\t\t\t// 'length' => 'length_here', \t\t\t\t\t// 'required' => true, \t\t\t\t\t// 'allowedValues' => array('value_1', 'value_2'), \t\t\t\t), \t\t\t\t// other fields go here \t\t\t), \t\t\t'primary_key_field_here', \t\t\tarray( // indeces \t\t\t\tarray( \t\t\t\t\t'fields' => array('field_1', 'field_2'), \t\t\t\t\t'type' => 'NORMAL', // UNIQUE or FULLTEXT \t\t\t\t), \t\t\t), \t\t); \t\t*/ \t} } EOF; return $contents; }
public static function generate(array $addOn, DevHelper_Config_Base $config, array $dataClass) { $className = self::getClassName($addOn, $config, $dataClass); $tableName = DevHelper_Generator_Db::getTableName($config, $dataClass['name']); $commentAutoGeneratedStart = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_START; $commentAutoGeneratedEnd = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_END; $intFields = DevHelper_Generator_File::varExport(DevHelper_Generator_Db::getIntFields($dataClass['fields'])); $contents = <<<EOF <?php class {$className} extends XenForo_Model { \t{$commentAutoGeneratedStart} \tpublic function getList(array \$conditions = array(), array \$fetchOptions = array()) { \t\t\$data = \$this->getAll{$dataClass['camelCase']}(\$conditions, \$fetchOptions); \t\t\$list = array(); \t\t \t\tforeach (\$data as \$id => \$row) { \t\t\t\$list[\$id] = \$row['{$dataClass['title_field']}']; \t\t} \t\t \t\treturn \$list; \t} \tpublic function get{$dataClass['camelCase']}ById(\$id, array \$fetchOptions = array()) { \t\t\$data = \$this->getAll{$dataClass['camelCase']}(array ('{$dataClass['id_field']}' => \$id), \$fetchOptions); \t\t \t\treturn reset(\$data); \t} \t \tpublic function getAll{$dataClass['camelCase']}(array \$conditions = array(), array \$fetchOptions = array()) { \t\t\$whereConditions = \$this->prepare{$dataClass['camelCase']}Conditions(\$conditions, \$fetchOptions); \t\t\$orderClause = \$this->prepare{$dataClass['camelCase']}OrderOptions(\$fetchOptions); \t\t\$joinOptions = \$this->prepare{$dataClass['camelCase']}FetchOptions(\$fetchOptions); \t\t\$limitOptions = \$this->prepareLimitFetchOptions(\$fetchOptions); \t\treturn \$this->fetchAllKeyed(\$this->limitQueryResults(" \t\t\t\tSELECT {$dataClass['name']}.* \t\t\t\t\t\$joinOptions[selectFields] \t\t\t\tFROM `{$tableName}` AS {$dataClass['name']} \t\t\t\t\t\$joinOptions[joinTables] \t\t\t\tWHERE \$whereConditions \t\t\t\t\t\$orderClause \t\t\t", \$limitOptions['limit'], \$limitOptions['offset'] \t\t), '{$dataClass['id_field']}'); \t} \t\t \tpublic function countAll{$dataClass['camelCase']}(array \$conditions = array(), array \$fetchOptions = array()) { \t\t\$whereConditions = \$this->prepare{$dataClass['camelCase']}Conditions(\$conditions, \$fetchOptions); \t\t\$orderClause = \$this->prepare{$dataClass['camelCase']}OrderOptions(\$fetchOptions); \t\t\$joinOptions = \$this->prepare{$dataClass['camelCase']}FetchOptions(\$fetchOptions); \t\t\$limitOptions = \$this->prepareLimitFetchOptions(\$fetchOptions); \t\treturn \$this->_getDb()->fetchOne(" \t\t\tSELECT COUNT(*) \t\t\tFROM `{$tableName}` AS {$dataClass['name']} \t\t\t\t\$joinOptions[joinTables] \t\t\tWHERE \$whereConditions \t\t"); \t} \t \tpublic function prepare{$dataClass['camelCase']}Conditions(array \$conditions, array &\$fetchOptions) { \t\t\$sqlConditions = array(); \t\t\$db = \$this->_getDb(); \t\t \t\tforeach ({$intFields} as \$intField) { \t\t\tif (!isset(\$conditions[\$intField])) continue; \t\t\t \t\t\tif (is_array(\$conditions[\$intField])) { \t\t\t\t\$sqlConditions[] = "{$dataClass['name']}.\$intField IN (" . \$db->quote(\$conditions[\$intField]) . ")"; \t\t\t} else { \t\t\t\t\$sqlConditions[] = "{$dataClass['name']}.\$intField = " . \$db->quote(\$conditions[\$intField]); \t\t\t} \t\t} \t\t \t\treturn \$this->getConditionsForClause(\$sqlConditions); \t} \t \tpublic function prepare{$dataClass['camelCase']}FetchOptions(array \$fetchOptions) { \t\t\$selectFields = ''; \t\t\$joinTables = ''; \t\treturn array( \t\t\t'selectFields' => \$selectFields, \t\t\t'joinTables' => \$joinTables \t\t); \t} \t \tpublic function prepare{$dataClass['camelCase']}OrderOptions(array &\$fetchOptions, \$defaultOrderSql = '') { \t\t\$choices = array( \t\t\t \t\t); \t\treturn \$this->getOrderByClause(\$choices, \$fetchOptions, \$defaultOrderSql); \t} \t{$commentAutoGeneratedStart} } EOF; return array($className, $contents); }
public static function generate(array $addOn, DevHelper_Config_Base $config) { $className = self::getClassName($addOn, $config); $tables = array(); $dataClasses = $config->getDataClasses(); foreach ($dataClasses as $dataClass) { $table = array(); $table['createQuery'] = DevHelper_Generator_Db::createTable($config, $dataClass); $table['dropQuery'] = DevHelper_Generator_Db::dropTable($config, $dataClass); $tables[$dataClass['name']] = $table; } $tables = DevHelper_Generator_File::varExport($tables); $patches = array(); $dataPatches = $config->getDataPatches(); foreach ($dataPatches as $table => $tablePatches) { foreach ($tablePatches as $dataPatch) { $patch = array(); $patch['table'] = $table; $patch['tableCheckQuery'] = DevHelper_Generator_Db::showTables($config, $table); if (!empty($dataPatch['index'])) { $patch['index'] = $dataPatch['name']; $patch['checkQuery'] = DevHelper_Generator_Db::showIndexes($config, $table, $dataPatch); $patch['addQuery'] = DevHelper_Generator_Db::alterTableAddIndex($config, $table, $dataPatch); $patch['dropQuery'] = DevHelper_Generator_Db::alterTableDropIndex($config, $table, $dataPatch); } else { $patch['field'] = $dataPatch['name']; $patch['checkQuery'] = DevHelper_Generator_Db::showColumns($config, $table, $dataPatch); $patch['addQuery'] = DevHelper_Generator_Db::alterTableAddColumn($config, $table, $dataPatch); $patch['dropQuery'] = DevHelper_Generator_Db::alterTableDropColumn($config, $table, $dataPatch); } $patches[] = $patch; } } $patches = DevHelper_Generator_File::varExport($patches); $commentAutoGeneratedStart = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_START; $commentAutoGeneratedEnd = DevHelper_Generator_File::COMMENT_AUTO_GENERATED_END; $contents = <<<EOF <?php class {$className} { {$commentAutoGeneratedStart} protected static \$_tables = {$tables}; protected static \$_patches = {$patches}; public static function install(\$existingAddOn, \$addOnData) { \$db = XenForo_Application::get('db'); foreach (self::\$_tables as \$table) { \$db->query(\$table['createQuery']); } foreach (self::\$_patches as \$patch) { \$tableExisted = \$db->fetchOne(\$patch['tableCheckQuery']); if (empty(\$tableExisted)) { continue; } \$existed = \$db->fetchOne(\$patch['checkQuery']); if (empty(\$existed)) { \$db->query(\$patch['addQuery']); } } self::installCustomized(\$existingAddOn, \$addOnData); } public static function uninstall() { \$db = XenForo_Application::get('db'); foreach (self::\$_patches as \$patch) { \$tableExisted = \$db->fetchOne(\$patch['tableCheckQuery']); if (empty(\$tableExisted)) { continue; } \$existed = \$db->fetchOne(\$patch['checkQuery']); if (!empty(\$existed)) { \$db->query(\$patch['dropQuery']); } } foreach (self::\$_tables as \$table) { \$db->query(\$table['dropQuery']); } self::uninstallCustomized(); } {$commentAutoGeneratedEnd} public static function installCustomized(\$existingAddOn, \$addOnData) { // customized install script goes here } public static function uninstallCustomized() { // customized uninstall script goes here } } EOF; return array($className, $contents); }