Last active
November 19, 2017 20:53
-
-
Save Bruno17/27b873fd397e5beef8c20914747bf270 to your computer and use it in GitHub Desktop.
MODX Revolution - snippet for recreating xPDO - schema from map-files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class rebuildSchemaFromMap{ | |
public $packageName = ''; | |
public $packagePath = ''; | |
public $modelPath = ''; | |
public $dbtype = ''; | |
public $defaultEngine = 'MyISAM'; | |
public $objects= array(); | |
public function __construct(& $modx,$config = array()) { | |
$this->modx= & $modx; | |
$this->packageName = $modx->getOption('packageName',$config,'modx'); | |
if ($this->packageName == 'modx'){ | |
$config['packagePath'] = ''; | |
} | |
$this->packagePath = $modx->getOption('core_path') . $modx->getOption('packagePath',$config,'components/' . $this->packageName . '/'); | |
$this->modelPath = $this->packagePath . 'model/'; | |
$this->dbtype = $modx->getOption('dbtype',$config,$modx->config['dbtype']); | |
$this->defaultEngine = $modx->getOption('defaultEngine',$config,'MyISAM'); | |
} | |
public function getClassnamesFromMetadata(){ | |
$modx = & $this->modx; | |
$classes = array(); | |
if (is_string($this->packageName) && !empty($this->packageName)) { | |
$metaFile = $this->modelPath . $this->packageName . '/metadata.' . $this->dbtype . '.php'; | |
if (file_exists($metaFile)) { | |
$xpdo_meta_map = ''; | |
include $metaFile; | |
if (!empty($xpdo_meta_map)) { | |
foreach ($xpdo_meta_map as $extends => $classnames) { | |
$classes = array_unique(array_merge($classes,$classnames)); | |
} | |
} | |
} else { | |
$modx->log(xPDO::LOG_LEVEL_WARN, "Could not load package metadata for package {$packageName}."); | |
} | |
} else { | |
$modx->log(xPDO::LOG_LEVEL_ERROR, 'setPackageMeta called with an invalid package name.'); | |
} | |
return $classes; | |
} | |
public function parseMapFiles($classnames){ | |
if (is_array($classnames)){ | |
foreach ($classnames as $classname){ | |
$mapFile = $this->modelPath . $this->packageName . '/' . $this->dbtype . '/' .strtolower($classname) . '.map.inc.php'; | |
$xpdo_meta_map = array(); | |
if (file_exists($mapFile)) { | |
include $mapFile; | |
if (!empty($xpdo_meta_map)) { | |
$this->buildObject($xpdo_meta_map); | |
} | |
} | |
} | |
} | |
} | |
public function buildField($fieldname,$fieldMeta){ | |
$spaces = ' '; | |
$field = ''; | |
if (is_string($fieldname) && !empty($fieldname)){ | |
if (is_array($fieldMeta)){ | |
$field = $spaces . "<field key=\"$fieldname\" "; | |
foreach ($fieldMeta as $fieldAttribute => $value){ | |
if (is_bool($value)){ | |
$value = $value ? 'true' : 'false'; | |
} | |
$field .= "$fieldAttribute=\"$value\" "; | |
} | |
$field .= "/>"; | |
} | |
} | |
return $field; | |
} | |
public function buildFields($meta){ | |
$fields = array(); | |
$fieldMetas = $meta['fieldMeta']; | |
if (is_array($fieldMetas)){ | |
foreach ($fieldMetas as $fieldname => $fieldMeta){ | |
$fields[$fieldname] = $this->buildField($fieldname,$fieldMeta); | |
} | |
} | |
return $fields; | |
} | |
public function buildIndexColumn($columnname,$columnAttributes){ | |
$spaces = ' '; | |
$field = ''; | |
if (is_string($columnname) && !empty($columnname)){ | |
if (is_array($columnAttributes)){ | |
$field = $spaces . "<column key=\"$columnname\" "; | |
foreach ($columnAttributes as $fieldAttribute => $value){ | |
if (is_bool($value)){ | |
$value = $value ? 'true' : 'false'; | |
} | |
$field .= "$fieldAttribute=\"$value\" "; | |
} | |
$field .= "/>"; | |
} | |
} | |
return $field; | |
} | |
public function buildIndexColumns($indexMeta){ | |
$columns = $indexMeta['columns']; | |
if (is_array($columns)){ | |
foreach ($columns as $columnname => $columnAttributes){ | |
$columns[$columnname] = $this->buildIndexColumn($columnname,$columnAttributes); | |
} | |
} | |
return $columns; | |
} | |
public function buildIndex($indexname,$indexMeta){ | |
$spaces = ' '; | |
$field = ''; | |
if (is_string($indexname) && !empty($indexname)){ | |
if (is_array($indexMeta)){ | |
$columns = $this->buildIndexColumns($indexMeta); | |
$field = $spaces . "<index name=\"$indexname\" "; | |
foreach ($indexMeta as $fieldAttribute => $value){ | |
if (is_bool($value)){ | |
$value = $value ? 'true' : 'false'; | |
} | |
if (is_string($value)){ | |
$field .= "$fieldAttribute=\"$value\" "; | |
} | |
} | |
$field .= ">\n"; | |
$field .= implode("\n",$columns) . "\n"; | |
$field .= $spaces . "</index>"; | |
} | |
} | |
return $field; | |
} | |
public function buildIndexes($meta){ | |
$indexes = array(); | |
$indexMetas = $meta['indexes']; | |
if (is_array($indexMetas)){ | |
foreach ($indexMetas as $indexname => $indexMeta){ | |
$indexes[$indexname] = $this->buildIndex($indexname,$indexMeta); | |
} | |
} | |
return $indexes; | |
} | |
public function buildObject($xpdo_meta_map){ | |
$spaces = ' '; | |
$keys = array_keys($xpdo_meta_map); | |
$classname = $keys[0]; | |
$extends = $xpdo_meta_map[$classname]['extends']; | |
$table = $xpdo_meta_map[$classname]['table']; | |
$table = !empty($table) ? " table=\"$table\"" : ""; | |
$fields = $this->buildFields($xpdo_meta_map[$classname]); | |
$indexes = $this->buildIndexes($xpdo_meta_map[$classname]); | |
$aggregates = $this->buildRelations($xpdo_meta_map[$classname],'aggregate'); | |
$composites = $this->buildRelations($xpdo_meta_map[$classname],'composite'); | |
$object = $spaces . "<object class=\"$classname\"$table extends=\"$extends\">\n"; | |
$object .= implode("\n",$fields) . "\n"; | |
if (!empty($indexes)){ | |
$object .= implode("\n",$indexes) . "\n"; | |
} | |
if (!empty($aggregates)){ | |
$object .= implode("\n",$aggregates) . "\n"; | |
} | |
if (!empty($composites)){ | |
$object .= implode("\n",$composites) . "\n"; | |
} | |
$object .= $spaces . "</object>"; | |
$this->objects[$classname] = $object; | |
} | |
public function buildRelationCriteria($fieldMeta){ | |
$spaces = ' '; | |
$criteria = $fieldMeta['criteria']; | |
$field = ''; | |
if (is_array($criteria)){ | |
$keys = array_keys($criteria); | |
$target = $keys[0]; | |
$c = $criteria[$target]; | |
$field = $spaces . "<criteria target=\"$target\"><![CDATA[\n"; | |
$field .= $spaces . ' ' . json_encode($c) . "\n"; | |
$field .= $spaces . "]]></criteria>\n"; | |
} | |
return $field; | |
} | |
public function buildRelation($fieldname,$fieldMeta,$type){ | |
$spaces = ' '; | |
$field = ''; | |
if (is_string($fieldname) && !empty($fieldname)){ | |
if (is_array($fieldMeta)){ | |
$criteria = $this->buildRelationCriteria($fieldMeta); | |
$field = $spaces . "<$type alias=\"$fieldname\" "; | |
foreach ($fieldMeta as $fieldAttribute => $value){ | |
if (is_bool($value)){ | |
$value = $value ? 'true' : 'false'; | |
} | |
if (is_string($value)){ | |
$field .= "$fieldAttribute=\"$value\" "; | |
} | |
} | |
if (!empty($criteria)){ | |
$field .= ">\n"; | |
$field .= $criteria; | |
$field .= $spaces . "</$type>"; | |
} else { | |
$field .= "/>"; | |
} | |
} | |
} | |
return $field; | |
} | |
public function buildRelations($meta,$type){ | |
$fields = array(); | |
$fieldMetas = $meta[$type . 's']; | |
if (is_array($fieldMetas)){ | |
foreach ($fieldMetas as $fieldname => $fieldMeta){ | |
$fields[$fieldname] = $this->buildRelation($fieldname,$fieldMeta,$type); | |
} | |
} | |
return $fields; | |
} | |
public function run(){ | |
$classnames = $this->getClassnamesFromMetadata(); | |
$this->parseMapFiles($classnames); | |
$output = '<?xml version="1.0" encoding="UTF-8"?>' . "\n"; | |
$output .= "<model package=\"$this->packageName\" baseClass=\"xPDOObject\" platform=\"$this->dbtype\" defaultEngine=\"$this->defaultEngine\" phpdoc-package=\"$this->packageName\" phpdoc-subpackage=\"\" version=\"1.1\">\n"; | |
$output .= implode("\n",$this->objects) . "\n"; | |
$output .= "</model>"; | |
return $output; | |
} | |
} | |
$app = new rebuildSchemaFromMap($modx,$scriptProperties); | |
return '<textarea style="width:100%;height:400px;">' . $app->run() . '</textarea>'; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment