Webylon 3.1 API Docs
  • Package
  • Class
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • auth
  • Booking
  • cart
    • shipping
    • steppedcheckout
  • Catalog
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • AdditionalMenuWidget_Item
  • AdvancedSliderHomepageWidget_Item
  • AssetManagerFolder
  • BannerWidget_Item
  • BaseObjectDecorator
  • BookingOrder
  • BookingPaymentMethod
  • BookingService
  • Boolean
  • ButtonsBlockHomepageWidget_Item
  • CarouselHomepageWidget_Item
  • CatalogRubricsHomepageWidget_CatalogDecorator
  • ClientEmailOrderNotification
  • ClientVKOrderNotification
  • ComponentSet
  • Currency
  • DatabaseAdmin
  • DataObject
  • DataObjectDecorator
  • DataObjectLog
  • DataObjectSet
  • DataObjectSet_Iterator
  • Date
  • DB
  • DBField
  • Decimal
  • DocumentItem
  • DocumentPage_File
  • Double
  • Enum
  • ErrorPageSubsite
  • FileDataObjectTrackingDecorator
  • FileImportDecorator
  • Float
  • ForeignKey
  • Hierarchy
  • HTMLText
  • HTMLVarchar
  • ImportLog_Item
  • Int
  • ManagerEmailOrderNotification
  • Material3D_File
  • MediawebPage_File
  • MediawebPage_Photo
  • MobileContentDecorator
  • Money
  • MultiEnum
  • MySQLDatabase
  • MySQLQuery
  • OrderDataObject
  • OrderHandlersDecorator
  • OrderItemVariationDecorator
  • OrderService
  • OrderServiceOrder
  • OrdersExportDecorator
  • PageIcon
  • PageWidgets
  • Payment
  • PaymentMethodShippingDecorator
  • PaymentOrderExtension
  • Percentage
  • PhotoAlbumItem
  • PhotoAlbumProductLinkDecorator
  • PhotoAlbumWidgetLinkDecorator
  • PhotoGalleryHomepageWidget_Item
  • PrimaryKey
  • Product3DDecorator
  • ProductCatalogCatalogLinkedDecorator
  • RatePeriod
  • RealtyImportLog
  • RealtyImportLog_Item
  • RedirectEntry
  • RoomOrder
  • RoomOrderPerson
  • RoomRate
  • RoomService
  • RoomServiceOrder
  • SberbankPaymentDecorator
  • SeoOpenGraphPageDecorator
  • ServiceOrder
  • ShippingMethodPaymentDecorator
  • ShopCountry
  • SimpleOrderCatalogDecorator
  • SimpleOrderProductDecorator
  • SiteConfigWidgets
  • SiteTreeDecorator
  • SiteTreeImportDecorator
  • SliderHomepageWidget_Item
  • SMSCOrderNotification
  • SMSOrderNotification
  • SortableDataObject
  • SQLMap
  • SQLMap_Iterator
  • SQLQuery
  • SS_Database
  • SS_Datetime
  • SS_Query
  • StringField
  • SubsiteDomain
  • Text
  • TextAnonsWidget_Item
  • Texture3D_File
  • Time
  • Varchar
  • Versioned
  • Versioned_Version
  • VideoCategory
  • VideoEntry
  • VKNotificationQueue
  • WebylonWidget_Item
  • YaMoneyPaymentDecorator
  • Year

