├── .gitignore
├── src
├── GeoIP-Lite
│ └── GeoIP.dat
├── Sifo
│ ├── Session
│ │ ├── SessionNameStrategy.php
│ │ └── SessionEnvironmentStrategy.php
│ ├── View
│ │ ├── Interface.php
│ │ └── Smarty.php
│ ├── Debug
│ │ ├── PredisProxyClient.php
│ │ └── Sphinxql.php
│ ├── AmazonS3.php
│ ├── Cache
│ │ ├── Memcache.php
│ │ ├── Memcached.php
│ │ ├── MemcacheAdapter.php
│ │ ├── Lock.php
│ │ └── Disk.php
│ ├── Keyspace.php
│ ├── CssPacker.php
│ ├── Model.php
│ ├── Crypt.php
│ ├── JsPacker.php
│ ├── MysqlModel.php
│ ├── Mail.php
│ ├── Benchmark.php
│ ├── FlashMessages.php
│ ├── View.php
│ ├── CLBootstrap.php
│ ├── Cache.php
│ ├── Registry.php
│ ├── imageController.php
│ ├── RedisModel.php
│ ├── MediaPacker.php
│ ├── Dir.php
│ ├── Cookie.php
│ ├── Session.php
│ ├── Images.php
│ ├── API
│ │ └── Youtube.php
│ ├── LoadBalancer.php
│ ├── Metadata.php
│ ├── Router.php
│ ├── Exceptions.php
│ ├── Search.php
│ ├── Config.php
│ └── DirectoryList.php
├── Twig-sifo-plugins
│ ├── function.t.php
│ ├── filter.normalize.php
│ ├── function.paginate.php
│ ├── filter.link_urls.php
│ ├── filter.number_format.php
│ ├── filter.search_links.php
│ ├── filter.custom_tpl.php
│ ├── filter.currency.php
│ ├── filter.time_format.php
│ ├── filter.create_links.php
│ ├── filter.size_format.php
│ ├── function.pagelink.php
│ ├── function.filln.php
│ ├── function.fill.php
│ ├── filter.time_since.php
│ └── function.email_obfuscator.php
├── Smarty-sifo-plugins
│ ├── function.paginate.php
│ ├── modifier.lower.php
│ ├── modifier.normalize.php
│ ├── modifier.nl2br.php
│ ├── modifier.custom_tpl.php
│ ├── modifier.link_urls.php
│ ├── modifier.search_links.php
│ ├── modifier.number_format.php
│ ├── modifier.currency.php
│ ├── modifier.time_format.php
│ ├── function.pagelink.php
│ ├── modifier.create_links.php
│ ├── modifier.size_format.php
│ ├── function.filln.php
│ ├── modifier.time_since.php
│ ├── function.email_obfuscator.php
│ ├── block.t.php
│ └── function.fill.php
├── RSS_PHP
│ └── rss_php.php
└── Core-js
│ └── classes
│ └── modals.min.js
├── .gitattributes
├── LICENSE
├── README.md
├── composer.json
└── .idea
└── workspace.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | composer.lock
3 | .idea
4 |
--------------------------------------------------------------------------------
/src/GeoIP-Lite/GeoIP.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sifophp/SIFO/HEAD/src/GeoIP-Lite/GeoIP.dat
--------------------------------------------------------------------------------
/src/Sifo/Session/SessionNameStrategy.php:
--------------------------------------------------------------------------------
1 | fetch( $aParam['data']['template'] );
9 | }
10 |
11 | return $sOut;
12 |
13 | }//smarty_paginate
14 | ?>
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/function.paginate.php:
--------------------------------------------------------------------------------
1 | fetch($args[0]['data']['template']);
11 | }
12 |
13 | return $sOut;
14 | }, ['is_variadic' => true]
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/filter.link_urls.php:
--------------------------------------------------------------------------------
1 | ".($matches[0])."";
13 | },
14 | $string
15 | );
16 | }
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/src/Sifo/Session/SessionEnvironmentStrategy.php:
--------------------------------------------------------------------------------
1 | getInstanceInheritance();
10 | $vertical_instance = array_pop($instance_inheritance);
11 | $instance_environment_initial = isset($_SERVER['APP_ENV'][0]) ? $_SERVER['APP_ENV'][0] : '';
12 | $instance_session_name = "SSID_{$instance_environment_initial}_{$vertical_instance}";
13 | session_name($instance_session_name);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/filter.number_format.php:
--------------------------------------------------------------------------------
1 | getLanguage());
11 | $locale = localeconv();
12 | setlocale(LC_NUMERIC, null);
13 | $thousand_separator = ($locale['thousands_sep'] == '') ? '.' : $locale['thousands_sep'];
14 | $decimal_separator = $locale['decimal_point'];
15 |
16 | return @utf8_encode(number_format($string, $decimals, $decimal_separator, $thousand_separator));
17 | }
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/filter.search_links.php:
--------------------------------------------------------------------------------
1 | $url", $text);
18 | }
19 | }
20 |
21 | return $text;
22 | }
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.lower.php:
--------------------------------------------------------------------------------
1 |
13 | * Name: lower
14 | * Purpose: convert string to lowercase
15 | *
16 | * @link http://smarty.php.net/manual/en/language.modifier.lower.php lower (Smarty online manual)
17 | * @author Monte Ohrt
18 | * @param string $
19 | * @return string
20 | */
21 | function smarty_modifier_lower($string)
22 | {
23 | if (function_exists('mb_strtolower')) {
24 | return mb_strtolower($string);
25 | } else {
26 | return strtolower($string);
27 | }
28 | }
29 |
30 | ?>
31 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.normalize.php:
--------------------------------------------------------------------------------
1 |
13 | * Name: default
14 | * Purpose: designate default value for empty variables
15 | * @link http://smarty.php.net/manual/en/language.modifier.default.php
16 | * default (Smarty online manual)
17 | * @author Monte Ohrt
18 | *
19 | * Slightly modified to normalize usign SIFO class.
20 | * @param string
21 | * @param string
22 | * @return string
23 | */
24 | function smarty_modifier_normalize($string, $strict = false)
25 | {
26 | $normalized_url = \Sifo\Urls::normalize( $string );
27 |
28 | return $normalized_url;
29 | }
30 |
31 | /* vim: set expandtab: */
32 |
33 | ?>
34 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/filter.custom_tpl.php:
--------------------------------------------------------------------------------
1 | getConfig('templates');
15 | if (isset($instance_templates[$template]))
16 | {
17 | $selected_template = $instance_templates[$template];
18 | }
19 | else
20 | {
21 | trigger_error("The template '{$template}' has not been found in the templates folder.", E_USER_ERROR);
22 |
23 | return false;
24 | }
25 |
26 | return $selected_template;
27 | }
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.nl2br.php:
--------------------------------------------------------------------------------
1 |
13 | * Name: nl2br
14 | * Date: Feb 26, 2003
15 | * Purpose: convert \r\n, \r or \n to <
>
16 | * Input:
17 | * - contents = contents to replace
18 | * - preceed_test = if true, includes preceeding break tags
19 | * in replacement
20 | * Example: {$text|nl2br}
21 | * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php
22 | * nl2br (Smarty online manual)
23 | * @version 1.0
24 | * @author Monte Ohrt
25 | * @param string
26 | * @return string
27 | */
28 | function smarty_modifier_nl2br($string)
29 | {
30 | return nl2br($string);
31 | }
32 |
33 | /* vim: set expandtab: */
34 |
35 | ?>
36 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.custom_tpl.php:
--------------------------------------------------------------------------------
1 | getConfig( 'templates' );
19 | if ( isset( $instance_templates[$template] ) )
20 | {
21 | $selected_template = $instance_templates[$template];
22 | }
23 | else
24 | {
25 | trigger_error( "The template '{$template}' has not been found in the templates folder.", E_USER_ERROR );
26 | return false;
27 | }
28 |
29 | return ( ROOT_PATH . "/$selected_template" );
30 | }
--------------------------------------------------------------------------------
/src/Sifo/Debug/PredisProxyClient.php:
--------------------------------------------------------------------------------
1 | client ) )
10 | {
11 | $call_data = array();
12 | $call_data['connection'] = $this->connection_params;
13 | $call_data['method'] = $method;
14 | $call_data['args'] = $args;
15 | $call_data['controller'] = $this->getCallerClass();
16 | $call_data['results'] = call_user_func_array( array( $this->client, $method ), $args );
17 |
18 | Debug::push( 'redis', $call_data );
19 |
20 | return $call_data['results'];
21 | }
22 |
23 | return null;
24 | }
25 |
26 | public function getCallerClass()
27 | {
28 | $trace = debug_backtrace();
29 | foreach( $trace as $steps )
30 | {
31 | $classes[$steps['class']] = $steps['class'];
32 | }
33 |
34 | return implode( ' > ', array_slice( $classes, 0, 4 ) );
35 | }
36 | }
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.link_urls.php:
--------------------------------------------------------------------------------
1 |
12 | * Name: link_urls
13 | * Purpose: performs a regex and replaces any url's with links containing themselves as the text
14 | * This could be improved by using a better regex.
15 | * And maybe it would be better for usability if the http:// was cut off the front?
16 | * @author Andrew
17 | * @return string
18 | */
19 |
20 | function smarty_modifier_link_urls($string)
21 | {
22 | $linkedString = preg_replace_callback(
23 | "/\b(https?):\/\/([-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]*)\b/i",
24 | static function($matches) {
25 | return "".($matches[0])."";
26 | },
27 | $string
28 | );
29 |
30 | return $linkedString;
31 | }
32 |
33 | ?>
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.search_links.php:
--------------------------------------------------------------------------------
1 |
13 | * Name: search_links
14 | * Date: 28 Dic, 2010
15 | * Purpose: In a plain text convert links to HTML.
16 | * Example: {$text|search_links}
17 | * @link http://www.harecoded.com
18 | * @version 1.0
19 | * @author Albert Lombarte
20 | * @param string
21 | * @return string
22 | */
23 | function smarty_modifier_search_links( $text, $title = '', $rel='nofollow' )
24 | {
25 | preg_match_all( '/(http|ftp)+(s)?:(\/\/)((\w|\.)+)(\/)?(\S+)?(\.*)?/i', $text, $matches );
26 | if ( !empty( $matches[0] ) )
27 | {
28 | array_unique( $matches[0] );
29 | foreach ( $matches[0] as $url )
30 | {
31 | $text = str_replace( $url, "$url", $text );
32 | }
33 | }
34 |
35 | return $text;
36 |
37 | }
38 |
39 | ?>
--------------------------------------------------------------------------------
/src/Sifo/AmazonS3.php:
--------------------------------------------------------------------------------
1 | getConfig( 'amazon', 's3' );
31 |
32 | return parent::__construct(
33 | $config['awsAccessKey'],
34 | $config['awsSecretKey'],
35 | $config['useSSL']
36 | );
37 | }
38 | }
39 |
40 | ?>
41 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.number_format.php:
--------------------------------------------------------------------------------
1 |
13 | * Name: number_format
14 | * Purpose: format strings via number_format
15 | * @author Albert Lombarte
16 | * @param string
17 | * @param string
18 | * @param string
19 | * @param string
20 | * @return string
21 | */
22 | function smarty_modifier_number_format( $string, $decimals = 2 )
23 | {
24 | // Numeric locale vars.
25 | // Remember to change the size_format modifier if you change the locales management here.
26 | setlocale( LC_NUMERIC, \Sifo\Domains::getInstance()->getLanguage() );
27 | $locale = localeconv();
28 | setlocale( LC_NUMERIC, null );
29 | $thousand_separator = ( $locale['thousands_sep'] == '' ) ? '.' : $locale['thousands_sep'];
30 | $decimal_separator = $locale['decimal_point'];
31 |
32 | return @utf8_encode(number_format( $string, $decimals, $decimal_separator, $thousand_separator ));
33 | }
34 |
35 | /* vim: set expandtab: */
36 |
37 | ?>
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2010-2012 Albert Lombarte
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
15 | ----------------------------------------------------------------------
16 | This license applies to all the folders of this project excluding the
17 | folders located under libs/ not named "SIFO". See their original
18 | license file (included in the source code) for more information.
19 | ----------------------------------------------------------------------
20 |
21 | Some SIFO files are licensed (because they created the files for SIFO) to:
22 |
23 | Albert Garcia
24 | Sergio Ambel
25 | Pablo Ros
26 | Jorge Tarrero
27 | Carlos Soriano
28 | Manel Fernández
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/filter.currency.php:
--------------------------------------------------------------------------------
1 | '€',
13 | 'GBP' => '£',
14 | 'USD' => '$'
15 | );
16 |
17 | $currency_symbol = $currency;
18 |
19 | if (array_key_exists($currency, $currency_symbols))
20 | {
21 | $currency_symbol = $currency_symbols[$currency];
22 | }
23 |
24 | if (!empty($tag))
25 | {
26 | $currency_symbol = '<' . $tag . '>' . $currency_symbol . '' . $tag . '>';
27 | }
28 |
29 | switch ($currency)
30 | {
31 | case 'USD':
32 | case 'GBP':
33 | {
34 | return $currency_symbol . number_format($amount, 2);
35 | }
36 |
37 | default:
38 | {
39 | return number_format($amount, 2, ',', '.') . $currency_symbol;
40 | }
41 | }
42 | }
43 | );
44 | }
45 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.currency.php:
--------------------------------------------------------------------------------
1 |
12 | * Name: currency
13 | * Purpose: Formats a number as a currency string, with the given currency symbol
14 | * @param float
15 | * @param string currency (default EUR)
16 | * @return string
17 | */
18 | function smarty_modifier_currency($amount, $currency='EUR', $tag='')
19 | {
20 | $currency_symbols = array(
21 | 'EUR' => '€',
22 | 'GBP' => '£',
23 | 'USD' => '$'
24 | );
25 |
26 | if ( array_key_exists( $currency, $currency_symbols ) )
27 | {
28 | $currency_symbol = $currency_symbols[$currency];
29 | }
30 | else
31 | {
32 | $currency_symbol = $currency;
33 | }
34 |
35 | if ( !empty( $tag ) )
36 | {
37 | $currency_symbol = '<'.$tag.'>'.$currency_symbol.''.$tag.'>';
38 | }
39 |
40 | switch( $currency )
41 | {
42 | case 'USD':
43 | case 'GBP':
44 | {
45 | return $currency_symbol.number_format($amount,2,'.',',');
46 | }
47 |
48 | default:
49 | {
50 | return number_format($amount,2,',','.').$currency_symbol;
51 | }
52 | }
53 | }
54 |
55 | ?>
56 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/filter.time_format.php:
--------------------------------------------------------------------------------
1 | getLanguage());
13 | $locale = localeconv();
14 | setlocale(LC_NUMERIC, null);
15 | $thousand_separator = ($locale['thousands_sep'] == '') ? '.' : $locale['thousands_sep'];
16 | $decimal_separator = $locale['decimal_point'];
17 |
18 | if (null === $decimals)
19 | {
20 | $decimals = 0;
21 | }
22 |
23 | $time *= 1000;
24 |
25 | if ($time < 100)
26 | {
27 | // Miliseconds.
28 | $formatted_time = number_format($time, $decimals, $decimal_separator, $thousand_separator) . ' milisec';
29 | }
30 | else
31 | {
32 | // Seconds.
33 | $formatted_time = number_format($time / 1000, $decimals, $decimal_separator, $thousand_separator) . ' sec';
34 | }
35 |
36 | return $formatted_time;
37 | }
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Sifo PHP
2 | ========
3 |
4 | [SIFO] is a battle-tested open source Legacy PHP framework currently running on several production
5 | sites since more than 7 years, from small installations to large websites with multiple servers.
6 |
7 | ---
8 |
9 | ## Installation
10 |
11 | ```bash
12 | composer require sifophp/sifo sifophp/sifo-common-instance
13 | ```
14 |
15 | ## Future of Sifo Framework
16 |
17 | ### Support
18 |
19 | * Sifo is actively maintained cost it is used by some companies in production
20 | * Fill free to open issue or a pull request for any kind of fix or improvement
21 |
22 | ### New Features
23 |
24 | * Although, the framework is actively maintained, we aren't go to add any new feature,
25 | Sifo has a lot of features that we are trying to remove in order to archieve a more cleaner integration between the
26 | framework and the business code.
27 |
28 | ### Deprecations
29 |
30 | * Use only classes located inner `Sifo\` namespace every other library included will be deleted in future releases
31 |
32 | ### Maybe
33 |
34 | * Allow Framework Agnostic Controllers
35 | * Clean package without external libraries
36 |
37 | ---
38 |
39 | More documentation in the *official site*: [https://web.archive.org/web/20180809060838/http://sifo.me/] [SIFO]
40 |
41 | [SIFO]: https://web.archive.org/web/20180809060838/http://sifo.me/
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/filter.create_links.php:
--------------------------------------------------------------------------------
1 | ()\[\]\{\}\s\x7F-\\xFF]*
40 | (
41 | [.!,?]+ [^.!,?"\\'<>()\\[\\]\{\\}\s\\x7F-\\xFF]+
42 | )*
43 | )?
44 | }ix
45 | REGEXP;
46 | }
47 |
48 | return preg_replace($regexp, '\1\4', $string);
49 | }
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/src/Sifo/Cache/Memcache.php:
--------------------------------------------------------------------------------
1 | set( 'a', 'my value' ); // Stores in the key 'a' the value 'my value'
13 | *
14 | * This class is based on Memcache object implementation: http://www.php.net/manual/en/book.memcache.php
15 | *
16 | */
17 | namespace Sifo;
18 |
19 | /**
20 | * Wrapper for the PECL Memcache extension.
21 | *
22 | * @see http://www.php.net/manual/en/memcache.installation.php
23 | */
24 | class CacheMemcache extends CacheBase
25 | {
26 | protected $cache_object = null;
27 |
28 | /**
29 | * Returns an instance of the Memcache object with the configured servers.
30 | */
31 | public function __construct()
32 | {
33 | try
34 | {
35 | $servers = \Sifo\Config::getInstance()->getConfig( 'cache', 'servers' );
36 | }
37 | catch ( \Sifo\Exception_Configuration $e )
38 | {
39 | // Default memcached address and listening port.
40 | $servers = array( array( '127.0.0.1' => 11211 ) );
41 | }
42 |
43 | $this->cache_object = new \CacheMemcacheAdapter();
44 |
45 | foreach ( $servers[0] as $server => $port )
46 | {
47 | $this->cache_object->addServer( $server, $port );
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.time_format.php:
--------------------------------------------------------------------------------
1 |
14 | * Name: time_format
15 | * Purpose: format times directly from DB.
16 | *
17 | * @param integer $time Time given in ms.
18 | * @param integer $decimals Number of decimals.
19 | * @return string
20 | */
21 | function smarty_modifier_time_format( $time, $decimals=3 )
22 | {
23 | // Numeric locale vars.
24 | // Remember to change the number_format modifier if you change the locales management here.
25 | setlocale( LC_NUMERIC, \Sifo\Domains::getInstance()->getLanguage() );
26 | $locale = localeconv();
27 | setlocale( LC_NUMERIC, null );
28 | $thousand_separator = ( $locale['thousands_sep'] == '' ) ? '.' : $locale['thousands_sep'];
29 | $decimal_separator = $locale['decimal_point'];
30 |
31 | if ( is_null( $decimals ) )
32 | {
33 | $decimals = 0;
34 | }
35 |
36 | $time = $time*1000;
37 |
38 | if ( $time < 100 )
39 | {
40 | // Miliseconds.
41 | $formatted_time = number_format( $time, $decimals, $decimal_separator, $thousand_separator ).' milisec';
42 | }
43 | else
44 | {
45 | // Seconds.
46 | $formatted_time = number_format( ( $time / 1000 ), $decimals, $decimal_separator, $thousand_separator ).' sec';
47 | }
48 |
49 | return $formatted_time;
50 | }
51 |
52 | /* vim: set expandtab: */
53 |
54 | ?>
55 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/function.pagelink.php:
--------------------------------------------------------------------------------
1 | getString( 'QUERY_STRING' );
22 | $_current_path = \Sifo\FilterServer::getInstance()->getString( 'REQUEST_URI' );
23 |
24 | if ( !empty( $_current_querystring ) )
25 | {
26 | $_current_querystring = '?' . $_current_querystring;
27 | $_current_path = str_replace( $_current_querystring, '', $_current_path );
28 | }
29 |
30 | $_current_url = array_reverse( explode( $_delimiter, $_current_path ) );
31 |
32 | if ( is_numeric( $_current_url[0] ) )
33 | {
34 | $_current_page = ( int )array_shift( $_current_url );
35 | }
36 | else
37 | {
38 | $_current_page = 1;
39 | }
40 |
41 | $_current_url = implode( $_delimiter, array_reverse( $_current_url ) );
42 |
43 | if ( !isset( $params['page'] ) )
44 | {
45 | trigger_error( "pagelink: You should provide the destination pagelink." );
46 | }
47 | else
48 | {
49 | if ( $params['page'] > 1 )
50 | {
51 | return $_current_url . $_delimiter . $params['page'];
52 | }
53 | else
54 | {
55 | return $_current_url;
56 | }
57 | }
58 | }
59 |
60 | /* vim: set expandtab: */
61 |
62 | ?>
63 |
--------------------------------------------------------------------------------
/src/Sifo/Cache/Memcached.php:
--------------------------------------------------------------------------------
1 | cache_object = new \Memcached();
38 |
39 | try
40 | {
41 | $servers = Config::getInstance()->getConfig( 'cache', 'servers' );
42 | }
43 | catch ( Exception_Configuration $e )
44 | {
45 | // Default memcached address and listening port.
46 | $servers = array( array( '127.0.0.1' => 11211 ) );
47 | }
48 |
49 | foreach ( $servers[0] as $server => $port )
50 | {
51 | $this->cache_object->addServer( $server, $port );
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Sifo/Keyspace.php:
--------------------------------------------------------------------------------
1 | getConfig( 'keyspace' );
33 | }
34 |
35 | if ( !isset( self::$keyspace[$key_name] ) )
36 | {
37 | throw new KeySpace_Exception( "Key named '$key_name' is not available in the key space." );
38 | }
39 |
40 |
41 | $key = self::$keyspace[$key_name];
42 |
43 | if ( is_array( $parameters ) )
44 | {
45 | foreach ( $parameters as $tag => $value )
46 | {
47 | $tag = preg_quote( $tag, '/' );
48 | $key = preg_replace( "/<($tag)>/", $value, $key);
49 | }
50 | }
51 |
52 | // Remove any missing parameters:
53 | if ( false !== strpos( $key, '<' ) )
54 | {
55 | throw new KeySpace_Exception( "The key contains undeclared parameters for replacement" );
56 | }
57 |
58 | return $key;
59 | }
60 |
61 | }
62 |
63 | class KeySpace_Exception extends \Exception
64 | {
65 |
66 | }
--------------------------------------------------------------------------------
/src/Sifo/CssPacker.php:
--------------------------------------------------------------------------------
1 |
12 | * Name: create_links
13 | * Purpose: create HTML markup for links
14 | * Input:
15 | * - string: text you want to search for links into
16 | * Params:
17 | * - string $regexp Optional in case you want to define a different regexp for URLs (like only internal links).
18 | *
19 | * @author Manuel Fernandez
20 | * @return string
21 | */
22 | function smarty_modifier_create_links($string,$regexp = '')
23 | {
24 | if ( empty( $regexp ) )
25 | {
26 | $regexp = <<()\[\]\{\}\s\x7F-\\xFF]*
54 | (
55 | [.!,?]+ [^.!,?"\\'<>()\\[\\]\{\\}\s\\x7F-\\xFF]+
56 | )*
57 | )?
58 | }ix
59 | REGEXP;
60 | }
61 |
62 | return preg_replace( $regexp, '\1\4', $string );
63 | }
64 |
65 | /* vim: set expandtab: */
66 |
67 | ?>
68 |
--------------------------------------------------------------------------------
/src/Sifo/Cache/MemcacheAdapter.php:
--------------------------------------------------------------------------------
1 | getLanguage());
13 | $locale = localeconv();
14 | setlocale(LC_NUMERIC, null);
15 | $thousand_separator = ($locale['thousands_sep'] == '') ? '.' : $locale['thousands_sep'];
16 | $decimal_separator = $locale['decimal_point'];
17 |
18 | if ($size < 1024)
19 | {
20 | if (null === $decimals)
21 | {
22 | $decimals = 0;
23 | }
24 | // Kilobytes.
25 | $formatted_size = number_format($size, $decimals, $decimal_separator, $thousand_separator) . ' B';
26 | }
27 | elseif ($size < 1048576)
28 | {
29 | if (null === $decimals)
30 | {
31 | $decimals = 0;
32 | }
33 | // Kylobytes.
34 | $formatted_size = number_format(($size / 1024), $decimals, $decimal_separator, $thousand_separator) . ' KB';
35 | }
36 | elseif ($size < 1073741824)
37 | {
38 | if (null === $decimals)
39 | {
40 | $decimals = 1;
41 | }
42 | // Megabytes.
43 | $formatted_size = number_format(($size / 1048576), $decimals, $decimal_separator, $thousand_separator) . ' MB';
44 | }
45 | else
46 | {
47 | if (null === $decimals)
48 | {
49 | $decimals = 1;
50 | }
51 | // Gigabytes.
52 | $formatted_size = number_format(($size / 1073741824), $decimals, $decimal_separator, $thousand_separator) . ' GB';
53 | }
54 |
55 | return $formatted_size;
56 | }
57 | );
58 | }
59 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.size_format.php:
--------------------------------------------------------------------------------
1 |
14 | * Name: size_format
15 | * Purpose: format sizes directly from DB.
16 | *
17 | * @param integer $size Size of a file.
18 | * @param integer $decimals Number of decimals.
19 | * @return string
20 | */
21 | function smarty_modifier_size_format( $size, $decimals=null )
22 | {
23 | // Numeric locale vars.
24 | // Remember to change the number_format modifier if you change the locales management here.
25 | setlocale( LC_NUMERIC, \Sifo\Domains::getInstance()->getLanguage() );
26 | $locale = localeconv();
27 | setlocale( LC_NUMERIC, null );
28 | $thousand_separator = ( $locale['thousands_sep'] == '' ) ? '.' : $locale['thousands_sep'];
29 | $decimal_separator = $locale['decimal_point'];
30 |
31 | if ( $size < 1024 )
32 | {
33 | if ( is_null( $decimals ) )
34 | {
35 | $decimals = 0;
36 | }
37 | // Kilobytes.
38 | $formatted_size = number_format( $size, $decimals, $decimal_separator, $thousand_separator ).' B';
39 | }
40 | elseif ( $size < 1048576 )
41 | {
42 | if ( is_null( $decimals ) )
43 | {
44 | $decimals = 0;
45 | }
46 | // Kylobytes.
47 | $formatted_size = number_format( ( $size / 1024 ), $decimals, $decimal_separator, $thousand_separator ).' KB';
48 | }
49 | elseif ( $size < 1073741824 )
50 | {
51 | if ( is_null( $decimals ) )
52 | {
53 | $decimals = 1;
54 | }
55 | // Megabytes.
56 | $formatted_size = number_format( ( $size / 1048576 ), $decimals, $decimal_separator, $thousand_separator ).' MB';
57 | }
58 | else
59 | {
60 | if ( is_null( $decimals ) )
61 | {
62 | $decimals = 1;
63 | }
64 | // Gigabytes.
65 | $formatted_size = number_format( ( $size / 1073741824 ), $decimals, $decimal_separator, $thousand_separator ).' GB';
66 |
67 | }
68 |
69 | return $formatted_size;
70 | }
71 |
72 | /* vim: set expandtab: */
73 |
74 | ?>
75 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/function.pagelink.php:
--------------------------------------------------------------------------------
1 | getString('QUERY_STRING');
16 | $current_path = \Sifo\FilterServer::getInstance()->getString('REQUEST_URI');
17 | $current_host = \Sifo\Urls::$base_url;
18 | }
19 | else
20 | {
21 | $current_querystring = $_SERVER['QUERY_STRING'];
22 | $current_path = $_SERVER['REQUEST_URI'];
23 | $current_host = ($_SERVER['HTTPS'] ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'];
24 | }
25 |
26 | // Clean querystring always. The URL could eventually include an empty "?".
27 | $current_path = str_ireplace('?' . $current_querystring, '', $current_path);
28 |
29 | $current_url = array_reverse(explode($delimiter, $current_path));
30 |
31 | if (isset($args[0]['base_url']))
32 | {
33 | $current_url = $args[0]['base_url'];
34 | }
35 | else
36 | {
37 | $current_url = implode($delimiter, array_reverse($current_url));
38 |
39 | if (isset($args[0]['absolute']))
40 | {
41 | $current_url = $current_host . $current_url;
42 | }
43 | }
44 |
45 | if (!isset($args[0]['page']))
46 | {
47 | trigger_error('pagelink: You should provide the destination pagelink. Params: ' . json_encode($args[0]), E_USER_WARNING);
48 | }
49 | else
50 | {
51 | if ($args[0]['page'] > 1 || (isset($args[0]['force_first_page']) && $args[0]['force_first_page'] == true))
52 | {
53 | return $current_url . $delimiter . $args[0]['page'];
54 | }
55 |
56 | return $current_url;
57 | }
58 | }, ['is_variadic' => true]
59 | );
60 | }
61 |
--------------------------------------------------------------------------------
/src/Sifo/Model.php:
--------------------------------------------------------------------------------
1 | init();
28 | return Database::getInstance();
29 | }
30 |
31 | /**
32 | * Use this method as constructor in chidren.
33 | */
34 | protected function init()
35 | {
36 | return true;
37 | }
38 |
39 | /**
40 | * Returns an element in the registry.
41 | *
42 | * @param string $key
43 | * @return mixed
44 | */
45 | protected function inRegistry( $key )
46 | {
47 | $reg = Registry::getInstance();
48 | if ( $reg->keyExists( $key ) )
49 | {
50 | return $reg->get( $key );
51 | }
52 |
53 | return false;
54 | }
55 |
56 | /**
57 | * Stores in the registry a value with the given key.
58 | *
59 | * @param string $key
60 | * @param mixed $value
61 | */
62 | protected function storeInRegistry( $key, $value )
63 | {
64 | $reg = Registry::getInstance()->set( $key, $value );
65 | }
66 |
67 | /**
68 | * Returns the translation of a string
69 | *
70 | * @param string $subject
71 | * @param string $var_1
72 | * @param string $var2
73 | * @param string $var_n
74 | * @return string
75 | */
76 | public function translate( $subject, $var_1 = '', $var2 = '', $var_n = '' )
77 | {
78 | $args = func_get_args();
79 | $variables = array();
80 | if ( 1 < count( $args ) )
81 | {
82 | foreach ( $args as $key => $value )
83 | {
84 | $variables['%'.$key] = $value;
85 | }
86 |
87 | }
88 |
89 | unset( $variables['%0'] );
90 | return I18N::getInstance( 'messages', Domains::getInstance()->getLanguage() )->getTranslation( $subject, $variables );
91 | }
92 |
93 | /**
94 | * When Database response is bad you can use $this->CacheExecute($seconds, "SELECT..'");. Writes to /cache are done.
95 | */
96 | }
97 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/function.filln.php:
--------------------------------------------------------------------------------
1 |
13 | * Name: fill
14 | * Input:
15 | * - [any] (required) - string
16 | * - subject (required) - string
17 | * - delimiter (optional, defaults to '%' ) - string
18 | * Purpose: Fills the variables found in 'subject' with the paramaters passed. The variables are any word surrounded by two delimiters.
19 | *
20 | * Examples of usage:
21 | *
22 | * {fill subject="http://domain.com/profile/%username%" username='fred'}
23 | * Output: http://domain.com/profile/fred
24 | *
25 | * {fill subject="Hello %user%, welcome aboard!" user=Fred}
26 | * Outputs: Hello Fred, welcome aboard
27 | *
28 | * {fill subject="http://||subdomain||.domain.com/||page||/||action||" subdomain='www' page='my-first-post' action='vote' delimiter='||'}
29 | * Outputs: http://www.domain.com/my-first-post/vote
30 | *
31 | * @link http://www.harecoded.com/fill-smarty-php-plugin-311577
32 | * @author Albert Lombarte
33 | * @param array
34 | * @param Smarty
35 | * @return string
36 | */
37 | function smarty_function_filln($params, &$smarty)
38 | {
39 |
40 | if (isset($params['delimiter'])) {
41 | $_delimiter = $params['delimiter'];
42 | unset($params['delimiter']);
43 | } else {
44 | $_delimiter = '%';
45 | }
46 |
47 | if (false !== strpos($_delimiter, '$')) {
48 | trigger_error("fill: The delimiter '$' is banned in function {url}", E_USER_NOTICE);
49 | }
50 |
51 | if (!isset($params['subject']) || count($params) < 2) {
52 | trigger_error("fill: The attribute 'subject' and at least one parameter is needed in function {url}", E_USER_NOTICE);
53 | }
54 |
55 | $_html_result = $params['subject'];
56 | $_tmp_result = $_html_result;
57 |
58 | unset($params['subject']);
59 |
60 | foreach ($params as $_key => $_val)
61 | {
62 | $_val = (string)$_val;
63 | $_tmp_result = str_replace($_delimiter . $_key . $_delimiter, $_val, $_tmp_result);
64 |
65 | $normalized_url = \Sifo\Urls::normalize($_val);
66 | $_html_result = str_replace($_delimiter . $_key . $_delimiter, $normalized_url, $_html_result);
67 | }
68 |
69 | return $_html_result;
70 |
71 | }
72 |
73 | /* vim: set expandtab: */
74 |
75 | ?>
76 |
--------------------------------------------------------------------------------
/src/Sifo/Crypt.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/modifier.time_since.php:
--------------------------------------------------------------------------------
1 |
16 | * Name: size_format
17 | * Purpose: format sizes directly from DB.
18 | *
19 | * @param integer $size Size of a file.
20 | * @param integer $decimals Number of decimals.
21 | * @return string
22 | */
23 | function smarty_modifier_time_since( $diff_time )
24 | {
25 | if ( !is_numeric ( $diff_time ) )
26 | $diff_time = strtotime( date("Y-m-d H:i:s") ) - strtotime($diff_time);
27 |
28 | if ( floor($diff_time/(60*60*24)) >= 365 )
29 | {
30 | $value[0] = floor($diff_time/(60*60*24*365));
31 | if ( 1 == $value[0] )
32 | $value[1] = \Sifo\I18N::getTranslation("year");
33 | else
34 | $value[1] = \Sifo\I18N::getTranslation("years");
35 | }
36 | elseif ( floor($diff_time/(60*60*24)) >= 30 )
37 | {
38 | $value[0] = floor($diff_time/(60*60*24*30));
39 | if ( 1 == $value[0] )
40 | $value[1] = \Sifo\I18N::getTranslation("month");
41 | else
42 | $value[1] = \Sifo\I18N::getTranslation("months");
43 | }
44 | elseif ( floor($diff_time/(60*60*24)) >= 7 )
45 | {
46 | $value[0] = floor($diff_time/(60*60*24*7));
47 | if ( 1 == $value[0] )
48 | $value[1] = \Sifo\I18N::getTranslation("week");
49 | else
50 | $value[1] = \Sifo\I18N::getTranslation("weeks");
51 | }
52 | elseif ( floor($diff_time/(60*60)) >= 24 )
53 | {
54 | $value[0] = floor($diff_time/(60*60*24));
55 | if ( 1 == $value[0] )
56 | $value[1] = \Sifo\I18N::getTranslation("day");
57 | else
58 | $value[1] = \Sifo\I18N::getTranslation("days");
59 | }elseif ( floor($diff_time/(60)) >= 60 )
60 | {
61 | $value[0] = floor($diff_time/(60*60));
62 | if ( 1 == $value[0] )
63 | $value[1] = \Sifo\I18N::getTranslation("hour");
64 | else
65 | $value[1] = \Sifo\I18N::getTranslation("hours");
66 | }
67 | elseif ( floor($diff_time/(60)) >= 1 )
68 | {
69 | $value[0] = floor($diff_time/(60));
70 | if ( 1 == $value[0] )
71 | $value[1] = \Sifo\I18N::getTranslation("minute");
72 | else
73 | $value[1] = \Sifo\I18N::getTranslation("minutes");
74 | }
75 | else
76 | {
77 | $value[0] = false;
78 | $value[1] = \Sifo\I18N::getTranslation("just some seconds");
79 | }
80 |
81 | $final_string = ($value > 0) ? $value[0] .' ' . $value[1] : $value[1];
82 |
83 | return \Sifo\I18N::getTranslation('%1 ago', ['%1' => $final_string]);
84 | }
85 |
--------------------------------------------------------------------------------
/src/Sifo/JsPacker.php:
--------------------------------------------------------------------------------
1 | instance_static_host}",
76 | Hash = window.Hash ? window.Hash : "unset",
77 | sInstance = window.sInstance ? window.sInstance : '',
78 | basePathConfig = {\n\t
79 | CODE;
80 | foreach ( $media_list as $group => $media_data )
81 | {
82 | $base_array[] = "\t'$group': sHostStatic + '/{$this->generated_files_public_path}/' + sInstance + '$group.js?rev=' + Hash";
83 | }
84 |
85 | $base_code .= implode( ",\n", $base_array ) . "\n\t};\n";
86 |
87 | return $base_code;
88 |
89 | }
90 |
91 | }
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/function.filln.php:
--------------------------------------------------------------------------------
1 | getString(
41 | 'SCRIPT_URI'
42 | ),
43 | E_USER_WARNING
44 | );
45 | }
46 |
47 | $subject = $args[0]['subject'];
48 | $tmp_result = $subject;
49 |
50 | foreach ($args[0] as $key => $current_value)
51 | {
52 | $current_value = (string) $current_value;
53 | $tmp_result = str_replace($delimiter . $key . $delimiter, $current_value, $tmp_result);
54 |
55 | if (method_exists('\Verticalroot\UrlsManagement', 'normalize'))
56 | {
57 | $urlized_val = \Verticalroot\UrlsManagement::normalize($current_value, $strict_params_normalize);
58 | $subject = str_replace($delimiter . $key . $delimiter, $urlized_val, $subject);
59 | }
60 | else if (method_exists('Urls', 'normalize'))
61 | {
62 | $urlized_val = \Sifo\Urls::normalize($current_value);
63 | $subject = str_replace($delimiter . $key . $delimiter, $urlized_val, $subject);
64 | }
65 | else
66 | {
67 | $subject = $tmp_result;
68 | }
69 | }
70 |
71 | return $subject;
72 | }, ['is_variadic' => true]
73 | );
74 | }
75 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | $PROJECT_DIR$/composer.json
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
42 |
43 |
44 |
45 |
46 | 1681212321240
47 |
48 |
49 | 1681212321240
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/function.fill.php:
--------------------------------------------------------------------------------
1 | escape_html;
43 | if (isset($args[0]['escapevar']))
44 | {
45 | $escapevar = ($twig->escape_html && ($args[0]['escapevar'] != 'no'));
46 | unset($args[0]['escapevar']);
47 | }
48 |
49 | $html_result = $args[0]['subject'];
50 | $tmp_result = $html_result;
51 | unset($args[0]['subject']);
52 |
53 | foreach ($args[0] as $key => $_val)
54 | {
55 | if ($escapevar)
56 | {
57 | $_val = htmlspecialchars($_val, ENT_QUOTES, SMARTY_RESOURCE_CHAR_SET);
58 | }
59 | $_val = (string) $_val;
60 | $tmp_result = str_replace($delimiter . $key . $delimiter, (string) $_val, $tmp_result);
61 |
62 | // The UrlParse::normalize, amongs other things lowers the string. Check if plugin calls with lower=no to skip:
63 | if ($normalize && true === \Sifo\Urls::$normalize_values && (!isset($args[0]['lower']) || $args[0]['lower'] != 'no'))
64 | {
65 | $html_result = str_replace($delimiter . $key . $delimiter, \Sifo\Urls::normalize((string) $_val), $html_result);
66 | }
67 | else
68 | {
69 | $html_result = $tmp_result;
70 | }
71 | }
72 |
73 | if (false !== strpos(urldecode($html_result), $delimiter))
74 | {
75 | trigger_error("fill: There are still parameters to replace, because the '$delimiter' delimiter was found in $html_result");
76 | }
77 |
78 | return $html_result;
79 | }, ['is_variadic' => true]
80 | );
81 | }
82 |
--------------------------------------------------------------------------------
/src/Sifo/Cache/Lock.php:
--------------------------------------------------------------------------------
1 | lock_id = uniqid();
49 | $this->key = $key;
50 | $this->cache_object = $cache_instance;
51 | }
52 |
53 | /**
54 | * @param string $original_key
55 | * @param CacheBase $cache_instance
56 | *
57 | * @return CacheLock
58 | */
59 | public static function getInstance( $original_key, $cache_instance )
60 | {
61 | $key = self::KEY_PREFIX . $original_key;
62 |
63 | if ( !isset( self::$instances[$key] ) )
64 | {
65 | self::$instances[$key] = new self( $key, $cache_instance );
66 | }
67 |
68 | return self::$instances[$key];
69 | }
70 |
71 | /**
72 | * Returns if another cache calculation is in progress.
73 | *
74 | * @return boolean
75 | */
76 | public function isLocked()
77 | {
78 | // The flow is not locked if the current process is the lock holder.
79 | return ( ( $value = $this->cache_object->get( $this->key ) ) && ( $value != $this->lock_id ) );
80 | }
81 |
82 |
83 | /**
84 | * Acquire lock.
85 | *
86 | * @return boolean
87 | */
88 | public function acquire()
89 | {
90 | $this->cache_object->set( $this->key, $this->lock_id, self::TTL );
91 | }
92 |
93 | /**
94 | * Releases the lock.
95 | *
96 | * @return boolean
97 | */
98 | public function release()
99 | {
100 | unset( self::$instances[$this->key] );
101 | return $this->cache_object->delete( $this->key );
102 | }
103 |
104 | /**
105 | * Release cache lock before object's destruction.
106 | *
107 | * If Exceptions, reDispatch, exit() or other hacks interfere with the normal workflow
108 | * the cache locks have to be released.
109 | */
110 | public function __destruct()
111 | {
112 | if ( !empty( self::$instances[$this->key] ) )
113 | {
114 | $this->release();
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/filter.time_since.php:
--------------------------------------------------------------------------------
1 | = 365)
15 | {
16 | $value[0] = floor($diff_time / (60 * 60 * 24 * 365));
17 | if (1 == $value[0])
18 | {
19 | $value[1] = \Sifo\I18N::getTranslation("year");
20 | }
21 | else
22 | {
23 | $value[1] = \Sifo\I18N::getTranslation("years");
24 | }
25 | }
26 | elseif (floor($diff_time / (60 * 60 * 24)) >= 30)
27 | {
28 | $value[0] = floor($diff_time / (60 * 60 * 24 * 30));
29 | if (1 == $value[0])
30 | {
31 | $value[1] = \Sifo\I18N::getTranslation("month");
32 | }
33 | else
34 | {
35 | $value[1] = \Sifo\I18N::getTranslation("months");
36 | }
37 | }
38 | elseif (floor($diff_time / (60 * 60 * 24)) >= 7)
39 | {
40 | $value[0] = floor($diff_time / (60 * 60 * 24 * 7));
41 | if (1 == $value[0])
42 | {
43 | $value[1] = \Sifo\I18N::getTranslation("week");
44 | }
45 | else
46 | {
47 | $value[1] = \Sifo\I18N::getTranslation("weeks");
48 | }
49 | }
50 | elseif (floor($diff_time / (60 * 60)) >= 24)
51 | {
52 | $value[0] = floor($diff_time / (60 * 60 * 24));
53 | if (1 == $value[0])
54 | {
55 | $value[1] = \Sifo\I18N::getTranslation("day");
56 | }
57 | else
58 | {
59 | $value[1] = \Sifo\I18N::getTranslation("days");
60 | }
61 | }
62 | elseif (floor($diff_time / (60)) >= 60)
63 | {
64 | $value[0] = floor($diff_time / (60 * 60));
65 | if (1 == $value[0])
66 | {
67 | $value[1] = \Sifo\I18N::getTranslation("hour");
68 | }
69 | else
70 | {
71 | $value[1] = \Sifo\I18N::getTranslation("hours");
72 | }
73 | }
74 | elseif (floor($diff_time / (60)) >= 1)
75 | {
76 | $value[0] = floor($diff_time / (60));
77 | if (1 == $value[0])
78 | {
79 | $value[1] = \Sifo\I18N::getTranslation("minute");
80 | }
81 | else
82 | {
83 | $value[1] = \Sifo\I18N::getTranslation("minutes");
84 | }
85 | }
86 | else
87 | {
88 | $value[0] = false;
89 | $value[1] = \Sifo\I18N::getTranslation("just some seconds");
90 | }
91 |
92 | $final_string = ($value > 0) ? $value[0] . ' ' . $value[1] : $value[1];
93 |
94 | return \Sifo\I18N::getTranslation('%1 ago', ['%1' => $final_string]);
95 | }
96 | );
97 | }
98 |
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/function.email_obfuscator.php:
--------------------------------------------------------------------------------
1 | .
18 | * @param string Email to obfuscate (received automatically).
19 | * @param string Text to show instead of the email.
20 | * @return string JavaScript to show the obfuscated email.
21 | */
22 | function smarty_function_email_obfuscator($params, &$smarty)
23 | {
24 |
25 | // email address to obfuscate.
26 | $email = ( isset( $params['email'] ) ) ? $params['email'] : '';
27 | // optional text to show instead the email
28 | $linktext = ( isset( $params['text'] ) ) ? $params['text'] : '';
29 | // style information via class.
30 | $style_class = ( isset( $params['class'] ) ) ? ' class=\"' . $params['class'] . '\" ' : '';
31 | // style information via id.
32 | $style_id = ( isset( $params['id'] ) ) ? ' id=\"' . $params['id'] . '\" ' : '';
33 |
34 | // Getting the extra params for the case of %1, %2, etc in the linktext. Using ; like separator.
35 | $extra_params = array();
36 | if ( isset( $params['extra'] ) ) {
37 | $extra_params = explode( ';', $params['extra'] );
38 | }
39 |
40 | // Translating linktext
41 | $textbefore = '';
42 | $textafter = '';
43 | if ( !empty( $linktext ) )
44 | {
45 | $calling_class = get_called_class();
46 | $obj = new $calling_class();
47 | $temp = smarty_block_t( $extra_params, $linktext, $obj);
48 | // If the email is inside the text string
49 | $email_position = strpos( $temp, $email );
50 | if ( $email_position )
51 | {
52 | // If the email is inside the string we make the link only in the email address
53 | $textbefore = substr( $temp, 0, $email_position );
54 | $textafter = substr( $temp, strpos( $temp, $email ) + strlen( $email ) );
55 | $linktext = '';
56 | }
57 | else
58 | {
59 | // Else the link is all the string
60 | $linktext = $temp;
61 | }
62 | }
63 |
64 | $character_set = '+-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
65 | $key = str_shuffle( $character_set );
66 | $cipher_text = '';
67 | $id = 'e'.rand( 1, 999999999 );
68 | for ( $i = 0; $i < strlen( $email ); $i += 1 )
69 | {
70 | $cipher_text.= $key[ strpos( $character_set, $email[ $i ] ) ];
71 | }
72 | $script = 'var namex="' . $linktext . '";var a="' . $key . '";var b=a.split("").sort().join("");var c="' . $cipher_text . '";var d="";';
73 | $script .= 'for(var e=0;e"+linktext+"<\/a>"+textafter';
75 | $script = "eval(\"".str_replace(array("\\",'"'),array("\\\\",'\"'), $script)."\")";
76 | $script = '';
77 | return '[javascript protected email address]' . $script;
78 | }
79 | ?>
80 |
--------------------------------------------------------------------------------
/src/Twig-sifo-plugins/function.email_obfuscator.php:
--------------------------------------------------------------------------------
1 | "+linktext+"<\/a>"+textafter';
60 | $script = "eval(\"" . str_replace(array("\\", '"'), array("\\\\", '\"'), $script) . "\")";
61 | $script = '';
62 |
63 | return '[javascript protected email address]' . $script;
64 | }, ['is_variadic' => true]
65 | );
66 | }
67 |
--------------------------------------------------------------------------------
/src/Sifo/MysqlModel.php:
--------------------------------------------------------------------------------
1 | keyExists( $key ) )
45 | {
46 | return $reg->get( $key );
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Stores in the registry a value with the given key.
54 | *
55 | * @param string $key
56 | * @param mixed $value
57 | */
58 | protected function storeInRegistry( $key, $value )
59 | {
60 | Registry::getInstance()->set( $key, $value );
61 | }
62 |
63 | /**
64 | * Returns the translation of a string
65 | *
66 | * @param string $subject
67 | * @param string $var_1
68 | * @param string $var2
69 | * @param string $var_n
70 | * @return string
71 | */
72 | public function translate( $subject, $var_1 = '', $var2 = '', $var_n = '' )
73 | {
74 | $args = func_get_args();
75 | $variables = array();
76 | if ( 1 < count( $args ) )
77 | {
78 | foreach ( $args as $key => $value )
79 | {
80 | $variables['%'.$key] = $value;
81 | }
82 |
83 | }
84 |
85 | unset( $variables['%0'] );
86 | return I18N::getInstance( 'messages', Domains::getInstance()->getLanguage() )->getTranslation( $subject, $variables );
87 | }
88 |
89 | /**
90 | * Returns the Database connection object.
91 | *
92 | * @param string $profile The profile to be used in the database connection.
93 | * @return Mysql|MysqlDebug
94 | */
95 | protected function connectDb( $profile = 'default' )
96 | {
97 | if ( Domains::getInstance()->getDebugMode() !== true )
98 | {
99 | return Mysql::getInstance( $profile );
100 | }
101 |
102 | return DebugMysql::getInstance( $profile );
103 | }
104 |
105 | /**
106 | * Magic method to retrieve table names from a configuration file.
107 | *
108 | * @param string $attribute
109 | *
110 | * @return string
111 | */
112 | public function __get( $attribute )
113 | {
114 | $tablenames = Config::getInstance()->getConfig( 'tablenames' );
115 |
116 | $domain = Domains::getInstance()->getDomain();
117 |
118 | if ( isset( $tablenames['names'][$domain][$attribute] ) )
119 | {
120 | return $tablenames['names'][$domain][$attribute];
121 | }
122 | elseif ( isset( $tablenames['names']['default'][$attribute] ) )
123 | {
124 | return $tablenames['names']['default'][$attribute];
125 | }
126 |
127 | return $attribute;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/Sifo/Mail.php:
--------------------------------------------------------------------------------
1 | getConfig('mail');
57 |
58 | $this->mail = new PHPMailer();
59 | $this->mail->CharSet = $config['CharSet'];
60 | $this->mail->From = $config['From'];
61 | $this->mail->FromName = $config['FromName'];
62 |
63 | foreach ($config as $property => $value)
64 | {
65 | $this->mail->$property = $value;
66 | }
67 |
68 | return $this->mail;
69 | }
70 |
71 |
72 | /**
73 | * Calls the PHPmailer methods.
74 | *
75 | * @param string $method
76 | * @param mixed $args
77 | *
78 | * @return mixed
79 | */
80 | public function __call($method, $args)
81 | {
82 | return call_user_func_array(array($this->mail, $method), $args);
83 | }
84 |
85 | /**
86 | * Get any phpmailer attribute.
87 | *
88 | * @param string $property
89 | */
90 | public function __get($property)
91 | {
92 | return $this->mail->$property;
93 | }
94 |
95 | /**
96 | * Set any phpmailer attribute.
97 | *
98 | * @param string $property
99 | * @param mixed $value
100 | */
101 | public function __set($property, $value)
102 | {
103 | $this->mail->$property = $value;
104 | }
105 |
106 |
107 | /**
108 | * Send an email.
109 | *
110 | * @param string $to
111 | * @param string $subject
112 | * @param string $body
113 | *
114 | * @return boolean
115 | */
116 | public function send($to, $subject, $body)
117 | {
118 | $this->mail->Subject = $subject;
119 | $this->mail->AltBody = strip_tags($body);
120 | $this->mail->AddAddress($to);
121 | $this->mail->MsgHTML($body);
122 |
123 | if (!$this->mail->Send())
124 | {
125 | trigger_error($this->mail->ErrorInfo);
126 |
127 | return false;
128 | }
129 |
130 | $this->mail->ClearAddresses();
131 |
132 | return true;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/Sifo/Benchmark.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Sifo/FlashMessages.php:
--------------------------------------------------------------------------------
1 | keyExists( 'flash_messages' ) )
60 | {
61 | $flash_messages = $registry->get( 'flash_messages' );
62 | }
63 |
64 | if ( is_array( $message ) ) // Dump of errors.
65 | {
66 | $flash_messages[$type] = $message;
67 | }
68 | else
69 | {
70 | $flash_messages[$type][] = $message;
71 | }
72 | $registry->set( "flash_messages", $flash_messages );
73 | }
74 |
75 | /**
76 | * Returns the messages stack.
77 | */
78 | static public function get( $type = null, $storage_engine = self::STORAGE_REGISTRY )
79 | {
80 | $messages = array();
81 | $existing_messages = self::_getMsgs( $storage_engine );
82 |
83 | if ( null === $type )
84 | {
85 | return $existing_messages;
86 | }
87 | else
88 | {
89 | if ( isset( $existing_messages[$type] ) )
90 | {
91 | return $existing_messages[$type];
92 | }
93 | return false;
94 | }
95 | }
96 |
97 | /**
98 | * Get the messages stack.
99 | *
100 | * @param integer $storage_engine The storage engine to retrieve the msgs.
101 | * @return array
102 | */
103 | static private function _getMsgs( $storage_engine )
104 | {
105 | $registry = self::_getStorageEngine( $storage_engine );
106 |
107 | $msgs = $registry->get( 'flash_messages' );
108 | if ( $msgs && $storage_engine === self::STORAGE_SESSION )
109 | {
110 | $registry->delete( 'flash_messages' );
111 | }
112 |
113 | if ( $msgs )
114 | {
115 | return $msgs;
116 | }
117 |
118 | return array();
119 | }
120 |
121 | static private function _getStorageEngine( $engine )
122 | {
123 | switch ( $engine )
124 | {
125 | case self::STORAGE_SESSION:
126 | return Session::getInstance();
127 | case self::STORAGE_REGISTRY:
128 | return Registry::getInstance();
129 | default:
130 | throw new Exception_503( 'Invalid storage type.' );
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/src/Sifo/View.php:
--------------------------------------------------------------------------------
1 | template_path = $template;
40 |
41 | $this->chooseTemplatingEngine();
42 | $this->assignVariables();
43 |
44 | return $this->templating_engine->fetch($this->template_path);
45 | }
46 |
47 | public function assign($variable_name, $value)
48 | {
49 | $this->variables[$variable_name] = $value;
50 | }
51 |
52 | public function getTemplateVars()
53 | {
54 | return $this->variables;
55 | }
56 |
57 | private function assignVariables()
58 | {
59 | foreach ($this->variables as $variable => $value)
60 | {
61 | $this->templating_engine->assign($variable, $value);
62 | }
63 | }
64 |
65 | private function chooseTemplatingEngine()
66 | {
67 | $file_extension = pathinfo($this->template_path, PATHINFO_EXTENSION);
68 |
69 | if ('twig' != $file_extension)
70 | {
71 | $this->setSmartyTemplatingEngine();
72 | }
73 | else
74 | {
75 | $this->setTwigTemplatingEngine();
76 | }
77 | }
78 |
79 | private function setSmartyTemplatingEngine()
80 | {
81 | if ($this->templating_engine instanceof ViewSmarty)
82 | {
83 | return;
84 | }
85 |
86 | $this->templating_engine = new ViewSmarty();
87 | }
88 |
89 | private function setTwigTemplatingEngine()
90 | {
91 | if ($this->templating_engine instanceof ViewTwig)
92 | {
93 | return;
94 | }
95 |
96 | $this->templating_engine = new ViewTwig();
97 | }
98 |
99 | public static function customErrorHandler($errno, $errstr, $errfile, $errline)
100 | {
101 | $error_has_been_silented = (0 === error_reporting());
102 | if ($error_has_been_silented)
103 | {
104 | return false;
105 | }
106 |
107 | $error_friendly = Debug::friendlyErrorType($errno);
108 | $error_string = "[{$error_friendly}] {$errstr} in {$errfile}:{$errline}";
109 |
110 | if (Domains::getInstance()->getDebugMode())
111 | {
112 | Debug::subSet('smarty_errors', $errfile, '' . $error_string . '
', true);
113 | }
114 |
115 | // Smarty only write PHP USER errors to log:
116 | if (($raw_url = Urls::$actual_url))
117 | {
118 | error_log("URL '{$raw_url}' launched the following Smarty error: {$error_string}");
119 |
120 | return true;
121 | }
122 |
123 | // Follow the error handling flow:
124 | return false;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/Sifo/View/Smarty.php:
--------------------------------------------------------------------------------
1 | smarty = new \Smarty();
13 |
14 | $this->smarty->inheritance_merge_compiled_includes = false;
15 |
16 | // Get the instances inheritance.
17 | $instance_inheritance = \Sifo\Domains::getInstance()->getInstanceInheritance();
18 |
19 | // If there is inheritance.
20 | if (is_array($instance_inheritance))
21 | {
22 | // First the child instance, last the parent instance.
23 | $instance_inheritance = array_reverse($instance_inheritance);
24 | foreach ($instance_inheritance as $current_instance)
25 | {
26 | $this->smarty->addPluginsDir(ROOT_PATH . '/instances/' . $current_instance . '/templates/_smarty/plugins');
27 | }
28 | }
29 | else
30 | {
31 | $this->smarty->addPluginsDir(ROOT_PATH . '/instances/' . Bootstrap::$instance . '/templates/_smarty/plugins');
32 | }
33 | // Last path is the default smarty plugins directory.
34 | $this->smarty->addPluginsDir(ROOT_PATH . '/vendor/sifophp/sifo/src/Smarty-sifo-plugins');
35 |
36 | $this->smarty->setTemplateDir(ROOT_PATH . '/'); // The templates are taken using the templates.config.php mappings, under the variable $_tpls.
37 |
38 | // Paths definition:
39 | $templates_path = ROOT_PATH . '/instances/' . Bootstrap::$instance . '/templates/';
40 | $this->smarty->setCompileDir($templates_path . '_smarty/compile/');
41 | $this->smarty->setConfigDir($templates_path . '_smarty/configs/');
42 | $this->smarty->setCacheDir($templates_path . '_smarty/cache/');
43 |
44 | if (($view_setting = Config::getInstance()->getConfig('views')) && (isset($view_setting['smarty'])))
45 | {
46 | $smarty_settings = $view_setting['smarty'];
47 |
48 | if (isset($smarty_settings['custom_plugins_dir']))
49 | {
50 | // If is set, this path will be the default smarty plugins directory.
51 | $this->smarty->addPluginsDir($smarty_settings['custom_plugins_dir']);
52 | }
53 | // Set this to false to avoid magical parsing of literal blocks without the {literal} tags.
54 | $this->smarty->auto_literal = $smarty_settings['auto_literal'];
55 | $this->smarty->escape_html = $smarty_settings['escape_html'];
56 | }
57 | }
58 |
59 |
60 | public function fetch($template)
61 | {
62 | $this->template_path = $template;
63 |
64 | set_error_handler(array(View::class, "customErrorHandler"));
65 | \Smarty::muteExpectedErrors();
66 |
67 | try
68 | {
69 | $result = $this->smarty->fetch(
70 | $template,
71 | $cache_id = null,
72 | $compile_id = null,
73 | $parent = null,
74 | $display = false,
75 | $merge_tpl_vars = true,
76 | $no_output_filter = false
77 | );
78 | }
79 | catch (\Exception $e)
80 | {
81 | trigger_error($e->getMessage(), E_USER_ERROR);
82 | $result = null;
83 | }
84 |
85 | // The current method launch an set_error_handler but inside self::muteExpectedErrors() ther is one more.
86 | // We need launch two restores to turn back to the preview expected behaviour.
87 | restore_error_handler();
88 | restore_error_handler();
89 |
90 | return $result;
91 | }
92 |
93 | public function assign($variable_name, $value)
94 | {
95 | $this->smarty->assign($variable_name, $value);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/Sifo/CLBootstrap.php:
--------------------------------------------------------------------------------
1 | timingStart();
35 | self::dispatch( $controller_name );
36 | Benchmark::getInstance()->timingStop();
37 | }
38 |
39 | /**
40 | * Sets the controller and view properties and executes the controller, sending the output buffer.
41 | *
42 | * @param string $controller Dispatches a specific controller. Defaults to null for compatibility with Bootstrap::dispatch
43 | */
44 | public static function dispatch( $controller = null, $container = null )
45 | {
46 | // Set Timezone as required by php 5.1+
47 | date_default_timezone_set('Europe/Madrid');
48 |
49 | self::$language = 'en_US';
50 |
51 | // This is the controller to use:
52 | $ctrl = self::invokeController( $controller, $container );
53 | $ctrl->setContainer(static::$container);
54 | self::$controller = $controller;
55 | $ctrl->build();
56 |
57 | // Debug:
58 | if ( Domains::getInstance()->getDebugMode() )
59 | {
60 | $ctrl_debug = self::invokeController( 'DebugCommandLineDebug' );
61 | $ctrl_debug->build();
62 | }
63 | }
64 |
65 | public static function is_domain( $var )
66 | {
67 | return ( false !== strpos( $var, "." ) );
68 | }
69 |
70 | public static function get_available_domains()
71 | {
72 | $domain_configuration = Config::getInstance()->getConfig( 'domains' );
73 | $configuration_keys = array_keys( $domain_configuration );
74 | $available_domains = array_filter( $configuration_keys, "self::is_domain");
75 |
76 | return $available_domains;
77 | }
78 |
79 | }
80 |
81 | // Disable whatever buffering default config.
82 | @ob_end_flush();
83 |
84 | // Instance name (folder under instances):
85 | preg_match("/\/([^\/]+)\/([^\/]+)\/[^\/]+$/", $_SERVER['PHP_SELF'], $matchs);
86 |
87 | // Set the real and active instance name.
88 | CLBootstrap::$instance = $matchs[1];
89 |
90 | if ( extension_loaded( 'newrelic' ) && isset( CLBootstrap::$instance ) )
91 | {
92 | newrelic_set_appname( ucfirst( CLBootstrap::$instance ) );
93 | }
94 |
95 | if (false === isset($argv)) {
96 | $argv = $_SERVER['argv'] ?? [];
97 | }
98 |
99 | if ( !isset( $argv[1] ) || ( '-h' == $argv[1] ) || ( '--help' == $argv[1] ) )
100 | {
101 | // Dump help info:
102 | require_once ROOT_PATH . '/vendor/sifophp/sifo-common-instance/controllers/shared/commandLine.php';
103 |
104 | echo PHP_EOL . "Execute 'php $argv[0] --help' to read the help information." . PHP_EOL . PHP_EOL;
105 | echo "Your available domains:" . PHP_EOL;
106 | $available_domains = CLBootstrap::get_available_domains();
107 | echo implode(PHP_EOL, $available_domains);
108 | die;
109 | }
110 | CLBootstrap::$command_line_params = $argv;
111 |
112 | // Setting the domain.
113 | FilterServer::getInstance()->setHost( $argv[1] );
114 |
--------------------------------------------------------------------------------
/src/Sifo/Cache.php:
--------------------------------------------------------------------------------
1 | isActive() )
88 | {
89 | trigger_error( 'Memcached is down! Falling back to Disk cache if available...' );
90 |
91 | // Use cache disk instead:
92 | $cache_object = new CacheDisk();
93 | self::$cache_type = self::CACHE_TYPE_DISK;
94 | }
95 |
96 | $cache_object->use_locking = (bool) $lock_enabled;
97 | self::$instance[$type][$lock_enabled] = $cache_object;
98 |
99 | return self::$instance[$type][$lock_enabled];
100 | }
101 |
102 | /**
103 | * Reads from configuration files the cache type this project is using by default.
104 | *
105 | * @return string Cache type.
106 | */
107 | static protected function discoverCacheType()
108 | {
109 | $cache_config = Config::getInstance()->getConfig( 'cache' );
110 |
111 | if ( true !== $cache_config['active'] || !isset( $cache_config['client'] ) )
112 | {
113 | return self::CACHE_TYPE_DISK;
114 | }
115 |
116 | if ( 'Memcached' === $cache_config['client'] )
117 | {
118 | return self::CACHE_TYPE_MEMCACHED;
119 | }
120 |
121 | if ( 'Memcache' === $cache_config['client'] )
122 | {
123 | return self::CACHE_TYPE_MEMCACHE;
124 | }
125 |
126 | return 'unknown';
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/src/Sifo/Registry.php:
--------------------------------------------------------------------------------
1 | array( $subkey => $value ) )
112 | *
113 | * @param string $key Name you want to store the value with.
114 | * @param mixed $value The object to store in the array.
115 | * @return void
116 | */
117 | public static function subSet( $key, $sub_key, $value )
118 | {
119 | self::$storage[$key][$sub_key] = $value;
120 | }
121 |
122 | /**
123 | * Adds another element to the end of the array.
124 | *
125 | * @param string $key
126 | * @param mixed $value
127 | * @return int New number of elements in the array.
128 | */
129 | public static function push( $key, $value )
130 | {
131 | if ( !self::keyExists( $key ) )
132 | {
133 | self::$storage[$key] = array();
134 | }
135 |
136 | if ( !is_array( self::$storage[$key] ) )
137 | {
138 | throw new Exception_Registry( 'Failed to PUSH an element in the registry because the given key is not an array.' );
139 | }
140 |
141 | return array_push( self::$storage[$key], $value );
142 | }
143 |
144 | /**
145 | * @param string $index
146 | * @returns boolean
147 | *
148 | */
149 | public static function keyExists( $key )
150 | {
151 | return array_key_exists( $key, self::$storage );
152 | }
153 |
154 | }
155 |
156 | class Exception_Registry extends \Exception {};
157 |
--------------------------------------------------------------------------------
/src/Sifo/imageController.php:
--------------------------------------------------------------------------------
1 | is_gif || $this->is_jpeg || $this->is_png || $this->is_bmp || $this->is_ico ) || ( $this->is_gif + $this->is_jpeg + $this->is_png + $this->is_bmp + $this->is_ico ) > 1 )
63 | {
64 | throw new Exception_500( "Please do the favour of use one (and only one) image content_type helper!" );
65 | }
66 |
67 | if ( $this->is_gif )
68 | {
69 | $content_type ='Content-type: image/gif';
70 | }
71 |
72 | if ( $this->is_jpeg )
73 | {
74 | $content_type ='Content-type: image/jpeg';
75 | }
76 |
77 | if ( $this->is_png )
78 | {
79 | $content_type ='Content-type: image/png';
80 | }
81 |
82 | if ( $this->is_bmp )
83 | {
84 | $content_type ='Content-type: image/bmp';
85 | }
86 |
87 | if ( $this->is_ico )
88 | {
89 | $content_type ='Content-type: image/x-icon';
90 | }
91 |
92 | Headers::set( 'Content-type', $content_type );
93 | }
94 |
95 | /**
96 | * Returns tha contents in cache or false.
97 | *
98 | * @return mixed
99 | */
100 | protected function grabCache()
101 | {
102 | if ( Domains::getInstance()->getDevMode() && ( FilterCookie::getInstance()->getInteger( 'rebuild_all' ) || FilterGet::getInstance()->getInteger( 'rebuild' ) ) )
103 | {
104 | return false;
105 | }
106 |
107 | $cache_key = $this->parseCache();
108 |
109 | // Controller does not use cache:
110 | if ( !$cache_key )
111 | {
112 | return false;
113 | }
114 |
115 | $cache = new CacheDisk();
116 | $content = $cache->get( $cache_key['name'] );
117 |
118 | return ( $content ? $content : false );
119 | }
120 |
121 | /**
122 | * Dispatch the controller.
123 | */
124 | public function dispatch()
125 | {
126 | $this->customizeHeader();
127 |
128 | $this->preDispatch();
129 | $cached_content = $this->grabCache();
130 | if ( false !== $cached_content )
131 | {
132 | echo $cached_content;
133 | $this->postDispatch();
134 | return;
135 | }
136 | $cache_key = $this->parseCache();
137 |
138 | $content = $this->build();
139 |
140 | if ( false !== $cache_key )
141 | {
142 | $cache = new CacheDisk();
143 | $cache->set( $cache_key['name'], $content, $cache_key['expiration'] );
144 | }
145 |
146 | $this->postDispatch();
147 | echo $content;
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/src/Sifo/RedisModel.php:
--------------------------------------------------------------------------------
1 | getConfig( 'redis', 'default' );
59 | }
60 | catch( Exception_Configuration $e )
61 | {
62 | // Connection taken from domains.config.php:
63 | $db_params = Domains::getInstance()->getParam( 'redis' );
64 | }
65 |
66 | }
67 | else // Advanced configuration taken from redis.config.php
68 | {
69 | $db_params = Config::getInstance()->getConfig( 'redis', $profile );
70 | }
71 |
72 | self::$connected_client[$profile] = PredisProxyClient::getInstance( $db_params );
73 | $this->profile = $profile;
74 | }
75 |
76 | return self::$connected_client[$profile];
77 | }
78 |
79 | /**
80 | * Disconnect from server and reset the static object for reconnection.
81 | */
82 | public function disconnect()
83 | {
84 | self::$connected_client[$this->profile]->disconnect();
85 | self::$connected_client[$this->profile] = null;
86 | }
87 |
88 | /**
89 | * Disconnect clients on object destruction.
90 | */
91 | public function __destruct()
92 | {
93 | foreach ( self::$connected_client as $client )
94 | {
95 | $client->disconnect();
96 | }
97 | }
98 | }
99 |
100 | class PredisProxyClient
101 | {
102 | static protected $instance;
103 |
104 | protected $client;
105 | protected $connection_params;
106 |
107 | public static function getInstance( Array $connection_params )
108 | {
109 | asort( $connection_params );
110 |
111 | $key = md5( serialize( $connection_params ) );
112 | if ( isset( self::$instance[$key] ) )
113 | {
114 | return self::$instance[$key];
115 | }
116 |
117 | if ( true !== Domains::getInstance()->getDebugMode() )
118 | {
119 | self::$instance[$key] = new self( $connection_params );
120 | }
121 | else
122 | {
123 | self::$instance[$key] = new DebugPredisProxyClient( $connection_params );
124 | }
125 |
126 | return self::$instance[$key];
127 | }
128 |
129 | protected function __construct( Array $connection_params )
130 | {
131 | $this->connection_params = $connection_params;
132 | $this->client = new \Predis\Client( $connection_params );
133 | }
134 |
135 | public function __call( $method, $args )
136 | {
137 | if ( is_object( $this->client ) )
138 | {
139 | return call_user_func_array( array( $this->client, $method ), $args );
140 | }
141 |
142 | return null;
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/Sifo/MediaPacker.php:
--------------------------------------------------------------------------------
1 | working_instance = Config::getInstance()->getInstanceName();
67 | $this->instance_static_host = Domains::getInstance()->getStaticHost();
68 |
69 | // Contents will be accessible by static server under this path:
70 | $this->generated_files_public_path = $this->media_type . '/generated';
71 |
72 | // Packed contents will be stored under this filesystem path. You can overwrite this property:
73 | $this->generated_files_folder = ROOT_PATH . '/instances/' . $this->working_instance . '/public/static/' . $this->generated_files_public_path;
74 |
75 |
76 | }
77 |
78 | /**
79 | * Takes all the available combinations of media files and creates all the packs.
80 | */
81 | public function packMedia()
82 | {
83 | $media = Config::getInstance()->getConfig( $this->media_type );
84 |
85 | foreach ( $media as $group => $media_name )
86 | {
87 | ksort( $media[$group] ); // Reorder elements by priority key, no matter how the array was created.
88 | $file = $this->generated_files_folder . '/' . $group . '.' . $this->media_type;
89 |
90 | // Add the basepath definition at the beginning of the 'default' JS file:
91 | $prepend_string = ( 'default' == $group && 'js' == $this->media_type ? $this->getBasePathConfig( $media ) : '' );
92 |
93 | $content = $this->getPackedContent( $media[$group], $prepend_string );
94 |
95 | // Create subdirs if needed:
96 | $file_info = pathinfo( $file );
97 | if ( !is_dir( $file_info['dirname'] ) )
98 | {
99 | // Create directory recursively if does not exist yet.
100 | mkdir( $file_info['dirname'], 0755, true );
101 | }
102 |
103 | // Write packed file to disk:
104 | file_put_contents( $file, $content );
105 | }
106 | }
107 |
108 | /**
109 | * Sets the directory where you want to write the generated files to.
110 | *
111 | * @param $path Real path to the directory storing
112 | *
113 | * @throws \RuntimeException
114 | */
115 | public function setGeneratedFolder( $path )
116 | {
117 | if ( is_dir( $path ) )
118 | {
119 | $this->generated_files_folder = $path;
120 | }
121 | else
122 | {
123 | throw new \RuntimeException( 'Path given to store generated content is not a valid dir.' );
124 | }
125 |
126 | }
127 |
128 | }
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/block.t.php:
--------------------------------------------------------------------------------
1 | escape_html ) )
60 | {
61 | // In the don't protected configuration, the expectd behaviour is escapeing html:
62 | $escape = ( isset($params['escape'] ) )? $params['escape'] : "html";
63 | unset($params['escape']);
64 |
65 | if( isset( $params['escapevar'] ) )
66 | {
67 | // Option not available when escape_html is false. You could use $var|escape
68 | unset( $params['escapevar'] );
69 | }
70 | }
71 | else
72 | {
73 | $escape = false;
74 | if ( isset($params['escape'] ) )
75 | {
76 | // (escape) Escape param is not available when escape_html is set to true.
77 | unset($params['escape']);
78 | }
79 |
80 | // set escape_var mode
81 | if ( ( !isset( $params['escapevar'] ) ) || ( $params['escapevar']!='no') )
82 | {
83 | foreach( $params as &$param )
84 | {
85 | $param = htmlspecialchars($param, ENT_QUOTES, SMARTY_RESOURCE_CHAR_SET );
86 | }
87 | }
88 | elseif( isset( $params['escapevar'] ) )
89 | {
90 | unset( $params['escapevar'] );
91 | }
92 | }
93 |
94 | // set plural version
95 | if (isset($params['plural'])) {
96 | $plural = $params['plural'];
97 | unset($params['plural']);
98 |
99 | // set count
100 | if (isset($params['count']) && ( 1 != $params['count'] ) ) {
101 | $text = $plural;
102 | unset($params['count']);
103 | }
104 | }
105 |
106 | $text = \Sifo\I18N::getTranslation( $text );
107 |
108 | // run strarg if there are parameters
109 | if (count($params)) {
110 | $text = smarty_gettext_strarg($text, $params);
111 | }
112 |
113 | switch ($escape) {
114 | case 'html':
115 | $text = nl2br(htmlspecialchars($text));
116 | break;
117 | case 'javascript':
118 | case 'js':
119 | // javascript escape
120 | $text = str_replace('\'', '\\\'', stripslashes($text));
121 | break;
122 | case 'url':
123 | // url escape
124 | $text = urlencode($text);
125 | break;
126 | }
127 |
128 | return $text;
129 | }
130 |
131 | ?>
132 |
--------------------------------------------------------------------------------
/src/Sifo/Dir.php:
--------------------------------------------------------------------------------
1 | Filename or Dirname
44 | * "relative" => Path relative to the starting point
45 | * "absolute" => Absolute path
46 | * "folder" => Parent folder
47 | *
48 | * @param string $base_path Path to starting directory.
49 | * @param string $relative_path Relative path added to base_path. If you have /path/to/dir and specify "dir" as relative_path then will list files in /path/to as dir/file1, dir/file2 ...
50 | */
51 | public function getFileListRecursive( $base_path, $relative_path = "" )
52 | {
53 | // If base path ends in / remove it.
54 | if ( substr( $base_path, -1, 1 ) == "/" )
55 | {
56 | $base_path = substr( $base_path, 0, -1 );
57 | }
58 | // If relative path starts in / remove it.
59 | if ( substr( $relative_path, 0, 1 ) == "/" )
60 | {
61 | $relative_path = substr( $relative_path, 1 );
62 | }
63 |
64 | $path = $base_path . "/" . $relative_path;
65 |
66 | if ( !is_dir( $path ) )
67 | {
68 | return false;
69 | }
70 |
71 | $list = array();
72 |
73 | $directory = opendir( "$path" );
74 |
75 | while ( $file = readdir( $directory ) )
76 | {
77 | if ( !in_array( $file, $this->ignored_files ) )
78 | {
79 | $f = $path . "/" . $file;
80 | $f = preg_replace( '/(\/){2,}/', '/', $f ); // Replace double slashes.
81 | if ( is_file( $f ) )
82 | {
83 | $list[] = array( "filename" => $file, "relative" => $relative_path . "/$file", "absolute" => $f, "folder"=> $relative_path );
84 | }
85 |
86 | if ( is_dir( $f ) ) // Ignore _smarty dir
87 | {
88 | $list = array_merge( $list, $this->getFileListRecursive( $base_path, $relative_path . "/$file" ) ); // Recursive call.
89 | }
90 | }
91 | }
92 | closedir( $directory );
93 | sort( $list );
94 | return $list ;
95 | }
96 |
97 | /**
98 | * Get subdirs
99 | *
100 | * @param string $path
101 | * @param string $relative_path
102 | * @return array
103 | */
104 | public function getDirs( $path )
105 | {
106 | if ( !is_dir( $path ) )
107 | {
108 | return false;
109 | }
110 |
111 | $list = array();
112 |
113 | $directory = opendir( "$path" );
114 |
115 | while ( $file = readdir( $directory ) )
116 | {
117 | if ( !in_array( $file, $this->ignored_files ) )
118 | {
119 | $f = $path . "/" . $file;
120 | $f = preg_replace( '/(\/){2,}/', '/', $f ); // Replace double slashes.
121 |
122 | if ( is_dir( $f ) )
123 | {
124 | $list[] = $file;
125 | }
126 | }
127 | }
128 | closedir( $directory );
129 | sort( $list );
130 |
131 | return $list;
132 | }
133 |
134 | public function setIgnore( Array $ignored_files )
135 | {
136 | $this->ignored_files = $ignored_files;
137 | }
138 |
139 | }
140 | ?>
--------------------------------------------------------------------------------
/src/Smarty-sifo-plugins/function.fill.php:
--------------------------------------------------------------------------------
1 |
13 | * Name: fill
14 | * Input:
15 | * - [any] (required) - string
16 | * - subject (required) - string
17 | * - delimiter (optional, defaults to '%' ) - string
18 | * - lower (optional, set to lower=no if you don't want lowercase) - string
19 | * - normalize (optional, set to normalize=no to override \Sifo\Urls::$normalize_values setting and disable it) - string
20 | * - escapevar (Set to no for avoid html escaping when the smarty escape_html attribute is true).
21 | * Purpose: Fills the variables found in 'subject' with the paramaters passed. The variables are any word surrounded by two delimiters.
22 | *
23 | * Examples of usage:
24 | *
25 | * {fill subject="http://domain.com/profile/%username%" username='fred'}
26 | * Output: http://domain.com/profile/fred
27 | *
28 | * {fill subject="Hello %user%, welcome aboard!" user=Fred}
29 | * Outputs: Hello Fred, welcome aboard
30 | *
31 | * {fill subject="http://||subdomain||.domain.com/||page||/||action||" subdomain='www' page='my-first-post' action='vote' delimiter='||'}
32 | * Outputs: http://www.domain.com/my-first-post/vote
33 | *
34 | * @link http://www.harecoded.com/fill-smarty-php-plugin-311577
35 | * @author Albert Lombarte
36 | * @param array
37 | * @param Smarty
38 | * @return string
39 | */
40 | function smarty_function_fill($params, &$smarty)
41 | {
42 |
43 | if ( isset($params['delimiter']) )
44 | {
45 | $_delimiter = $params['delimiter'];
46 | unset($params['delimiter']);
47 | } else {
48 | $_delimiter = '%';
49 | }
50 |
51 | $_normalize = true;
52 |
53 | if ( isset($params['normalize']) )
54 | {
55 | switch( $params['normalize'] )
56 | {
57 | case 'no':
58 | case '0':
59 | case 'false':
60 | $_normalize = false;
61 | break;
62 | default:
63 | $_normalize = true;
64 | }
65 | }
66 | else
67 | {
68 | $params['normalize'] = true;
69 | }
70 |
71 |
72 | if ( false !== strpos($_delimiter, '$' ) )
73 | {
74 | trigger_error("fill: The delimiter '$' is banned in function {url}", E_USER_NOTICE);
75 | }
76 |
77 | if (!isset($params['subject']) || count($params)<2) {
78 | trigger_error("fill: The attribute 'subject' and at least one parameter is needed in function {url}", E_USER_NOTICE);
79 | }
80 |
81 | $escapevar = $smarty->escape_html;
82 | if ( isset( $params['escapevar'] ) )
83 | {
84 | $escapevar = ( $smarty->escape_html && ( $params['escapevar'] != 'no') );
85 | unset( $params['escapevar'] );
86 | }
87 |
88 | $_html_result = $params['subject'];
89 | $_tmp_result = $_html_result;
90 | unset( $params['subject'] );
91 |
92 | foreach( $params as $_key => $_val )
93 | {
94 | if( $escapevar )
95 | {
96 | $_val = htmlspecialchars($_val, ENT_QUOTES, SMARTY_RESOURCE_CHAR_SET );
97 | }
98 | $_val = (string)$_val;
99 | $_tmp_result = str_replace( $_delimiter . $_key . $_delimiter, (string)$_val, $_tmp_result);
100 |
101 | // The UrlParse::normalize, amongs other things lowers the string. Check if plugin calls with lower=no to skip:
102 | if ( $_normalize && true === \Sifo\Urls::$normalize_values && ( !isset($params['lower'] ) || $params['lower'] != 'no' ) )
103 | {
104 | $_html_result = str_replace( $_delimiter . $_key . $_delimiter, \Sifo\Urls::normalize( (string)$_val ), $_html_result);
105 | }
106 | else
107 | {
108 | $_html_result = $_tmp_result;
109 | }
110 | }
111 |
112 | if ( false !== strpos(urldecode($_html_result), $_delimiter) )
113 | {
114 | trigger_error("fill: There are still parameters to replace, because the '$_delimiter' delimiter was found in $_html_result");
115 | }
116 |
117 | return $_html_result;
118 |
119 | }
120 |
121 | /* vim: set expandtab: */
122 |
123 | ?>
124 |
--------------------------------------------------------------------------------
/src/Sifo/Debug/Sphinxql.php:
--------------------------------------------------------------------------------
1 | timingStart( 'sphinxql' );
46 | $sphinx_results = parent::multiQuery( $tag );
47 | $sphinx_time = Benchmark::getInstance()->timingCurrentToRegistry( 'sphinxql' );
48 |
49 | foreach( $this->queries as $key => $query )
50 | {
51 | $query_info['query'] = $query['query'];
52 | $query_info['tag'] = $query['tag'];
53 | $query_info['resultset'] = ( !empty( $sphinx_results[$key] ) ) ? $sphinx_results[$key] : array();
54 | $query_info['returned_rows'] = ( !empty( $sphinx_results[$key] ) ) ? count( $query_info['resultset'] ) : 0;
55 | $this->query_debug['queries'][] = $query_info;
56 | }
57 |
58 | $this->query_debug['backtrace'] = $this->getCallerClass();
59 | $this->query_debug['time'] = $sphinx_time;
60 | $this->query_debug['error'] = ( $this->sphinxql->errno ) ? $this->sphinxql->error : '';
61 | $this->query_debug['tag'] = $tag;
62 | $this->query_debug['connection_data'] = $this->sphinx_config;
63 |
64 | Debug::push( 'sphinxql', $this->query_debug );
65 |
66 | if ( $this->sphinxql->errno )
67 | {
68 | Debug::push( 'sphinxql_errors', $this->sphinxql->error );
69 | }
70 |
71 | unset( $this->query_debug );
72 | unset( $this->queries );
73 |
74 | return $sphinx_results;
75 | }
76 |
77 | /**
78 | * Redefines addQuery method adding debug information.
79 | * @param $query
80 | * @param null $tag
81 | * @param array $parameters
82 | *
83 | * @return string The query after being prepared.
84 | */
85 | public function addQuery( $query, $tag = null, $parameters = array() )
86 | {
87 | $prepared_query = parent::addQuery( $query, $tag, $parameters );
88 | $this->queries[] = array( 'query' => $prepared_query . ';', 'tag' => $tag );
89 |
90 | return $prepared_query;
91 | }
92 |
93 | /**
94 | * Build the caller classes stack.
95 | * @return string
96 | */
97 | public function getCallerClass()
98 | {
99 | $array_debug = debug_backtrace();
100 |
101 | $trace = array();
102 | $step = 0;
103 | foreach ( array_reverse( $array_debug ) as $debug_step )
104 | {
105 | if ( !isset( $debug_step['class'] ) )
106 | {
107 | $debug_step['class'] = '';
108 | }
109 | if ( !isset( $debug_step['function'] ) )
110 | {
111 | $debug_step['function'] = '';
112 | }
113 | if ( !isset( $debug_step['file'] ) )
114 | {
115 | $debug_step['file'] = '';
116 | }
117 | if ( !isset( $debug_step['line'] ) )
118 | {
119 | $debug_step['line'] = '';
120 | }
121 |
122 | ++$step;
123 | $trace[] = "$step > ".$debug_step['class'].'::'.$debug_step['function']
124 | .' - '.basename ( $debug_step['file'] )
125 | .':'.$debug_step['line']." [".dirname( $debug_step['file'] )."]";
126 |
127 | if ( in_array( $debug_step['function'], array( 'query', 'multiQuery' ) ) )
128 | {
129 | break;
130 | }
131 | }
132 |
133 | return $trace;
134 | }
135 |
136 | /**
137 | * Redefines logError class. Errors will be shown on debug.
138 | * @param $error
139 | */
140 | protected function logError( $error )
141 | {}
142 | }
--------------------------------------------------------------------------------
/src/Sifo/Cookie.php:
--------------------------------------------------------------------------------
1 | request[$key] = $value;
33 | }
34 |
35 | static public function deleteCookie( $key )
36 | {
37 | unset( self::getInstance()->request[$key] );
38 | }
39 | }
40 |
41 | class Cookie
42 | {
43 |
44 | static protected $cookies;
45 | static private $domain;
46 | static private $path;
47 |
48 | static private function _initDomain()
49 | {
50 | self::$cookies = array( );
51 | // Take domain from configuration to allow multiple subdomain compatibility with cookies.
52 | self::$domain = Domains::getInstance()->getDomain();
53 | self::$path = '/';
54 | }
55 |
56 | static public function set( $name, $value, $days = 14, $domain = false, $secure = false, $httpOnly = false, string $samesite = null )
57 | {
58 | $domain ?: self::_initDomain();
59 |
60 | $expires = 0 == $days ? 0 : time() + ( 86400 * $days );
61 |
62 | $result = static::setCookie( $name, $value, $expires, self::$path, self::$domain, $secure, $httpOnly, $samesite );
63 |
64 | if ( !$result )
65 | {
66 | trigger_error( "COOKIE WRITE FAIL: Tried to write '$name' with value '$value' but failed." );
67 | return false;
68 | }
69 |
70 | // Filter runtime update:
71 | FilterCookieRuntime::setCookie( $name, $value );
72 |
73 | return true;
74 | }
75 |
76 | static public function delete( $name )
77 | {
78 | self::_initDomain();
79 | $result = static::setCookie( $name, '', time() - 3600, self::$path, self::$domain);
80 | if ( !$result )
81 | {
82 | trigger_error( "COOKIE DELETE FAIL: Tried to delete '$name' but failed." );
83 | return false;
84 | }
85 |
86 | // Filter runtime update:
87 | FilterCookieRuntime::deleteCookie( $name );
88 |
89 | return true;
90 | }
91 |
92 | /**
93 | * Read one (string) or several (array) cookies and returns it with a simple sanitization of the content.
94 | *
95 | * @deprecated The Cookie::get from FilterCookie::getString.
96 | * @param string|array $cookie
97 | * @return string|false
98 | */
99 | static public function get( $cookies )
100 | {
101 | trigger_error( "'Cookie::get' is deprecated, please use 'FilterCookie'. Ex: FilterCookie::getInstance()->getString( 'cookie_key' );" );
102 |
103 | if ( is_array( $cookies ) )
104 | {
105 | foreach ( $cookies as $cookie )
106 | {
107 | $values[$cookie] = self::_sanitizeCookie( $cookie );
108 | }
109 |
110 | if ( !isset( $values ) )
111 | {
112 | return false;
113 | }
114 |
115 | return $values;
116 | }
117 | else
118 | {
119 | return self::_sanitizeCookie( $cookies );
120 | }
121 | }
122 |
123 | /**
124 | * Returns a sanitized Cookie.
125 | *
126 | * @param array $cookies
127 | * @return string|false
128 | */
129 | static private function _sanitizeCookie( $cookie )
130 | {
131 | if ( FilterCookie::getInstance()->isSent( $cookie ) )
132 | {
133 | return FilterCookie::getInstance()->getString( $cookie );
134 | }
135 |
136 | return false;
137 | }
138 |
139 | static protected function setCookie(string $name, $value = "", $expires = 0, $path = "", $domain = "", $secure = false, $httponly = false, string $samesite = null): bool
140 | {
141 | $options = [
142 | 'expires' => $expires,
143 | 'path' => $path,
144 | 'domain' => $domain,
145 | 'secure' => $secure,
146 | 'httponly' => $httponly,
147 | ];
148 |
149 | if ( $samesite !== null) {
150 | $options['samesite'] = $samesite;
151 | }
152 |
153 | return setcookie( $name, $value, $options );
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/Sifo/Session.php:
--------------------------------------------------------------------------------
1 | getDomain() );
35 | }
36 |
37 | if ( !isset( $_SESSION ) )
38 | {
39 | if ( headers_sent ( ) )
40 | {
41 | trigger_error( "Session: The session was not started before the sending of the headers." );
42 | return;
43 | }
44 |
45 | if ($session_name instanceof SessionNameStrategy) {
46 | $session_name->set();
47 | }
48 |
49 | // Session init.
50 | session_start();
51 | }
52 | }
53 |
54 | /**
55 | * Singleton
56 | *
57 | * @static
58 | * @return Session
59 | */
60 | public static function getInstance()
61 | {
62 | if ( !isset( self::$instance ) )
63 | {
64 | $session_name_environment = FilterEnv::getInstance()->getString('SESSION_NAME');
65 |
66 | switch ($session_name_environment) {
67 | case 'environment_and_vertical':
68 | $session_name_strategy = new SessionEnvironmentStrategy();
69 | break;
70 | default:
71 | $session_name_strategy = null;
72 | }
73 |
74 | self::$instance = new self($session_name_strategy);
75 | }
76 | return self::$instance;
77 | }
78 |
79 | /**
80 | * Use it to set a single var like $ses->set( 'name', 'val' ); or an array of pairs key-value like $ses->set( array( 'key' => 'val' ) );
81 | *
82 | * @param string|array $name
83 | * @param string|null $value
84 | * @return boolean
85 | */
86 | public function set( $name, $value = null )
87 | {
88 | if ( is_array( $name ) && null === $value )
89 | {
90 | foreach ( $name as $key => $val )
91 | {
92 | $_SESSION[$key] = $val;
93 | }
94 | }
95 | elseif ( !isset( $name ) || !isset( $value ) )
96 | {
97 | trigger_error( 'Session: Missing parameter or parameters.', E_USER_WARNING);
98 | return false;
99 | }
100 | else
101 | {
102 | $_SESSION[$name] = $value;
103 | }
104 |
105 | return true;
106 | }
107 |
108 | public function get( $name )
109 | {
110 | if ( !isset( $_SESSION[$name] ) )
111 | {
112 | return null;
113 | }
114 |
115 | return $_SESSION[$name];
116 | }
117 |
118 | public function getId()
119 | {
120 | if ( !isset( $_SESSION ) )
121 | {
122 | return null;
123 | }
124 |
125 | return session_id();
126 | }
127 |
128 | public function delete( $name )
129 | {
130 | if ( !isset( $_SESSION[$name] ) )
131 | {
132 | trigger_error( "Session: $name variable does not exist.", E_USER_WARNING );
133 | return false;
134 | }
135 | else
136 | {
137 | unset( $_SESSION[$name] );
138 | return true;
139 | }
140 | }
141 |
142 | /**
143 | * @param string $index
144 | * @returns boolean
145 | *
146 | */
147 | public static function keyExists( $key )
148 | {
149 | return isset( $_SESSION[$key] );
150 | }
151 |
152 | /**
153 | * Remove all the session saved data. And the Session continue started.
154 | *
155 | * @return bool
156 | */
157 | public function reset()
158 | {
159 | $this->destroy();
160 | session_start();
161 |
162 | return true;
163 | }
164 |
165 | public function destroy()
166 | {
167 | if ( isset( $_SESSION ) )
168 | {
169 | unset( $_SESSION );
170 | $_SESSION = array( );
171 | session_destroy();
172 | }
173 |
174 | return true;
175 | }
176 |
177 | /**
178 | * Ends the current session and store session data.
179 | */
180 | public function writeClose()
181 | {
182 | session_write_close();
183 | }
184 |
185 | public static function setExpirationTime( $time )
186 | {
187 | ini_set( 'session.cache_expire', $time );
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/src/Sifo/Images.php:
--------------------------------------------------------------------------------
1 | $resizeUp,
56 | 'preserveAlpha' => $transparency,
57 | 'preserveTransparency' => $transparency,
58 | 'jpegQuality' => $quality,
59 | ]
60 | );
61 |
62 | if (self::isCropRequired($crop)) {
63 | $thumb->adaptiveResize($width, $height, $crop['x'], $crop['y']);
64 | } else {
65 | $thumb->resize($width, $height);
66 | }
67 |
68 | $thumb->save($to, $fileinfo['extension']);
69 |
70 | return true;
71 | }
72 |
73 | /**
74 | * Crop an image using specific points where the crop have to begin.
75 | *
76 | * @param string $from Origin file name
77 | * @param string $to Final file name
78 | * @param $startX X point where the crop have to begin.
79 | * @param $startY Y point where the crop have to begin.
80 | * @param $width Final width.
81 | * @param $height Final height
82 | * @param bool $resizeUp
83 | * @param bool $transparency
84 | * @param int $quality
85 | * @return bool
86 | */
87 | static public function cropAndSave(
88 | string $from,
89 | string $to,
90 | int $startX,
91 | int $startY,
92 | int $width,
93 | int $height,
94 | bool $resizeUp = false,
95 | bool $transparency = false,
96 | int $quality = 100
97 | ) {
98 | $fileInfo = pathinfo($to);
99 |
100 | $thumb = \PhpThumbFactory::create(
101 | $from,
102 | [
103 | 'resizeUp' => $resizeUp,
104 | 'preserveAlpha' => $transparency,
105 | 'preserveTransparency' => $transparency,
106 | 'jpegQuality' => $quality,
107 | ]
108 | );
109 |
110 | $thumb->crop($startX, $startY, $width, $height);
111 |
112 | $thumb->save($to, $fileInfo['extension']);
113 |
114 | return true;
115 | }
116 |
117 | /**
118 | * Upload and resize an image.
119 | *
120 | * @param file $from
121 | * @param file $to
122 | * @param integer $width
123 | * @param integer $height
124 | * @param boolean $crop
125 | * @return boolean
126 | */
127 | static public function uploadResizeAndSave(
128 | array $post_file,
129 | string $destination,
130 | int $width,
131 | int $height,
132 | array $crop = [],
133 | bool $resizeUp = false,
134 | bool $transparency = false
135 | ) {
136 | $old_name = $post_file['tmp_name'];
137 | $upload_info = pathinfo( $old_name );
138 | $new_name = $upload_info['dirname'].'/'.$post_file['name'];
139 | static::moveFile($old_name, $new_name);
140 |
141 | self::resizeAndSave($new_name, $destination, $width, $height, (array)$crop, $resizeUp, $transparency);
142 |
143 | return true;
144 | }
145 |
146 | private static function isCropRequired(array $crop): bool
147 | {
148 | return array_key_exists('x', $crop)
149 | && is_int($crop['x'])
150 | && array_key_exists('y', $crop)
151 | && is_int($crop['y']);
152 | }
153 |
154 | protected static function moveFile(string $from, string $to): void
155 | {
156 | move_uploaded_file($from, $to);
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/Sifo/API/Youtube.php:
--------------------------------------------------------------------------------
1 | getVideoData( $video_url );
35 | *
36 | * The format of the returned data is an array with these keys:
37 | * [video_id] => ybNJb6EuU1Y
38 | * [url_player] => http://www.youtube.com/watch?v=ybNJb6EuU1Y&feature=youtube_gdata
39 | * [title] => Video title
40 | * [description] => Video description
41 | * [keywords] => Array
42 | * (
43 | * [0] => keyword1
44 | * [1] => keyword2
45 | * ...
46 | * [N] => keywordN
47 | * )
48 | * [url_embed] => http://www.youtube.com/v/ybNJb6EuU1Y?f=videos&app=youtube_gdata
49 | * [duration] => Duration (in seconds)
50 | * [thumbnails] => Array
51 | * (
52 | * [0] => http://i.ytimg.com/vi/ybNJb6EuU1Y/2.jpg
53 | * [1] => http://i.ytimg.com/vi/ybNJb6EuU1Y/1.jpg
54 | * [2] => http://i.ytimg.com/vi/ybNJb6EuU1Y/3.jpg
55 | * )
56 | */
57 | class APIYoutube
58 | {
59 | /**
60 | * Youtube API url to retreive data.
61 | *
62 | * @var string
63 | */
64 | protected $api_url = 'http://gdata.youtube.com/feeds/api/videos/';
65 |
66 | /**
67 | * Media namespace to format the XML.
68 | *
69 | * @var string
70 | */
71 | protected $media_namespace = 'http://search.yahoo.com/mrss/';
72 |
73 | /**
74 | * Get video data from Youtube API.
75 | *
76 | * @param string $video_url Video URL or video ID.
77 | * @return array
78 | */
79 | public function getVideoData( $video_url )
80 | {
81 | $video_id = $this->_getVideoId( $video_url );
82 |
83 | $multi_curl = EpiCurl::getInstance();
84 | $curl = curl_init( $this->api_url . $video_id );
85 | curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 );
86 | $response = $multi_curl->addCurl( $curl );
87 |
88 | if ( 200 !== $response->code )
89 | {
90 | return false;
91 | }
92 |
93 | try
94 | {
95 | $xml_data = @new SimpleXMLElement( $response->data );
96 | }
97 | catch( \Exception $e )
98 | {
99 | if ( 'Invalid id' === $response->data )
100 | {
101 | return false;
102 | }
103 | }
104 |
105 | $video_data['video_id'] = $video_id;
106 | $video_data['url_player'] = ( string ) $xml_data->link[0]->attributes()->href[0];
107 |
108 | $media_group = $xml_data->children( $this->media_namespace );
109 | $video_data['title'] = ( string ) $media_group->group->title;
110 | $video_data['description'] = ( string ) $media_group->group->description;
111 | $video_data['keywords'] = explode( ',', ( string ) $media_group->group->keywords );
112 |
113 | if ( !isset( $media_group->group->content[0] ) )
114 | {
115 | return false;
116 | }
117 |
118 | $content_attrs = $media_group->group->content[0]->attributes();
119 | $video_data['url_embed'] = ( string ) $content_attrs['url'];
120 | $video_data['duration'] = ( int ) $content_attrs['duration'];
121 |
122 | foreach ( $media_group->group->thumbnail as $key => $val )
123 | {
124 | $thumb_attrs = $val->attributes();
125 | $thumb_width = ( int ) $thumb_attrs['width'];
126 | if ( $thumb_width == 120 )
127 | {
128 | $video_data['thumbnails'][] = ( string ) $thumb_attrs['url'];
129 | }
130 | }
131 |
132 | return $video_data;
133 | }
134 |
135 | /**
136 | * Get video ID from URL.
137 | *
138 | * @param string $video_url Video URL or video ID.
139 | * @return string
140 | */
141 | private function _getVideoId( $video_url )
142 | {
143 | $video_id = '';
144 | $url_parts = parse_url( $video_url );
145 | if ( !isset( $url_parts['query'] ) )
146 | {
147 | $video_id = $video_url;
148 | }
149 | else
150 | {
151 | parse_str( $url_parts['query'], $query_parts );
152 | if ( isset( $query_parts['v'] ) )
153 | {
154 | $video_id = $query_parts['v'];
155 | }
156 | }
157 |
158 | return $video_id;
159 | }
160 | }
161 |
162 | ?>
163 |
--------------------------------------------------------------------------------
/src/Sifo/LoadBalancer.php:
--------------------------------------------------------------------------------
1 | load_balancer_cache_key = $this->load_balancer_cache_key
66 | . '_' . Bootstrap::$instance
67 | . '_' . (Domains::getInstance()->getDevMode() ? 'dev' : 'prod');
68 | }
69 |
70 | /**
71 | * Sets the nodes to work with.
72 | * @param array $nodes
73 | * @throws Exception_500
74 | * @return integer Number of nodes added.
75 | */
76 | public function setNodes( array $nodes )
77 | {
78 | $cache = Cache::getInstance();
79 | $available_servers = trim( $cache->get( $this->load_balancer_cache_key ) ); // CacheDisk returns " " when no cache.
80 |
81 | if ( empty( $available_servers ) )
82 | {
83 | foreach( $nodes as $key => $node_properties )
84 | {
85 | $this->addNodeIfAvailable( $key, $node_properties );
86 | }
87 |
88 | // Save in cache available servers (even if none):
89 | $serialized_nodes = serialize( array( 'nodes' => $this->nodes, 'total_weights' => $this->total_weights ) );
90 | $cache->set( $this->load_balancer_cache_key, $serialized_nodes, self::CACHE_EXPIRATION );
91 | }
92 | else
93 | {
94 | $available_servers = unserialize( $available_servers );
95 | $this->nodes = $available_servers['nodes'];
96 | $this->total_weights = $available_servers['total_weights'];
97 | }
98 |
99 | $num_nodes = count( $this->nodes );
100 |
101 | if ( 1 > $num_nodes )
102 | {
103 | // This exception will be shown for CACHE_EXPIRATION seconds until servers are up again.
104 | throw new Exception_500( '[LOAD BALANCER] No available servers in profile' );
105 | }
106 |
107 | return $num_nodes;
108 |
109 |
110 | }
111 |
112 | /**
113 | * Adds a server to the battery of available.
114 | * @param integer $index Number of server.
115 | * @param integer $weight Weight of this server.
116 | *
117 | * @return integer Position in battery
118 | */
119 | protected function addServer( $index, $weight )
120 | {
121 | $x = (!is_array($this->nodes)) ? 0 : count( $this->nodes );
122 | $this->nodes[$x] = new \stdClass;
123 | $this->nodes[$x]->index = $index;
124 | $this->total_weights += ( $this->nodes[$x]->weight = abs( $weight ) );
125 |
126 | return $x;
127 | }
128 |
129 | /**
130 | * Retrieves a random node, the more weight, the more chances to be the picked.
131 | */
132 | public function get()
133 | {
134 | if ( !isset( $this->nodes ) )
135 | {
136 | throw new LoadBalancer_Exception( "There aren't any nodes set in the balancer. Have you called setNodes( Array nodes ) ?" );
137 | }
138 |
139 | $x = round( mt_rand( 0, $this->total_weights ) );
140 |
141 | $max = ( $i = 0 );
142 | do
143 | {
144 | $max += $this->nodes[ $i++ ]->weight;
145 | }
146 | while ( $x > $max );
147 |
148 | return $this->nodes[ ( $i-1 ) ]->index;
149 | }
150 |
151 | /**
152 | * Removes a server from the list of availables.
153 | *
154 | * @param integer $index
155 | */
156 | public function removeServer( $index )
157 | {
158 | if ( isset( $this->nodes[$index] ) )
159 | {
160 | $this->total_weights -= $this->nodes[$index]->weight;
161 | unset( $this->nodes[$index]);
162 | $this->nodes = array_values( $this->nodes );
163 | }
164 | }
165 | }
166 |
167 | class LoadBalancer_Exception extends \Exception {}
--------------------------------------------------------------------------------
/src/Sifo/Metadata.php:
--------------------------------------------------------------------------------
1 | assign( 'metadata', Metadata::get() );
33 | *
34 | * metadata_es_ES.config.php:
35 | * $config['test'] = array(
36 | * 'title' => "%name% - %section%. YourBrandName",
37 | * 'description' => "Description of %name% - %section%",
38 | * 'keywords' => "%name%,%section%"
39 | * );
40 | *
41 | * FINALLY, THE RESULT IS:
42 | *
43 | * $config['test'] = array(
44 | * 'title' => "Test name - Test section. YourBrandName",
45 | * 'description' => "Description of Test name - Test section",
46 | * 'keywords' => "Test name,Test section"
47 | * );
48 | *
49 | */
50 | class Metadata
51 | {
52 | /**
53 | * Store metadata key. It's not mandatory define a key. If you don't set a key the metadata key will be the URL path.
54 | *
55 | * @param string $key This key should be defined in the metadata_lang.config.php
56 | */
57 | static public function setKey( $key )
58 | {
59 | self::set( null, $key, true );
60 | }
61 |
62 | /**
63 | * Store values to do a replacement in the metadata definition. If an array is passed
64 | * in the values the var_name is ignored. Keys are used as var_names.
65 | *
66 | * @param string $var_name Var name defined in the metadata config.
67 | * @param string|array $value Value or values to replace in the metadata config (as string or key=>value).
68 | */
69 | static public function setValues( $var_name, $value )
70 | {
71 | if ( is_array( $value ) )
72 | {
73 | foreach ( $value as $key => $val )
74 | {
75 | self::set( "%$key%", $val );
76 | }
77 | }
78 | else
79 | {
80 | self::set( "%$var_name%", $value );
81 | }
82 | }
83 |
84 | /**
85 | * Get metadata. It uses the metadata key or path to return the metadata.
86 | *
87 | * @return array
88 | */
89 | static public function get()
90 | {
91 | $metadata_info = self::_getMetadataInformation();
92 | $metadata_raw = Config::getInstance()->getConfig( 'lang/metadata_' . Domains::getInstance()->getLanguage() );
93 | $metadata = $metadata_raw['default'];
94 |
95 | if ( isset( $metadata_info['metadata_key'] ) )
96 | {
97 | $metadata = $metadata_raw[ $metadata_info['metadata_key'] ];
98 | }
99 | else
100 | {
101 | $reversal_path = Router::getReversalRoute( Urls::getInstance( Bootstrap::$instance )->getPath() );
102 | if( $reversal_path && isset( $metadata_raw[ $reversal_path ] ) )
103 | {
104 | $metadata = $metadata_raw[ $reversal_path ];
105 | }
106 | }
107 |
108 | return self::_replaceVars( $metadata, $metadata_info );
109 | }
110 |
111 | /**
112 | * Replace Metadata vars in the metadata defined in metadata config.
113 | *
114 | * @param array $metadata Metadata get it of metadat config.
115 | * @param array $metadata_info Metadata info with the vars to do the replacement.
116 | * @return array
117 | */
118 | static private function _replaceVars( $metadata, $metadata_info )
119 | {
120 | if ( isset( $metadata_info['vars'] ) && is_array( $metadata ) )
121 | {
122 | foreach ( $metadata as $name => $value )
123 | {
124 | $metadata[ $name ] = strtr( $metadata[ $name ], $metadata_info['vars'] );
125 | }
126 | }
127 |
128 | return $metadata;
129 | }
130 |
131 | /**
132 | * Store metadata information in registry.
133 | *
134 | * @param string $key Variable name.
135 | * @param string $value Variable value.
136 | * @param boolean $is_metadata_key If it's the metadata key this value is true, others false.
137 | */
138 | static public function set( $key, $value, $is_metadata_key = false )
139 | {
140 | $registry = Registry::getInstance();
141 | if ( $registry->keyExists( 'metadata_information' ) )
142 | {
143 | $metadata_information = $registry->get( 'metadata_information' );
144 | }
145 |
146 | if ( $is_metadata_key )
147 | {
148 | $metadata_information['metadata_key'] = $value;
149 | }
150 | else
151 | {
152 | $metadata_information['vars'][$key] = $value;
153 | }
154 |
155 | $registry->set( 'metadata_information', $metadata_information );
156 | }
157 |
158 | /**
159 | * Get the metadata information.
160 | *
161 | * @return array
162 | */
163 | static private function _getMetadataInformation()
164 | {
165 | $msgs = Registry::getInstance()->get( 'metadata_information');
166 |
167 | if ( $msgs )
168 | {
169 | return $msgs;
170 | }
171 |
172 | return array();
173 | }
174 | }
--------------------------------------------------------------------------------
/src/RSS_PHP/rss_php.php:
--------------------------------------------------------------------------------
1 |
8 | Published: 200801 :: blacknet :: via rssphp.net
9 |
10 | RSS_PHP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
11 |
12 | Usage:
13 | See the documentation at http://rssphp.net/documentation
14 | Examples:
15 | Can be found online at http://rssphp.net/examples
16 | */
17 |
18 | class rss_php {
19 |
20 | public $document;
21 | public $channel;
22 | public $items;
23 |
24 | /****************************
25 | public load methods
26 | ***/
27 | # load RSS by URL
28 | public function load($url=false, $unblock=true) {
29 | if($url) {
30 | if($unblock) {
31 | $this->loadParser(file_get_contents($url, false, $this->randomContext()));
32 | } else {
33 | $this->loadParser(file_get_contents($url));
34 | }
35 | }
36 | }
37 | # load raw RSS data
38 | public function loadRSS($rawxml=false) {
39 | if($rawxml) {
40 | $this->loadParser($rawxml);
41 | }
42 | }
43 |
44 | /****************************
45 | public load methods
46 | @param $includeAttributes BOOLEAN
47 | return array;
48 | ***/
49 | # return full rss array
50 | public function getRSS($includeAttributes=false) {
51 | if($includeAttributes) {
52 | return $this->document;
53 | }
54 | return $this->valueReturner();
55 | }
56 | # return channel data
57 | public function getChannel($includeAttributes=false) {
58 | if($includeAttributes) {
59 | return $this->channel;
60 | }
61 | return $this->valueReturner($this->channel);
62 | }
63 | # return rss items
64 | public function getItems($includeAttributes=false) {
65 | if($includeAttributes) {
66 | return $this->items;
67 | }
68 | return $this->valueReturner($this->items);
69 | }
70 |
71 | /****************************
72 | internal methods
73 | ***/
74 | private function loadParser($rss=false) {
75 | if($rss) {
76 | $this->document = array();
77 | $this->channel = array();
78 | $this->items = array();
79 | $DOMDocument = new DOMDocument;
80 | $DOMDocument->strictErrorChecking = false;
81 | $DOMDocument->loadXML($rss);
82 | $this->document = $this->extractDOM($DOMDocument->childNodes);
83 | }
84 | }
85 |
86 | private function valueReturner($valueBlock=false) {
87 | if(!$valueBlock) {
88 | $valueBlock = $this->document;
89 | }
90 | foreach($valueBlock as $valueName => $values) {
91 | if(isset($values['value'])) {
92 | $values = $values['value'];
93 | }
94 | if(is_array($values)) {
95 | $valueBlock[$valueName] = $this->valueReturner($values);
96 | } else {
97 | $valueBlock[$valueName] = $values;
98 | }
99 | }
100 | return $valueBlock;
101 | }
102 |
103 | private function extractDOM($nodeList,$parentNodeName=false) {
104 | $itemCounter = 0;
105 | foreach($nodeList as $values) {
106 | if(substr($values->nodeName,0,1) != '#') {
107 | if($values->nodeName == 'item') {
108 | $nodeName = $values->nodeName.':'.$itemCounter;
109 | $itemCounter++;
110 | } else {
111 | $nodeName = $values->nodeName;
112 | }
113 | $tempNode[$nodeName] = array();
114 | if($values->attributes) {
115 | for($i=0;$values->attributes->item($i);$i++) {
116 | $tempNode[$nodeName]['properties'][$values->attributes->item($i)->nodeName] = $values->attributes->item($i)->nodeValue;
117 | }
118 | }
119 | if(!$values->firstChild) {
120 | $tempNode[$nodeName]['value'] = $values->textContent;
121 | } else {
122 | $tempNode[$nodeName]['value'] = $this->extractDOM($values->childNodes, $values->nodeName);
123 | }
124 | if(in_array($parentNodeName, array('channel','rdf:RDF'))) {
125 | if($values->nodeName == 'item') {
126 | $this->items[] = $tempNode[$nodeName]['value'];
127 | } elseif(!in_array($values->nodeName, array('rss','channel'))) {
128 | $this->channel[$values->nodeName] = $tempNode[$nodeName];
129 | }
130 | }
131 | } elseif(substr($values->nodeName,1) == 'text') {
132 | $tempValue = trim(preg_replace('/\s\s+/',' ',str_replace("\n",' ', $values->textContent)));
133 | if($tempValue) {
134 | $tempNode = $tempValue;
135 | }
136 | } elseif(substr($values->nodeName,1) == 'cdata-section'){
137 | $tempNode = $values->textContent;
138 | }
139 | }
140 | return $tempNode;
141 | }
142 |
143 | private function randomContext() {
144 | $headerstrings = array();
145 | $headerstrings['User-Agent'] = 'Mozilla/5.0 (Windows; U; Windows NT 5.'.rand(0,2).'; en-US; rv:1.'.rand(2,9).'.'.rand(0,4).'.'.rand(1,9).') Gecko/2007'.rand(10,12).rand(10,30).' Firefox/2.0.'.rand(0,1).'.'.rand(1,9);
146 | $headerstrings['Accept-Charset'] = rand(0,1) ? 'en-gb,en;q=0.'.rand(3,8) : 'en-us,en;q=0.'.rand(3,8);
147 | $headerstrings['Accept-Language'] = 'en-us,en;q=0.'.rand(4,6);
148 | $setHeaders = 'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'."\r\n".
149 | 'Accept-Charset: '.$headerstrings['Accept-Charset']."\r\n".
150 | 'Accept-Language: '.$headerstrings['Accept-Language']."\r\n".
151 | 'User-Agent: '.$headerstrings['User-Agent']."\r\n";
152 | $contextOptions = array(
153 | 'http'=>array(
154 | 'method'=>"GET",
155 | 'header'=>$setHeaders
156 | )
157 | );
158 | return stream_context_create($contextOptions);
159 | }
160 |
161 | }
162 |
163 | ?>
164 |
--------------------------------------------------------------------------------
/src/Sifo/Router.php:
--------------------------------------------------------------------------------
1 | getString( 'HTTPS' ) == 'on' || $server->getString( 'HTTP_X_FORWARDED_PROTO' ) == 'https' )
46 | {
47 | $used_url .= "s";
48 | }
49 | $used_url .= "://";
50 |
51 | if ( $server->getString( 'HTTP_HOST' ) )
52 | {
53 | $hostname = $server->getString( 'HTTP_HOST' );
54 | }
55 | else
56 | {
57 | $hostname = $server->getString( "SERVER_NAME" );
58 | }
59 |
60 | if ( $server->getString( 'SERVER_PORT' ) != "80" )
61 | {
62 | $used_url .= $hostname . ":" . $server->getString( 'SERVER_PORT' ) . $server->getString( "REQUEST_URI" );
63 | }
64 | else
65 | {
66 | $used_url .= $hostname . $server->getString( "REQUEST_URI" );
67 | }
68 |
69 | return $used_url;
70 | }
71 |
72 | /**
73 | * Looks if the path has a known pattern handled by a controller.
74 | */
75 | public function __construct( $path, $instance, $subdomain = false, $language = false, $www_mode = false )
76 | {
77 | // Look for routes:
78 | $routes = Config::getInstance( $instance )->getConfig( 'router' );
79 |
80 | // Failed to parse routes file.
81 | if ( !$routes )
82 | {
83 | throw new Exception_500( "Failed opening router conifiguration file" );
84 | }
85 |
86 | if ( $language )
87 | {
88 | try
89 | {
90 | self::$routes_for_this_language = Config::getInstance( $instance )->getConfig( 'lang/router_' . $language );
91 |
92 |
93 | // Translation of URLs:
94 | foreach ( self::$routes_for_this_language as $translated_route => $destiny )
95 | {
96 | if ( isset( $routes[$translated_route] ) && $translated_route != $destiny )
97 | {
98 | // Replace a translation of the URL by the english entry.
99 | $routes[$destiny] = $routes[$translated_route];
100 |
101 | // Delete the English entry.
102 | unset( $routes[$translated_route] );
103 | }
104 |
105 |
106 | // Create a mapping table with the association translated => original
107 | self::$reversal_map[$destiny] = $translated_route;
108 | }
109 | }
110 | catch ( Exception_Configuration $e )
111 | {
112 | // trigger_error( "Failed to load url config profile for language '$language'" );
113 | }
114 | }
115 |
116 | foreach ( $routes as $route => $controller )
117 | {
118 | // The subdomain can define the controller to use.
119 | if ( $subdomain == $route )
120 | {
121 | $this->main_controller = $controller;
122 | return;
123 | }
124 | // No valid subdomain for controller, use path to define controller instead:
125 | elseif ( $path == $route )
126 | {
127 | $this->main_controller = $controller;
128 | return;
129 | }
130 | }
131 |
132 | // The controller cannot be determined by parsing the path or the subdomain, is a home?
133 | if ( !isset( $this->main_controller ) )
134 | {
135 | if ( ( strlen( $path ) == 0 ) && !( ( $subdomain != "www" && true == $www_mode || strlen( $subdomain ) > 0 && false == $www_mode) ) )
136 | {
137 | $this->main_controller = $routes['__HOME__'];
138 | }
139 | else
140 | {
141 | if ( $rules_301 = Config::getInstance( $instance )->getConfig( '301_rules' ) )
142 | {
143 | $used_url = self::getUsedUrl();
144 | foreach ( $rules_301 as $regexp => $replacement )
145 | {
146 | $destiny = preg_replace( $regexp, $replacement, $used_url, -1, $count );
147 |
148 | // $count indicates the replaces. If $count gt 0 means that was matchs.
149 | if ( $count )
150 | {
151 | throw new Exception_301( $destiny );
152 | }
153 | }
154 | }
155 | // No route found, use default.
156 | $this->main_controller = $routes['__NO_ROUTE_FOUND__'];
157 | }
158 | }
159 | }
160 |
161 | public function getController()
162 | {
163 | return $this->main_controller;
164 | }
165 |
166 | /**
167 | * Returns the key associated to a translated route. Or same string if no reversal found.
168 | *
169 | * For instance, if you pass 'ayuda' should return 'help'.
170 | *
171 | * @param string $translated_route
172 | * @return string
173 | */
174 | static public function getReversalRoute( $translated_route )
175 | {
176 | if ( isset( self::$reversal_map[$translated_route] ) )
177 | {
178 | // The path has translation:
179 | return self::$reversal_map[$translated_route];
180 | }
181 |
182 | if ( !isset( self::$routes_for_this_language[ $translated_route ] ) )
183 | {
184 | // There are not available translation for this route.
185 | return $translated_route;
186 | }
187 |
188 | return false;
189 | }
190 | }
191 |
--------------------------------------------------------------------------------
/src/Sifo/Cache/Disk.php:
--------------------------------------------------------------------------------
1 | cache_object = &$this;
37 | return $this;
38 | }
39 |
40 | /**
41 | * Stores variable "var" with "key" only if such key doesn't exist at the server yet.
42 | *
43 | * @param string $key
44 | * @param mixed $var
45 | * @param integer $expire Seconds until this item will expire. Zero for persistent caching (never expire).
46 | *
47 | * @return bool
48 | */
49 | public function add( $key, $var, $expire = 0 )
50 | {
51 | if ( false != $this->get( $key ) )
52 | {
53 | return false;
54 | }
55 | return $this->set( $key, $var, $expire );
56 | }
57 |
58 |
59 | /**
60 | * Increment an existing integer value
61 | *
62 | * @param string $key
63 | * @param integer $value
64 | * @param integer $expire Seconds until this item will expire. Zero for persistent caching (never expire).
65 | *
66 | * @return bool
67 | */
68 | public function increment( $key, $value = 1, $expire = 0 )
69 | {
70 | if ( !is_numeric( $current_value = $this->get( $key ) ) )
71 | {
72 | return false;
73 | }
74 |
75 | $new_value = $current_value + $value;
76 | return ( $this->set( $key, $new_value, $expire ) ? $new_value : false );
77 | }
78 |
79 | /**
80 | * Increment an existing integer value
81 | *
82 | * @param string $key
83 | * @param integer $value
84 | * @param integer $expire Seconds until this item will expire. Zero for persistent caching (never expire).
85 | * @return bool
86 | */
87 | public function decrement( $key, $value = 1, $expire = 0 )
88 | {
89 | if ( !is_numeric( $current_value = $this->get( $key ) ) )
90 | {
91 | return false;
92 | }
93 |
94 | $new_value = $current_value - $value;
95 | return ( $this->set( $key, $new_value, $expire ) ? $new_value : false );
96 | }
97 |
98 | /**
99 | * Write content in cache
100 | *
101 | * @param string $key
102 | * @param string $contents
103 | * @param integer $expire Seconds until this item will expire. Zero for persistent caching (never expire).
104 | *
105 | * @return boolean
106 | */
107 | public function set( $key, $contents, $expire = 0 )
108 | {
109 | $source_file = $this->getCacheFilename( $key );
110 |
111 | $cache_content = array(
112 | 'key' => $key,
113 | 'expiration' => $expire,
114 | 'content' => $contents
115 | );
116 | return file_put_contents( $source_file, var_export( $cache_content, true ) );
117 | }
118 |
119 | /**
120 | * Returns the content associated to that key or FALSE.
121 | *
122 | * Also deletes the cache file if has expired when checking it.
123 | *
124 | * @param string $key
125 | *
126 | * @return mixed Cached content or FALSE.
127 | */
128 | public function get( $key )
129 | {
130 | if ( $this->hasRebuild() )
131 | {
132 | return false;
133 | }
134 |
135 | $source_file = $this->getCacheFilename( $key );
136 |
137 | $file_content = @file_get_contents( $source_file );
138 | if ( !$file_content )
139 | {
140 | return false;
141 | }
142 |
143 | $cache_content = eval( 'return ' . $file_content . ';' );
144 |
145 | if ( !isset( $cache_content['expiration'] ) || !isset( $cache_content['content'] ) )
146 | {
147 | return false;
148 | }
149 |
150 | // Check if content has expired (expiration=0 means persistent cache):
151 | if ( $cache_content['expiration'] > 0 )
152 | {
153 | $mtime = filemtime( $source_file );
154 | if ( ( $mtime + $cache_content['expiration'] ) < time() )
155 | {
156 | // Delete the file.
157 | @unlink( $source_file );
158 | return false;
159 | }
160 | }
161 |
162 | return $cache_content['content'];
163 |
164 |
165 | }
166 |
167 | /**
168 | * Deletes the cache key.
169 | *
170 | * @param $key
171 | *
172 | * @return bool
173 | */
174 | public function delete( $key )
175 | {
176 | return @unlink( $this->getCacheFilename( $key ) );
177 | }
178 |
179 |
180 | /**
181 | * Check if cache to Disk will work.
182 | *
183 | * @return integer
184 | */
185 | public function isActive()
186 | {
187 | $cache_path = $this->getPathBase();
188 | return is_writable( $cache_path ) && is_readable( $cache_path );
189 | }
190 |
191 |
192 | /**
193 | * Returns the full path to the cache filename related to the given key.
194 | *
195 | * @param $key
196 | *
197 | * @return string
198 | */
199 | private function getCacheFilename( $key )
200 | {
201 | $hash = sha1( $key );
202 | return $this->getPathBase() . "{$hash}.cache";
203 | }
204 |
205 | /**
206 | * Returns the base folder where cache will be stored.
207 | *
208 | * @return string
209 | */
210 | private function getPathBase()
211 | {
212 | return ROOT_PATH . '/instances/' . Bootstrap::$instance . '/templates/_smarty/cache/';
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/src/Sifo/Exceptions.php:
--------------------------------------------------------------------------------
1 | = $current_exception_code ) )
60 | {
61 | $this->redirect = true;
62 | }
63 |
64 | if ( isset( Headers::$http_codes[$current_exception_code] ) )
65 | {
66 | $this->http_code = $current_exception_code;
67 | $this->http_code_msg = Headers::$http_codes[$current_exception_code];
68 | }
69 | else
70 | {
71 | // The passed exception is not in the list. Pass a 500 error.
72 | $this->http_code = 500;
73 | $this->http_code_msg = 'Internal Server Error';
74 | }
75 |
76 | // Set internal exception vars if they are empty (non declared in constructor).
77 | // This allows usage of methods as $e->getMessage() or $e->getCode()
78 | if ( 0 == $this->code )
79 | {
80 | $this->code = $this->http_code;
81 | }
82 |
83 | if ( null === $this->message )
84 | {
85 | $this->message = $this->http_code_msg;
86 | }
87 | }
88 |
89 | /**
90 | * Raises a Sifo exceptions based on the given HTTP status code
91 | * @param string $message Reason
92 | * @param int $code HTTP status code
93 | */
94 | public static function raise( $message, $code )
95 | {
96 | if ( isset( Headers::$http_codes[$code] ) )
97 | {
98 | $exception = '\Sifo\Exception_' . $code;
99 | throw new $exception( $message );
100 | }
101 | else
102 | {
103 | // Unknown status code.
104 | throw new Exception_500( $message, $code );
105 | }
106 | }
107 |
108 | /** http://fabien.potencier.org/php-serialization-stack-traces-and-exceptions.html */
109 | public function serialize()
110 | {
111 | return serialize( array( $this->code, $this->message, $this->http_code, $this->http_code_msg, $this->redirect ) );
112 | }
113 |
114 | public function unserialize($serialized)
115 | {
116 | list( $this->code, $this->message, $this->http_code, $this->http_code_msg, $this->redirect ) = unserialize( $serialized );
117 | }
118 | }
119 |
120 | /**
121 | * Redirect (Moved permanently).
122 | */
123 | class Exception_301 extends SEO_Exception{}
124 |
125 | /**
126 | * Found (redirection).
127 | */
128 | class Exception_302 extends SEO_Exception{}
129 |
130 | /**
131 | * See other.
132 | */
133 | class Exception_303 extends SEO_Exception{}
134 |
135 | /**
136 | * Not modified headers. TODO, implement Etag.
137 | */
138 | class Exception_304 extends SEO_Exception{}
139 |
140 | /*
141 | * Temporary redirect
142 | */
143 | class Exception_307 extends SEO_Exception{}
144 |
145 | /**
146 | * Bad request
147 | */
148 | class Exception_400 extends SEO_Exception{}
149 |
150 | /**
151 | * Unauthorized Exception.
152 | */
153 | class Exception_401 extends SEO_Exception{}
154 |
155 | /**
156 | * Forbidden.
157 | */
158 | class Exception_403 extends SEO_Exception{}
159 |
160 | /**
161 | * Not found.
162 | */
163 | class Exception_404 extends SEO_Exception{}
164 |
165 | /**
166 | * Method not allowed.
167 | */
168 | class Exception_405 extends SEO_Exception{}
169 |
170 | /**
171 | * Oooops. Internal server error.
172 | */
173 | class Exception_500 extends SEO_Exception{}
174 |
175 | /**
176 | * Service unavailable.
177 | */
178 | class Exception_503 extends SEO_Exception{}
179 |
180 | /* Not so common status codes */
181 | class Exception_100 extends SEO_Exception{}
182 | class Exception_101 extends SEO_Exception{}
183 | class Exception_201 extends SEO_Exception{}
184 | class Exception_202 extends SEO_Exception{}
185 | class Exception_203 extends SEO_Exception{}
186 | class Exception_204 extends SEO_Exception{}
187 | class Exception_205 extends SEO_Exception{}
188 | class Exception_206 extends SEO_Exception{}
189 | class Exception_300 extends SEO_Exception{}
190 | class Exception_305 extends SEO_Exception{}
191 | class Exception_402 extends SEO_Exception{}
192 | class Exception_406 extends SEO_Exception{}
193 | class Exception_407 extends SEO_Exception{}
194 | class Exception_408 extends SEO_Exception{}
195 | class Exception_409 extends SEO_Exception{}
196 | class Exception_410 extends SEO_Exception{}
197 | class Exception_411 extends SEO_Exception{}
198 | class Exception_412 extends SEO_Exception{}
199 | class Exception_413 extends SEO_Exception{}
200 | class Exception_414 extends SEO_Exception{}
201 | class Exception_415 extends SEO_Exception{}
202 | class Exception_416 extends SEO_Exception{}
203 | class Exception_417 extends SEO_Exception{}
204 | class Exception_501 extends SEO_Exception{}
205 | class Exception_502 extends SEO_Exception{}
206 | class Exception_504 extends SEO_Exception{}
207 | class Exception_505 extends SEO_Exception{}
208 |
--------------------------------------------------------------------------------
/src/Sifo/Search.php:
--------------------------------------------------------------------------------
1 | sphinx_config = $this->getConnectionParams( $profile );
52 |
53 | // Check if Sphinx is enabled by configuration:
54 | if ( true === $this->sphinx_config['active'] )
55 | {
56 | self::$search_engine = 'Sphinx';
57 | $this->sphinx = self::connect( $this->sphinx_config );
58 | }
59 | }
60 |
61 | /**
62 | * Singleton get instance. Return one search engine object.
63 | *
64 | * @param string $profile
65 | * @return object Config
66 | */
67 | public static function getInstance( $profile = 'default' )
68 | {
69 | if ( !isset ( self::$instance[$profile] ) )
70 | {
71 | if ( Domains::getInstance()->getDebugMode() !== true )
72 | {
73 | self::$instance[$profile] = new Search( $profile );
74 | }
75 | else
76 | {
77 | self::$instance[$profile] = new DebugSearch( $profile );
78 | }
79 | }
80 |
81 | return self::$instance[$profile];
82 | }
83 |
84 | /**
85 | * Get Sphinx connection params from config files.
86 | *
87 | * @param $profile
88 | * @throws Exception_500
89 | * @return array
90 | */
91 | protected function getConnectionParams( $profile )
92 | {
93 | // The domains.config file has priority, let's fetch it.
94 | $sphinx_config = \Sifo\Domains::getInstance()->getParam( 'sphinx' );
95 |
96 | if ( empty( $sphinx_config ) )
97 | {
98 | try
99 | {
100 | // If the domains.config doesn't define the params, we use the sphinx.config.
101 | $sphinx_config = Config::getInstance()->getConfig( 'sphinx' );
102 |
103 | if ( isset( $sphinx_config[$profile] ) )
104 | {
105 | $sphinx_config = $this->checkBalancedProfile( $sphinx_config[$profile] );
106 | }
107 | elseif ( isset( $sphinx_config['default'] ) )
108 | {
109 | // Is using profiles but there isn't the required one.
110 | throw new \Sifo\Exception_500( "Expected sphinx settings not defined for profile {$profile} in sphinx.config." );
111 | }
112 | // Deprecated:
113 | else
114 | {
115 | if ( Domains::getInstance()->getDebugMode() === true )
116 | {
117 | trigger_error( "DEPRECATED: You aren't using profiles for your sphinx.config file. Please, define at least the 'default' one. (This message is only readable with the debug flag enabled)", E_USER_DEPRECATED );
118 | }
119 | }
120 | $sphinx_config['config_file'] = 'sphinx';
121 | }
122 | catch ( Exception_Configuration $e )
123 | {
124 | throw new \Sifo\Exception_500( 'You must define the connection params in sphinx.config or domains.config file' );
125 | }
126 | }
127 | else
128 | {
129 | $sphinx_config['config_file'] = 'domains';
130 | }
131 |
132 | return $sphinx_config;
133 | }
134 |
135 | /**
136 | * Check if one profile has balanced servers or single server. Returns the connection to use.
137 | * @param $sphinx_config
138 | * @return array
139 | */
140 | private function checkBalancedProfile( $sphinx_config )
141 | {
142 | if ( isset( $sphinx_config[0] ) && is_array( $sphinx_config[0] ) )
143 | {
144 | $lb = new LoadBalancerSearch();
145 | $lb->setNodes( $sphinx_config );
146 | $selected_server = $lb->get();
147 | $sphinx_config = $sphinx_config[$selected_server];
148 | }
149 |
150 | return $sphinx_config;
151 | }
152 |
153 | /**
154 | * Delegate all calls to the proper class.
155 | *
156 | * @param string $method
157 | * @param mixed $args
158 | * @return mixed
159 | */
160 | function __call( $method, $args )
161 | {
162 | if ( is_object( $this->sphinx ) )
163 | {
164 | return call_user_func_array( array( $this->sphinx, $method ), $args );
165 | }
166 | return null;
167 | }
168 |
169 | /**
170 | * Use this method to connect to Sphinx.
171 | * @param $node_properties
172 | * @return \SphinxClient
173 | * @throws Exception_500
174 | */
175 | static function connect( $node_properties )
176 | {
177 | if ( true === $node_properties['active'] )
178 | {
179 | $sphinx = new \SphinxClient();
180 | $sphinx->SetServer( $node_properties['server'], $node_properties['port'] );
181 |
182 | // If it's defined a time out connection in config file:
183 | if( isset( $node_properties['time_out'] ) )
184 | {
185 | $sphinx->SetConnectTimeout( $node_properties['time_out'] );
186 | }
187 |
188 | // Check if Sphinx is listening:
189 | if ( false === $sphinx->Status() )
190 | {
191 | throw new \Sifo\Exception_500( 'Sphinx (' . $node_properties['server'] . ':' . $node_properties['port'] . ') is down!' );
192 | }
193 | }
194 |
195 | return $sphinx;
196 | }
197 | }
198 |
199 | class LoadBalancerSearch extends LoadBalancer
200 | {
201 | /**
202 | * Name of the cache where the results of server status are stored.
203 | * @var string
204 | */
205 | protected $load_balancer_cache_key = 'BalancedNodesSearch';
206 |
207 | protected function addNodeIfAvailable( $index, $node_properties )
208 | {
209 | try
210 | {
211 | Search::connect( $node_properties );
212 | $this->addServer( $index, $node_properties['weight'] );
213 | }
214 | catch( \Sifo\Exception_500 $e )
215 | {
216 | trigger_error('[SEARCH LOAD BALANCER] ' . $e->getMessage(), E_USER_WARNING);
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/src/Sifo/Config.php:
--------------------------------------------------------------------------------
1 | instance_name = $instance_name;
69 | if ( $instance_name === 'tests' )
70 | {
71 | $this->config_path = ROOT_PATH . '/' . $instance_name ."/config/";
72 | }
73 | else
74 | {
75 | $this->config_path = ROOT_PATH . "/instances/" . $instance_name ."/config/";
76 | }
77 |
78 | include( $this->config_path . $this->configuration_files );
79 | $this->paths_to_configs = $config;
80 |
81 | $env_file = (isset($_SERVER['APP_ENV']) && $_SERVER['APP_ENV'] === 'test') ? '.env.test' : '.env';
82 | $dotenv = new Dotenv();
83 |
84 | try {
85 | $dotenv->load(ROOT_PATH . "/$env_file");
86 | } catch (PathException $exception) {
87 | return;
88 | }
89 | }
90 |
91 | /**
92 | * Singleton of config class.
93 | *
94 | * @param string $instance_name Instance Name, needed to determine correct paths.
95 | * @return Config
96 | */
97 | public static function getInstance( $instance_name = null, $force = false )
98 | {
99 | // Load instance from bootsrap
100 | if ( !isset( $instance_name ) )
101 | {
102 | $instance_name = Bootstrap::$instance;
103 | }
104 |
105 | if ( !isset ( self::$instance[$instance_name] ) || $force === true )
106 | {
107 | self::$instance[$instance_name] = new self( $instance_name );
108 | }
109 |
110 | return self::$instance[$instance_name];
111 | }
112 |
113 | /**
114 | * Loads the desired config file for a given valid 'profile'.
115 | *
116 | * @param string $profile The requested profile.
117 | * @throws Exception_Configuration When isn't set the self::PROFILE_NAME_FOR_CONFIG_FILES section or the desired profile.
118 | * @return boolean
119 | */
120 | protected function loadConfig( $profile )
121 | {
122 | if( !isset( $this->paths_to_configs[$profile] ) )
123 | {
124 | throw new Exception_Configuration( "The profile '$profile' was not found" );
125 | }
126 | else
127 | {
128 | if ( !include( ROOT_PATH . '/' . $this->paths_to_configs[$profile] ) )
129 | {
130 | throw new Exception_Configuration( "Failed to include file " . ROOT_PATH . '/' . $this->paths_to_configs[$profile] , E_USER_ERROR );
131 | }
132 | else
133 | {
134 | // The file was correctly included. We include the variable $config found.
135 | if ( !isset( $config ) )
136 | {
137 | throw new Exception_Configuration( 'The configuration files must have a variable named $config' );
138 | }
139 |
140 | return $config;
141 | }
142 | }
143 | }
144 |
145 | /**
146 | * Gets the profile config variables for the desired profile.
147 | *
148 | * @param string $profile The requested profile.
149 | * @param string $group The requested group inside the profile.
150 | * @throws Exception_Configuration When the selected group or profile doesn't exist.
151 | * @return mixed $config_values The config values in the config file of the current profile.
152 | */
153 | public function getConfig( $profile, $group = null )
154 | {
155 | if ( !isset( $this->config_values[$profile] ) )
156 | {
157 | $this->config_values[$profile] = $this->loadConfig( $profile );
158 | }
159 |
160 | if ( is_null( $group ) )
161 | {
162 | return $this->config_values[$profile];
163 | }
164 | if ( isset( $this->config_values[$profile][$group] ) )
165 | {
166 | return $this->config_values[$profile][$group];
167 | }
168 |
169 | throw new Exception_Configuration( "The group '$group' for profile '$profile' was never set.", E_USER_ERROR );
170 | }
171 |
172 | /**
173 | * Instance name.
174 | *
175 | * @return string
176 | */
177 | public function getInstanceName()
178 | {
179 | return $this->instance_name;
180 | }
181 |
182 | /**
183 | * Returns the library assigned to the given alias.
184 | *
185 | * @param string $alias Alias of the library, e.g: 'smarty'
186 | * @return string Effective name of the folder with the library
187 | */
188 | public function getLibrary( $alias )
189 | {
190 | $libraries = $this->getConfig( 'libraries', 'default' );
191 |
192 | // User requested a different profile, combine with default for missing attributes.
193 | if ( self::$libraries_profile != 'default' )
194 | {
195 | $libraries = array_merge( $libraries, $this->getConfig( 'libraries', self::$libraries_profile ) );
196 | }
197 |
198 | if ( !isset( $libraries[$alias] ) )
199 | {
200 | throw new Exception_Configuration( "The library '$alias' you are loading is not set in profile " . self::$libraries_profile );
201 | }
202 |
203 | return $libraries[$alias];
204 | }
205 | }
206 |
207 | /**
208 | * Exception for the process.
209 | */
210 | class Exception_Configuration extends \Exception
211 | {
212 | }
213 |
214 | ?>
215 |
--------------------------------------------------------------------------------
/src/Sifo/DirectoryList.php:
--------------------------------------------------------------------------------
1 | getRecursiveList( $path );
37 | *
38 | * // Recursive list of PHP and HTML files (hiding dirs)
39 | * $iterator = $dir->getRecursiveList( $path, false, array( 'php', 'html' ) );
40 | *
41 | * // List of immediate files and dirs (non recursive):
42 | * $iterator = $dir->getList( $path );
43 | *
44 | *
45 | * Then you can iterate the result $iterator in a foreach ( $path => $DirectoryIterator )
46 | * where $DirectoryIterator has many interesting methods such as:
47 | * ->getATime()
48 | * ->getBasename ( $ending_part_to_remove )
49 | * ->getCTime()
50 | * ->getExtension()
51 | * ->getFilename()
52 | * ->getGroup()
53 | * ->getInode()
54 | * ->getMTime()
55 | * ->getOwner()
56 | * ->getPath()
57 | * ->getPathname()
58 | * ->getPerms()
59 | * ->getSize()
60 | * ->getType()
61 | * ->isDir()
62 | * ->isDot()
63 | * ->isExecutable()
64 | * ->isFile()
65 | * ->isLink()
66 | * ->isReadable()
67 | * ->isWritable()
68 | * ->valid()
69 | *
70 | * @see http://www.php.net/manual/en/spl.iterators.php
71 | */
72 | class DirectoryList
73 | {
74 |
75 | /**
76 | * Returns the list of *immediate* files [isFile()] and folders [isDir()] on the given path.
77 | *
78 | * Non-recursive function.
79 | *
80 | * @param string $path Directory where you want to start parsing.
81 | * @param array $valid_extensions
82 | * @return \IteratorIterator
83 | */
84 | public function getList( $path, $valid_extensions = array( ) )
85 | {
86 | // Using RecursiveDirectoryIterator because compared to DirectoryIterator this one removes dot folders:
87 | $recursive_dir_iterator = new \RecursiveDirectoryIterator( $path );
88 | $recursive_dir_iterator->setFlags( \RecursiveDirectoryIterator::SKIP_DOTS );
89 |
90 | if ( !empty( $valid_extensions ) )
91 | {
92 | return new FilterFilesByExtensionIterator(
93 | new \IteratorIterator( $recursive_dir_iterator ),
94 | $valid_extensions );
95 | }
96 | else
97 | {
98 |
99 | return new \IteratorIterator( $recursive_dir_iterator );
100 | }
101 |
102 | }
103 |
104 | /**
105 | * Recursive listing of directory, files and dirs. If a set of extensions is
106 | * passed only matching files will be returned (do not pass the dot in the extensions)
107 | *
108 | * @param string $path Directory where you want to start parsing.
109 | * @param bool $accept_directories
110 | * @param array $valid_extensions List of accepted extensions in the list, empty array for no filtering.
111 | * @return \RecursiveIteratorIterator|\Sifo\FilterFilesByExtensionIterator ratorIterator of RecursiveDirectoryIterator
112 | */
113 | public function getRecursiveList( $path, $accept_directories = true, $valid_extensions = array( ) )
114 | {
115 | $mode = $this->_getIteratorMode( $accept_directories );
116 | $recursive_dir_iterator = new \RecursiveDirectoryIterator( $path );
117 | $recursive_dir_iterator->setFlags( \RecursiveDirectoryIterator::SKIP_DOTS );
118 |
119 | if ( !empty( $valid_extensions ) )
120 | {
121 | return new FilterFilesByExtensionIterator(
122 | new \RecursiveIteratorIterator(
123 | $recursive_dir_iterator,
124 | $mode, \RecursiveIteratorIterator::CATCH_GET_CHILD
125 | ),
126 | $valid_extensions );
127 | }
128 | else
129 | {
130 | return new \RecursiveIteratorIterator( $recursive_dir_iterator, $mode, \RecursiveIteratorIterator::CATCH_GET_CHILD );
131 | }
132 |
133 | }
134 |
135 | private function _getIteratorMode( $accept_directories )
136 | {
137 | /**
138 | * Available modes for RecursiveIteratorIterator:
139 | *
140 | * RecursiveIteratorIterator::LEAVES_ONLY (don't show folders, default)
141 | * RecursiveIteratorIterator::SELF_FIRST (show parent folders before children)
142 | * RecursiveIteratorIterator::CHILD_FIRST (show parent folders after children, unusual)
143 | *
144 | * Flags (set in flags, not in mode):
145 | * RecursiveIteratorIterator::CATCH_GET_CHILD = Catches exceptions in getChildren() call
146 | */
147 | return ( $accept_directories ?
148 | \RecursiveIteratorIterator::SELF_FIRST :
149 | \RecursiveIteratorIterator::LEAVES_ONLY
150 | );
151 |
152 | }
153 |
154 | }
155 |
156 | /**
157 | * Filters out unwanted files from the iterator. Pass an array with the list of
158 | * extensions you want to accept.
159 | */
160 | class FilterFilesByExtensionIterator extends \FilterIterator
161 | {
162 |
163 | protected $allowed_extensions;
164 |
165 | public function __construct( \Iterator $iterator, Array $allowed_extensions )
166 | {
167 | $this->allowed_extensions = $allowed_extensions;
168 | parent::__construct( $iterator );
169 |
170 | }
171 |
172 | /**
173 | * Checks if current file matches the allowed extension or not. If directories
174 | * are passed will be accepted.
175 | *
176 | * @return boolean
177 | */
178 | public function accept()
179 | {
180 | // If directories are passed, we accept them. Is duty of the calling function:
181 |
182 | if ( $this->current()->isDir() )
183 | {
184 | return true;
185 | }
186 |
187 | if ( !empty( $this->allowed_extensions ) )
188 | {
189 | foreach ( $this->allowed_extensions as $ext )
190 | {
191 | if ( pathinfo( $this->getBaseName(), PATHINFO_EXTENSION ) == $ext )
192 | {
193 | return true;
194 | }
195 | }
196 | return false;
197 | }
198 |
199 | return true;
200 |
201 | }
202 |
203 | }
--------------------------------------------------------------------------------
/src/Core-js/classes/modals.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @depracated It will be deleted cost is part of a third party library.
3 | */
4 | CORE.classes.modal = {
5 | oDefault : {
6 | sUrl : '#', // Default URL to open
7 | filters: [], // List of filters used
8 | callbacks: { // Sepcific callbacks
9 | beforeShowCont: function() {
10 | width = $('.nyroModalCont').width();
11 | height = $('.nyroModalCont').height();
12 | $('.nyroModalCont iframe').css('width', width);
13 | $('.nyroModalCont iframe').css('height', height);
14 | }
15 | },
16 | anims: {}, // Sepcific animations functions
17 | loadFilter: undefined, // Name of the filter used for loading
18 |
19 | modal: false, // Indicates if it's a modal window or not
20 | closeOnEscape: true, // Indicates if the modal should close on Escape key
21 | closeOnClick: true, // Indicates if a click on the background should close the modal
22 | useKeyHandler: false, // Indicates if the modal has to handle key down event
23 |
24 | showCloseButton: true, // Indicates if the closeButonn should be added
25 | closeButton: 'Close', // Close button HTML
26 |
27 | stack: false, // Indicates if links automatically binded inside the modal should stack or not
28 | nonStackable: 'form', // Filter to not stack DOM element
29 |
30 | header: undefined, // header include in every modal
31 | footer: undefined, // footer include in every modal
32 |
33 | // Specific confirguation for gallery filter
34 | galleryLoop: true, // Indicates if the gallery should loop
35 | galleryCounts: true, // Indicates if the gallery counts should be shown
36 | ltr: true, // Left to Right by default. Put to false for Hebrew or Right to Left language. Used in gallery filter
37 |
38 | // Specific confirguation for DOM filter
39 | domCopy: false, // Indicates if DOM element should be copied or moved
40 |
41 | // Specific confirguation for link and form filters
42 | ajax: {}, // Ajax options to be used in link and form filter
43 |
44 | // Specific confirguation for image filter
45 | imageRegex: '[^\.]\.(jpg|jpeg|png|tiff|gif|bmp)\s*$', // Regex used to detect image link
46 |
47 | selIndicator: 'nyroModalSel', // Value added when a form or Ajax is sent with a filter content
48 |
49 | swfObjectId: undefined, // Object id for swf object
50 | swf: { // Default SWF attributes
51 | allowFullScreen: 'true',
52 | allowscriptaccess: 'always',
53 | wmode: 'transparent'
54 | },
55 |
56 | store: {}, // Storage object for filters.
57 | errorMsg: 'An error occured', // Error message
58 | elts: { // HTML elements for the modal
59 | all: undefined,
60 | bg: undefined,
61 | load: undefined,
62 | cont: undefined,
63 | hidden: undefined
64 | },
65 | sizes: { // Size information
66 | initW: undefined, // Initial width
67 | initH: undefined, // Initial height
68 | w: undefined, // width
69 | h: undefined, // height
70 | minW: undefined, // minimum Width
71 | minH: undefined, // minimum height
72 | wMargin: undefined, // Horizontal margin
73 | hMargin: undefined // Vertical margin
74 | },
75 | anim: { // Animation names to use
76 | def: undefined, // Default animation set to use if sspecific are not defined or doesn't exist
77 | showBg: undefined, // Set to use for showBg animation
78 | hideBg: undefined, // Set to use for hideBg animation
79 | showLoad: undefined, // Set to use for showLoad animation
80 | hideLoad: undefined, // Set to use for hideLoad animation
81 | showCont: undefined, // Set to use for showCont animation
82 | hideCont: undefined, // Set to use for hideCont animation
83 | showTrans: undefined, // Set to use for showTrans animation
84 | hideTrans: undefined, // Set to use for hideTrans animation
85 | resize: undefined // Set to use for resize animation
86 | },
87 |
88 | _open: false, // Indicates if the modal is open
89 | _bgReady: false, // Indicates if the background is ready
90 | _opened: false, // Indicates if the modal was opened (useful for stacking)
91 | _loading: false, // Indicates if the loading is shown
92 | _animated: false, // Indicates if the modal is currently animated
93 | _transition: false, //Indicates if the modal is in transition
94 | _nmOpener: undefined, // nmObj of the modal that opened the current one in non stacking mode
95 | _nbContentLoading: 0, // Counter for contentLoading call
96 | _scripts: '', // Scripts tags to be included
97 | _scriptsShown: '' //Scripts tags to be included once the modal is swhon
98 | }
99 | };
100 |
101 | CORE.classes.modal.init = function (oOptions){
102 |
103 | var self = this;
104 | var Cm = CORE.modules;
105 | var Cc = CORE.classes;
106 | var Cg = CORE.globals;
107 | var oSettings = self.oDefault;
108 | var key = '';
109 |
110 | for ( key in oOptions ) {
111 | if(oOptions.hasOwnProperty(key)) {
112 | oSettings[key] = oOptions[key];
113 | }
114 | }
115 |
116 | // Load the CSS
117 | if (oSettings.pathCss) {
118 | // Load the nyroModal Css
119 | //console.log (oSettings.pathCss);
120 | $(document.body).append('');
121 | }
122 |
123 | if (Cg.isIE6) {
124 |
125 | $LAB.script(Cm.nyromodal_ie).wait( function() {
126 | Cc.modal.load(oSettings);
127 | });
128 |
129 | }
130 | else
131 | {
132 | Cc.modal.bind(oSettings);
133 | }
134 |
135 | };
136 |
137 | CORE.classes.modal.autobind = function (oTarget){
138 |
139 | $(oTarget).nyroModal();
140 |
141 | };
142 |
143 | CORE.classes.modal.open = function (oOptions){
144 |
145 | var self = this;
146 | var oSettings = self.oDefault;
147 |
148 | if (oOptions === undefined)
149 | {
150 | var oOptions = {};
151 | }
152 |
153 | for ( key in oOptions ) {
154 | if(oOptions.hasOwnProperty(key)) {
155 | oSettings[key] = oOptions[key];
156 | }
157 | }
158 |
159 |
160 | if(oSettings.sUrl !== undefined || oSettings.sUrl !== '#') {
161 | $.nmManual(oSettings.sUrl, oSettings);
162 | }
163 |
164 | };
165 |
166 | CORE.classes.modal.close = function(){
167 | $.nmTop().close();
168 | };
--------------------------------------------------------------------------------