/** * constructor to set up the object. * * @since 1.0 */ public function __construct() { self::$logger = new Logger('LogoutController'); self::$logger->debug('>>__construct()'); // ensure that the super class constructor is called, indicating the rights group parent::__construct('Public'); $config = ConfigProvider::getInstance(); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); if ($session->get('currentUser') !== false) { $this->setRecord($session->get('currentUser')); } else { self::$logger->warn('Logout controller called when no user is logged in'); } // set up the title and meta details $this->setTitle('Logged out successfully.'); $this->setDescription('Logout page.'); $this->setKeywords('Logout,logon'); self::$logger->debug('<<__construct'); }
/** * (non-PHPdoc). * * @see Alpha\Model\ActiveRecordProviderInterface::isTableOverloaded() */ public function isTableOverloaded() { self::$logger->debug('>>isTableOverloaded()'); $reflection = new ReflectionClass($this->BO); $classname = $reflection->getShortName(); $tablename = ucfirst($this->BO->getTableName()); // use reflection to check to see if we are dealing with a persistent type (e.g. DEnum) which are never overloaded $implementedInterfaces = $reflection->getInterfaces(); foreach ($implementedInterfaces as $interface) { if ($interface->name == 'Alpha\\Model\\Type\\TypeInterface') { self::$logger->debug('<<isTableOverloaded [false]'); return false; } } if ($classname != $tablename) { // loop over all BOs to see if there is one using the same table as this BO $BOclasses = ActiveRecord::getBOClassNames(); foreach ($BOclasses as $BOclassName) { $reflection = new ReflectionClass($BOclassName); $classname = $reflection->getShortName(); if ($tablename == $classname) { self::$logger->debug('<<isTableOverloaded [true]'); return true; } } throw new BadTableNameException('The table name [' . $tablename . '] for the class [' . $classname . '] is invalid as it does not match a BO definition in the system!'); self::$logger->debug('<<isTableOverloaded [false]'); return false; } else { // check to see if there is already a "classname" column in the database for this BO $sqlQuery = 'PRAGMA table_info(' . $this->BO->getTableName() . ')'; $result = self::getConnection()->query($sqlQuery); $this->BO->setLastQuery($sqlQuery); if (!$result) { self::$logger->warn('Error during pragma table info lookup [' . self::getLastDatabaseError() . ']'); } else { while ($row = $result->fetchArray(SQLITE3_ASSOC)) { if ('classname' == $row['name']) { self::$logger->debug('<<isTableOverloaded [true]'); return true; } } } self::$logger->debug('<<isTableOverloaded [false]'); return false; } }
/** * Handle GET requests. * * @param Alpha\Util\Http\Request $request * * @return Alpha\Util\Http\Response * * @since 1.0 */ public function doGET($request) { self::$logger->debug('>>doGET(request=[' . var_export($request, true) . '])'); $config = ConfigProvider::getInstance(); if ($config->get('app.check.installed') && !ActiveRecord::isInstalled()) { $response = new Response(301); $response->redirect($config->get('app.url') . '/install'); self::$logger->warn('App not installed so re-directing to the install controller'); self::$logger->debug('<<doGET'); return $response; } $params = $request->getParams(); $body = View::loadTemplateFragment('html', 'head.phtml', array('title' => $config->get('app.title'), 'description' => 'Welcome to our site', 'allowCSSOverrides' => true)); $body .= View::loadTemplateFragment('html', 'index.phtml'); $body .= View::loadTemplateFragment('html', 'footer.phtml'); self::$logger->debug('<<doGET'); return new Response(200, $body, array('Content-Type' => 'text/html')); }
/** * Handle POST requests. * * @param Alpha\Util\Http\Response $request * * @throws Alpha\Exception\SecurityException * @throws Alpha\Exception\IllegalArguementException * * @return Alpha\Util\Http\Response * * @since 1.0 */ public function doPOST($request) { self::$logger->debug('>>doPOST($request=[' . var_export($request, true) . '])'); $params = $request->getParams(); try { // check the hidden security fields before accepting the form POST data if (!$this->checkSecurityFields()) { throw new SecurityException('This page cannot accept post data from remote servers!'); } if (!is_array($params)) { throw new IllegalArguementException('Bad $params [' . var_export($params, true) . '] passed to doPOST method!'); } if (isset($params['clearCache']) && $params['clearCache'] == 'true') { try { FileUtils::deleteDirectoryContents($this->dataDir, array('.htaccess', 'html', 'images', 'pdf', 'xls')); $this->setStatusMessage(View::displayUpdateMessage('Cache contents deleted successfully.')); $config = ConfigProvider::getInstance(); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); self::$logger->info('Cache contents deleted successfully by user [' . $session->get('currentUser')->get('displayName') . '].'); } catch (AlphaException $e) { self::$logger->error($e->getMessage()); $this->setStatusMessage(View::displayErrorMessage($e->getMessage())); } } return $this->doGET($request); } catch (SecurityException $e) { $this->setStatusMessage(View::displayErrorMessage($e->getMessage())); self::$logger->warn($e->getMessage()); } catch (IllegalArguementException $e) { self::$logger->error($e->getMessage()); $this->setStatusMessage(View::displayErrorMessage($e->getMessage())); } $body = View::displayPageHead($this); $message = $this->getStatusMessage(); if (!empty($message)) { $body .= $message; } $body .= View::displayPageFoot($this); self::$logger->debug('<<doPOST'); return new Response(200, $body, array('Content-Type' => 'text/html')); }
/** * {@inheritdoc} */ public function process($request) { $client = $request->getUserAgent(); // if no user agent string is provided, we can't filter by it anyway to might as well skip if ($client == null) { return; } if (!empty($client)) { $badClient = new BlacklistedClient(); try { $badClient->loadByAttribute('client', $client); } catch (RecordNotFoundException $bonf) { // client is not on the list! return; } // if we got this far then the client is bad self::$logger->warn('The client [' . $client . '] was blocked from accessing the resource [' . $request->getURI() . ']'); throw new ResourceNotAllowedException('Not allowed!'); } }
/** * {@inheritdoc} */ public function process($request) { $config = ConfigProvider::getInstance(); $client = $request->getUserAgent(); $IP = $request->getIP(); // if no user agent string or IP are provided, we can't filter by these anyway to might as well skip if ($client == null || $IP == null) { return; } if (!empty($client) && !empty($IP)) { $badRequest = new BadRequest(); $badRequest->set('client', $client); $badRequest->set('IP', $IP); $badRequestCount = $badRequest->getBadRequestCount(); if ($badRequestCount >= $config->get('security.client.temp.blacklist.filter.limit')) { // if we got this far then the client is bad self::$logger->warn('The client [' . $client . '] was blocked from accessing the resource [' . $request->getURI() . '] on a temporary basis'); throw new ResourceNotAllowedException('Not allowed!'); } } }
/** * Handle GET requests. * * @param Alpha\Util\Http\Request $request * * @return Alpha\Util\Http\Response * * @throws Alpha\Exception\IllegalArguementException * * @since 1.0 */ public function doGET($request) { self::$logger->debug('>>doGET($request=[' . var_export($request, true) . '])'); $params = $request->getParams(); $body = ''; try { // load the business object (BO) definition if (isset($params['logPath']) && file_exists(urldecode($params['logPath']))) { $logPath = urldecode($params['logPath']); } else { throw new IllegalArguementException('No log file available to view!'); } $this->logPath = $logPath; $body .= View::displayPageHead($this); $log = new LogProviderFile(); $log->setPath($this->logPath); if (preg_match('/alpha.*/', basename($this->logPath))) { $body .= $log->renderLog(array('Date/time', 'Level', 'Class', 'Message', 'Client', 'IP', 'Server hostname', 'URI')); } if (preg_match('/search.*/', basename($this->logPath))) { $body .= $log->renderLog(array('Search query', 'Search date', 'Client Application', 'Client IP')); } if (preg_match('/feeds.*/', basename($this->logPath))) { $body .= $log->renderLog(array('Business object', 'Feed type', 'Request date', 'Client Application', 'Client IP')); } if (preg_match('/tasks.*/', basename($this->logPath))) { $body .= $log->renderLog(array('Date/time', 'Level', 'Class', 'Message')); } $body .= View::displayPageFoot($this); } catch (IllegalArguementException $e) { self::$logger->warn($e->getMessage()); $body .= View::displayPageHead($this); $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayPageFoot($this); } self::$logger->debug('<<doGET'); return new Response(200, $body, array('Content-Type' => 'text/html')); }
/** * Handle POST requests. * * @param alpha\Util\Http\Request $request * * @return alpha\Util\Http\Response * * @since 1.0 */ public function doPOST($request) { self::$logger->debug('>>doPOST($request=[' . var_export($request, true) . '])'); $params = $request->getParams(); $config = ConfigProvider::getInstance(); $body = View::displayPageHead($this); try { // check the hidden security fields before accepting the form POST data if (!$this->checkSecurityFields()) { throw new SecurityException('This page cannot accept post data from remote servers!'); } if (isset($params['createTableBut'])) { try { $classname = $params['createTableClass']; $BO = new $classname(); $BO->makeTable(); self::$logger->action('Created the table for class ' . $classname); $body .= View::displayUpdateMessage('The table for the class ' . $classname . ' has been successfully created.'); } catch (AlphaException $e) { self::$logger->error($e->getMessage()); $body .= View::displayErrorMessage('Error creating the table for the class ' . $classname . ', check the log!'); } } if (isset($params['createHistoryTableBut'])) { try { $classname = $params['createTableClass']; $BO = new $classname(); $BO->makeHistoryTable(); self::$logger->action('Created the history table for class ' . $classname); $body .= View::displayUpdateMessage('The history table for the class ' . $classname . ' has been successfully created.'); } catch (AlphaException $e) { self::$logger->error($e->getMessage()); $body .= View::displayErrorMessage('Error creating the history table for the class ' . $classname . ', check the log!'); } } if (isset($params['recreateTableClass']) && $params['admin_' . stripslashes($params['recreateTableClass']) . '_button_pressed'] == 'recreateTableBut') { try { $classname = $params['recreateTableClass']; $BO = new $classname(); $BO->rebuildTable(); self::$logger->action('Recreated the table for class ' . $classname); $body .= View::displayUpdateMessage('The table for the class ' . $classname . ' has been successfully recreated.'); } catch (AlphaException $e) { self::$logger->error($e->getMessage()); $body .= View::displayErrorMessage('Error recreating the table for the class ' . $classname . ', check the log!'); } } if (isset($params['updateTableClass']) && $params['admin_' . stripslashes($params['updateTableClass']) . '_button_pressed'] == 'updateTableBut') { try { $classname = $params['updateTableClass']; $BO = new $classname(); $missingFields = $BO->findMissingFields(); $count = count($missingFields); for ($i = 0; $i < $count; ++$i) { $BO->addProperty($missingFields[$i]); } self::$logger->action('Updated the table for class ' . $classname); $body .= View::displayUpdateMessage('The table for the class ' . $classname . ' has been successfully updated.'); } catch (AlphaException $e) { self::$logger->error($e->getMessage()); $body .= View::displayErrorMessage('Error updating the table for the class ' . $classname . ', check the log!'); } } } catch (SecurityException $e) { $body .= View::displayErrorMessage($e->getMessage()); self::$logger->warn($e->getMessage()); } $body .= $this->displayBodyContent(); $body .= View::displayPageFoot($this); self::$logger->debug('<<doPOST'); return new Response(200, $body, array('Content-Type' => 'text/html')); }
/** * Delete all object instances from the database by the specified attribute matching the value provided. * * @param string $attribute The name of the field to delete the objects by. * @param mixed $value The value of the field to delete the objects by. * * @return int The number of rows deleted. * * @since 1.0 * * @throws Alpha\Exception\FailedDeleteException */ public function deleteAllByAttribute($attribute, $value) { self::$logger->debug('>>deleteAllByAttribute(attribute=[' . $attribute . '], value=[' . $value . '])'); if (method_exists($this, 'before_deleteAllByAttribute_callback')) { $this->before_deleteAllByAttribute_callback(); } try { $doomedObjects = $this->loadAllByAttribute($attribute, $value); $deletedRowCount = 0; foreach ($doomedObjects as $object) { $object->delete(); ++$deletedRowCount; } } catch (RecordNotFoundException $bonf) { // nothing found to delete self::$logger->warn($bonf->getMessage()); return 0; } catch (AlphaException $e) { throw new FailedDeleteException('Failed to delete objects, error is [' . $e->getMessage() . ']'); self::$logger->debug('<<deleteAllByAttribute [0]'); return 0; } if (method_exists($this, 'after_deleteAllByAttribute_callback')) { $this->after_deleteAllByAttribute_callback(); } self::$logger->debug('<<deleteAllByAttribute [' . $deletedRowCount . ']'); return $deletedRowCount; }
/** * Returns the name of a custom controller if one is found, otherwise returns null. * * @param string $ActiveRecordType The classname of the active record * * @return string * * @since 1.0 */ public static function getCustomControllerName($ActiveRecordType) { if (self::$logger == null) { self::$logger = new Logger('Controller'); } self::$logger->debug('>>getCustomControllerName(ActiveRecordType=[' . $ActiveRecordType . ']'); $config = ConfigProvider::getInstance(); try { $class = new ReflectionClass($ActiveRecordType); $controllerName = $class->getShortname() . 'Controller'; } catch (Exception $e) { self::$logger->warn('Bad active record name [' . $ActiveRecordType . '] passed to getCustomControllerName()'); return; } self::$logger->debug('Custom controller name is [' . $controllerName . ']'); if (file_exists($config->get('app.root') . 'Controller/' . $controllerName . '.php')) { $controllerName = 'Controller\\' . $controllerName; self::$logger->debug('<<getCustomControllerName [' . $controllerName . ']'); return $controllerName; } elseif (file_exists($config->get('app.root') . 'Alpha/Controller/' . $controllerName . '.php')) { $controllerName = 'Alpha\\Controller\\' . $controllerName; self::$logger->debug('<<getCustomControllerName [' . $controllerName . ']'); return $controllerName; } else { self::$logger->debug('<<getCustomControllerName'); return; } }
/** * Handles get requests. * * @param Alpha\Util\Http\Request $request * * @return Alpha\Util\Http\Response * * @since 1.0 * * @throws Alpha\Exception\ResourceNotFoundException * @throws Alpha\Exception\ResourceNotAllowedException */ public function doGet($request) { self::$logger->debug('>>doGet(request=[' . var_export($request, true) . '])'); $config = ConfigProvider::getInstance(); $params = $request->getParams(); try { $imgSource = urldecode($params['source']); $imgWidth = $params['width']; $imgHeight = $params['height']; $imgType = $params['type']; $imgQuality = (double) $params['quality']; $imgScale = new Boolean($params['scale']); $imgSecure = new Boolean($params['secure']); } catch (\Exception $e) { self::$logger->error('Required param missing for ImageController controller[' . $e->getMessage() . ']'); throw new ResourceNotFoundException('File not found'); } $modified = filemtime($imgSource); $responseHeaders = array(); $responseHeaders['Last-Modified'] = date('D, d M Y H:i:s', $modified) . ' GMT'; $responseHeaders['Cache-Control'] = 'max-age=1800'; // exit if not modified if ($request->getHeader('If-Modified-Since') != null) { if (strtotime($request->getHeader('If-Modified-Since')) == $modified) { return new Response(304, '', $responseHeaders); } } // handle secure tokens if ($imgSecure->getBooleanValue() && $config->get('cms.images.widget.secure')) { $valid = $this->checkSecurityFields(); // if not valid, just return a blank black image of the same dimensions if (!$valid) { $im = imagecreatetruecolor($imgWidth, $imgHeight); $bgc = imagecolorallocate($im, 0, 0, 0); imagefilledrectangle($im, 0, 0, $imgWidth, $imgHeight, $bgc); if ($imgSource == 'png' && $config->get('cms.images.perserve.png')) { ob_start(); imagepng($im); $body = ob_get_contents(); $contentType = 'image/png'; ob_end_clean(); } else { ob_start(); imagejpeg($im); $body = ob_get_contents(); $contentType = 'image/jpeg'; ob_end_clean(); } imagedestroy($im); self::$logger->warn('The client [' . $request->getUserAgent() . '] was blocked from accessing the file [' . $imgSource . '] due to bad security tokens being provided'); $responseHeaders['Content-Type'] = $contentType; return new Response(200, $body, $responseHeaders); } } try { $image = new Image($imgSource, $imgWidth, $imgHeight, $imgType, $imgQuality, $imgScale->getBooleanValue(), $imgSecure->getBooleanValue()); ob_start(); $image->renderImage(); $body = ob_get_contents(); ob_end_clean(); } catch (IllegalArguementException $e) { self::$logger->error($e->getMessage()); throw new ResourceNotFoundException('File not found'); } self::$logger->debug('<<__doGet'); if ($imgSource == 'png' && $config->get('cms.images.perserve.png')) { $responseHeaders['Content-Type'] = 'image/png'; } else { $responseHeaders['Content-Type'] = 'image/jpeg'; } return new Response(200, $body, $responseHeaders); }
/** * {@inheritdoc} */ public function getRelated($sourceObject, $returnType = 'all', $start = 0, $limit = 10, $distinct = '') { $config = ConfigProvider::getInstance(); // the result objects $results = array(); // matching tags with weights $matches = array(); // only used in conjunction with distinct param $distinctValues = array(); if ($config->get('cache.provider.name') != '') { $key = get_class($sourceObject) . '-' . $sourceObject->getOID() . '-related' . ($distinct == '' ? '' : '-distinct'); $matches = $this->loadFromCache($key); } if (count($matches) == 0) { // all the tags on the source object for comparison $tags = $sourceObject->getPropObject('tags')->getRelatedObjects(); foreach ($tags as $tag) { $Tag = new Tag(); if ($distinct == '') { $matchingTags = $Tag->query('SELECT * FROM ' . $Tag->getTableName() . " WHERE \n content='" . $tag->get('content') . "' AND NOT \n (taggedOID = '" . $sourceObject->getOID() . "' AND taggedClass = '" . get_class($sourceObject) . "');"); } else { // filter out results where the source object field is identical to distinct param $matchingTags = $Tag->query('SELECT * FROM ' . $Tag->getTableName() . " WHERE \n content='" . $tag->get('content') . "' AND NOT \n (taggedOID = '" . $sourceObject->getOID() . "' AND taggedClass = '" . get_class($sourceObject) . "')\n AND taggedOID IN (SELECT OID FROM " . $sourceObject->getTableName() . ' WHERE ' . $distinct . " != '" . addslashes($sourceObject->get($distinct)) . "');"); } foreach ($matchingTags as $matchingTag) { if ($returnType == 'all' || $tag->get('taggedClass') == $returnType) { $key = $matchingTag['taggedClass'] . '-' . $matchingTag['taggedOID']; // matches on the distinct if defined need to be skipped if ($distinct != '') { try { $BO = new $matchingTag['taggedClass'](); $BO->load($matchingTag['taggedOID']); // skip where the source object field is identical if ($sourceObject->get($distinct) == $BO->get($distinct)) { continue; } if (!in_array($BO->get($distinct), $distinctValues)) { $distinctValues[] = $BO->get($distinct); } else { continue; } } catch (RecordNotFoundException $e) { self::$logger->warn('Error loading object [' . $matchingTag['taggedOID'] . '] of type [' . $matchingTag['taggedClass'] . '], probable orphan'); } } if (isset($matches[$key])) { // increment the weight if the same BO is tagged more than once $weight = intval($matches[$key]) + 1; $matches[$key] = $weight; } else { $matches[$key] = 1; } } } if ($config->get('cache.provider.name') != '') { $key = get_class($sourceObject) . '-' . $sourceObject->getOID() . '-related' . ($distinct == '' ? '' : '-distinct'); $this->addToCache($key, $matches); } } } // sort the matches based on tag frequency weight arsort($matches); $this->numberFound = count($matches); // now paginate $matches = array_slice($matches, $start, $limit); // now load each object foreach ($matches as $key => $weight) { $parts = explode('-', $key); $BO = new $parts[0](); $BO->load($parts[1]); $results[] = $BO; } return $results; }
/** * Handle POST requests. * * @param Alpha\Util\Http\Request $request * * @return Alpha\Util\Http\Response * * @throws Alpha\Exception\SecurityException * @throws Alpha\Exception\IllegalArguementException * * @since 1.0 */ public function doPOST($request) { self::$logger->debug('>>doPOST($request=[' . var_export($request, true) . '])'); $params = $request->getParams(); try { // check the hidden security fields before accepting the form POST data if (!$this->checkSecurityFields()) { throw new SecurityException('This page cannot accept post data from remote servers!'); } if (isset($params['clearTaggedClass']) && $params['clearTaggedClass'] != '') { try { self::$logger->info('About to start rebuilding the tags for the class [' . $params['clearTaggedClass'] . ']'); $startTime = microtime(true); $record = new $params['clearTaggedClass'](); $records = $record->loadAll(); self::$logger->info('Loaded all of the active records (elapsed time [' . round(microtime(true) - $startTime, 5) . '] seconds)'); ActiveRecord::begin(); $tag = new Tag(); $tag->deleteAllByAttribute('taggedClass', $params['clearTaggedClass']); self::$logger->info('Deleted all of the old tags (elapsed time [' . round(microtime(true) - $startTime, 5) . '] seconds)'); $this->regenerateTagsOnRecords($records); self::$logger->info('Saved all of the new tags (elapsed time [' . round(microtime(true) - $startTime, 5) . '] seconds)'); self::$logger->action('Tags recreated on the [' . $params['clearTaggedClass'] . '] class'); ActiveRecord::commit(); $this->setStatusMessage(View::displayUpdateMessage('Tags recreated on the ' . $record->getFriendlyClassName() . ' class.')); self::$logger->info('Tags recreated on the [' . $params['clearTaggedClass'] . '] class (time taken [' . round(microtime(true) - $startTime, 5) . '] seconds).'); } catch (AlphaException $e) { self::$logger->error($e->getMessage()); ActiveRecord::rollback(); } ActiveRecord::disconnect(); return $this->doGET($request); } elseif (isset($params['ActiveRecordType']) && isset($params['ActiveRecordOID'])) { $ActiveRecordType = urldecode($params['ActiveRecordType']); $ActiveRecordOID = $params['ActiveRecordOID']; if (class_exists($ActiveRecordType)) { $record = new $ActiveRecordType(); } else { throw new IllegalArguementException('No ActiveRecord available to display tags for!'); } if (isset($params['saveBut'])) { try { $record->load($ActiveRecordOID); $tags = $record->getPropObject('tags')->getRelatedObjects(); ActiveRecord::begin(); foreach ($tags as $tag) { $tag->set('content', Tag::cleanTagContent($params['content_' . $tag->getID()])); $tag->save(); self::$logger->action('Saved tag ' . $tag->get('content') . ' on ' . $ActiveRecordType . ' instance with OID ' . $ActiveRecordOID); } // handle new tag if posted if (isset($params['NewTagValue']) && trim($params['NewTagValue']) != '') { $newTag = new Tag(); $newTag->set('content', Tag::cleanTagContent($params['NewTagValue'])); $newTag->set('taggedOID', $ActiveRecordOID); $newTag->set('taggedClass', $ActiveRecordType); $newTag->save(); self::$logger->action('Created a new tag ' . $newTag->get('content') . ' on ' . $ActiveRecordType . ' instance with OID ' . $ActiveRecordOID); } ActiveRecord::commit(); $this->setStatusMessage(View::displayUpdateMessage('Tags on ' . get_class($record) . ' ' . $record->getID() . ' saved successfully.')); return $this->doGET($request); } catch (ValidationException $e) { /* * The unique key has most-likely been violated because this BO is already tagged with this * value. */ ActiveRecord::rollback(); $this->setStatusMessage(View::displayErrorMessage('Tags on ' . get_class($record) . ' ' . $record->getID() . ' not saved due to duplicate tag values, please try again.')); return $this->doGET($request); } catch (FailedSaveException $e) { self::$logger->error('Unable to save the tags of id [' . $params['ActiveRecordOID'] . '], error was [' . $e->getMessage() . ']'); ActiveRecord::rollback(); $this->setStatusMessage(View::displayErrorMessage('Tags on ' . get_class($record) . ' ' . $record->getID() . ' not saved, please check the application logs.')); return $this->doGET($request); } ActiveRecord::disconnect(); } } else { return parent::doPOST($request); } } catch (SecurityException $e) { $this->setStatusMessage(View::displayErrorMessage($e->getMessage())); self::$logger->warn($e->getMessage()); } catch (IllegalArguementException $e) { self::$logger->error($e->getMessage()); } catch (RecordNotFoundException $e) { self::$logger->warn($e->getMessage()); $this->setStatusMessage(View::displayErrorMessage('Failed to load the requested item from the database!')); } self::$logger->debug('<<doPOST'); }
/** * Handle GET requests. * * @param Alpha\Util\Http\Request $request * * @return Alpha\Util\Http\Response * * @since 1.0 */ public function doGET($request) { self::$logger->debug('>>doGET($request=[' . var_export($request, true) . '])'); $config = ConfigProvider::getInstance(); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); // if there is nobody logged in, we will send them off to the Login controller to do so before coming back here if ($session->get('currentUser') === false) { self::$logger->info('Nobody logged in, invoking Login controller...'); $controller = new LoginController(); $controller->setName('LoginController'); $controller->setRequest($request); $controller->setUnitOfWork(array('Alpha\\Controller\\LoginController', 'Alpha\\Controller\\InstallController')); self::$logger->debug('<<__construct'); return $controller->doGET($request); } $params = $request->getParams(); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); $body = View::displayPageHead($this); $body .= '<h1>Installing the ' . $config->get('app.title') . ' application</h1>'; try { $body .= $this->createApplicationDirs(); } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); return new Response(500, $body, array('Content-Type' => 'text/html')); } // start a new database transaction ActiveRecord::begin(); /* * Create DEnum tables */ $DEnum = new DEnum(); $DEnumItem = new DEnumItem(); try { $body .= '<p>Attempting to create the DEnum tables...'; if (!$DEnum->checkTableExists()) { $DEnum->makeTable(); } self::$logger->info('Created the [' . $DEnum->getTableName() . '] table successfully'); if (!$DEnumItem->checkTableExists()) { $DEnumItem->makeTable(); } self::$logger->info('Created the [' . $DEnumItem->getTableName() . '] table successfully'); // create a default article DEnum category $DEnum = new DEnum('Alpha\\Model\\Article::section'); $DEnumItem = new DEnumItem(); $DEnumItem->set('value', 'Main'); $DEnumItem->set('DEnumID', $DEnum->getID()); $DEnumItem->save(); $body .= View::displayUpdateMessage('DEnums set up successfully.'); } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); self::$logger->error($e->getMessage()); ActiveRecord::rollback(); return new Response(500, $body, array('Content-Type' => 'text/html')); } /* * Loop over each business object in the system, and create a table for it */ $classNames = ActiveRecord::getBOClassNames(); $loadedClasses = array(); foreach ($classNames as $classname) { array_push($loadedClasses, $classname); } foreach ($loadedClasses as $classname) { try { $body .= '<p>Attempting to create the table for the class [' . $classname . ']...'; try { $BO = new $classname(); if (!$BO->checkTableExists()) { $BO->makeTable(); } else { if ($BO->checkTableNeedsUpdate()) { $missingFields = $BO->findMissingFields(); $count = count($missingFields); for ($i = 0; $i < $count; ++$i) { $BO->addProperty($missingFields[$i]); } } } } catch (FailedIndexCreateException $eice) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($eice->getMessage()); } catch (FailedLookupCreateException $elce) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($elce->getMessage()); } self::$logger->info('Created the [' . $BO->getTableName() . '] table successfully'); $body .= View::displayUpdateMessage('Created the [' . $BO->getTableName() . '] table successfully'); } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); self::$logger->error($e->getMessage()); ActiveRecord::rollback(); return new Response(500, $body, array('Content-Type' => 'text/html')); } } $body .= View::displayUpdateMessage('All business object tables created successfully!'); /* * Create the Admin and Standard groups */ $adminGroup = new Rights(); $adminGroup->set('name', 'Admin'); $standardGroup = new Rights(); $standardGroup->set('name', 'Standard'); try { try { $body .= '<p>Attempting to create the Admin and Standard groups...'; $adminGroup->save(); $standardGroup->save(); self::$logger->info('Created the Admin and Standard rights groups successfully'); $body .= View::displayUpdateMessage('Created the Admin and Standard rights groups successfully'); } catch (FailedIndexCreateException $eice) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($eice->getMessage()); } catch (FailedLookupCreateException $elce) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($elce->getMessage()); } } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); self::$logger->error($e->getMessage()); ActiveRecord::rollback(); return new Response(500, $body, array('Content-Type' => 'text/html')); } /* * Save the admin user to the database in the right group */ try { try { $body .= '<p>Attempting to save the Admin account...'; $admin = new Person(); $admin->set('displayName', 'Admin'); $admin->set('email', $session->get('currentUser')->get('email')); $admin->set('password', $session->get('currentUser')->get('password')); $admin->save(); self::$logger->info('Created the admin user account [' . $session->get('currentUser')->get('email') . '] successfully'); $adminGroup->loadByAttribute('name', 'Admin'); $lookup = $adminGroup->getMembers()->getLookup(); $lookup->setValue(array($admin->getID(), $adminGroup->getID())); $lookup->save(); self::$logger->info('Added the admin account to the Admin group successfully'); $body .= View::displayUpdateMessage('Added the admin account to the Admin group successfully'); } catch (FailedIndexCreateException $eice) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($eice->getMessage()); } catch (FailedLookupCreateException $elce) { // this are safe to ignore for now as they will be auto-created later once all of the tables are in place self::$logger->warn($elce->getMessage()); } } catch (\Exception $e) { $body .= View::displayErrorMessage($e->getMessage()); $body .= View::displayErrorMessage('Aborting.'); self::$logger->error($e->getMessage()); ActiveRecord::rollback(); return new Response(500, $body, array('Content-Type' => 'text/html')); } $body .= '<br><p align="center"><a href="' . FrontController::generateSecureURL('act=Alpha\\Controller\\ListActiveRecordsController') . '">Administration Home Page</a></p><br>'; $body .= View::displayPageFoot($this); // commit ActiveRecord::commit(); self::$logger->info('Finished installation!'); self::$logger->action('Installed the application'); self::$logger->debug('<<doGET'); return new Response(200, $body, array('Content-Type' => 'text/html')); }
/** * Processes the supplied request by invoking the callable defined matching the request's URI. * * @param Alpha\Util\Http\Request $request The request to process * * @return Alpha\Util\Http\Response * * @throws Alpha\Exception\ResourceNotFoundException * @throws Alpha\Exception\ResourceNotAllowedException * @throws Alpha\Exception\AlphaException * * @since 2.0 */ public function process($request) { foreach ($this->filters as $filter) { $filter->process($request); } try { $callback = $this->getRouteCallback($request->getURI()); } catch (IllegalArguementException $e) { self::$logger->warn($e->getMessage()); throw new ResourceNotFoundException('Resource not found'); } if ($request->getURI() != $this->currentRoute) { if (isset($this->defaultParamValues[$this->currentRoute])) { $request->parseParamsFromRoute($this->currentRoute, $this->defaultParamValues[$this->currentRoute]); } else { $request->parseParamsFromRoute($this->currentRoute); } } try { $response = call_user_func($callback, $request); } catch (ResourceNotFoundException $rnfe) { self::$logger->info('ResourceNotFoundException throw, source message [' . $rnfe->getMessage() . ']'); return new Response(404, $rnfe->getMessage()); } if ($response instanceof Response) { return $response; } else { self::$logger->error('The callable defined for route [' . $request->getURI() . '] does not return a Response object'); throw new AlphaException('Unable to process request'); } }
/** * Method to handle DELETE requests. * * @param Alpha\Util\Http\Request $request * * @throws Alpha\Exception\IllegalArguementException * @throws Alpha\Exception\SecurityException * * @return Alpha\Util\Http\Response * * @since 2.0 */ public function doDELETE($request) { self::$logger->debug('>>doDELETE(request=[' . var_export($request, true) . '])'); $config = ConfigProvider::getInstance(); $params = $request->getParams(); $accept = $request->getAccept(); try { // check the hidden security fields before accepting the form data if (!$this->checkSecurityFields()) { throw new SecurityException('This page cannot accept data from remote servers!'); } if (isset($params['ActiveRecordType'])) { $ActiveRecordType = urldecode($params['ActiveRecordType']); } else { throw new IllegalArguementException('No ActiveRecord available to edit!'); } if (class_exists($ActiveRecordType)) { $record = new $ActiveRecordType(); } else { throw new IllegalArguementException('No ActiveRecord [' . $ActiveRecordType . '] available to edit!'); } // check the hidden security fields before accepting the form POST data if (!$this->checkSecurityFields()) { throw new SecurityException('This page cannot accept post data from remote servers!'); } $record->load($params['ActiveRecordOID']); ActiveRecord::begin(); $record->delete(); ActiveRecord::commit(); ActiveRecord::disconnect(); self::$logger->action('Deleted ' . $ActiveRecordType . ' instance with OID ' . $params['ActiveRecordOID']); if ($accept == 'application/json') { $response = new Response(200); $response->setHeader('Content-Type', 'application/json'); $response->setBody(json_encode(array('message' => 'deleted'))); } else { $response = new Response(301); if (isset($params['statusMessage'])) { $this->setStatusMessage(View::displayUpdateMessage($params['statusMessage'])); } else { $this->setStatusMessage(View::displayUpdateMessage('Deleted')); } if ($this->getNextJob() != '') { $response->redirect($this->getNextJob()); } else { if ($this->request->isSecureURI()) { $response->redirect(FrontController::generateSecureURL('act=Alpha\\Controller\\ActiveRecordController&ActiveRecordType=' . $ActiveRecordType . '&start=0&limit=' . $config->get('app.list.page.amount'))); } else { $response->redirect($config->get('app.url') . '/records/' . $params['ActiveRecordType']); } } } } catch (SecurityException $e) { self::$logger->warn($e->getMessage()); throw new ResourceNotAllowedException($e->getMessage()); } catch (RecordNotFoundException $e) { self::$logger->warn($e->getMessage()); throw new ResourceNotFoundException('The item that you have requested cannot be found!'); } catch (AlphaException $e) { self::$logger->error($e->getMessage()); ActiveRecord::rollback(); } self::$logger->debug('<<doDELETE'); return $response; }
/** * Method to handle PUT requests. * * @param Alpha\Util\Http\Request * * @return Alpha\Util\Http\Response * * @since 1.0 */ public function doPUT($request) { self::$logger->debug('>>doPUT($request=[' . var_export($request, true) . '])'); $config = ConfigProvider::getInstance(); $params = $request->getParams(); try { // check the hidden security fields before accepting the form POST data if (!$this->checkSecurityFields()) { throw new SecurityException('This page cannot accept post data from remote servers!'); self::$logger->debug('<<doPUT'); } if (isset($params['markdownTextBoxRows']) && $params['markdownTextBoxRows'] != '') { $viewState = ViewState::getInstance(); $viewState->set('markdownTextBoxRows', $params['markdownTextBoxRows']); } if (isset($params['title']) || isset($params['ActiveRecordOID'])) { if (isset($params['ActiveRecordType']) && class_exists($params['ActiveRecordType'])) { $record = new $params['ActiveRecordType'](); } else { $record = new Article(); } if (isset($params['title'])) { $title = str_replace($config->get('cms.url.title.separator'), ' ', $params['title']); $record->loadByAttribute('title', $title, false, array('OID', 'version_num', 'created_ts', 'updated_ts', 'title', 'author', 'published', 'content', 'headerContent')); } else { $record->load($params['ActiveRecordOID']); } // uploading an article attachment if (isset($params['uploadBut'])) { $source = $request->getFile('userfile')['tmp_name']; $dest = $record->getAttachmentsLocation() . '/' . $request->getFile('userfile')['name']; // upload the file to the attachments directory FileUtils::copy($source, $dest); if (!file_exists($dest)) { throw new AlphaException('Could not move the uploaded file [' . $request->getFile('userfile')['name'] . ']'); } // set read/write permissions on the file $success = chmod($dest, 0666); if (!$success) { throw new AlphaException('Unable to set read/write permissions on the uploaded file [' . $dest . '].'); } if ($success) { self::$logger->action('File ' . $source . ' uploaded to ' . $dest); $this->setStatusMessage(View::displayUpdateMessage('File ' . $source . ' uploaded to ' . $dest)); } } elseif (isset($params['deletefile']) && $params['deletefile'] != '') { $success = unlink($record->getAttachmentsLocation() . '/' . $params['deletefile']); if (!$success) { throw new AlphaException('Could not delete the file [' . $params['deletefile'] . ']'); } if ($success) { self::$logger->action('File ' . $record->getAttachmentsLocation() . '/' . $params['deletefile'] . ' deleted'); $this->setStatusMessage(View::displayUpdateMessage('File ' . $record->getAttachmentsLocation() . '/' . $params['deletefile'] . ' deleted')); } } else { self::$logger->debug('<<doPUT'); return parent::doPUT($request); } } else { throw new IllegalArguementException('No valid article ID provided!'); } } catch (SecurityException $e) { $this->setStatusMessage(View::displayErrorMessage($e->getMessage())); self::$logger->warn($e->getMessage()); } catch (IllegalArguementException $e) { $this->setStatusMessage(View::displayErrorMessage($e->getMessage())); self::$logger->error($e->getMessage()); } catch (RecordNotFoundException $e) { self::$logger->warn($e->getMessage()); $this->setStatusMessage(View::displayErrorMessage('Failed to load the requested article from the database!')); } catch (AlphaException $e) { $this->setStatusMessage(View::displayErrorMessage($e->getMessage())); self::$logger->error($e->getMessage()); } $response = new Response(301); if ($this->getNextJob() != '') { $response->redirect($this->getNextJob()); } else { if ($this->request->isSecureURI()) { $response->redirect(FrontController::generateSecureURL('act=Alpha\\Controller\\ActiveRecordController&ActiveRecordType=Alpha\\Model\\Article&ActiveRecordOID=' . $record->getOID() . '&view=edit')); } else { $title = str_replace(' ', $config->get('cms.url.title.separator'), $record->get('title')); $response->redirect($config->get('app.url') . '/a/' . $title . '/edit'); } } self::$logger->debug('<<doPUT'); return $response; }
/** * Constructor that sets up the DEnum options. * * @param Alpha\Model\Type\String $name */ public function __construct($name = null) { self::$logger = new Logger('DEnum'); // ensure to call the parent constructor parent::__construct(); $this->markTransient('options'); $this->markTransient('value'); $this->markTransient('helper'); $this->name = new String($name); if (isset($name) && $this->checkTableExists()) { try { $this->loadByAttribute('name', $name); } catch (RecordNotFoundException $e) { // DEnum does not exist so create it $this->save(); } try { $this->getOptions(); } catch (AlphaException $e) { self::$logger->warn($e->getMessage()); } } }
/** * Handle POST requests. * * @param Alpha\Util\Http\Request $request * * @return Alpha\Util\Http\Response * * @throws Alpha\Exception\SecurityException * * @since 1.0 */ public function doPOST($request) { self::$logger->debug('>>doPOST($request=[' . var_export($request, true) . '])'); $params = $request->getParams(); try { // check the hidden security fields before accepting the form POST data if (!$this->checkSecurityFields()) { throw new SecurityException('This page cannot accept post data from remote servers!'); self::$logger->debug('<<doPOST'); } // ensure that a OID is provided if (isset($params['denumOID'])) { $BOoid = $params['denumOID']; } else { throw new IllegalArguementException('Could not load the DEnum object as an denumOID was not supplied!'); } if (isset($params['saveBut'])) { try { $this->BO->load($BOoid); // update the object from post data $this->BO->populateFromArray($params); ActiveRecord::begin(); $this->BO->save(); self::$logger->action('DEnum ' . $this->BO->getOID() . ' saved'); // now save the DEnumItems $tmp = new DEnumItem(); $denumItems = $tmp->loadItems($this->BO->getID()); foreach ($denumItems as $item) { $item->set('value', $params['value_' . $item->getID()]); $item->save(); self::$logger->action('DEnumItem ' . $item->getOID() . ' saved'); } // handle new DEnumItem if posted if (isset($params['new_value']) && trim($params['new_value']) != '') { $newItem = new DEnumItem(); $newItem->set('value', $params['new_value']); $newItem->set('DEnumID', $this->BO->getID()); $newItem->save(); self::$logger->action('DEnumItem ' . $newItem->getOID() . ' created'); } ActiveRecord::commit(); $this->setStatusMessage(View::displayUpdateMessage(get_class($this->BO) . ' ' . $this->BO->getID() . ' saved successfully.')); return $this->doGET($request); } catch (FailedSaveException $e) { self::$logger->error('Unable to save the DEnum of id [' . $params['oid'] . '], error was [' . $e->getMessage() . ']'); ActiveRecord::rollback(); } ActiveRecord::disconnect(); } } catch (SecurityException $e) { $this->setStatusMessage(View::displayErrorMessage($e->getMessage())); self::$logger->warn($e->getMessage()); } catch (IllegalArguementException $e) { $this->setStatusMessage(View::displayErrorMessage($e->getMessage())); self::$logger->error($e->getMessage()); } catch (RecordNotFoundException $e) { self::$logger->warn($e->getMessage()); $this->setStatusMessage(View::displayErrorMessage('Failed to load the requested item from the database!')); } $body = View::displayPageHead($this); $message = $this->getStatusMessage(); if (!empty($message)) { $body .= $message; } $body .= View::displayPageFoot($this); self::$logger->debug('<<doPOST'); return new Response(200, $body, array('Content-Type' => 'text/html')); }
/** * Handle POST requests (adds $currentUser Person to the session). * * @param Alpha\Util\Http\Request $request * * @return Alpha\Util\Http\Response * * @throws Alpha\Exception\IllegalArguementException * * @since 1.0 */ public function doPOST($request) { self::$logger->debug('>>doPOST($request=[' . var_export($request, true) . '])'); $params = $request->getParams(); if (!is_array($params)) { throw new IllegalArguementException('Bad $params [' . var_export($params, true) . '] passed to doPOST method!'); } $config = ConfigProvider::getInstance(); $body = ''; try { // check the hidden security fields before accepting the form POST data if (!$this->checkSecurityFields()) { throw new SecurityException('This page cannot accept post data from remote servers!'); } if (isset($params['loginBut'])) { // if the database has not been set up yet, accept a login from the config admin username/password if (!ActiveRecord::isInstalled()) { if ($params['email'] == $config->get('app.install.username') && password_verify($params['password'], password_hash($config->get('app.install.password'), PASSWORD_DEFAULT, ['cost' => 12]))) { self::$logger->info('Logging in [' . $params['email'] . '] at [' . date('Y-m-d H:i:s') . ']'); $admin = new Person(); $admin->set('displayName', 'Admin'); $admin->set('email', $params['email']); $admin->set('password', password_hash($params['password'], PASSWORD_DEFAULT, ['cost' => 12])); $admin->set('OID', '00000000001'); $sessionProvider = $config->get('session.provider.name'); $session = SessionProviderFactory::getInstance($sessionProvider); $session->set('currentUser', $admin); $response = new Response(301); if ($this->getNextJob() != '') { $response->redirect(FrontController::generateSecureURL('act=' . $this->getNextJob())); $this->clearUnitOfWorkAttributes(); } else { $response->redirect(FrontController::generateSecureURL('act=InstallController')); } return $response; } else { throw new ValidationException('Failed to login user ' . $params['email'] . ', the password is incorrect!'); } } else { // here we are attempting to load the person from the email address $this->personObject->loadByAttribute('email', $params['email'], true); ActiveRecord::disconnect(); // checking to see if the account has been disabled if (!$this->personObject->isTransient() && $this->personObject->get('state') == 'Disabled') { throw new SecurityException('Failed to login user ' . $params['email'] . ', that account has been disabled!'); } // check the password return $this->doLoginAndRedirect($params['password']); } $body .= View::displayPageHead($this); $body .= $this->personView->displayLoginForm(); } if (isset($params['resetBut'])) { // here we are attempting to load the person from the email address $this->personObject->loadByAttribute('email', $params['email']); ActiveRecord::disconnect(); // generate a new random password $newPassword = $this->personObject->generatePassword(); // now encrypt and save the new password, then e-mail the user $this->personObject->set('password', password_hash($newPassword, PASSWORD_DEFAULT, ['cost' => 12])); $this->personObject->save(); $message = 'The password for your account has been reset to ' . $newPassword . ' as you requested. You can now login to the site using your ' . 'e-mail address and this new password as before.'; $subject = 'Password change request'; $this->personObject->sendMail($message, $subject); $body .= View::displayUpdateMessage('The password for the user <strong>' . $params['email'] . '</strong> has been reset, and the new password ' . 'has been sent to that e-mail address.'); $body .= '<a href="' . $config->get('app.url') . '">Home Page</a>'; } } catch (ValidationException $e) { $body .= View::displayPageHead($this); $body .= View::displayErrorMessage($e->getMessage()); if (isset($params['reset'])) { $body .= $this->personView->displayResetForm(); } else { $body .= $this->personView->displayLoginForm(); } self::$logger->warn($e->getMessage()); } catch (SecurityException $e) { $body .= View::displayPageHead($this); $body .= View::displayErrorMessage($e->getMessage()); self::$logger->warn($e->getMessage()); } catch (RecordNotFoundException $e) { $body .= View::displayPageHead($this); $body .= View::displayErrorMessage('Failed to find the user \'' . $params['email'] . '\''); if (isset($params['reset'])) { $body .= $this->personView->displayResetForm(); } else { $body .= $this->personView->displayLoginForm(); } self::$logger->warn($e->getMessage()); } $body .= View::displayPageFoot($this); self::$logger->debug('<<doPOST'); return new Response(200, $body, array('Content-Type' => 'text/html')); }