      1: <?php
      2:
      3: // include the config file
      4: if(!isset($config)) {
      5:     require_once '../util/AlphaConfig.inc';
      6:     $config = AlphaConfig::getInstance();
      7:
      8:     require_once $config->get('app.root').'alpha/util/AlphaAutoLoader.inc';
      9: }
     10:
     11: /**
     12:  *
     13:  * Controller used install the database
     14:  *
     15:  * @package alpha::controller
     16:  * @since 1.0
     17:  * @author John Collins <dev@alphaframework.org>
     18:  * @version $Id: Install.php 1551 2012-07-30 22:46:18Z alphadevx $
     19:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
     20:  * @copyright Copyright (c) 2012, John Collins (founder of Alpha Framework).
     21:  * All rights reserved.
     22:  *
     23:  * <pre>
     24:  * Redistribution and use in source and binary forms, with or
     25:  * without modification, are permitted provided that the
     26:  * following conditions are met:
     27:  *
     28:  * * Redistributions of source code must retain the above
     29:  *   copyright notice, this list of conditions and the
     30:  *   following disclaimer.
     31:  * * Redistributions in binary form must reproduce the above
     32:  *   copyright notice, this list of conditions and the
     33:  *   following disclaimer in the documentation and/or other
     34:  *   materials provided with the distribution.
     35:  * * Neither the name of the Alpha Framework nor the names
     36:  *   of its contributors may be used to endorse or promote
     37:  *   products derived from this software without specific
     38:  *   prior written permission.
     39:  *
     40:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
     41:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
     42:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     43:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     44:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     45:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     46:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     47:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     48:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     49:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     50:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     51:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     52:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     53:  * </pre>
     54:  *
     55:  */
     56: class Install extends AlphaController implements AlphaControllerInterface {
     57:     /**
     58:      * Trace logger
     59:      *
     60:      * @var Logger
     61:      * @since 1.0
     62:      */
     63:     private static $logger = null;
     64:
     65:     /**
     66:      * the constructor
     67:      *
     68:      * @since 1.0
     69:      */
     70:     public function __construct() {
     71:         self::$logger = new Logger('Install');
     72:         self::$logger->debug('>>__construct()');
     73:
     74:         global $config;
     75:
     76:         parent::__construct('Public');
     77:
     78:         // if there is nobody logged in, we will send them off to the Login controller to do so before coming back here
     79:         if(!isset($_SESSION['currentUser'])) {
     80:             self::$logger->info('Nobody logged in, invoking Login controller...');
     81:
     82:             require_once $config->get('app.root').'alpha/controller/Login.php';
     83:
     84:             $controller = new Login();
     85:             $controller->setName('Login');
     86:             $controller->setUnitOfWork(array('Login', 'Install'));
     87:             $controller->doGET(array());
     88:
     89:             self::$logger->debug('<<__construct');
     90:             exit;
     91:         }else{
     92:
     93:             // ensure that the super class constructor is called, indicating the rights group
     94:             parent::__construct('Admin');
     95:
     96:             // set up the title and meta details
     97:             $this->setTitle('Installing '.$config->get('app.title'));
     98:
     99:             self::$logger->debug('<<__construct');
    100:         }
    101:     }
    102:
    103:     /**
    104:      * Handle GET requests
    105:      *
    106:      * @param array $params
    107:      * @since 1.0
    108:      */
    109:     public function doGET($params) {
    110:         self::$logger->debug('>>doGET($params=['.var_export($params, true).'])');
    111:
    112:         global $config;
    113:
    114:         echo AlphaView::displayPageHead($this);
    115:
    116:         $this->createAppDirectories();
    117:
    118:         // start a new database transaction
    119:         AlphaDAO::begin();
    120:
    121:         /*
    122:          * Create DEnum tables
    123:          */
    124:         $DEnum = new DEnum();
    125:         $DEnumItem = new DEnumItem();
    126:         try{
    127:             echo '<p>Attempting to create the DEnum tables...';
    128:             if(!$DEnum->checkTableExists())
    129:                 $DEnum->makeTable();
    130:             self::$logger->info('Created the ['.$DEnum->getTableName().'] table successfully');
    131:
    132:             if(!$DEnumItem->checkTableExists())
    133:                 $DEnumItem->makeTable();
    134:             self::$logger->info('Created the ['.$DEnumItem->getTableName().'] table successfully');
    135:
    136:
    137:             // create a default article DEnum category
    138:             $DEnum = new DEnum('ArticleObject::section');
    139:             $DEnumItem = new DEnumItem();
    140:             $DEnumItem->set('value', 'Main');
    141:             $DEnumItem->set('DEnumID', $DEnum->getID());
    142:             $DEnumItem->save();
    143:
    144:             echo AlphaView::displayUpdateMessage('DEnums set up successfully.');
    145:         }catch (Exception $e) {
    146:             echo AlphaView::displayErrorMessage($e->getMessage());
    147:             echo AlphaView::displayErrorMessage('Aborting.');
    148:             self::$logger->error($e->getMessage());
    149:             AlphaDAO::rollback();
    150:             exit;
    151:         }
    152:
    153:         /*
    154:          * Loop over each business object in the system, and create a table for it
    155:          */
    156:         $classNames = AlphaDAO::getBOClassNames();
    157:         $loadedClasses = array();
    158:
    159:         foreach($classNames as $classname) {
    160:             AlphaDAO::loadClassDef($classname);
    161:             array_push($loadedClasses, $classname);
    162:         }
    163:
    164:         foreach($loadedClasses as $classname) {
    165:             try {
    166:                 echo '<p>Attempting to create the table for the class ['.$classname.']...';
    167:
    168:                 try {echo '1<br>';
    169:                     $BO = new $classname();
    170:
    171:                     if(!$BO->checkTableExists()) {
    172:                         $BO->makeTable();
    173:                     }else{
    174:                         if($BO->checkTableNeedsUpdate()) {
    175:                             $missingFields = $BO->findMissingFields();
    176:
    177:                             $count = count($missingFields);
    178:
    179:                             for($i = 0; $i < $count; $i++)
    180:                                 $BO->addProperty($missingFields[$i]);
    181:                         }
    182:                     }
    183:                 }catch (FailedIndexCreateException $eice) {
    184:                     // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    185:                     self::$logger->warn($eice->getMessage());
    186:                 }catch (FailedLookupCreateException $elce) {
    187:                     // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    188:                     self::$logger->warn($elce->getMessage());
    189:                 }
    190:
    191:                 self::$logger->info('Created the ['.$BO->getTableName().'] table successfully');
    192:                 echo AlphaView::displayUpdateMessage('Created the ['.$BO->getTableName().'] table successfully');
    193:             }catch (Exception $e) {
    194:                 echo AlphaView::displayErrorMessage($e->getMessage());
    195:                 echo AlphaView::displayErrorMessage('Aborting.');
    196:                 self::$logger->error($e->getMessage());
    197:                 AlphaDAO::rollback();
    198:                 exit;
    199:             }
    200:         }
    201:
    202:         echo AlphaView::displayUpdateMessage('All business object tables created successfully!');
    203:
    204:         /*
    205:          * Create the Admin and Standard groups
    206:          */
    207:         $adminGroup = new RightsObject();
    208:         $adminGroup->set('name', 'Admin');
    209:         $standardGroup = new RightsObject();
    210:         $standardGroup->set('name', 'Standard');
    211:         try{
    212:             try{
    213:                 echo '<p>Attempting to create the Admin and Standard groups...';
    214:                 $adminGroup->save();
    215:                 $standardGroup->save();
    216:
    217:                 self::$logger->info('Created the Admin and Standard rights groups successfully');
    218:                 echo AlphaView::displayUpdateMessage('Created the Admin and Standard rights groups successfully');
    219:             }catch (FailedIndexCreateException $eice) {
    220:                 // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    221:                 self::$logger->warn($eice->getMessage());
    222:             }catch (FailedLookupCreateException $elce) {
    223:                 // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    224:                 self::$logger->warn($elce->getMessage());
    225:             }
    226:         }catch (Exception $e) {
    227:             echo AlphaView::displayErrorMessage($e->getMessage());
    228:             echo AlphaView::displayErrorMessage('Aborting.');
    229:             self::$logger->error($e->getMessage());
    230:             AlphaDAO::rollback();
    231:             exit;
    232:         }
    233:
    234:         /*
    235:          * Save the admin user to the database in the right group
    236:          */
    237:         try{
    238:             try {
    239:                 echo '<p>Attempting to save the Admin account...';
    240:                 $admin = new PersonObject();
    241:                 $admin->set('displayName', 'Admin');
    242:                 $admin->set('email', $_SESSION['currentUser']->get('email'));
    243:                 $admin->set('password', $_SESSION['currentUser']->get('password'));
    244:                 $admin->save();
    245:                 self::$logger->info('Created the admin user account ['.$_SESSION['currentUser']->get('email').'] successfully');
    246:
    247:                 $adminGroup->loadByAttribute('name', 'Admin');
    248:
    249:                 $lookup = $adminGroup->getMembers()->getLookup();
    250:                 $lookup->setValue(array($admin->getID(), $adminGroup->getID()));
    251:                 $lookup->save();
    252:
    253:                 self::$logger->info('Added the admin account to the Admin group successfully');
    254:                 echo AlphaView::displayUpdateMessage('Added the admin account to the Admin group successfully');
    255:             }catch (FailedIndexCreateException $eice) {
    256:                 // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    257:                 self::$logger->warn($eice->getMessage());
    258:             }catch (FailedLookupCreateException $elce) {
    259:                 // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    260:                 self::$logger->warn($elce->getMessage());
    261:             }
    262:         }catch (Exception $e) {
    263:             echo AlphaView::displayErrorMessage($e->getMessage());
    264:             echo AlphaView::displayErrorMessage('Aborting.');
    265:             self::$logger->error($e->getMessage());
    266:             AlphaDAO::rollback();
    267:             exit;
    268:         }
    269:
    270:         echo '<br><p align="center"><a href="'.FrontController::generateSecureURL('act=ListBusinessObjects').'">Administration Home Page</a></p><br>';
    271:         echo AlphaView::displayPageFoot($this);
    272:
    273:         // commit
    274:         AlphaDAO::commit();
    275:
    276:         self::$logger->info('Finished installation!');
    277:         self::$logger->debug('<<doGET');
    278:     }
    279:
    280:     /**
    281:      * Copies a .htaccess file that restricts public access to the target directory
    282:      *
    283:      * @param string $dir
    284:      * @since 1.0
    285:      */
    286:     private function copyRestrictedAccessFileToDirectory($dir) {
    287:         global $config;
    288:
    289:         copy($config->get('app.root').'alpha/.htaccess', $dir.'/.htaccess');
    290:     }
    291:
    292:     /**
    293:      * Creates the standard application directories
    294:      *
    295:      * @since 1.0
    296:      */
    297:     private function createAppDirectories() {
    298:         global $config;
    299:
    300:         // set the umask first before attempt mkdir
    301:         umask(0);
    302:
    303:         /*
    304:          * Create the logs directory, then instantiate a new logger
    305:          */
    306:         try {
    307:             $logsDir = $config->get('app.file.store.dir').'logs';
    308:
    309:             echo '<p>Attempting to create the logs directory <em>'.$logsDir.'</em>...';
    310:
    311:             if(!file_exists($logsDir))
    312:                 mkdir($logsDir, 0766);
    313:
    314:             $this->copyRestrictedAccessFileToDirectory($logsDir);
    315:
    316:             self::$logger = new Logger('Install');
    317:             self::$logger->info('Started installation process!');
    318:             self::$logger->info('Logs directory ['.$logsDir.'] successfully created');
    319:             echo AlphaView::displayUpdateMessage('Logs directory ['.$logsDir.'] successfully created');
    320:         }catch (Exception $e) {
    321:             echo AlphaView::displayErrorMessage($e->getMessage());
    322:             echo AlphaView::displayErrorMessage('Aborting.');
    323:             exit;
    324:         }
    325:
    326:         /*
    327:          * Create the cron tasks directory
    328:          */
    329:         try {
    330:             $tasksDir = $config->get('app.root').'tasks';
    331:
    332:             echo '<p>Attempting to create the tasks directory <em>'.$tasksDir.'</em>...';
    333:
    334:             if(!file_exists($tasksDir))
    335:                 mkdir($tasksDir, 0766);
    336:
    337:             $this->copyRestrictedAccessFileToDirectory($logsDir);
    338:
    339:             self::$logger->info('Tasks directory ['.$tasksDir.'] successfully created');
    340:             echo AlphaView::displayUpdateMessage('Tasks directory ['.$tasksDir.'] successfully created');
    341:         }catch (Exception $e) {
    342:             echo AlphaView::displayErrorMessage($e->getMessage());
    343:             echo AlphaView::displayErrorMessage('Aborting.');
    344:             exit;
    345:         }
    346:
    347:         /*
    348:          * Create the controller directory
    349:          */
    350:         try {
    351:             $controllerDir = $config->get('app.root').'controller';
    352:
    353:             echo '<p>Attempting to create the controller directory <em>'.$controllerDir.'</em>...';
    354:
    355:             if(!file_exists($controllerDir))
    356:                 mkdir($controllerDir, 0766);
    357:
    358:             self::$logger->info('Controller directory ['.$controllerDir.'] successfully created');
    359:             echo AlphaView::displayUpdateMessage('Controllers directory ['.$controllerDir.'] successfully created');
    360:         }catch (Exception $e) {
    361:             echo AlphaView::displayErrorMessage($e->getMessage());
    362:             echo AlphaView::displayErrorMessage('Aborting.');
    363:             exit;
    364:         }
    365:
    366:         /*
    367:          * Create the model directory
    368:          */
    369:         try {
    370:             $modelDir = $config->get('app.root').'model';
    371:
    372:             echo '<p>Attempting to create the model directory <em>'.$modelDir.'</em>...';
    373:
    374:             if(!file_exists($modelDir))
    375:                 mkdir($modelDir, 0766);
    376:
    377:             $this->copyRestrictedAccessFileToDirectory($modelDir);
    378:
    379:             self::$logger->info('Model directory ['.$modelDir.'] successfully created');
    380:             echo AlphaView::displayUpdateMessage('Model directory ['.$modelDir.'] successfully created');
    381:         }catch (Exception $e) {
    382:             echo AlphaView::displayErrorMessage($e->getMessage());
    383:             echo AlphaView::displayErrorMessage('Aborting.');
    384:             exit;
    385:         }
    386:
    387:         /*
    388:          * Create the view directory
    389:          */
    390:         try {
    391:             $viewDir = $config->get('app.root').'view';
    392:
    393:             echo '<p>Attempting to create the view directory <em>'.$viewDir.'</em>...';
    394:
    395:             if(!file_exists($viewDir))
    396:                 mkdir($viewDir, 0766);
    397:
    398:             $this->copyRestrictedAccessFileToDirectory($viewDir);
    399:
    400:             self::$logger->info('View directory ['.$viewDir.'] successfully created');
    401:             echo AlphaView::displayUpdateMessage('View directory ['.$viewDir.'] successfully created');
    402:         }catch (Exception $e) {
    403:             echo AlphaView::displayErrorMessage($e->getMessage());
    404:             echo AlphaView::displayErrorMessage('Aborting.');
    405:             exit;
    406:         }
    407:
    408:         /*
    409:          * Create the attachments directory
    410:          */
    411:         try {
    412:             $attachmentsDir = $config->get('app.file.store.dir').'attachments';
    413:
    414:             echo '<p>Attempting to create the attachments directory <em>'.$attachmentsDir.'</em>...';
    415:
    416:             if(!file_exists($attachmentsDir))
    417:                 mkdir($attachmentsDir, 0766);
    418:
    419:             $this->copyRestrictedAccessFileToDirectory($attachmentsDir);
    420:
    421:             self::$logger->info('Attachments directory ['.$attachmentsDir.'] successfully created');
    422:             echo AlphaView::displayUpdateMessage('Attachments directory ['.$attachmentsDir.'] successfully created');
    423:         }catch (Exception $e) {
    424:             echo AlphaView::displayErrorMessage($e->getMessage());
    425:             echo AlphaView::displayErrorMessage('Aborting.');
    426:             exit;
    427:         }
    428:
    429:         /*
    430:          * Create the cache directory and sub-directories
    431:          */
    432:         try {
    433:             $cacheDir = $config->get('app.file.store.dir').'cache';
    434:             $htmlDir = $config->get('app.file.store.dir').'cache/html';
    435:             $imagesDir = $config->get('app.file.store.dir').'cache/images';
    436:             $pdfDir = $config->get('app.file.store.dir').'cache/pdf';
    437:             $xlsDir = $config->get('app.file.store.dir').'cache/xls';
    438:
    439:             // cache
    440:             echo '<p>Attempting to create the cache directory <em>'.$cacheDir.'</em>...';
    441:             if(!file_exists($cacheDir))
    442:                 mkdir($cacheDir, 0766);
    443:
    444:             $this->copyRestrictedAccessFileToDirectory($cacheDir);
    445:
    446:             self::$logger->info('Cache directory ['.$cacheDir.'] successfully created');
    447:             echo AlphaView::displayUpdateMessage('Cache directory ['.$cacheDir.'] successfully created');
    448:
    449:             // cache/html
    450:             echo '<p>Attempting to create the HTML cache directory <em>'.$htmlDir.'</em>...';
    451:             if(!file_exists($htmlDir))
    452:                 mkdir($htmlDir, 0766);
    453:
    454:             $this->copyRestrictedAccessFileToDirectory($htmlDir);
    455:
    456:             self::$logger->info('Cache directory ['.$htmlDir.'] successfully created');
    457:             echo AlphaView::displayUpdateMessage('Cache directory ['.$htmlDir.'] successfully created');
    458:
    459:             // cache/images
    460:             echo '<p>Attempting to create the cache directory <em>'.$imagesDir.'</em>...';
    461:             if(!file_exists($imagesDir))
    462:                 mkdir($imagesDir, 0766);
    463:
    464:             $this->copyRestrictedAccessFileToDirectory($imagesDir);
    465:
    466:             self::$logger->info('Cache directory ['.$imagesDir.'] successfully created');
    467:             echo AlphaView::displayUpdateMessage('Cache directory ['.$imagesDir.'] successfully created');
    468:
    469:             // cache/pdf
    470:             echo '<p>Attempting to create the cache directory <em>'.$pdfDir.'</em>...';
    471:             if(!file_exists($pdfDir))
    472:                 mkdir($pdfDir, 0766);
    473:
    474:             $this->copyRestrictedAccessFileToDirectory($pdfDir);
    475:
    476:             self::$logger->info('Cache directory ['.$pdfDir.'] successfully created');
    477:             echo AlphaView::displayUpdateMessage('Cache directory ['.$pdfDir.'] successfully created');
    478:
    479:             // cache/xls
    480:             echo '<p>Attempting to create the cache directory <em>'.$xlsDir.'</em>...';
    481:             if(!file_exists($xlsDir))
    482:                 mkdir($xlsDir, 0766);
    483:
    484:             $this->copyRestrictedAccessFileToDirectory($xlsDir);
    485:
    486:             self::$logger->info('Cache directory ['.$xlsDir.'] successfully created');
    487:             echo AlphaView::displayUpdateMessage('Cache directory ['.$xlsDir.'] successfully created');
    488:         }catch (Exception $e) {
    489:             echo AlphaView::displayErrorMessage($e->getMessage());
    490:             echo AlphaView::displayErrorMessage('Aborting.');
    491:             exit;
    492:         }
    493:     }
    494:
    495:     /**
    496:      * Handle POST requests
    497:      *
    498:      * @param array $params
    499:      * @since 1.0
    500:      */
    501:     public function doPOST($params) {
    502:         self::$logger->debug('>>doPOST($params=['.var_export($params, true).'])');
    503:
    504:         self::$logger->debug('<<doPOST');
    505:     }
    506:
    507:     /**
    508:      * Custom version of the check rights method that only checks for a session for the config admin username/password,
    509:      * when the system database is not set-up
    510:      *
    511:      * @return boolean
    512:      * @since 1.0
    513:      */
    514:     public function checkRights() {
    515:         self::$logger->debug('>>checkRights()');
    516:
    517:         global $config;
    518:
    519:         if ($this->getVisibility() == 'Public') {
    520:             self::$logger->debug('<<checkRights [true]');
    521:             return true;
    522:         }
    523:
    524:         if(AlphaDAO::isInstalled()) {
    525:             self::$logger->debug('<<checkRights [false]');
    526:             return false;
    527:         }
    528:
    529:         // the person is logged in?
    530:         if (isset($_SESSION['currentUser'])) {
    531:             if ($_SESSION['currentUser']->get('email') == $config->get('app.install.username')) {
    532:                 self::$logger->debug('<<checkRights [true]');
    533:                 return true;
    534:             }
    535:         }
    536:     }
    537: }
    538:
    539: // now build the new controller
    540: if(basename($_SERVER['PHP_SELF']) == 'Install.php') {
    541:     $controller = new Install();
    542:
    543:     if(!empty($_POST)) {
    544:         $controller->doPOST($_REQUEST);
    545:     }else{
    546:         $controller->doGET($_GET);
    547:     }
    548: }
    549:
    550: ?>