Interfaces

  • CompositeDBField
  • CurrentPageIdentifier
  • DataObjectInterface
  1 <?php
  2 // Include the DB class
  3 require_once("core/model/DB.php");
  4 
  5 /**
  6  * DatabaseAdmin class
  7  *
  8  * Utility functions for administrating the database. These can be accessed
  9  * via URL, e.g. http://www.yourdomain.com/db/build.
 10  * 
 11  * @package sapphire
 12  * @subpackage model
 13  */
 14 class DatabaseAdmin extends Controller {
 15 
 16     /// SECURITY ///
 17     static $allowed_actions = array(
 18         'index',
 19         'build',
 20         'cleanup',
 21         'testinstall',
 22         'import'
 23     );
 24     
 25     function init() {
 26         parent::init();
 27         
 28         // We allow access to this controller regardless of live-status or ADMIN permission only
 29         // if on CLI or with the database not ready. The latter makes it less errorprone to do an
 30         // initial schema build without requiring a default-admin login.
 31         // Access to this controller is always allowed in "dev-mode", or of the user is ADMIN.
 32         $canAccess = (
 33             Director::isDev() 
 34             || !Security::database_is_ready() 
 35             || Director::is_cli() 
 36             || Permission::check("ADMIN")
 37         );
 38         if(!$canAccess) {
 39             return Security::permissionFailure($this,
 40                 "This page is secured and you need administrator rights to access it. " .
 41                 "Enter your credentials below and we will send you right along.");
 42         }
 43     }
 44 
 45     /**
 46      * Get the data classes, grouped by their root class
 47      *
 48      * @return array Array of data classes, grouped by their root class
 49      */
 50     function groupedDataClasses() {
 51         // Get all root data objects
 52         $allClasses = get_declared_classes();
 53         foreach($allClasses as $class) {
 54             if(get_parent_class($class) == "DataObject")
 55                 $rootClasses[$class] = array();
 56         }
 57 
 58         // Assign every other data object one of those
 59         foreach($allClasses as $class) {
 60             if(!isset($rootClasses[$class]) && is_subclass_of($class, "DataObject")) {
 61                 foreach($rootClasses as $rootClass => $dummy) {
 62                     if(is_subclass_of($class, $rootClass)) {
 63                         $rootClasses[$rootClass][] = $class;
 64                         break;
 65                     }
 66                 }
 67             }
 68         }
 69         return $rootClasses;
 70     }
 71 
 72 
 73     /**
 74      * Display a simple HTML menu of database admin helpers.
 75      */
 76     function index() {
 77         echo "<h2>Database Administration Helpers</h2>";
 78         echo "<p><a href=\"build\">Add missing database fields (similar to sanity check).</a></p>";
 79         echo "<p><a href=\"../images/flush\">Flush <b>all</b> of the generated images.</a></p>";
 80     }
 81 
 82 
 83     /**
 84      * Updates the database schema, creating tables & fields as necessary.
 85      */
 86     function build() {
 87         // The default time limit of 30 seconds is normally not enough
 88         increase_time_limit_to(600);
 89 
 90         // Get all our classes
 91         ManifestBuilder::create_manifest_file();
 92         require(MANIFEST_FILE);
 93         
 94         if(isset($_GET['returnURL'])) {
 95             echo "<p>Setting up the database; you will be returned to your site shortly....</p>";
 96             $this->doBuild(true);
 97             echo "<p>Done!</p>";
 98             Director::redirect($_GET['returnURL']);
 99         } else {
100             if(!Director::is_cli() && Director::urlParam('Controller') == __CLASS__) {
101                 echo '<p style="color: red;"><i>db/build</i> has been deprecated. Please use <b>dev/build</b> instead.</p>';
102             }
103             $this->doBuild(isset($_REQUEST['quiet']) || isset($_REQUEST['from_installer']), !isset($_REQUEST['dont_populate']));
104         }
105     }
106 
107     /**
108      * Check if database needs to be built, and build it if it does.
109      */
110     static function autoBuild() {
111         $dataClasses = ClassInfo::subclassesFor('DataObject');
112         $lastBuilt = self::lastBuilt();
113         foreach($dataClasses as $class) {
114             if(filemtime(getClassFile($class)) > $lastBuilt) {
115                 $da = new DatabaseAdmin();
116                 $da->doBuild(true);
117                 return;
118             }
119         }
120     }
121 
122 
123     /**
124      * Returns the timestamp of the time that the database was last built
125      *
126      * @return string Returns the timestamp of the time that the database was
127      *                last built
128      */
129     static function lastBuilt() {
130         $file = TEMP_FOLDER . '/database-last-generated-' .
131             str_replace(array('\\','/',':'), '.' , Director::baseFolder());
132 
133         if(file_exists($file)) {
134             return filemtime($file);
135         }
136     }
137 
138 
139     /**
140      * Updates the database schema, creating tables & fields as necessary.
141      *
142      * @param boolean $quiet Don't show messages
143      * @param boolean $populate Populate the database, as well as setting up its schema
144      */
145     function doBuild($quiet = false, $populate = true, $testMode = false) {
146         if($quiet) {
147             DB::quiet();
148         } else {
149             $conn = DB::getConn();
150             $databaseName = (method_exists($conn, 'currentDatabase')) ? $conn->currentDatabase() : "";
151             
152             if(Director::is_cli()) echo "\n\nBuilding Database $databaseName\n\n";
153             else echo "<h2>Building Database $databaseName</h2>";
154         }
155 
156         // Set up the initial database
157         if(!DB::isActive()) {
158             if(!$quiet) {
159                 echo '<p><b>Creating database</b></p>';
160             }
161             global $databaseConfig;
162             $parameters = $databaseConfig ? $databaseConfig : $_REQUEST['db'];
163             $connect = DB::getConnect($parameters);
164             $username = $parameters['username'];
165             $password = $parameters['password'];
166             $database = $parameters['database'];
167 
168             if(!$database) {
169                 user_error("No database name given; please give a value for \$databaseConfig['database']", E_USER_ERROR);
170             }
171 
172             DB::createDatabase($connect, $username, $password, $database);
173         }
174 
175         // Build the database.  Most of the hard work is handled by DataObject
176         $dataClasses = ClassInfo::subclassesFor('DataObject');
177         array_shift($dataClasses);
178 
179         if(!$quiet) {
180             if(Director::is_cli()) echo "\nCREATING DATABASE TABLES\n\n";
181             else echo "\n<p><b>Creating database tables</b></p>\n\n";
182         }
183 
184         $conn = DB::getConn();
185         $conn->beginSchemaUpdate();
186         foreach($dataClasses as $dataClass) {
187             // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness
188             if(class_exists($dataClass)) {
189                 $SNG = singleton($dataClass);
190                 if($testMode || !($SNG instanceof TestOnly)) {
191                     if(!$quiet) {
192                         if(Director::is_cli()) echo " * $dataClass\n";
193                         else echo "<li>$dataClass</li>\n";
194                     }
195                     $SNG->requireTable();
196                 }
197             }
198         }
199         $conn->endSchemaUpdate();
200         ClassInfo::reset_db_cache();
201 
202         if($populate) {
203             if(!$quiet) {
204                 if(Director::is_cli()) echo "\nCREATING DATABASE RECORDS\n\n";
205                 else echo "\n<p><b>Creating database records</b></p>\n\n";
206             }
207 
208             foreach($dataClasses as $dataClass) {
209                 // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness
210                 // Test_ indicates that it's the data class is part of testing system
211                 if(strpos($dataClass,'Test_') === false && class_exists($dataClass)) {
212                     if(!$quiet) {
213                         if(Director::is_cli()) echo " * $dataClass\n";
214                         else echo "<li>$dataClass</li>\n";
215                     }
216 
217                     singleton($dataClass)->requireDefaultRecords();
218                 }
219             }
220         }
221 
222         touch(TEMP_FOLDER . '/database-last-generated-' .
223                     str_replace(array('\\', '/', ':'), '.', Director::baseFolder()));
224 
225         if(isset($_REQUEST['from_installer'])) {
226             echo "OK";
227         }
228         
229         if(!$quiet) echo "<p>Database build completed!</p>";
230         ClassInfo::reset_db_cache();
231     }
232     
233     /**
234      * Clear all data out of the database
235      * @todo Move this code into SS_Database class, for DB abstraction
236      */
237     function clearAllData() {
238         $tables = DB::getConn()->tableList();
239         foreach($tables as $table) {
240             if(method_exists(DB::getConn(), 'clearTable')) DB::getConn()->clearTable($table);
241             else DB::query("TRUNCATE \"$table\"");
242         }
243     }
244 
245 
246     /**
247      * Method used to check mod_rewrite is working correctly in the installer.
248      */
249     function testinstall() {
250         echo "OK";
251     }
252 
253 
254     /**
255      * Remove invalid records from tables - that is, records that don't have
256      * corresponding records in their parent class tables.
257      */
258     function cleanup() {
259         $allClasses = get_declared_classes();
260         foreach($allClasses as $class) {
261             if(get_parent_class($class) == 'DataObject') {
262                 $baseClasses[] = $class;
263             }
264         }
265 
266         foreach($baseClasses as $baseClass) {
267             // Get data classes
268             $subclasses = ClassInfo::subclassesFor($baseClass);
269             unset($subclasses[0]);
270             foreach($subclasses as $k => $subclass) {
271                 if(DataObject::database_fields($subclass)) {
272                     unset($subclasses[$k]);
273                 }
274             }
275 
276             if($subclasses) {
277                 $records = DB::query("SELECT * FROM \"$baseClass\"");
278 
279 
280                 foreach($subclasses as $subclass) {
281                     $recordExists[$subclass] =
282                         DB::query("SELECT \"ID\" FROM \"$subclass\"")->keyedColumn();
283                 }
284 
285                 foreach($records as $record) {
286                     foreach($subclasses as $subclass) {
287                         $id = $record['ID'];
288                         if(($record['ClassName'] != $subclass) &&
289                              (!is_subclass_of($record['ClassName'], $subclass)) &&
290                              (isset($recordExists[$subclass][$id]))) {
291                             $sql = "DELETE FROM \"$subclass\" WHERE \"ID\" = $record[ID]";
292                             echo "<li>$sql";
293                             DB::query($sql);
294                         }
295                     }
296                 }
297             }
298         }
299     }
300 
301 }
302 
303 ?>
304 
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -
Webylon 3.1 API Docs API documentation generated by ApiGen 2.8.0