Joostina CMS / CMF v2.* API
  • Docs
  • Package
  • Class
  • Tree
  • Todo
Overview

Packages

  • Components
    • Acls
      • Models
        • Admin
        • Site
    • BlogCategory
      • Models
        • Admin
        • Site
    • Blogs
      • Controllers
        • Admin
        • Site
      • Helpers
      • Models
        • Admin
        • Site
    • Coder
      • Controllers
        • Admin
      • Models
        • Admin
    • Comments
      • Controllers
        • Admin
        • Site
      • Helpers
      • Models
        • Admin
        • Site
    • CommentsCounter
      • Models
        • Admin
        • Site
    • Mainpage
      • Controllers
        • Site
    • News
      • Controllers
        • Admin
        • Site
      • Helpers
      • Models
        • Admin
        • Site
    • Pages
      • Controllers
        • Admin
        • Site
      • Models
        • Site
    • Search
      • Controllers
        • Site
    • Site
      • Controllers
        • Admin
        • Site
    • Sitemap
      • Controllers
        • Admin
        • Site
      • Models
        • Admin
        • Site
    • Test
      • Controllers
        • Site
    • Torrents
      • Controllers
        • Site
    • Users
      • Controllers
        • Admin
        • Site
      • Models
        • Admin
        • Site
  • Compression
  • Core
    • Libraries
      • Arhive
      • Array
      • Attached
      • Autoadmin
      • Autoloader
      • Benchmark
      • Breadcrumbs
      • Cache
      • Config
      • Cookie
      • Csrf
      • Database
        • Drivers
          • Interfaces
      • Datetime
      • Debug
      • Editor
      • Events
      • File
      • Filter
      • Flashmessage
      • Folder
      • Hit
      • Html
      • Image
      • Inflector
      • Inputfilter
      • Libraries
      • Mail
      • Module
      • Nestedset
      • Pager
      • Pages
      • Params
      • Randomizer
      • Request
      • RobotLoader
      • Route
      • Security
      • Session
      • Static
      • String
      • Text
      • Trash
      • Validate
  • Email
  • Extra
    • Libraries
      • Basket
  • Joostina
    • Controller
    • Core
    • Document
  • JSMin
  • Libraries
    • Extra
      • Basket
        • Models
          • Site
  • None
  • Plugins
    • Autoadmin
    • Editor
    • Sitemap
  • SimpleMail
  • Vendors
    • Libraries
      • Email

Classes

  • helperAcl
  • joosAdminToolbarButtons
  • joosAdminView
  • joosAdminViewToolbarEdit
  • joosAdminViewToolbarListing
  • joosAutoadminHTML
  • joosTemplater
  • joosValidateHelper
  • modelAdminCoder_Faker
  • moduleActions
  • moduleActionsLogin
  • moduleActionsMenu
  • moduleActionsNews
  • moduleActionsTest
  • Route
  • rulesValidation
  • TreeBuilder

Interfaces

  • joosAutoadminPluginsEdit
  • joosAutoadminPluginsTable

Exceptions

  • joosAutoadminClassPlugionNotFoundException
  • joosAutoadminFilePluginNotFoundException
  • joosAutoloaderClassNotFoundException
  • joosAutoloaderFileNotFoundException
  • joosAutoloaderOnStartFileNotFoundException
  • joosCacheException
  • joosCoreException
  • joosDatabaseException
  • joosException
  • joosFileLibrariesException
  • joosFolderLibrariesException
  • joosImageLibrariesException
  • joosModulesException
  • joosSimpleMailException
  • joosUploadLibrariesException
  • joosUserException
  • JSMinException

