Source of file DevBuildExtension.php
Size: 9,026 Bytes - Last Modified: 2021-12-23T10:00:25+00:00
/var/www/docs.ssmods.com/process/src/src/Extensions/DevBuildExtension.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 | <?php namespace LeKoala\DevToolkit\Extensions; use Exception; use SilverStripe\ORM\DB; use RecursiveIteratorIterator; use RecursiveDirectoryIterator; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Extension; use SilverStripe\ORM\DataObject; use SilverStripe\Control\Director; use LeKoala\DevToolkit\Helpers\FileHelper; use LeKoala\DevToolkit\Helpers\SubsiteHelper; /** * Allow the following functions before dev build * - renameColumns * - truncateSiteTree * * Allow the following functions after dev build: * - generateQueryTraits * - clearCache * - clearEmptyFolders * - provisionLocales * * Preserve current subsite * * @property \SilverStripe\Dev\DevBuildController|\LeKoala\DevToolkit\Extensions\DevBuildExtension $owner */ class DevBuildExtension extends Extension { protected $currentSubsite; public function beforeCallActionHandler() { $this->currentSubsite = SubsiteHelper::currentSubsiteID(); $renameColumns = $this->owner->getRequest()->getVar('fixTableCase'); if ($renameColumns) { $this->displayMessage("<div class='build'><p><b>Fixing tables case</b></p><ul>\n\n"); $this->fixTableCase(); $this->displayMessage("</ul>\n<p><b>Tables fixed!</b></p></div>"); } $renameColumns = $this->owner->getRequest()->getVar('renameColumns'); if ($renameColumns) { $this->displayMessage("<div class='build'><p><b>Renaming columns</b></p><ul>\n\n"); $this->renameColumns(); $this->displayMessage("</ul>\n<p><b>Columns renamed!</b></p></div>"); } $truncateSiteTree = $this->owner->getRequest()->getVar('truncateSiteTree'); if ($truncateSiteTree) { $this->displayMessage("<div class='build'><p><b>Truncating SiteTree</b></p><ul>\n\n"); $this->truncateSiteTree(); $this->displayMessage("</ul>\n<p><b>SiteTree truncated!</b></p></div>"); } } protected function fixTableCase() { if (!Director::isDev()) { throw new Exception("Only available in dev mode"); } $conn = DB::get_conn(); $dbName = $conn->getSelectedDatabase(); $tablesSql = "SELECT table_name FROM information_schema.tables WHERE table_schema = '$dbName';"; $result = DB::query($tablesSql); //TODO: check list of tables name and match any lowercased one to the right one from the db schema } protected function truncateSiteTree() { if (!Director::isDev()) { throw new Exception("Only available in dev mode"); } $sql = <<<SQL TRUNCATE TABLE ErrorPage; TRUNCATE TABLE ErrorPage_Live; TRUNCATE TABLE ErrorPage_Versions; TRUNCATE TABLE SiteTree; TRUNCATE TABLE SiteTree_CrossSubsiteLinkTracking; TRUNCATE TABLE SiteTree_EditorGroups; TRUNCATE TABLE SiteTree_ImageTracking; TRUNCATE TABLE SiteTree_LinkTracking; TRUNCATE TABLE SiteTree_Live; TRUNCATE TABLE SiteTree_Versions; TRUNCATE TABLE SiteTree_ViewerGroups; SQL; DB::query($sql); $this->displayMessage($sql); } /** * Loop on all DataObjects and look for rename_columns property * * It will rename old columns from old_value => new_value * * @return void */ protected function renameColumns() { $classes = $this->getDataObjects(); foreach ($classes as $class) { if (!property_exists($class, 'rename_columns')) { continue; } $fields = $class::$rename_columns; $schema = DataObject::getSchema(); $tableName = $schema->baseDataTable($class); $dbSchema = DB::get_schema(); foreach ($fields as $oldName => $newName) { if ($dbSchema->hasField($tableName, $oldName)) { if ($dbSchema->hasField($tableName, $newName)) { $this->displayMessage("<li>$oldName still exists in $tableName. Data will be migrated to $newName and old column $oldName will be dropped.</li>"); // Migrate data DB::query("UPDATE $tableName SET $newName = $oldName WHERE $newName IS NULL"); // Remove column DB::query("ALTER TABLE $tableName DROP COLUMN $oldName"); } else { $this->displayMessage("<li>Renaming $oldName to $newName in $tableName</li>"); $dbSchema->renameField($tableName, $oldName, $newName); } } else { $this->displayMessage("<li>$oldName does not exist anymore in $tableName</li>"); } // Look for fluent $fluentTable = $tableName . '_Localised'; if ($dbSchema->hasTable($fluentTable)) { if ($dbSchema->hasField($fluentTable, $oldName)) { if ($dbSchema->hasField($fluentTable, $newName)) { $this->displayMessage("<li>$oldName still exists in $fluentTable. Data will be migrated to $newName and old column $oldName will be dropped.</li>"); // Migrate data DB::query("UPDATE $fluentTable SET $newName = $oldName WHERE $newName IS NULL"); // Remove column DB::query("ALTER TABLE $fluentTable DROP COLUMN $oldName"); } else { $this->displayMessage("<li>Renaming $oldName to $newName in $fluentTable</li>"); $dbSchema->renameField($fluentTable, $oldName, $newName); } } else { $this->displayMessage("<li>$oldName does not exist anymore in $fluentTable</li>"); } } } } } public function afterCallActionHandler() { // Other helpers $clearCache = $this->owner->getRequest()->getVar('clearCache'); $clearEmptyFolders = $this->owner->getRequest()->getVar('clearEmptyFolders'); $this->displayMessage("<div class='build'>"); if ($clearCache) { $this->clearCache(); } if ($clearEmptyFolders) { $this->clearEmptyFolders(); } $this->displayMessage("</div>"); // Restore subsite if ($this->currentSubsite) { SubsiteHelper::changeSubsite($this->currentSubsite); } $provisionLocales = $this->owner->getRequest()->getVar('provisionLocales'); if ($provisionLocales) { $this->displayMessage("<div class='build'><p><b>Provisioning locales</b></p><ul>\n\n"); try { \LeKoala\Multilingual\LangHelper::provisionLocales(); $this->displayMessage("</ul>\n<p><b>Locales provisioned!</b></p></div>"); } catch (Exception $ex) { $this->displayMessage($ex->getMessage() . '<br/>'); } } } protected function clearCache() { $this->displayMessage("<strong>Clearing cache folder</strong>"); $folder = Director::baseFolder() . '/silverstripe-cache'; if (!is_dir($folder)) { $this->displayMessage("silverstripe-cache does not exist in base folder\n"); return; } FileHelper::rmDir($folder); mkdir($folder, 0755); $this->displayMessage("Cleared silverstripe-cache folder\n"); } protected function clearEmptyFolders() { $this->displayMessage("<strong>Clearing empty folders in assets</strong>"); $folder = Director::publicFolder() . '/assets'; if (!is_dir($folder)) { $this->displayMessage("assets folder does not exist in public folder\n"); return; } $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($folder), RecursiveIteratorIterator::SELF_FIRST); foreach ($objects as $name => $object) { if ($object->isDir()) { $path = $object->getPath(); if (!is_readable($path)) { $this->displayMessage("$path is not readable\n"); continue; } if (!FileHelper::dirContainsChildren($path)) { rmdir($path); $this->displayMessage("Removed $path\n"); } } } } /** * @return array */ protected function getDataObjects() { $classes = ClassInfo::subclassesFor(DataObject::class); array_shift($classes); // remove dataobject return $classes; } /** * @param $message */ protected function displayMessage($message) { echo Director::is_cli() ? strip_tags($message) : nl2br($message); } } |