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); }
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); }
protected function _generateParentCode() { $parentField = DevHelper_Generator_Db::getParentField($this->_dataClass['name'], $this->_dataClass['fields']); if ($parentField === false) { // no parent field... return; } $displayOrderField = false; $depthField = false; $lftField = false; $rgtField = false; foreach ($this->_dataClass['fields'] as $field) { if ($field['name'] == 'display_order') { $displayOrderField = $field['name']; } elseif ($field['name'] == 'depth') { $depthField = $field['name']; } elseif ($field['name'] == 'lft') { $lftField = $field['name']; } elseif ($field['name'] == 'rgt') { $rgtField = $field['name']; } } if (empty($displayOrderField) or empty($depthField) or empty($lftField) or empty($rgtField)) { // no hierarchy fields return; } $tableName = DevHelper_Generator_Db::getTableName($this->_config, $this->_dataClass['name']); $rebuildStructureFunctionName = DevHelper_Generator_Code_Model::generateRebuildStructureFunctionName($this->_addOn, $this->_config, $this->_dataClass); $titleFieldPostSaveConditions = ''; if (!empty($this->_dataClass['title_field']) and !is_array($this->_dataClass['title_field'])) { $titleFieldPostSaveConditions = "\n OR \$this->isChanged('{$this->_dataClass['title_field']}')"; } $this->_addMethod('_postSave', 'protected', array(), "\n\nif (\$this->isInsert()\n OR \$this->isChanged('{$displayOrderField}')\n OR \$this->isChanged('{$parentField}'){$titleFieldPostSaveConditions}\n) {\n \$this->_get{$this->_dataClass['camelCase']}Model()->{$rebuildStructureFunctionName}();\n}\n\n "); $this->_addMethod('_postDelete', 'protected', array(), "\n\n\$this->_db->update('{$tableName}',\n array('{$parentField}' => \$this->get('{$parentField}')),\n '{$parentField} = ' . \$this->_db->quote(\$this->get('{$parentField}'))\n);\n\n\$this->_get{$this->_dataClass['camelCase']}Model()->{$rebuildStructureFunctionName}();\n\n "); }
protected function _generateParentCode() { $parentField = DevHelper_Generator_Db::getParentField($this->_dataClass['name'], $this->_dataClass['fields']); if ($parentField === false) { // no parent field... return; } if (count($this->_dataClass['primaryKey']) > 1) { throw new XenForo_Exception(sprintf('Cannot generate parent code for %s: too many fields in primary key', $this->_getClassName())); } $idField = reset($this->_dataClass['primaryKey']); $displayOrderField = false; $depthField = false; $lftField = false; $rgtField = false; $breadcrumbField = DevHelper_Generator_Db::getBreadcrumbField($this->_dataClass['name'], $this->_dataClass['fields']); foreach ($this->_dataClass['fields'] as $field) { if ($field['name'] == 'display_order') { $displayOrderField = $field['name']; } elseif ($field['name'] == 'depth') { $depthField = $field['name']; } elseif ($field['name'] == 'lft') { $lftField = $field['name']; } elseif ($field['name'] == 'rgt') { $rgtField = $field['name']; } } if (empty($displayOrderField) or empty($depthField) or empty($lftField) or empty($rgtField)) { // no hierarchy fields return; } $tableName = DevHelper_Generator_Db::getTableName($this->_config, $this->_dataClass['name']); $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); $rebuildStructureFunctionName = self::generateRebuildStructureFunctionName($this->_addOn, $this->_config, $this->_dataClass); $getStructureChangesFunctionName = '_getStructureChanges'; $groupByParentsFunctionName = self::generateGroupByParentsFunctionName($this->_addOn, $this->_config, $this->_dataClass); $this->_addMethod($rebuildStructureFunctionName, '', array(), "\n\n\$grouped = \$this->{$groupByParentsFunctionName}(\$this->{$getFunctionName}(array(), array('order' => '{$displayOrderField}')));\n\n\$db = \$this->_getDb();\nXenForo_Db::beginTransaction(\$db);\n\n\$changes = \$this->{$getStructureChangesFunctionName}(\$grouped);\nforeach (\$changes AS \$id => \$oneChanges) {\n \$db->update('{$tableName}', \$oneChanges, '{$idField} = ' . \$db->quote(\$id));\n}\n\nXenForo_Db::commit(\$db);\n\nreturn \$changes;\n\n "); $titleFieldBreadcrumb = ''; if (!empty($this->_dataClass['title_field']) and !is_array($this->_dataClass['title_field'])) { $titleFieldBreadcrumb = "\n '{$this->_dataClass['title_field']}' => \${$variableName}['{$this->_dataClass['title_field']}'],"; } $breadcrumbStatements = ''; if (!empty($breadcrumbField)) { $breadcrumbStatements = "\n if (\${$variableName}['category_breadcrumb'] != \$serializedBreadcrumb) {"; $breadcrumbStatements .= "\n \$thisChanges['category_breadcrumb'] = \$serializedBreadcrumb;"; $breadcrumbStatements .= "\n }"; } $this->_addMethod($getStructureChangesFunctionName, 'protected', array('$grouped' => 'array $grouped', '$parentId' => '$parentId = 0', '$depth' => '$depth = 0', '$startPosition' => '$startPosition = 1', 'nextPosition' => '&$nextPosition = 0', '$breadcrumb' => 'array $breadcrumb = array()'), "\n\n\$nextPosition = \$startPosition;\n\nif (!isset(\$grouped[\$parentId])) {\n return array();\n}\n\n\$changes = array();\n\$serializedBreadcrumb = serialize(\$breadcrumb);\n\nforeach (\$grouped[\$parentId] AS \$id => \${$variableName}) {\n \$left = \$nextPosition;\n \$nextPosition++;\n\n \$thisBreadcrumb = \$breadcrumb + array(\n \$id => array(\n '{$idField}' => \$id,{$titleFieldBreadcrumb}\n '{$parentField}' => \${$variableName}['{$parentField}'],\n )\n );\n\n \$changes += \$this->{$getStructureChangesFunctionName}(\n \$grouped,\n \$id,\n \$depth + 1,\n \$nextPosition,\n \$nextPosition,\n \$thisBreadcrumb\n );\n\n \$thisChanges = array();\n if (\${$variableName}['depth'] != \$depth) {\n \$thisChanges['depth'] = \$depth;\n }\n if (\${$variableName}['lft'] != \$left) {\n \$thisChanges['lft'] = \$left;\n }\n if (\${$variableName}['rgt'] != \$nextPosition) {\n \$thisChanges['rgt'] = \$nextPosition;\n }{$breadcrumbStatements}\n\n if (!empty(\$thisChanges)) {\n \$changes[\$id] = \$thisChanges;\n }\n\n \$nextPosition++;\n}\n\nreturn \$changes;\n\n "); $this->_addMethod($groupByParentsFunctionName, '', array(sprintf('$%s', $variableNamePlural) => sprintf('array $%s', $variableNamePlural)), "\n\n\$grouped = array();\nforeach (\${$variableNamePlural} AS \${$variableName}) {\n \$grouped[\${$variableName}['{$parentField}']][\${$variableName}['{$idField}']] = \${$variableName};\n}\n\nreturn \$grouped;\n\n "); }