Functions

  • navigation_ul_li_recurse
  • quoted_printable_encode
  1: <?php defined('_JOOS_CORE') or exit();
  2: 
  3: /**
  4:  * Работа с ссылками и роутингом
  5:  *
  6:  * @version    1.0
  7:  * @package    Core\Libraries
  8:  * @subpackage Route
  9:  * @category   Libraries
 10:  * @author     Joostina Team <info@joostina.ru>
 11:  * @copyright  (C) 2007-2012 Joostina Team
 12:  * @license    MIT License http://www.opensource.org/licenses/mit-license.php
 13:  * Информация об авторах и лицензиях стороннего кода в составе Joostina CMS: docs/copyrights
 14:  *
 15:  * */
 16: class joosRoute extends Route
 17: {
 18:     private static $current_url;
 19: 
 20:     public static function init()
 21:     {
 22:         /**
 23:          *
 24:          * @todo файл с пользовательскими роутами, должен конфигурироваться и подключаться в bootstrap.php
 25:          */
 26:         $routes = require(JPATH_APP_CONFIG . DS . 'routes.php');
 27: 
 28:         foreach ($routes as $route_name => $route) {
 29:             self::set($route_name, $route['href'], (isset($route['params_rules']) ? $route['params_rules'] : null))->defaults($route['defaults']);
 30:         }
 31: 
 32:         //$uri = $_SERVER['QUERY_STRING'] = rtrim($_SERVER['QUERY_STRING'], '/');
 33:         $uri = $_SERVER['REQUEST_URI'] = trim($_SERVER['REQUEST_URI'], '/');
 34:         self::$current_url = urldecode($uri);
 35: 
 36:     }
 37: 
 38:     public static function route()
 39:     {
 40:         self::init();
 41: 
 42:         $routes = self::all();
 43:         $params = NULL;
 44: 
 45:         foreach ($routes as $name => $route) {
 46:             // We found something suitable
 47:             if (($params = $route->matches(self::$current_url))) {
 48:                 joosController::$activroute = $name;
 49:                 joosController::$controller = $params['controller'];
 50:                 joosController::$task = $params['action'];
 51:                 joosController::$param = $params;
 52: 
 53:                 return;
 54:             }
 55:         }
 56: 
 57:         // если включена отладка - скажем что именно не так
 58:         if (JDEBUG) {
 59:             throw new joosException('Не найдено правило роутинга для ссылки :location', array(':location' => self::$current_url));
 60:         } else {
 61:             // отладка не включена - просто перекинем на 404 страницу с понятным текстом
 62:             joosPages::page404('Такая ссылка на сайте невозможна');
 63:         }
 64:     }
 65: 
 66:     /**
 67:      * Формирование ссылки
 68:      *
 69:      * @param  string $route_name название правила роутинга
 70:      * @param  array  $params     массив параметров для формирования ссылки
 71:      * @return string
 72:      */
 73:     public static function href($route_name, array $params = array())
 74:     {
 75:         return JPATH_SITE . '/' . self::get($route_name)->uri($params);
 76:     }
 77: 
 78:     /**
 79:      * Системный 301 редирект
 80:      *
 81:      * @param  string $url  ссылка, на которую надо перейти
 82:      * @param  string $msg  текст сообщения, отображаемый после перехода
 83:      * @param  string $type тип перехода - ошибка, предупреждение, сообщение и т.д.
 84:      * @return void
 85:      */
 86:     public static function redirect($url, $msg = '', $type = 'success')
 87:     {
 88:         $iFilter = joosInputFilter::instance();
 89:         $url = $iFilter->process($url);
 90: 
 91:         empty($msg) ? null : joosFlashMessage::add($iFilter->process($msg), $type);
 92: 
 93:         $url = preg_split("/[\r\n]/", $url);
 94:         $url = $url[0];
 95: 
 96:         if ($iFilter->badAttributeValue(array('href', $url))) {
 97:             $url = JPATH_SITE;
 98:         }
 99: 
100:         if (headers_sent()) {
101:             echo "<script>document.location.href='$url';</script>\n";
102:         } else {
103:             !ob_get_level() ? : ob_end_clean();
104:             joosRequest::send_headers_by_code(301);
105:             joosRequest::send_headers("Location: " . $url);
106:         }
107: 
108:         exit();
109:     }
110: 
111:     /**
112:      * Получение название текущего активного правила роутинга
113:      *
114:      * @return string
115:      */
116:     public static function get_active_route()
117:     {
118:         return joosController::$activroute;
119:     }
120: 
121:     /**
122:      * Получение текущий ссылки ( в адресной сроке браузера )
123:      *
124:      * @return string
125:      */
126:     public static function get_current_url()
127:     {
128:         return self::$current_url == '' ? JPATH_SITE : JPATH_SITE . '/' . self::$current_url;
129:     }
130: 
131: }
132: 
133: /**
134:  * Базовый класс роутинга
135:  * Базируется на оригинальной работе Kohana Team
136:  */
137: class Route
138: {
139:     // Defines the pattern of a <segment>
140: 
141:     const REGEX_KEY = '<([a-zA-Z0-9_]++)>';
142: 
143:     // What can be part of a <segment> value
144:     const REGEX_SEGMENT = '[^/.,;?\n]++';
145: 
146:     // What must be escaped in the route regex
147:     const REGEX_ESCAPE = '[.\\+*?[^\\]${}=!|]';
148: 
149:     /**
150:      * @var  string  default protocol for all routes
151:      *
152:      * @tutorial  'http://'
153:      */
154:     public static $default_protocol = 'http://';
155: 
156:     /**
157:      * @var  string  default action for all routes
158:      */
159:     public static $default_action = 'index';
160: 
161:     /**
162:      * @var  bool Indicates whether routes are cached
163:      */
164:     public static $cache = FALSE;
165: 
166:     /**
167:      * @var  array
168:      */
169:     protected static $_routes = array();
170: 
171:     /**
172:      * Stores a named route and returns it. The "action" will always be set to
173:      * "index" if it is not defined.
174:      *
175:      *     self::set('default', '(<controller>(/<action>(/<id>)))')
176:      *         ->defaults(array(
177:      *             'controller' => 'welcome',
178:      *         ));
179:      *
180:      * @param   string   route name
181:      * @param   string   URI pattern
182:      * @param   array    regex patterns for route keys
183:      *
184:      * @return Route
185:      */
186:     protected static function set($name, $uri_callback = NULL, $regex = NULL)
187:     {
188:         return self::$_routes[$name] = new self($uri_callback, $regex);
189:     }
190: 
191:     /**
192:      * Retrieves a named route.
193:      *
194:      *     $route = self::get('default');
195:      *
196:      * @param   string  route name
197:      *
198:      * @return Route
199:      * @throws joosException
200:      */
201:     protected static function get($name)
202:     {
203:         if (!isset(self::$_routes[$name])) {
204:             throw new joosException('Не найдено правило роутинга: :route', array(':route' => $name));
205:         }
206: 
207:         return self::$_routes[$name];
208:     }
209: 
210:     /**
211:      * Retrieves all named routes.
212:      *
213:      *     $routes = self::all();
214:      *
215:      * @return array routes by name
216:      */
217:     protected static function all()
218:     {
219:         return self::$_routes;
220:     }
221: 
222:     /**
223:      * Returns the compiled regular expression for the route. This translates
224:      * keys and optional groups to a proper PCRE regular expression.
225:      *
226:      *     $compiled = self::compile(
227:      *        '<controller>(/<action>(/<id>))',
228:      *         array(
229:      *           'controller' => '[a-z]+',
230:      *           'id' => '\d+',
231:      *         )
232:      *     );
233:      *
234:      * @return string
235:      * @uses    self::REGEX_ESCAPE
236:      * @uses    self::REGEX_SEGMENT
237:      */
238:     private static function compile($uri, array $regex = NULL)
239:     {
240:         if (!is_string($uri)) {
241:             return;
242:         }
243: 
244:         // The URI should be considered literal except for keys and optional parts
245:         // Escape everything preg_quote would escape except for : ( ) < >
246:         $expression = preg_replace('#' . self::REGEX_ESCAPE . '#', '\\\\$0', $uri);
247: 
248:         if (strpos($expression, '(') !== FALSE) {
249:             // Make optional parts of the URI non-capturing and optional
250:             $expression = str_replace(array('(', ')'), array('(?:', ')?'), $expression);
251:         }
252: 
253:         // Insert default regex for keys
254:         $expression = str_replace(array('<', '>'), array('(?P<', '>' . self::REGEX_SEGMENT . ')'), $expression);
255: 
256:         // правила краткой записи регулярок роутинга
257:         $rules = array(':any' => '.+?', ':maybe' => '.*?', ':digit' => '[\d]+', ':alpha' => '[a-zA-Z]+', ':rus_alpha' => '[a-zA-Zа-яА-ЯёЁ]+', ':word' => '[\w-_]+', ':slug' => '[a-zA-Zа-яА-ЯёЁ0-9\-]+',);
258: 
259:         if ($regex) {
260:             $search = $replace = array();
261:             foreach ($regex as $key => $value) {
262: 
263:                 $value = strtr($value, $rules);
264: 
265:                 $search[] = "<$key>" . self::REGEX_SEGMENT;
266:                 $replace[] = "<$key>$value";
267:             }
268: 
269:             // Replace the default regex with the user-specified regex
270:             $expression = str_replace($search, $replace, $expression);
271:         }
272: 
273:         return '#^' . $expression . '$#uD';
274:     }
275: 
276:     /**
277:      * @var  string  route URI
278:      */
279:     protected $_uri = '';
280: 
281:     /**
282:      * @var  array
283:      */
284:     protected $_regex = array();
285: 
286:     /**
287:      * @var  array
288:      */
289:     protected $_defaults = array('action' => 'index', 'host' => FALSE);
290: 
291:     /**
292:      * @var  string
293:      */
294:     protected $_route_regex;
295: 
296:     /**
297:      * Creates a new route. Sets the URI and regular expressions for keys.
298:      * Routes should always be created with [self::set] or they will not
299:      * be properly stored.
300:      *
301:      *    $route = new Route($uri, $regex);
302:      *
303:      * @param   mixed    route URI pattern
304:      * @param   array    key patterns
305:      *
306:      * @return void
307:      * @uses    self::_compile
308:      */
309:     public function __construct($uri = NULL, $regex = NULL)
310:     {
311:         if ($uri === NULL) {
312:             // заморочка с кешем
313:             return;
314:         }
315: 
316:         if (!empty($uri)) {
317:             $this->_uri = $uri;
318:         }
319: 
320:         if (!empty($regex)) {
321:             $this->_regex = $regex;
322:         }
323: 
324:         // Store the compiled regex locally
325:         $this->_route_regex = self::compile($uri, $regex);
326:     }
327: 
328:     /**
329:      * Provides default values for keys when they are not present. The default
330:      * action will always be "index" unless it is overloaded here.
331:      *
332:      *     $route->defaults(array(
333:      *         'controller' => 'welcome',
334:      *         'action'     => 'index'
335:      *     ));
336:      *
337:      * @param   array  key values
338:      *
339:      * @return  $this
340:      */
341:     protected function defaults(array $defaults = NULL)
342:     {
343:         $this->_defaults = $defaults;
344: 
345:         return $this;
346:     }
347: 
348:     /**
349:      * Tests if the route matches a given URI. A successful match will return
350:      * all of the routed parameters as an array. A failed match will return
351:      * boolean FALSE.
352:      *
353:      *     // Params: controller = users, action = edit, id = 10
354:      *     $params = $route->matches('users/edit/10');
355:      *
356:      * This method should almost always be used within an if/else block:
357:      *
358:      *     if ($params = $route->matches($uri))
359:      *     {
360:      *         // Parse the parameters
361:      *     }
362:      *
363:      * @param   string  URI to match
364:      *
365:      * @return array on success
366:      * @return FALSE on failure
367:      */
368:     protected function matches($uri)
369:     {
370:         if (!preg_match($this->_route_regex, $uri, $matches)) {
371:             return FALSE;
372:         }
373: 
374:         $params = array();
375:         foreach ($matches as $key => $value) {
376:             if (is_int($key)) {
377:                 // Skip all unnamed keys
378:                 continue;
379:             }
380: 
381:             // Set the value for all matched keys
382:             $params[$key] = $value;
383:         }
384: 
385:         foreach ($this->_defaults as $key => $value) {
386:             if (!isset($params[$key]) OR $params[$key] === '') {
387:                 // Set default values for any key that was not matched
388:                 $params[$key] = $value;
389:             }
390:         }
391: 
392:         return $params;
393:     }
394: 
395:     /**
396:      * Generates a URI for the current route based on the parameters given.
397:      *
398:      *     // Using the "default" route: "users/profile/10"
399:      *     $route->uri(array(
400:      *         'controller' => 'users',
401:      *         'action'     => 'profile',
402:      *         'id'         => '10'
403:      *     ));
404:      *
405:      * @param   array   URI parameters
406:      *
407:      * @return string
408:      * @throws joosException
409:      * @uses    self::REGEX_Key
410:      */
411:     protected function uri(array $params = NULL)
412:     {
413:         // Start with the routed URI
414:         $uri = $this->_uri;
415: 
416:         // если в ссылке нет динамических параметров - сразу её возвратим
417:         if (strpos($uri, '<') === FALSE AND strpos($uri, '(') === FALSE) {
418:             return $uri;
419:         }
420: 
421:         while (preg_match('#' . self::REGEX_KEY . '#', $uri, $match)) {
422:             list($key, $param) = $match;
423:             if (!isset($params[$param])) {
424:                 // Look for a default
425:                 if (isset($this->_defaults[$param])) {
426:                     $params[$param] = $this->_defaults[$param];
427:                 } else {
428:                     // отсутствуют требуемые параметры
429:                     throw new joosException('Требуемый параметр :param не найден в полученных данных для условия :uri', array(':param' => $param, ':uri' => joosFilter::htmlspecialchars($this->_uri)));
430:                 }
431:             }
432: 
433:             $uri = str_replace($key, $params[$param], $uri);
434:         }
435: 
436:         // чистка от лишних и дублирующихся /
437:         $uri = preg_replace('#//+#', '/', rtrim($uri, '/'));
438: 
439:         return $uri;
440:     }
441: 
442: }
443: 
Joostina CMS / CMF v2.* API API documentation generated by ApiGen 2.6.1 – Template adapted by @olvlv and Joostina Team