From: <pan...@us...> - 2008-10-05 15:11:16
|
Revision: 405 http://acmcontester.svn.sourceforge.net/acmcontester/?rev=405&view=rev Author: panzaboi Date: 2008-10-05 15:06:51 +0000 (Sun, 05 Oct 2008) Log Message: ----------- Application() -> __construct() Added Logger Dynamic DB Encoding (From UTF-8) Changed Structure -> modules with multi-lang support Extended Error_Handler to catch NOT_ALLOWED,NO_CONTROLLER,NO_ACTION errors on preDispatch + NOTALLOwED - new Exception Type Ostacium_Controller_Plugin_Router_Exception More flexible configuration for Zend_View + Zend_Layout Extended Zend_Auth_Adapter_DbTable to be able to select from multiple tables during authorication Added Multilanguage support (ability to change language during navigation/set per user) Removed Messages from DB (translations will be read from file) Added Custom Routes Support Extended Zend_Controller_Router_Route_Module to support :lang/:module/:controller/:action/:params Removed ?> at the end of files Ostacium_Date: Small fix + removed ?> Ostacium_View_Helper_BaseUrl: New implementation from Zend Framework proposals with slashes stripping Ostacium_View_Helper_Currency: Added default options - can be set statically in bootstrap from config Ostacium_View_Helper_CurrentUrl: Removed as duplicate of: $this->url(); Ostacium_View_Helper_Truncate: fixed to extend Zend_View_Helper_Abstract db.sql: Updated DB Structure Ostacium_Controller_Plugin_Layout: Support separate layouts for different modules + general one in failuture Ostacium_Controller_Request_Http: Added getIP function Ostacium_View_Helper_DebugInfo: Ability to show debug info + write to logger during development stage todo.txt: update Todo List index.php: changed DIRECTORY_SEPARATOR to / as make no difference config.ini: updated configurations Modified Paths: -------------- website/config/config.ini website/httpdocs/index.php website/lang/en.csv website/lang/uk.csv website/library/Application.php website/library/Ostacium/Acl.php website/library/Ostacium/Controller/Action.php website/library/Ostacium/Controller/Plugin/ErrorHandler.php website/library/Ostacium/Controller/Plugin/Router.php website/library/Ostacium/Date.php website/library/Ostacium/Db/Table/Rowset.php website/library/Ostacium/Db/Table.php website/library/Ostacium/Model.php website/library/Ostacium/View/Helper/BaseUrl.php website/library/Ostacium/View/Helper/Currency.php website/library/Ostacium/View/Helper/FormFile.php website/library/Ostacium/View/Helper/ListTable.php website/library/Ostacium/View/Helper/Truncate.php website/other/db.sql Added Paths: ----------- website/library/Ostacium/Auth/ website/library/Ostacium/Auth/Adapter/ website/library/Ostacium/Auth/Adapter/DbTable.php website/library/Ostacium/Controller/Plugin/Layout.php website/library/Ostacium/Controller/Request/ website/library/Ostacium/Controller/Request/Http.php website/library/Ostacium/Controller/Router/ website/library/Ostacium/Controller/Router/Route/ website/library/Ostacium/Controller/Router/Route/Language.php website/library/Ostacium/Log/ website/library/Ostacium/Log/Writer/ website/library/Ostacium/Log/Writer/Db.php website/library/Ostacium/View/Helper/DebugInfo.php website/other/todo.txt Modified: website/config/config.ini =================================================================== --- website/config/config.ini 2008-10-04 23:18:38 UTC (rev 404) +++ website/config/config.ini 2008-10-05 15:06:51 UTC (rev 405) @@ -4,7 +4,7 @@ error.display = "1" error.throw = "1" -date.timezone = "Europe/Kiev" +#date.timezone = "Europe/Kiev" truncate.length = "300" truncate.ending = "..." @@ -13,6 +13,8 @@ table.perpage = "10" +date.format_type = "php" + #auth.noauth.module = "default" auth.noauth.controller = "index" auth.noauth.action = "index" @@ -26,18 +28,50 @@ auth.user = "username" auth.pass = "password" auth.passtreat = "MD5(?) AND activated IS NULL" +auth.referenceMap.0.table = "usersdetails"; +auth.referenceMap.0.reference = "usersdetails.username=users.username"; +auth.referenceMap.0.columns = "*"; +auth.referenceMap.1.table = "roles"; +auth.referenceMap.1.reference = "roles.id=users.roleid"; +auth.referenceMap.1.columns = "roles.name as role"; +lang.languageKey = "language"; lang.path = "lang/"; lang.default = "uk"; lang.langs[] = "uk"; lang.langs[] = "en"; +layout.layoutpath = "application/layouts"; +layout.layout = "layout"; +layout.contentKey = "content"; +layout.pluginclass = "Ostacium_Controller_Plugin_Layout"; + +view.encoding = "UTF-8"; +view.helperPathPrefix = "Ostacium_View_Helper"; +view.helperPath = "/library/Ostacium/View/Helper"; + +log.table = "log"; +log.columnMap.type = "priorityName"; +log.columnMap.message = "message"; +log.columnMap.username = "username"; +log.columnMap.when = "timestamp"; +log.columnMap.ip = "ip"; + +email.admin = "admin" + +listtable.class = "crudtable" + +#currency.format = "1" +#currency.precision = "2" +currency.display = "2" + title = "ACM Contester" titlesep = " - " [development: general] db.adapter = "Mysqli" +db.encoding = "UTF8" db.params.host = "localhost" db.params.dbname = "acm" db.params.username = "acm" Modified: website/httpdocs/index.php =================================================================== --- website/httpdocs/index.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/httpdocs/index.php 2008-10-05 15:06:51 UTC (rev 405) @@ -6,10 +6,8 @@ $_docroot = dirname($_SERVER["DOCUMENT_ROOT"]); $_approot = dirname(__FILE__); -require_once $_docroot . DIRECTORY_SEPARATOR . 'library/Application.php'; +require_once $_docroot . '/library/Application.php'; $app = new Application($_approot); $app->setEnvironment('development'); -$app->bootstrap(); - -?> \ No newline at end of file +$app->bootstrap(); \ No newline at end of file Modified: website/lang/en.csv =================================================================== --- website/lang/en.csv 2008-10-04 23:18:38 UTC (rev 404) +++ website/lang/en.csv 2008-10-05 15:06:51 UTC (rev 405) @@ -5,6 +5,7 @@ error_other;There was unknow error, please contact administrator error_404;The page you requested was not found +error_403;You don't have the rights to access that page errorBetween;Value should be between %1$s and %2$s characters Modified: website/lang/uk.csv =================================================================== --- website/lang/uk.csv 2008-10-04 23:18:38 UTC (rev 404) +++ website/lang/uk.csv 2008-10-05 15:06:51 UTC (rev 405) @@ -5,6 +5,7 @@ error_other;There was unknow error, please contact administrator error_404;The page you requested was not found +error_403;You don't have the rights to access that page errorBetween;Value should be between %1$s and %2$s characters Modified: website/library/Application.php =================================================================== --- website/library/Application.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Application.php 2008-10-05 15:06:51 UTC (rev 405) @@ -4,18 +4,25 @@ { protected $_environment; protected static $_approot; + protected static $_start; protected $_docroot; - public function Application($_approot) + public function __construct($_approot) { self::$_approot = $_approot; $this->_docroot = dirname($_SERVER["DOCUMENT_ROOT"]); + self::$_start = microtime(true); } public static function getAppRoot() { return self::$_approot; } + + public static function getRunTime() + { + return (microtime(true) - self::$_start); + } public function setEnvironment($environment) { @@ -32,15 +39,18 @@ if (!$this->_environment) { throw new Exception('Please set the environment using ::setEnvironment'); } - + try { $frontController = $this->_initialize(); - $this->setupRoutes($frontController); + $this->_setupRoutes($frontController); $frontController->dispatch(); } catch (Exception $e) { - var_dump($e); + if(Zend_Registry::offsetExists('Zend_Log')) + Zend_Registry::get('Zend_Log')->log($e->getMessage(), Zend_Log::ERR); + else + var_dump($e); } } @@ -61,29 +71,29 @@ // Setup Session Zend_Session::start(); - // Setup Date - Ostacium_Date::setOptions(array('format_type' => 'php')); - // Setup Config $_config = $this->_setupConfig(); + + // Setup Front Controller + $frontController = $this->_setupFrontController(); + + // Setup Date + Ostacium_Date::setOptions($_config->date->toArray()); + //date_default_timezone_set($_config->date->timezone); // Setup DB $this->_setupDB(); - + // Setup Helpers Ostacium_View_Helper_Truncate::setDefault($_config->truncate->toArray()); - Ostacium_View_Helper_listTable::setDefaultAttribs(array('class' => 'crudtable')); - - // Setup Front Controller - $frontController = $this->_setupFrontController(); + Ostacium_View_Helper_listTable::setDefaultAttribs($_config->listtable->toArray()); - // Setup Error Handler - $frontController->registerPlugin(new Ostacium_Controller_Plugin_ErrorHandler(array( - 'module' => $_config->auth->noacl->module, - 'controller' => $_config->auth->noacl->controller, - 'action' => $_config->auth->noacl->action - ))); + // Setup Log + $this->_setupLog(); + // Setup Authorication + $acl = $this->_setupAuth(); + // Setup Languages $this->_setupLang(); @@ -92,15 +102,13 @@ // Setup View $this->_setupView(); - - // Setup Authorication - $acl = $this->_setupAuth(); // Setup Email - $mail = new Zend_Mail_Transport_Sendmail('-fadmin@'.$_SERVER["SERVER_NAME"]); + $mail = new Zend_Mail_Transport_Sendmail('-f'.$_config->email->admin.'@'.$_SERVER["SERVER_NAME"]); Zend_Mail::setDefaultTransport($mail); - $routerPlugin = new Ostacium_Controller_Plugin_Router($acl, $_config->auth->noauth->toArray(), $_config->auth->noacl->toArray()); + // Setup Plugins + $routerPlugin = new Ostacium_Controller_Plugin_Router($acl, $_config->auth->noauth->toArray(), $_config->auth->noacl->toArray()); $frontController->registerPlugin($routerPlugin, -1); return $frontController; @@ -127,7 +135,6 @@ error_reporting((int)$_config->error->report); ini_set('display_errors', (int)$_config->error->display); - date_default_timezone_set($_config->date->timezone); Zend_Registry::set('config', $_config); @@ -139,7 +146,8 @@ $_config = Zend_Registry::get('config'); $_db = Zend_Db::factory($_config->db); - $_db->query("SET NAMES UTF8"); + $_db->query("SET NAMES ".$_config->db->encoding); + Ostacium_Db_Table::setDefaultAdapter($_db); Ostacium_Db_CrudTable::setPerPage($_config->table->perpage); @@ -153,10 +161,17 @@ $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions((bool) $_config->error->throw); $frontController->setParam('environment', $this->_environment); - $frontController->setControllerDirectory(array( - 'default' => $this->_docroot . '/application/default/controllers', - 'admin' => $this->_docroot . '/application/admin/controllers', - )); + $frontController->setModuleControllerDirectoryName('controllers'); + $frontController->addModuleDirectory($this->_docroot . '/application/modules/'); + $frontController->setRequest('Ostacium_Controller_Request_Http'); + + // Error Handler + $frontController->setParam('noErrorHandler', 1); + $frontController->registerPlugin(new Ostacium_Controller_Plugin_ErrorHandler(array( + 'module' => $_config->auth->noacl->module, + 'controller' => $_config->auth->noacl->controller, + 'action' => $_config->auth->noacl->action + ))); return $frontController; } @@ -165,21 +180,20 @@ { $_config = Zend_Registry::get('config'); - Zend_Layout::startMvc(array('layoutPath' => $this->_docroot . '/application/default/layouts')); - - $view = new Zend_View( array( - 'encoding' => 'UTF-8', - 'helperPathPrefix' => 'Ostacium_View_Helper', - 'helperPath' => $this->_docroot . '/library/Ostacium/View/Helper' - )); - + $options = $_config->view->toArray(); + $options['helperPath'] = $this->_docroot . '/' . $options['helperPath']; + $view = new Zend_View($options); + + // Setup DocType $view->doctype('XHTML1_TRANSITIONAL'); // Setup Title - //$view->placeholder('title')->set($_config->title); $view->headTitle($_config->title)->setSeparator($_config->titlesep); // Setup Dojo Zend_Dojo::enableView($view); + $options = $_config->layout->toArray(); + $options['layoutpath'] = $this->_docroot . '/' . $options['layoutpath']; + Zend_Layout::startMvc($options + array('view' => $view)); $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view); Zend_Controller_Action_HelperBroker::addHelper($viewRenderer); @@ -190,7 +204,8 @@ $_config = Zend_Registry::get('config'); $acl = new Ostacium_Acl($_config->auth->order); - $auth = new Zend_Auth_Adapter_DbTable(Zend_Registry::get('db'), $_config->auth->table, $_config->auth->user, $_config->auth->pass, $_config->auth->passtreat); + $auth = new Ostacium_Auth_Adapter_DbTable(Zend_Registry::get('db'), $_config->auth->table, $_config->auth->user, $_config->auth->pass, $_config->auth->passtreat); + $auth->setReferenceMap($_config->auth->referenceMap->toArray()); Zend_Registry::set('auth', $auth); Zend_Registry::set('acl', $acl); @@ -202,50 +217,51 @@ { $_config = Zend_Registry::get('config'); $_db = Zend_Registry::get('db'); + $_auth = Zend_Auth::getInstance(); - $translate = new Zend_Translate('csv', $this->_docroot.'/'.$_config->lang->path . $_config->lang->default . '.csv', $_config->lang->default); + $translate = new Zend_Translate('csv', $this->_docroot . '/' . $_config->lang->path . $_config->lang->default . '.csv', $_config->lang->default); foreach($_config->lang->langs as $lang) { if ($lang != $_config->lang->default) - $translate->addTranslation($this->_docroot.'/'.$_config->lang->path . $lang .'.csv', 'en'); + $translate->addTranslation($this->_docroot . '/' . $_config->lang->path . $lang .'.csv', 'en'); } - $translate->setLocale($_config->lang->default); + if ($_auth->hasIdentity()) + $language = $_auth->getIdentity()->language; + else + $language = $_config->lang->default; + + $translate->setLocale($language); Zend_Registry::set('Zend_Translate', $translate); - - /**********************************************/ - $user_messages = $_db->select()->from('messages')->query()->fetchAll(); - - $stdMessages = new stdClass(); - foreach ($user_messages as $values) - { - $stdMessages->{$values['name']} = $values['message']; - } - - Zend_Registry::set('messages', $stdMessages); } - protected function setupRoutes(Zend_Controller_Front $frontController) + protected function _setupRoutes(Zend_Controller_Front $frontController) { - // Retrieve the router from the frontcontroller + $_config = Zend_Registry::get('config'); $router = $frontController->getRouter(); + + $router->addRoute('default', new Ostacium_Controller_Router_Route_Language(array(), $frontController->getDispatcher(), $frontController->getRequest())); + + if ($_config->routes) + $router->addConfig($_config->routes); - /* - * You can add routes here like so: - * $router->addRoute( - * 'home', - * new Zend_Controller_Router_Route('home', array( - * 'controller' => 'index', - * 'action' => 'index' - * )) - * ); - */ - return $router; } + + protected function _setupLog() + { + $_db = Zend_Registry::get('db'); + $_config = Zend_Registry::get('config'); + + $writer = new Ostacium_Log_Writer_Db($_db, $_config->log->table, $_config->log->columnMap); + $log = new Zend_Log($writer); + $log->addWriter(new Zend_Log_Writer_Firebug()); + + Zend_Registry::set('Zend_Log', $log); + } }; -function br2nl($text) +/*function br2nl($text) { return preg_replace('/<br\\\\s*?\\/??>/i', "\\n", $text); } @@ -258,5 +274,4 @@ return $string; } -} -?> \ No newline at end of file +}*/ \ No newline at end of file Modified: website/library/Ostacium/Acl.php =================================================================== --- website/library/Ostacium/Acl.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/Acl.php 2008-10-05 15:06:51 UTC (rev 405) @@ -63,12 +63,9 @@ } } - public function getRoleById($id) { return (isset($this->_idtorole[$id]) ? $this->_idtorole[$id] : 'guest' ); } -} - -?> \ No newline at end of file +} \ No newline at end of file Property changes on: website/library/Ostacium/Auth ___________________________________________________________________ Added: tsvn:logminsize + 5 Property changes on: website/library/Ostacium/Auth/Adapter ___________________________________________________________________ Added: tsvn:logminsize + 5 Added: website/library/Ostacium/Auth/Adapter/DbTable.php =================================================================== --- website/library/Ostacium/Auth/Adapter/DbTable.php (rev 0) +++ website/library/Ostacium/Auth/Adapter/DbTable.php 2008-10-05 15:06:51 UTC (rev 405) @@ -0,0 +1,69 @@ +<?php + +class Ostacium_Auth_Adapter_DbTable extends Zend_Auth_Adapter_DbTable +{ + /** + * $_referenceMap - Other tables to be used while fetching result rows + * + * @var array + */ + protected $_referenceMap = null; + + /** + * __construct() - Sets configuration options + * + * @param Zend_Db_Adapter_Abstract $zendDb + * @param string $tableName + * @param string $identityColumn + * @param string $credentialColumn + * @param string $credentialTreatment + * @param array $referenceMap + * @return void + */ + public function __construct(Zend_Db_Adapter_Abstract $zendDb, $tableName = null, $identityColumn = null, + $credentialColumn = null, $credentialTreatment = null, $referenceMap = null) + { + parent::__construct($zendDb, $tableName, $identityColumn, $credentialColumn, $credentialTreatment); + + if (null !== $referenceMap) { + $this->setReferenceMap($referenceMap); + } + } + + + /** + * setReferenceMap() - set the reference of the tables to be fetched during authotication + * + * @param array $referenceMap + * @return Zend_Auth_Adapter_DbTable Provides a fluent interface + */ + public function setReferenceMap($referenceMap) + { + $this->_referenceMap = $referenceMap; + return $this; + } + + /** + * _authenticateCreateSelect() - This method creates a Zend_Db_Select object that + * is completely configured to be queried against the database. + * + * @return Zend_Db_Select + */ + protected function _authenticateCreateSelect() + { + $dbSelect = parent::_authenticateCreateSelect(); + + if (null !== $this->_referenceMap && is_array($this->_referenceMap)) + { + foreach ($this->_referenceMap as $options) + { + $dbSelect->joinInner($options['table'], $options['reference'], $options['columns']); + } + } + + $dbSelect->reset( Zend_Db_Select::WHERE ); + $dbSelect->where($this->_zendDb->quoteIdentifier($this->_tableName . '.' . $this->_identityColumn, true) . ' = ?', $this->_identity); + + return $dbSelect; + } +} \ No newline at end of file Modified: website/library/Ostacium/Controller/Action.php =================================================================== --- website/library/Ostacium/Controller/Action.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/Controller/Action.php 2008-10-05 15:06:51 UTC (rev 405) @@ -12,11 +12,11 @@ $name = ucfirst($this->getRequest()->getControllerName()); // Setup LayoutPath - $layoutPath = $this->_helper->getHelper('viewRenderer')->getModuleDirectory() . DIRECTORY_SEPARATOR . 'layouts'; - $this->_helper->layout()->setLayoutPath($layoutPath); + //$layoutPath = $this->_helper->getHelper('viewRenderer')->getModuleDirectory() . '/layouts'; + //$this->_helper->layout()->setLayoutPath($layoutPath); // Setup ModelPath - $modelPath = $this->_helper->getHelper('viewRenderer')->getModuleDirectory() . DIRECTORY_SEPARATOR . 'models'; + $modelPath = $this->_helper->getHelper('viewRenderer')->getModuleDirectory() . '/models'; set_include_path( $modelPath . PATH_SEPARATOR . get_include_path() ); // Setup Model @@ -74,6 +74,4 @@ { return $this->_translate->_($msg); } -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: website/library/Ostacium/Controller/Plugin/ErrorHandler.php =================================================================== --- website/library/Ostacium/Controller/Plugin/ErrorHandler.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/Controller/Plugin/ErrorHandler.php 2008-10-05 15:06:51 UTC (rev 405) @@ -4,29 +4,38 @@ { protected $_isPreDispatch = false; + const EXCEPTION_NOTALLOWED = 'EXCEPTION_NOTALLOWED'; + public function preDispatch(Zend_Controller_Request_Abstract $request) - { + { $frontController = Zend_Controller_Front::getInstance(); $dispatcher = $frontController->getDispatcher(); $response = $this->getResponse(); - if ($frontController->getParam('noErrorHandler') || $this->_isInsideErrorHandlerLoop) { - return; - } - $error = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS); $error->exception = current($response->getException()); if (!$dispatcher->isDispatchable($request)) { $error->type = self::EXCEPTION_NO_CONTROLLER; + if (!$error->exception) + $error->exception = new Zend_Controller_Dispatcher_Exception("Resource doesn't exist", 404); } elseif (!$this->isProperAction($dispatcher, $request)) { $error->type = self::EXCEPTION_NO_ACTION; + if (!$error->exception) + $error->exception = new Zend_Controller_Dispatcher_Exception("Resource doesn't exist", 404); + } elseif ($error->exception) { + $error->type = self::EXCEPTION_OTHER; + } elseif ($request->getParam('error_message') != "") + { + $error->type = self::EXCEPTION_NOTALLOWED; + if (!$error->exception) + $error->exception = new Ostacium_Controller_Plugin_Router_Exception("No rights to access the resouce", 403); } if (isset($error->type)) { $this->_isInsideErrorHandlerLoop = true; $this->_isPreDispatch = true; - $this->_exceptionCountAtFirstEncounter = count($response->getException()); + $this->_exceptionCountAtFirstEncounter = count($response->getException()); $error->request = clone $request; $request->setParam('error_handler', $error) @@ -38,27 +47,78 @@ public function postDispatch(Zend_Controller_Request_Abstract $request) { - $response = $this->getResponse(); - if (!$this->_isInsideErrorHandlerLoop && count($response->getException()) > $this->_exceptionCountAtFirstEncounter) + $response = $this->getResponse(); + + if (!$this->_isInsideErrorHandlerLoop && count($response->getException()) > $this->_exceptionCountAtFirstEncounter) { - parent::postDispatch($request); + + if ($this->_isInsideErrorHandlerLoop) { + $exceptions = $response->getException(); + if (count($exceptions) > $this->_exceptionCountAtFirstEncounter) { + // Exception thrown by error handler; tell the front controller to throw it + $frontController->throwExceptions(true); + throw array_pop($exceptions); + } + } + + // check for an exception AND allow the error handler controller the option to forward + if (($response->isException()) && (!$this->_isInsideErrorHandlerLoop)) { + $this->_isInsideErrorHandlerLoop = true; + + // Get exception information + $error = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS); + $exceptions = $response->getException(); + $exception = $exceptions[0]; + $exceptionType = get_class($exception); + $error->exception = $exception; + switch ($exceptionType) { + case 'Zend_Controller_Dispatcher_Exception': + $error->type = self::EXCEPTION_NO_CONTROLLER; + break; + case 'Zend_Controller_Action_Exception': + if (404 == $exception->getCode()) { + $error->type = self::EXCEPTION_NO_ACTION; + } else { + $error->type = self::EXCEPTION_OTHER; + } + break; + default: + $error->type = self::EXCEPTION_OTHER; + break; + } + + // Keep a copy of the original request + $error->request = clone $request; + + // get a count of the number of exceptions encountered + $this->_exceptionCountAtFirstEncounter = count($exceptions); + + // Forward to the error handler + $request->setParam('error_handler', $error) + ->setModuleName($this->getErrorHandlerModule()) + ->setControllerName($this->getErrorHandlerController()) + ->setActionName($this->getErrorHandlerAction()) + ->setDispatched(false); + } } - } public function isProperAction($dispatcher, $request) { $className = $dispatcher->loadClass($dispatcher->getControllerClass($request)); $actionName = $request->getActionName(); + if (empty($actionName)) { $actionName = $dispatcher->getDefaultAction(); } + $methodName = $dispatcher->formatActionName($actionName); + $class = new ReflectionClass($className); - $class = new ReflectionClass($className); if ($class->hasMethod($methodName)) { return true; } + return false; } } \ No newline at end of file Added: website/library/Ostacium/Controller/Plugin/Layout.php =================================================================== --- website/library/Ostacium/Controller/Plugin/Layout.php (rev 0) +++ website/library/Ostacium/Controller/Plugin/Layout.php 2008-10-05 15:06:51 UTC (rev 405) @@ -0,0 +1,25 @@ +<?php + +class Ostacium_Controller_Plugin_Layout extends Zend_Layout_Controller_Plugin_Layout +{ + protected $_defaultLayoutPath = ''; + + public function __construct(Zend_Layout $layout = null) + { + parent::__construct($layout); + + $this->_defaultLayoutPath = $this->getLayout()->getLayoutPath(); + } + + public function preDispatch(Zend_Controller_Request_Abstract $request) + { + $_config = Zend_Registry::get('config'); + $path = Zend_Controller_Front::getInstance()->getModuleDirectory() . '/layouts/'; + + if (file_exists($path . $this->getLayout()->getLayout() . '.' . $this->getLayout()->getViewSuffix())) + $this->getLayout()->setLayoutPath($path); + else + $this->getLayout()->setLayoutPath($this->_defaultLayoutPath); + } + +} \ No newline at end of file Modified: website/library/Ostacium/Controller/Plugin/Router.php =================================================================== --- website/library/Ostacium/Controller/Plugin/Router.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/Controller/Plugin/Router.php 2008-10-05 15:06:51 UTC (rev 405) @@ -1,7 +1,9 @@ <?php -class Ostacium_Controller_Plugin_Router extends Zend_Controller_Plugin_Abstract { +class Ostacium_Controller_Plugin_Router_Exception extends Zend_Controller_Exception {} +class Ostacium_Controller_Plugin_Router extends Zend_Controller_Plugin_Abstract +{ private $_acl; private $_noauth = array( /*'module' => 'default',*/ 'controller' => 'index', @@ -19,6 +21,7 @@ public function preDispatch(Zend_Controller_Request_Abstract $request) { $auth = Zend_Auth::getInstance(); + $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher(); if ($auth->hasIdentity()) { $role = $this->_acl->getRoleById($auth->getIdentity()->roleid) ? $this->_acl->getRoleById($auth->getIdentity()->roleid) : 'guest'; @@ -31,16 +34,12 @@ $module = $request->getModuleName(); $resource = ($module != 'default' ? $module . ':' . $controller : $controller); - if (!$this->_acl->has($resource)) + if (!$this->_acl->has($resource) || !$dispatcher->isDispatchable($request) || !$this->isProperAction($dispatcher, $request)) { $e = new Zend_Controller_Dispatcher_Exception("Resource doesn't exist", 404); $response = $this->getResponse(); $response->setException($e); - -// $module = $this->_noacl['module']; -// $controller = $this->_noacl['controller']; -// $action = $this->_noacl['action']; } elseif (!$this->_acl->isAllowed($role, $resource, $action)) { if (!$auth->hasIdentity()) { @@ -48,13 +47,13 @@ $controller = $this->_noauth['controller']; $action = $this->_noauth['action']; - $request->setParam('message', 'nologin'); + $request->setParam('error_message', 'nologin'); } else { $module = $this->_noacl['module']; $controller = $this->_noacl['controller']; $action = $this->_noacl['action']; - $request->setParam('message', 'noallowed'); + $request->setParam('error_message', 'noallowed'); } } @@ -62,6 +61,23 @@ $request->setControllerName($controller); $request->setActionName($action); } -} - -?> \ No newline at end of file + + public function isProperAction($dispatcher, $request) + { + $className = $dispatcher->loadClass($dispatcher->getControllerClass($request)); + $actionName = $request->getActionName(); + + if (empty($actionName)) { + $actionName = $dispatcher->getDefaultAction(); + } + + $methodName = $dispatcher->formatActionName($actionName); + $class = new ReflectionClass($className); + + if ($class->hasMethod($methodName)) { + return true; + } + + return false; + } +} \ No newline at end of file Property changes on: website/library/Ostacium/Controller/Request ___________________________________________________________________ Added: tsvn:logminsize + 5 Added: website/library/Ostacium/Controller/Request/Http.php =================================================================== --- website/library/Ostacium/Controller/Request/Http.php (rev 0) +++ website/library/Ostacium/Controller/Request/Http.php 2008-10-05 15:06:51 UTC (rev 405) @@ -0,0 +1,9 @@ +<?php + +class Ostacium_Controller_Request_Http extends Zend_Controller_Request_Http +{ + public function getIP() + { + return $this->getServer('HTTP_X_FORWARDED_FOR', $this->getServer('HTTP_VIA', $this->getServer('REMOTE_ADDR', '0.0.0.0') ) ); + } +} \ No newline at end of file Property changes on: website/library/Ostacium/Controller/Router ___________________________________________________________________ Added: tsvn:logminsize + 5 Property changes on: website/library/Ostacium/Controller/Router/Route ___________________________________________________________________ Added: tsvn:logminsize + 5 Added: website/library/Ostacium/Controller/Router/Route/Language.php =================================================================== --- website/library/Ostacium/Controller/Router/Route/Language.php (rev 0) +++ website/library/Ostacium/Controller/Router/Route/Language.php 2008-10-05 15:06:51 UTC (rev 405) @@ -0,0 +1,139 @@ +<?php + +class Ostacium_Controller_Router_Route_Language extends Zend_Controller_Router_Route_Module +{ + protected $translate; + protected $config; + + protected $_languageKey = 'language'; + + public function __construct(array $defaults = array(), + Zend_Controller_Dispatcher_Interface $dispatcher = null, + Zend_Controller_Request_Abstract $request = null) + { + parent::__construct($defaults, $dispatcher, $request); + + $this->translate = Zend_Registry::get('Zend_Translate'); + $this->config = Zend_Registry::get('config'); + } + + protected function _setRequestKeys() + { + parent::_setRequestKeys(); + + $this->_languageKey = $this->config->lang->languageKey; + $language = $this->translate->getLocale(); + + if (null !== $this->_dispatcher) { + $this->_defaults += array($this->_languageKey => $language); + } + } + + public function match($path) + { + $this->_setRequestKeys(); + + $values = array(); + $params = array(); + $path = trim($path, self::URI_DELIMITER); + + if ($path != '') { + $path = explode(self::URI_DELIMITER, $path); + + if ($this->translate->isAvailable($path[0])) { + $values[$this->_languageKey] = array_shift($path); + $this->translate->setLocale($values[$this->_languageKey]); + } + + if (count($path) && !empty($path[0]) && $this->_dispatcher && $this->_dispatcher->isValidModule($path[0])) { + $values[$this->_moduleKey] = array_shift($path); + $this->_moduleValid = true; + } + + if (count($path) && !empty($path[0])) { + $values[$this->_controllerKey] = array_shift($path); + } + + if (count($path) && !empty($path[0])) { + $values[$this->_actionKey] = array_shift($path); + } + + if ($numSegs = count($path)) { + for ($i = 0; $i < $numSegs; $i = $i + 2) { + $key = urldecode($path[$i]); + $val = isset($path[$i + 1]) ? urldecode($path[$i + 1]) : null; + $params[$key] = $val; + } + } + } + + $this->_values = $values + $params; + + return $this->_values + $this->_defaults; + } + + public function assemble($data = array(), $reset = false, $encode = true) + { + if (!$this->_keysSet) { + $this->_setRequestKeys(); + } + + $params = (!$reset) ? $this->_values : array(); + + foreach ($data as $key => $value) { + if ($value !== null) { + $params[$key] = $value; + } elseif (isset($params[$key])) { + unset($params[$key]); + } + } + + $params += $this->_defaults; + + $url = ''; + + $language = $params[$this->_languageKey]; + unset($params[$this->_languageKey]); + + if ($this->_moduleValid || array_key_exists($this->_moduleKey, $data)) { + if ($params[$this->_moduleKey] != $this->_defaults[$this->_moduleKey]) { + $module = $params[$this->_moduleKey]; + } + } + unset($params[$this->_moduleKey]); + + $controller = $params[$this->_controllerKey]; + unset($params[$this->_controllerKey]); + + $action = $params[$this->_actionKey]; + unset($params[$this->_actionKey]); + + foreach ($params as $key => $value) { + if ($encode) $value = urlencode($value); + $url .= '/' . $key; + $url .= '/' . $value; + } + + if (!empty($url) || $action !== $this->_defaults[$this->_actionKey]) { + if ($encode) $action = urlencode($action); + $url = '/' . $action . $url; + } + + if (!empty($url) || $controller !== $this->_defaults[$this->_controllerKey]) { + if ($encode) $controller = urlencode($controller); + $url = '/' . $controller . $url; + } + + if (isset($module)) { + if ($encode) $module = urlencode($module); + $url = '/' . $module . $url; + } + + if ($this->translate->isAvailable($language)) { + if ($encode) $language = urlencode($language); + $url = '/' . $language . $url; + } + + return ltrim($url, self::URI_DELIMITER); + } +} \ No newline at end of file Modified: website/library/Ostacium/Date.php =================================================================== --- website/library/Ostacium/Date.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/Date.php 2008-10-05 15:06:51 UTC (rev 405) @@ -8,8 +8,6 @@ } public static function getInstance($date = null, $part = null, $locale = null) { - return new self($date = null, $part = null, $locale = null); + return new self($date, $part, $locale); } -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: website/library/Ostacium/Db/Table/Rowset.php =================================================================== --- website/library/Ostacium/Db/Table/Rowset.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/Db/Table/Rowset.php 2008-10-05 15:06:51 UTC (rev 405) @@ -38,6 +38,4 @@ return parent::toArray(); } } -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: website/library/Ostacium/Db/Table.php =================================================================== --- website/library/Ostacium/Db/Table.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/Db/Table.php 2008-10-05 15:06:51 UTC (rev 405) @@ -10,10 +10,8 @@ public function get($pPrimaryKey) { $get = parent::find($pPrimaryKey)->current(); - if ($get) - return $get->toArray(); - else - return $get; + + return $get; } public function insert($data) @@ -31,8 +29,7 @@ public function count($_where = null) { - $select = $this->select() - ->from($this->_name, new Zend_Db_Expr('COUNT(*)')); + $select = $this->select()->from($this->_name, new Zend_Db_Expr('COUNT(*)')); if ($_where !== null) { @@ -60,6 +57,4 @@ $data = array_intersect_key($data, array_flip($this->_cols)); } -} - -?> \ No newline at end of file +} \ No newline at end of file Property changes on: website/library/Ostacium/Log ___________________________________________________________________ Added: tsvn:logminsize + 5 Property changes on: website/library/Ostacium/Log/Writer ___________________________________________________________________ Added: tsvn:logminsize + 5 Added: website/library/Ostacium/Log/Writer/Db.php =================================================================== --- website/library/Ostacium/Log/Writer/Db.php (rev 0) +++ website/library/Ostacium/Log/Writer/Db.php 2008-10-05 15:06:51 UTC (rev 405) @@ -0,0 +1,20 @@ +<?php + +class Ostacium_Log_Writer_Db extends Zend_Log_Writer_Db +{ + protected function _write($event) + { + $auth = Zend_Auth::getInstance(); + $_config = Zend_Registry::get('config'); + + if ($auth->hasIdentity()) + $event['username'] = $auth->getIdentity()->{$_config->auth->user}; + else + $event['username'] = 'guest'; + + $event['ip'] = Zend_Controller_Front::getInstance()->getRequest()->getIp(); + $event['timestamp'] = time(); + + return parent::_write($event); + } +} \ No newline at end of file Modified: website/library/Ostacium/Model.php =================================================================== --- website/library/Ostacium/Model.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/Model.php 2008-10-05 15:06:51 UTC (rev 405) @@ -13,6 +13,4 @@ } public function init() {} -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: website/library/Ostacium/View/Helper/BaseUrl.php =================================================================== --- website/library/Ostacium/View/Helper/BaseUrl.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/View/Helper/BaseUrl.php 2008-10-05 15:06:51 UTC (rev 405) @@ -1,12 +1,18 @@ <?php -class Ostacium_View_Helper_BaseUrl +class Ostacium_View_Helper_BaseUrl extends Zend_View_Helper_Abstract { public function baseUrl($file = null) { - return Zend_Controller_Front::getInstance()->getRequest()->getBaseUrl() - . ($file ? ('/' . trim((string) $file, '/\\')) : ''); + // Get baseUrl + $baseUrl = Zend_Controller_Front::getInstance()->getBaseUrl(); + + // Remove trailing slashes + $file = ($file !== null) ? ltrim($file, '/\\') : null; + + // Build return + $return = rtrim($baseUrl, '/\\') . (($file !== null) ? ('/' . $file) : ''); + + return $return; } -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: website/library/Ostacium/View/Helper/Currency.php =================================================================== --- website/library/Ostacium/View/Helper/Currency.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/View/Helper/Currency.php 2008-10-05 15:06:51 UTC (rev 405) @@ -1,16 +1,19 @@ <?php -class Ostacium_View_Helper_Currency +class Ostacium_View_Helper_Currency extends Zend_View_Helper_Abstract { + public static $default_options = array('display' => Zend_Currency::USE_SYMBOL); + + public static function setDefault(array $options) { + self::$default_options = $options; + } + public function currency($amount, $currency, $locale = null) { - if (isset($locale)) - $c = new Zend_Currency($currency, $locale); - else - $c = new Zend_Currency($currency); - - return $c->toCurrency($amount, array('display' => Zend_Currency::USE_SYMBOL)); + if (!isset($locale)) + $locale = Zend_Registry::get('Zend_Translate')->getLocale(); + + $currency = new Zend_Currency($currency, $locale); + return $currency->toCurrency($amount, self::$default_options); } -} - -?> \ No newline at end of file +} \ No newline at end of file Added: website/library/Ostacium/View/Helper/DebugInfo.php =================================================================== --- website/library/Ostacium/View/Helper/DebugInfo.php (rev 0) +++ website/library/Ostacium/View/Helper/DebugInfo.php 2008-10-05 15:06:51 UTC (rev 405) @@ -0,0 +1,24 @@ +<?php + +class Ostacium_View_Helper_DebugInfo extends Zend_View_Helper_Abstract +{ + public function debugInfo($writetolog = false) + { + $translate = Zend_Registry::get('Zend_Translate'); + $profiler = Zend_Registry::get('db')->getProfiler(); + $environment = Zend_Controller_Front::getInstance()->getParam('environment'); + $return = null; + + if ($environment == 'development') + { + $return = $translate->_('runtime') . ': ' .Application::getRunTime() . '; ' . $translate->_('totalqueries') . ': ' . $profiler->getTotalNumQueries() . '; ' . $translate->_('totalqueriestime') . ': ' . $profiler->getTotalElapsedSecs(); + + if ($writetolog) + { + Zend_Registry::get('Zend_Log')->log($return, Zend_Log::NOTICE); + } + } + + return $return; + } +} \ No newline at end of file Modified: website/library/Ostacium/View/Helper/FormFile.php =================================================================== --- website/library/Ostacium/View/Helper/FormFile.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/View/Helper/FormFile.php 2008-10-05 15:06:51 UTC (rev 405) @@ -18,6 +18,4 @@ return $xhtml; } -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: website/library/Ostacium/View/Helper/ListTable.php =================================================================== --- website/library/Ostacium/View/Helper/ListTable.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/View/Helper/ListTable.php 2008-10-05 15:06:51 UTC (rev 405) @@ -140,6 +140,4 @@ break; } } -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: website/library/Ostacium/View/Helper/Truncate.php =================================================================== --- website/library/Ostacium/View/Helper/Truncate.php 2008-10-04 23:18:38 UTC (rev 404) +++ website/library/Ostacium/View/Helper/Truncate.php 2008-10-05 15:06:51 UTC (rev 405) @@ -1,8 +1,7 @@ <?php -class Ostacium_View_Helper_Truncate +class Ostacium_View_Helper_Truncate extends Zend_View_Helper_Abstract { - public $view; public static $default_options = array( 'length' => 300, 'ending' => '...', @@ -10,10 +9,6 @@ 'considerHtml' => true ); - public function setView(Zend_View_Interface $view) { - $this->view = $view; - } - public static function setDefault(array $options) { self::$default_options = $options; } @@ -131,9 +126,6 @@ } return $truncate; - } -} - -?> \ No newline at end of file +} \ No newline at end of file Modified: website/other/db.sql =================================================================== --- website/other/db.sql 2008-10-04 23:18:38 UTC (rev 404) +++ website/other/db.sql 2008-10-05 15:06:51 UTC (rev 405) @@ -3,7 +3,7 @@ -- http://www.phpmyadmin.net -- -- Host: localhost --- Generation Time: Sep 20, 2008 at 10:52 PM +-- Generation Time: Oct 05, 2008 at 05:59 PM -- Server version: 5.0.51 -- PHP Version: 5.2.6 @@ -46,8 +46,6 @@ CREATE TABLE IF NOT EXISTS `challenges` ( `id` int(11) NOT NULL auto_increment, - `name` varchar(200) NOT NULL, - `description` text NOT NULL, `timelimit` double NOT NULL default '0', `memorylimit` int(11) NOT NULL default '0', `outputlimit` int(11) NOT NULL default '0', @@ -62,216 +60,431 @@ -- Dumping data for table `challenges` -- -INSERT INTO `challenges` (`id`, `name`, `description`, `timelimit`, `memorylimit`, `outputlimit`, `tries`, `accepted`, `author`, `enabled`) VALUES -(1000, 'Swap', '<P align=left><B>Завдання</B></P><P>Дано два цілих числа a та b. Написати програму, яка б міняла їхні значення місцями. Тобто після виконання програми замість а значення b, а замість b - а. <P><B>Вхідні дані</B></P><P>В єдиному рядку записано два числа - а та b. (-32000 < a, b < 32000). <P><B>Вихідні дані</B></P><P>Вивести в єдиний рядок через пропуск два числа: спочатку b, а потім a. <P><B>Приклад введення 1</B></P><P><PRE>1 2</PRE><P><B>Приклад виведення 1</B></P><P><PRE>2 1</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>2 3</PRE><P><B>Приклад виведення 2</B></P><P><PRE>3 2</PRE><BR>', 1000, 5120000, 204800, 0, 0, '', 1), -(1001, 'A in power k', '<P align=left><B>Завдання</B></P><P>Для заданого цілого а та натурального k обчислити a<SUP>k</SUP>.<P><B>Вхідні дані</B></P><P>В єдиному рядку записано два числа a та k (-32000 < a <= 32000, 0 < k < 32000).<P><B>Вихідні дані</B></P><P>Єдине число - відповідь. Гарантується, що відповідь не більша за 2*10<SUP>9</SUP>.<P><B>Приклад введення 1</B></P><P><PRE>1 1</PRE><P><B>Приклад виведення 1</B></P><P><PRE>1</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>2 3</PRE><P><B>Приклад виведення 2</B></P><P><PRE>8</PRE><BR>', 1000, 5120000, 204800, 0, 0, '', 1), -(1002, 'Послідовність Фібоначчі', '<P align=left><B>Завдання</B></P><P>Послідовність фібоначчі визначається наступним чином:<BR></P><UL><LI>a<SUB>0</SUB>=0;<LI>a<SUB>1</SUB>=1;<LI>a<SUB>k</SUB>=a<SUB>k-1</SUB> + a<SUB>k-2</SUB></LI></UL><BR><BR>Для заданого n знайти значення n-го елемента послідовності Фібоначчі (a<SUB>n</SUB>).<P><B>Вхідні дані</B></P><P>В єдиному рядку записане єдине число N (1 <= N <= 40).<P><B>Вихідні дані</B></P><P>Єдине число - відповідь.<P><B>Приклад введення 1</B></P><P><PRE>1</PRE><P><B>Приклад виведення 1</B></P><P><PRE>1</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>5</PRE><P><B>Приклад виведення 2</B></P><P><PRE>5</PRE><BR><P><B>Приклад введення 3</B></P><P><PRE>8</PRE><P><B>Приклад виведення 3</B></P><P><PRE>21</PRE><BR>', 1000, 5120000, 204800, 0, 0, '', 1), -(1003, 'Рукавички', '<P align=left><B>Завдання</B></P><P>Комірник видає по К рукавичок кожному робітнику. Тобто другий робітник отримає рукавички від (K+1)-шої до (2∙K)-ї включно, рукавички номер (2∙K+2) отримає третій робітник і для нього вони будуть другими.<P>Напишіть програму, яка за номером виданих рукавичок визначає номер робітника, якому їх видано та порядковий номер цих рукавичок в цього робітника<P><B>Вхідні дані</B></P><P>В єдиному рядку записано два числа - K та N. K - кількість рукавичок кожному робітнику, N - номер пари рукавичок (1 <= K <= 200, 1 <= N <= 20000) розділені пропуском.<P><B>Вихідні дані</B></P><P>Номер робітника та номер рукавичок в цього робітника, розділені пропуском.<P><B>Приклад введення 1</B></P><P><PRE>50 1</PRE><P><B>Приклад виведення 1</B></P><P><PRE>1 1</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>20 25</PRE><P><B>Приклад виведення 2</B></P><P><PRE>2 5</PRE><BR><P><B>Приклад введення 3</B></P><P><PRE>15 43</PRE><P><B>Приклад виведення 3</B></P><P><PRE>3 13</PRE><BR>', 1000, 5120000, 204800, 0, 0, '', 1), -(1004, 'Супер проста проблема', '<P align=left><B>Завдання</B></P><P>Знайти квадрат N-го простого числа.<P><B>Вхідні дані</B></P><P>В єдиному рядку записане єдине число N (1 <= N <= 100).<P><B>Вихідні дані</B></P><P>Єдине число - квадрат N-го простого числа<P><B>Приклад введення 1</B></P><P><PRE>1</PRE><P><B>Приклад виведення 1</B></P><P><PRE>4</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>2</PRE><P><B>Приклад виведення 2</B></P><P><PRE>9</PRE><BR><P><B>Приклад введення 3</B></P><P><PRE>5</PRE><P><B>Приклад виведення 3</B></P><P><PRE>121</PRE><BR>', 1000, 3072000, 204800, 0, 0, '', 1), -(1005, '0-1 проблема', '<P align=left><B>Завдання</B></P><P>Над рядочком 01 виконаємо наступні операції:<UL><LI>Скопіюємо в кінець рядочка самого себе (отримаємо 0101)<LI>В другій половині рядка всі 0 змінимо на 1, а всі 1 на 0 (отримаємо 0110)</LI></UL>Над рядочком 0110 виконаємо ті самі операції. Отримаємо 01101001. І т. д.Таким чином отримаємо нескінченний рядочок нулів та одиниць.Ваше завдання – знайти n-тий символ такого рядочка.<P><B>Вхідні дані</B></P><P>В єдиному рядку записане єдине число N (1 <= N <= 2000000000).<P><B>Вихідні дані</B></P><P>Єдиний символ, який буде на N-й позиції.<P><B>Приклад введення 1</B></P><P><PRE>1</PRE><P><B>Приклад виведення 1</B></P><P><PRE>0</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>2</PRE><P><B>Приклад виведення 2</B></P><P><PRE>1</PRE><BR><P><B>Приклад введення 3</B></P><P><PRE>5</PRE><P><B>Приклад виведення 3</B></P><P><PRE>1</PRE><BR>', 1000, 3072000, 2048, 0, 0, '', 1), -(1006, 'Одинадцять', '<P align=left><B>Завдання</B></P><P>Ваше завдання – визначити чи ділиться дане число на 11.<P><B>Вхідні дані</B></P><P>В єдиному рядку записане єдине число N (1 <= n). Число має не більше тисячі знаків.<P><B>Вихідні дані</B></P><P>Вам потрібно вивести “Yes” – якщо число ділиться на 11, і “No” – в протилежному випадку.<P><B>Приклад введення 1</B></P><P><PRE>323455693</PRE><P><B>Приклад виведення 1</B></P><P><PRE>Yes</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>5038297</PRE><P><B>Приклад виведення 2</B></P><P><PRE>Yes</PRE><BR><P><B>Приклад введення 3</B></P><P><PRE>112234</PRE><P><B>Приклад виведення 3</B></P><P><PRE>No</PRE><BR>', 1000, 3072000, 2048, 0, 0, '', 1), -(1007, 'Супер послідовність', '<P align=left><B>Завдання</B></P><P>Послідовність чисел a1, a2, … an називається супер послідовністю, якщо виконуються наступні умови:<UL><LI>0 < a1 < a2 < … < an<LI>жодне з чисел не є сумою двох або більше інших чисел</LI></UL><P><B>Вхідні дані</B></P><P>В єдиному рядку записане число N (1 <= n <= 50), далі задано N чисел, кожне з яких не менше 1 і не більше 1000.<P><B>Вихідні дані</B></P><P>Вам необхідно вивести “Yes” – якщо дано супер послідовність, “No” – в протилежному випадку.<P><B>Приклад введення 1</B></P><P><PRE>2 1 2</PRE><P><B>Приклад виведення 1</B></P><P><PRE>Yes</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>3 1 2 3</PRE><P><B>Приклад виведення 2</B></P><P><PRE>No</PRE><BR><P><B>Приклад введення 3</B></P><P><PRE>10 1 3 16 19 25 70 100 243 245 306</PRE><P><B>Приклад виведення 3</B></P><P><PRE>No</PRE><BR>', 1000, 3072000, 2048, 0, 0, '', 1), -(1008, 'Супер яйця', '<P align=left><B>Задання</B></P><P>Нехай у вас є n супер яєць і ви живете в k поверховому будинку. Вам необхідно визначити за найменшу кількість кидків найбільший номер поверху з якого кинуте вниз супер яйце не розбивається. Тобто, за яку найменшу кількість спроб можна визначити найвищий поверх, з якого супер яйце не розбивається. Зауважте, якщо в результаті деякої спроби яйце не розбилось, то воно може бути використане в наступних спробах.<P><B>Вхідні дані</B></P><P>В єдиному рядку записано 2 цілих числа N (N<=30)- кількість яєць та M (M<=2 000 000 000)- кількість поверхів.<P><B>Вихідні дані</B></P><P>У єдиному рядку треба вивести єдине число – мінімальна необхідна кількість спроб. Якщо необхідно більше 30 спроб виведіть -1.<P><B>Приклад введення 1</B></P><P><PRE>1 15</PRE><P><B>Приклад виведення 1</B></P><P><PRE>15</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>2 100</PRE><P><B>Приклад виведення 2</B></P><P><PRE>14</PRE><BR><P><B>Приклад введення 3</B></P><P><PRE>10 786599</PRE><P><B>Приклад виведення 3</B></P><P><PRE>21</PRE><BR><P><B>Приклад введення 4</B></P><P><PRE>4 786599</PRE><P><B>Приклад виведення 3</B></P><P><PRE>-1</PRE><BR>', 1000, 5120000, 2048, 0, 0, '', 1), -(1009, 'Супер карти', '<P align=left><B>Завдання</B></P><P>Дана колода впорядкованих супер карт від 1 до n. Верхня супер карта має номер 1, нижня – n. Поки в колоді є хоча б дві супер карти викидаємо верхню карту, а наступну ставимо вниз колоди.<P>Необхідно знайти номер супер карти, що залишиться.<P><B>Вхідні дані</B></P><P>В єдиному рядку записане єдине число N - число супер карт в колоді (1 <= n <= 1000000).<P><B>Вихідні дані</B></P><P>Єдине число - номер супер карти, що залишиться.<P><B>Приклад введення 1</B></P><P><PRE>7</PRE><P><B>Приклад виведення 1</B></P><P><PRE>6</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>19</PRE><P><B>Приклад виведення 2</B></P><P><PRE>6</PRE><BR><P><B>Приклад введення 3</B></P><P><PRE>10</PRE><P><B>Приклад виведення 3</B></P><P><PRE>4</PRE><BR><P><B>Приклад введення 4</B></P><P><PRE>6</PRE><P><B>Приклад виведення 4</B></P><P><PRE>4</PRE><BR>', 1000, 3072000, 2048, 0, 0, '', 1), -(1010, 'Остання проблема', '<P align=left><B>Завдання</B></P><P>Ваше завдання – визначити чи дане число N можна представити у вигляді суми двох простих чисел.<P><B>Вхідні дані</B></P><P>В єдиному рядку записане єдине число N (1 <= N <= 1000000).<P><B>Вихідні дані</B></P><P>Cума двох простих чисел, що рівна n, або -1, якщо такої не існує. В сумі перше число не більше другого і якщо існує декілька таких можливих сум – вивести ту, в якої перший доданок найменший.<P><B>Приклад введення 1</B></P><P><PRE>9</PRE><P><B>Приклад виведення 1</B></P><P><PRE>2+7</PRE><BR><P><B>Приклад введення 2</B></P><P><PRE>10</PRE><P><B>Приклад виведення 2</B></P><P><PRE>3+7</PRE><BR><P><B>Приклад введення 3</B></P><P><PRE>11</PRE><P><B>Приклад виведення 3</B></P><P><PRE>-1</PRE><BR>', 1000, 3072000, 2048, 0, 0, '', 1), -(1011, 'Медіанний фільтр', '<P align=left><B>Завдання</B></P><P>Медіаною у відсортованому по неспаданню масиву розмірності N називається елемент, який знаходиться у середній позиції масиву, тобто у позиції (N+1)/2 (цілочисельне ділення). <P>Медіанним фільтром для растрового зображення називається таке перетворення кожної точки, колір якої вибирається як медіана із множини точок з певного околу (радіусом R) цієї точки (квадратної області із центром у вибраній точці – розміри квадрата рівні [R+1+ R]×[ R+1+R]). Медіанний фільтр використовують для видалення дрібного шуму із зображення. На межі зображення точки, що виходять за межі, вважаються точками із кольором фону (абсолютне значення рівне нулю).<P>Для заданого малюнку прямокутної форми шириною W та висотою H знайдіть максимальне значення медіани для розміру околу R. Вважається, що малюнок монохромний із 256 градаціями одного кольору.<P><B>Вхідні дані</B></P><P>В першому рядку задані 3 числа: розмір околу R (1≤R≤20), H(1≤H≤400), W(1≤W≤250). В наступних H рядках знаходиться по W чисел розділених пропуском. Числа – це кольори відповідних точок.<P><B>Вихідні дані</B></P><P>Виведіть результат – максимальне значення медіани для заданого малюнку та радіусу.<P><B>Приклад введення</B></P><P><PRE>1 4 3</PRE><PRE>1 1 1</PRE><PRE>1 2 4</PRE><PRE>2 3 2</PRE><PRE>1 1 1</PRE><P><B>Приклад виведення</B></P><P><PRE>2</PRE>', 1500, 3072000, 204800, 0, 0, '', 1), -(1012, 'Дужки і Нобелівська премія', '<P align=left><B>Завдання</B></P><P>Директор однієї відомої програмістської фірми Білл (ви напевно його знаєте) захотів одержати Нобелівську премію. Для цього він запропонував додати в арифметичні вирази крім круглих дужок ще й квадратні, причому: спочатку виконуються обчислення в квадратних дужках, що стоять лівіше, потім в наступних квадратних і т.д.; в такому ж порядку виконуються обчислення в круглих дужках. Наприклад: у виразі порядок обчислення виразів в дужках такий: <CENTER><IMG src="/fusion/images/problems/1012/pic1.jpg"></CENTER><P>Працівники фірми встигнуть в запланований термін реалізувати тільки виконання всіх потрібних операцій в виразах без дужок. Тому пан Білл звернувся до нас за допомогою. Отже, ваше завдання таке: <BR>1) виведіть на екран "YES", якщо дужки у виразі розставлені правильно і "NO" в протилежному випадку;<BR>2) у випадку правильно розставлених дужок виведіть на екран через пропуск в окремому рядку для кожної пари дужок позиції їх розташування в заданому виразі, якщо він буде обчислюватися згідно описаних вище правил. <P><B>Вхідні дані</B></P><P>В першому рядку знаходиться вираз. Довжина рядка не перевищує 255 символів. <P><B>Вихідні дані</B></P><P>Результат виконання програми. <P><B>Приклад введення</B></P><P><PRE>а+(2-с)-[21-8*b+(-2)]+[3]</PRE><P><B>Приклад виведення</B></P><P><PRE>YES</PRE><PRE>17 20</PRE><PRE>9 21</PRE><PRE>23 25</PRE><PRE>3 7<BR></PRE>', 500, 3072000, 2048, 0, 0, '', 1), -(1013, 'Електронний пристрій', '<P align=left><B>Завдання</B></P><P>Одному визначному вченому майже вдалося побудувати новий електронний пристрій визначення поведінки погоди. Йому потрібна програма, яка б дозволяла аналізувати вміст результатів дослідження. Ваше завдання – допомогти йому. <P>Результати – це послідовність чисел (нуль або один). Вам потрібно дати відповідь чи всі числа рівні між і-тим та j-тим елементами послідовності включно. <P><B>Вхідні дані</B></P><P>В першому рядку задано число N(0 < N ≤ 3*10<SUP>5</SUP>) – кількість елементів послідовності. В другому рядку розділені пропуском записані елементи послідовності. В третьому рядку записано число M(0 < M ≤ 5*10<SUP>4</SUP>) – кількість запитань. Далі в M рядках розділ... [truncated message content] |