      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 1765 2014-04-22 21:26:23Z alphadevx $
     19:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
     20:  * @copyright Copyright (c) 2014, 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:         echo '<h1>Installing the '.$config->get('app.title').' application</h1>';
    117:
    118:         $this->createAppDirectories();
    119:
    120:         // start a new database transaction
    121:         AlphaDAO::begin();
    122:
    123:         /*
    124:          * Create DEnum tables
    125:          */
    126:         $DEnum = new DEnum();
    127:         $DEnumItem = new DEnumItem();
    128:         try{
    129:             echo '<p>Attempting to create the DEnum tables...';
    130:             if(!$DEnum->checkTableExists())
    131:                 $DEnum->makeTable();
    132:             self::$logger->info('Created the ['.$DEnum->getTableName().'] table successfully');
    133:
    134:             if(!$DEnumItem->checkTableExists())
    135:                 $DEnumItem->makeTable();
    136:             self::$logger->info('Created the ['.$DEnumItem->getTableName().'] table successfully');
    137:
    138:
    139:             // create a default article DEnum category
    140:             $DEnum = new DEnum('ArticleObject::section');
    141:             $DEnumItem = new DEnumItem();
    142:             $DEnumItem->set('value', 'Main');
    143:             $DEnumItem->set('DEnumID', $DEnum->getID());
    144:             $DEnumItem->save();
    145:
    146:             echo AlphaView::displayUpdateMessage('DEnums set up successfully.');
    147:         }catch (Exception $e) {
    148:             echo AlphaView::displayErrorMessage($e->getMessage());
    149:             echo AlphaView::displayErrorMessage('Aborting.');
    150:             self::$logger->error($e->getMessage());
    151:             AlphaDAO::rollback();
    152:             exit;
    153:         }
    154:
    155:         /*
    156:          * Loop over each business object in the system, and create a table for it
    157:          */
    158:         $classNames = AlphaDAO::getBOClassNames();
    159:         $loadedClasses = array();
    160:
    161:         foreach($classNames as $classname) {
    162:             AlphaDAO::loadClassDef($classname);
    163:             array_push($loadedClasses, $classname);
    164:         }
    165:
    166:         foreach($loadedClasses as $classname) {
    167:             try {
    168:                 echo '<p>Attempting to create the table for the class ['.$classname.']...';
    169:
    170:                 try {echo '1<br>';
    171:                     $BO = new $classname();
    172:
    173:                     if(!$BO->checkTableExists()) {
    174:                         $BO->makeTable();
    175:                     }else{
    176:                         if($BO->checkTableNeedsUpdate()) {
    177:                             $missingFields = $BO->findMissingFields();
    178:
    179:                             $count = count($missingFields);
    180:
    181:                             for($i = 0; $i < $count; $i++)
    182:                                 $BO->addProperty($missingFields[$i]);
    183:                         }
    184:                     }
    185:                 }catch (FailedIndexCreateException $eice) {
    186:                     // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    187:                     self::$logger->warn($eice->getMessage());
    188:                 }catch (FailedLookupCreateException $elce) {
    189:                     // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    190:                     self::$logger->warn($elce->getMessage());
    191:                 }
    192:
    193:                 self::$logger->info('Created the ['.$BO->getTableName().'] table successfully');
    194:                 echo AlphaView::displayUpdateMessage('Created the ['.$BO->getTableName().'] table successfully');
    195:             }catch (Exception $e) {
    196:                 echo AlphaView::displayErrorMessage($e->getMessage());
    197:                 echo AlphaView::displayErrorMessage('Aborting.');
    198:                 self::$logger->error($e->getMessage());
    199:                 AlphaDAO::rollback();
    200:                 exit;
    201:             }
    202:         }
    203:
    204:         echo AlphaView::displayUpdateMessage('All business object tables created successfully!');
    205:
    206:         /*
    207:          * Create the Admin and Standard groups
    208:          */
    209:         $adminGroup = new RightsObject();
    210:         $adminGroup->set('name', 'Admin');
    211:         $standardGroup = new RightsObject();
    212:         $standardGroup->set('name', 'Standard');
    213:         try{
    214:             try{
    215:                 echo '<p>Attempting to create the Admin and Standard groups...';
    216:                 $adminGroup->save();
    217:                 $standardGroup->save();
    218:
    219:                 self::$logger->info('Created the Admin and Standard rights groups successfully');
    220:                 echo AlphaView::displayUpdateMessage('Created the Admin and Standard rights groups successfully');
    221:             }catch (FailedIndexCreateException $eice) {
    222:                 // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    223:                 self::$logger->warn($eice->getMessage());
    224:             }catch (FailedLookupCreateException $elce) {
    225:                 // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    226:                 self::$logger->warn($elce->getMessage());
    227:             }
    228:         }catch (Exception $e) {
    229:             echo AlphaView::displayErrorMessage($e->getMessage());
    230:             echo AlphaView::displayErrorMessage('Aborting.');
    231:             self::$logger->error($e->getMessage());
    232:             AlphaDAO::rollback();
    233:             exit;
    234:         }
    235:
    236:         /*
    237:          * Save the admin user to the database in the right group
    238:          */
    239:         try{
    240:             try {
    241:                 echo '<p>Attempting to save the Admin account...';
    242:                 $admin = new PersonObject();
    243:                 $admin->set('displayName', 'Admin');
    244:                 $admin->set('email', $_SESSION['currentUser']->get('email'));
    245:                 $admin->set('password', $_SESSION['currentUser']->get('password'));
    246:                 $admin->save();
    247:                 self::$logger->info('Created the admin user account ['.$_SESSION['currentUser']->get('email').'] successfully');
    248:
    249:                 $adminGroup->loadByAttribute('name', 'Admin');
    250:
    251:                 $lookup = $adminGroup->getMembers()->getLookup();
    252:                 $lookup->setValue(array($admin->getID(), $adminGroup->getID()));
    253:                 $lookup->save();
    254:
    255:                 self::$logger->info('Added the admin account to the Admin group successfully');
    256:                 echo AlphaView::displayUpdateMessage('Added the admin account to the Admin group successfully');
    257:             }catch (FailedIndexCreateException $eice) {
    258:                 // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    259:                 self::$logger->warn($eice->getMessage());
    260:             }catch (FailedLookupCreateException $elce) {
    261:                 // this are safe to ignore for now as they will be auto-created later once all of the tables are in place
    262:                 self::$logger->warn($elce->getMessage());
    263:             }
    264:         }catch (Exception $e) {
    265:             echo AlphaView::displayErrorMessage($e->getMessage());
    266:             echo AlphaView::displayErrorMessage('Aborting.');
    267:             self::$logger->error($e->getMessage());
    268:             AlphaDAO::rollback();
    269:             exit;
    270:         }
    271:
    272:         echo '<br><p align="center"><a href="'.FrontController::generateSecureURL('act=ListBusinessObjects').'">Administration Home Page</a></p><br>';
    273:         echo AlphaView::displayPageFoot($this);
    274:
    275:         // commit
    276:         AlphaDAO::commit();
    277:
    278:         self::$logger->info('Finished installation!');
    279:         self::$logger->action('Installed the application');
    280:         self::$logger->debug('<<doGET');
    281:     }
    282:
    283:     /**
    284:      * Copies a .htaccess file that restricts public access to the target directory
    285:      *
    286:      * @param string $dir
    287:      * @since 1.0
    288:      */
    289:     private function copyRestrictedAccessFileToDirectory($dir) {
    290:         global $config;
    291:
    292:         copy($config->get('app.root').'alpha/.htaccess', $dir.'/.htaccess');
    293:     }
    294:
    295:     /**
    296:      * Creates the standard application directories
    297:      *
    298:      * @since 1.0
    299:      */
    300:     private function createAppDirectories() {
    301:         global $config;
    302:
    303:         // set the umask first before attempt mkdir
    304:         umask(0);
    305:
    306:         /*
    307:          * Create the logs directory, then instantiate a new logger
    308:          */
    309:         try {
    310:             $logsDir = $config->get('app.file.store.dir').'logs';
    311:
    312:             echo '<p>Attempting to create the logs directory <em>'.$logsDir.'</em>...';
    313:
    314:             if(!file_exists($logsDir))
    315:                 mkdir($logsDir, 0774);
    316:
    317:             $this->copyRestrictedAccessFileToDirectory($logsDir);
    318:
    319:             self::$logger = new Logger('Install');
    320:             self::$logger->info('Started installation process!');
    321:             self::$logger->info('Logs directory ['.$logsDir.'] successfully created');
    322:             echo AlphaView::displayUpdateMessage('Logs directory ['.$logsDir.'] successfully created');
    323:         }catch (Exception $e) {
    324:             echo AlphaView::displayErrorMessage($e->getMessage());
    325:             echo AlphaView::displayErrorMessage('Aborting.');
    326:             exit;
    327:         }
    328:
    329:         /*
    330:          * Create the cron tasks directory
    331:          */
    332:         try {
    333:             $tasksDir = $config->get('app.root').'tasks';
    334:
    335:             echo '<p>Attempting to create the tasks directory <em>'.$tasksDir.'</em>...';
    336:
    337:             if(!file_exists($tasksDir))
    338:                 mkdir($tasksDir, 0774);
    339:
    340:             $this->copyRestrictedAccessFileToDirectory($logsDir);
    341:
    342:             self::$logger->info('Tasks directory ['.$tasksDir.'] successfully created');
    343:             echo AlphaView::displayUpdateMessage('Tasks directory ['.$tasksDir.'] successfully created');
    344:         }catch (Exception $e) {
    345:             echo AlphaView::displayErrorMessage($e->getMessage());
    346:             echo AlphaView::displayErrorMessage('Aborting.');
    347:             exit;
    348:         }
    349:
    350:         /*
    351:          * Create the controller directory
    352:          */
    353:         try {
    354:             $controllerDir = $config->get('app.root').'controller';
    355:
    356:             echo '<p>Attempting to create the controller directory <em>'.$controllerDir.'</em>...';
    357:
    358:             if(!file_exists($controllerDir))
    359:                 mkdir($controllerDir, 0774);
    360:
    361:             self::$logger->info('Controller directory ['.$controllerDir.'] successfully created');
    362:             echo AlphaView::displayUpdateMessage('Controllers directory ['.$controllerDir.'] successfully created');
    363:         }catch (Exception $e) {
    364:             echo AlphaView::displayErrorMessage($e->getMessage());
    365:             echo AlphaView::displayErrorMessage('Aborting.');
    366:             exit;
    367:         }
    368:
    369:         /*
    370:          * Create the model directory
    371:          */
    372:         try {
    373:             $modelDir = $config->get('app.root').'model';
    374:
    375:             echo '<p>Attempting to create the model directory <em>'.$modelDir.'</em>...';
    376:
    377:             if(!file_exists($modelDir))
    378:                 mkdir($modelDir, 0774);
    379:
    380:             $this->copyRestrictedAccessFileToDirectory($modelDir);
    381:
    382:             self::$logger->info('Model directory ['.$modelDir.'] successfully created');
    383:             echo AlphaView::displayUpdateMessage('Model directory ['.$modelDir.'] successfully created');
    384:         }catch (Exception $e) {
    385:             echo AlphaView::displayErrorMessage($e->getMessage());
    386:             echo AlphaView::displayErrorMessage('Aborting.');
    387:             exit;
    388:         }
    389:
    390:         /*
    391:          * Create the view directory
    392:          */
    393:         try {
    394:             $viewDir = $config->get('app.root').'view';
    395:
    396:             echo '<p>Attempting to create the view directory <em>'.$viewDir.'</em>...';
    397:
    398:             if(!file_exists($viewDir))
    399:                 mkdir($viewDir, 0774);
    400:
    401:             $this->copyRestrictedAccessFileToDirectory($viewDir);
    402:
    403:             self::$logger->info('View directory ['.$viewDir.'] successfully created');
    404:             echo AlphaView::displayUpdateMessage('View directory ['.$viewDir.'] successfully created');
    405:         }catch (Exception $e) {
    406:             echo AlphaView::displayErrorMessage($e->getMessage());
    407:             echo AlphaView::displayErrorMessage('Aborting.');
    408:             exit;
    409:         }
    410:
    411:         /*
    412:          * Create the attachments directory
    413:          */
    414:         try {
    415:             $attachmentsDir = $config->get('app.file.store.dir').'attachments';
    416:
    417:             echo '<p>Attempting to create the attachments directory <em>'.$attachmentsDir.'</em>...';
    418:
    419:             if(!file_exists($attachmentsDir))
    420:                 mkdir($attachmentsDir, 0774);
    421:
    422:             $this->copyRestrictedAccessFileToDirectory($attachmentsDir);
    423:
    424:             self::$logger->info('Attachments directory ['.$attachmentsDir.'] successfully created');
    425:             echo AlphaView::displayUpdateMessage('Attachments directory ['.$attachmentsDir.'] successfully created');
    426:         }catch (Exception $e) {
    427:             echo AlphaView::displayErrorMessage($e->getMessage());
    428:             echo AlphaView::displayErrorMessage('Aborting.');
    429:             exit;
    430:         }
    431:
    432:         /*
    433:          * Create the cache directory and sub-directories
    434:          */
    435:         try {
    436:             $cacheDir = $config->get('app.file.store.dir').'cache';
    437:             $htmlDir = $config->get('app.file.store.dir').'cache/html';
    438:             $imagesDir = $config->get('app.file.store.dir').'cache/images';
    439:             $pdfDir = $config->get('app.file.store.dir').'cache/pdf';
    440:             $xlsDir = $config->get('app.file.store.dir').'cache/xls';
    441:
    442:             // cache
    443:             echo '<p>Attempting to create the cache directory <em>'.$cacheDir.'</em>...';
    444:             if(!file_exists($cacheDir))
    445:                 mkdir($cacheDir, 0774);
    446:
    447:             $this->copyRestrictedAccessFileToDirectory($cacheDir);
    448:
    449:             self::$logger->info('Cache directory ['.$cacheDir.'] successfully created');
    450:             echo AlphaView::displayUpdateMessage('Cache directory ['.$cacheDir.'] successfully created');
    451:
    452:             // cache/html
    453:             echo '<p>Attempting to create the HTML cache directory <em>'.$htmlDir.'</em>...';
    454:             if(!file_exists($htmlDir))
    455:                 mkdir($htmlDir, 0774);
    456:
    457:             $this->copyRestrictedAccessFileToDirectory($htmlDir);
    458:
    459:             self::$logger->info('Cache directory ['.$htmlDir.'] successfully created');
    460:             echo AlphaView::displayUpdateMessage('Cache directory ['.$htmlDir.'] successfully created');
    461:
    462:             // cache/images
    463:             echo '<p>Attempting to create the cache directory <em>'.$imagesDir.'</em>...';
    464:             if(!file_exists($imagesDir))
    465:                 mkdir($imagesDir, 0774);
    466:
    467:             $this->copyRestrictedAccessFileToDirectory($imagesDir);
    468:
    469:             self::$logger->info('Cache directory ['.$imagesDir.'] successfully created');
    470:             echo AlphaView::displayUpdateMessage('Cache directory ['.$imagesDir.'] successfully created');
    471:
    472:             // cache/pdf
    473:             echo '<p>Attempting to create the cache directory <em>'.$pdfDir.'</em>...';
    474:             if(!file_exists($pdfDir))
    475:                 mkdir($pdfDir, 0774);
    476:
    477:             $this->copyRestrictedAccessFileToDirectory($pdfDir);
    478:
    479:             self::$logger->info('Cache directory ['.$pdfDir.'] successfully created');
    480:             echo AlphaView::displayUpdateMessage('Cache directory ['.$pdfDir.'] successfully created');
    481:
    482:             // cache/xls
    483:             echo '<p>Attempting to create the cache directory <em>'.$xlsDir.'</em>...';
    484:             if(!file_exists($xlsDir))
    485:                 mkdir($xlsDir, 0774);
    486:
    487:             $this->copyRestrictedAccessFileToDirectory($xlsDir);
    488:
    489:             self::$logger->info('Cache directory ['.$xlsDir.'] successfully created');
    490:             echo AlphaView::displayUpdateMessage('Cache directory ['.$xlsDir.'] successfully created');
    491:         }catch (Exception $e) {
    492:             echo AlphaView::displayErrorMessage($e->getMessage());
    493:             echo AlphaView::displayErrorMessage('Aborting.');
    494:             exit;
    495:         }
    496:     }
    497:
    498:     /**
    499:      * Handle POST requests
    500:      *
    501:      * @param array $params
    502:      * @since 1.0
    503:      */
    504:     public function doPOST($params) {
    505:         self::$logger->debug('>>doPOST($params=['.var_export($params, true).'])');
    506:
    507:         self::$logger->debug('<<doPOST');
    508:     }
    509:
    510:     /**
    511:      * Custom version of the check rights method that only checks for a session for the config admin username/password,
    512:      * when the system database is not set-up
    513:      *
    514:      * @return boolean
    515:      * @since 1.0
    516:      */
    517:     public function checkRights() {
    518:         self::$logger->debug('>>checkRights()');
    519:
    520:         global $config;
    521:
    522:         if ($this->getVisibility() == 'Public') {
    523:             self::$logger->debug('<<checkRights [true]');
    524:             return true;
    525:         }
    526:
    527:         if(AlphaDAO::isInstalled()) {
    528:             self::$logger->debug('<<checkRights [false]');
    529:             return false;
    530:         }
    531:
    532:         // the person is logged in?
    533:         if (isset($_SESSION['currentUser'])) {
    534:             if ($_SESSION['currentUser']->get('email') == $config->get('app.install.username')) {
    535:                 self::$logger->debug('<<checkRights [true]');
    536:                 return true;
    537:             }
    538:         }
    539:     }
    540: }
    541:
    542: // now build the new controller
    543: if(basename($_SERVER['PHP_SELF']) == 'Install.php') {
    544:     $controller = new Install();
    545:
    546:     if(!empty($_POST)) {
    547:         $controller->doPOST($_REQUEST);
    548:     }else{
    549:         $controller->doGET($_GET);
    550:     }
    551: }
    552:
    553: ?>