protected function _generateImageCode() { $imageField = DevHelper_Generator_Db::getImageField($this->_dataClass['fields']); if ($imageField === false) { // no image field... return ''; } if (count($this->_dataClass['primaryKey']) > 1) { throw new XenForo_Exception(sprintf('Cannot generate image code for %s: too many fields in primary key', $this->_getClassName())); } $idField = reset($this->_dataClass['primaryKey']); $getFunctionName = self::generateGetDataFunctionName($this->_addOn, $this->_config, $this->_dataClass); $variableName = self::getVariableName($this->_addOn, $this->_config, $this->_dataClass); $variableNamePlural = self::getVariableNamePlural($this->_addOn, $this->_config, $this->_dataClass); $dwClassName = DevHelper_Generator_Code_DataWriter::getClassName($this->_addOn, $this->_config, $this->_dataClass); $configPrefix = $this->_config->getPrefix(); $imagePath = "{$configPrefix}/{$this->_dataClass['camelCase']}"; $imagePath = strtolower($imagePath); $this->_addMethod($getFunctionName, '', array(), "\n\n// build image urls and make them ready for all the records\n\$imageSizes = XenForo_DataWriter::create('{$dwClassName}')->getImageSizes();\nforeach (\${$variableNamePlural} as &\${$variableName}) {\n \${$variableName}['images'] = array();\n if (!empty(\${$variableName}['{$imageField}'])) {\n foreach (\$imageSizes as \$imageSizeCode => \$imageSize) {\n \${$variableName}['images'][\$imageSizeCode] = \$this->getImageUrl(\${$variableName}, \$imageSizeCode);\n }\n }\n}\n\n ", '100'); $this->_addMethod('getImageFilePath', 'public static', array(sprintf('$%s', $variableName) => sprintf('array $%s', $variableName), '$size' => '$size = \'l\''), "\n\n\$internal = self::_getImageInternal(\${$variableName}, \$size);\n\nif (!empty(\$internal)) {\n return XenForo_Helper_File::getExternalDataPath() . \$internal;\n} else {\n return '';\n}\n\n "); $this->_addMethod('getImageUrl', 'public static', array(sprintf('$%s', $variableName) => sprintf('array $%s', $variableName), '$size' => '$size = \'l\''), "\n\n\$internal = self::_getImageInternal(\${$variableName}, \$size);\n\nif (!empty(\$internal)) {\n return XenForo_Application::\$externalDataUrl . \$internal;\n} else {\n return '';\n}\n\n "); $this->_addMethod('_getImageInternal', 'protected static', array(sprintf('$%s', $variableName) => sprintf('array $%s', $variableName), '$size'), "\n\nif (empty(\${$variableName}['{$idField}']) OR empty(\${$variableName}['{$imageField}'])) {\n return '';\n}\n\nreturn '/{$imagePath}/' . \${$variableName}['{$idField}'] . '_' . \${$variableName}['{$imageField}'] . strtolower(\$size) . '.jpg';\n\n "); return true; }
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); }