820715be by Jeff Balicki

ee

1 parent 40e9d171
Showing 900 changed files with 5032 additions and 0 deletions
1 <?php
2
3 if (!defined('NEXTEND_SMARTSLIDER_3_URL_PATH')) {
4 define('NEXTEND_SMARTSLIDER_3_URL_PATH', 'smart-slider3');
5 }
6
7 define('N2WORDPRESS', 1);
8 define('N2JOOMLA', 0);
9
10 define('N2GSAP', 0);
11 define('N2SSPRO', 0);
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend;
4
5 class Autoloader {
6
7 private static $instance = null;
8
9 private $aliases = array(
10 'N2Data' => '\\Nextend\\Framework\\Data\\Data',
11 'N2SmartSliderBackup' => '\\Nextend\\SmartSlider3\\BackupSlider\\BackupData',
12 'N2SmartSliderImport' => '\\Nextend\\SmartSlider3\\BackupSlider\\ImportSlider',
13 'N2SmartSliderExport' => '\\Nextend\\SmartSlider3\\BackupSlider\\ExportSlider',
14 );
15
16 /**
17 * An associative array where the key is a namespace prefix and the value
18 * is an array of base directories for classes in that namespace.
19 *
20 * @var array
21 */
22 protected $prefixes = array();
23
24 public function __construct() {
25 $this->addNamespace('Nextend\\', dirname(__FILE__));
26
27
28 $this->register();
29
30 $currentPath = dirname(__FILE__) . '/';
31 foreach (scandir($currentPath) as $file) {
32 if ($file == '.' || $file == '..') continue;
33 $path = $currentPath . $file;
34 if (is_dir($path)) {
35
36 $className = '\\Nextend\\' . $file . '\\' . $file;
37
38 if (class_exists($className) && is_callable(array(
39 $className,
40 'getInstance'
41 ))) {
42 call_user_func_array(array(
43 $className,
44 'getInstance'
45 ), array());
46 }
47 }
48 }
49
50 Nextend::getInstance();
51 }
52
53 public static function getInstance() {
54 if (self::$instance == null) {
55 self::$instance = new Autoloader();
56 }
57
58 return self::$instance;
59 }
60
61 /**
62 * Register loader with SPL autoloader stack.
63 *
64 * @return void
65 */
66 public function register() {
67 spl_autoload_register(array(
68 $this,
69 'loadClass'
70 ));
71 }
72
73 /**
74 * Adds a base directory for a namespace prefix.
75 *
76 * @param string $prefix The namespace prefix.
77 * @param string $base_dir A base directory for class files in the
78 * namespace.
79 * @param bool $prepend If true, prepend the base directory to the stack
80 * instead of appending it; this causes it to be searched first rather
81 * than last.
82 *
83 * @return void
84 */
85 public function addNamespace($prefix, $base_dir, $prepend = false) {
86 // normalize namespace prefix
87 $prefix = trim($prefix, '\\') . '\\';
88
89 // normalize the base directory with a trailing separator
90 $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/';
91
92 // initialize the namespace prefix array
93 if (isset($this->prefixes[$prefix]) === false) {
94 $this->prefixes[$prefix] = array();
95 }
96
97 // retain the base directory for the namespace prefix
98 if ($prepend) {
99 array_unshift($this->prefixes[$prefix], $base_dir);
100 } else {
101 array_push($this->prefixes[$prefix], $base_dir);
102 }
103 }
104
105 /**
106 * Loads the class file for a given class name.
107 *
108 * @param string $class The fully-qualified class name.
109 *
110 * @return mixed The mapped file name on success, or boolean false on
111 * failure.
112 */
113 public function loadClass($class) {
114 // the current namespace prefix
115 $prefix = $class;
116
117 // work backwards through the namespace names of the fully-qualified
118 // class name to find a mapped file name
119 while (false !== $pos = strrpos($prefix, '\\')) {
120
121 // retain the trailing namespace separator in the prefix
122 $prefix = substr($class, 0, $pos + 1);
123
124 // the rest is the relative class name
125 $relative_class = substr($class, $pos + 1);
126
127 // try to load a mapped file for the prefix and relative class
128 $mapped_file = $this->loadMappedFile($prefix, $relative_class);
129 if ($mapped_file) {
130 return $mapped_file;
131 }
132
133 // remove the trailing namespace separator for the next iteration
134 // of strrpos()
135 $prefix = rtrim($prefix, '\\');
136 }
137
138 if (isset($this->aliases[$class]) && class_exists($this->aliases[$class])) {
139 /**
140 * Create class alias for old class names
141 */
142 class_alias($this->aliases[$class], $class);
143
144 return true;
145 }
146
147 // never found a mapped file
148 return false;
149 }
150
151 /**
152 * Load the mapped file for a namespace prefix and relative class.
153 *
154 * @param string $prefix The namespace prefix.
155 * @param string $relative_class The relative class name.
156 *
157 * @return mixed Boolean false if no mapped file can be loaded, or the
158 * name of the mapped file that was loaded.
159 */
160 protected function loadMappedFile($prefix, $relative_class) {
161 // are there any base directories for this namespace prefix?
162 if (isset($this->prefixes[$prefix]) === false) {
163 return false;
164 }
165
166 // look through base directories for this namespace prefix
167 foreach ($this->prefixes[$prefix] as $base_dir) {
168
169 // replace the namespace prefix with the base directory,
170 // replace namespace separators with directory separators
171 // in the relative class name, append with .php
172 $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
173
174 // if the mapped file exists, require it
175 if ($this->requireFile($file)) {
176 // yes, we're done
177 return $file;
178 }
179 }
180
181 // never found it
182 return false;
183 }
184
185 /**
186 * If a file exists, require it from the file system.
187 *
188 * @param string $file The file to require.
189 *
190 * @return bool True if the file exists, false if not.
191 */
192 protected function requireFile($file) {
193 if (file_exists($file)) {
194 require $file;
195
196 return true;
197 }
198
199 return false;
200 }
201 }
202
203 Autoloader::getInstance();
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Acl;
4
5 use Nextend\Framework\Pattern\MVCHelperTrait;
6
7 abstract class AbstractPlatformAcl {
8
9 /**
10 * @param $action
11 * @param MVCHelperTrait $MVCHelper
12 *
13 * @return bool
14 */
15 abstract public function authorise($action, $MVCHelper);
16 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Acl;
4
5 use Nextend\Framework\Acl\Joomla\JoomlaAcl;
6 use Nextend\Framework\Acl\WordPress\WordPressAcl;
7 use Nextend\Framework\Pattern\MVCHelperTrait;
8
9 class Acl {
10
11 /**
12 * @var AbstractPlatformAcl
13 */
14 private static $instance;
15
16 public function __construct() {
17 self::$instance = new WordPressAcl();
18 }
19
20 /**
21 * @param $action
22 * @param MVCHelperTrait $MVCHelper
23 *
24 * @return bool
25 */
26 public static function canDo($action, $MVCHelper) {
27 return self::$instance->authorise($action, $MVCHelper);
28 }
29 }
30
31 new Acl();
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Acl\WordPress;
4
5 use Nextend\Framework\Acl\AbstractPlatformAcl;
6 use function current_user_can;
7
8 class WordPressAcl extends AbstractPlatformAcl {
9
10 public function authorise($action, $MVCHelper) {
11 return current_user_can($action) && current_user_can('unfiltered_html');
12 }
13 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework;
5
6
7 use Exception;
8 use JHttp;
9 use Nextend\Framework\Misc\Base64;
10 use Nextend\Framework\Misc\HttpClient;
11 use Nextend\Framework\Notification\Notification;
12 use Nextend\Framework\Platform\Platform;
13 use Nextend\Framework\Url\Url;
14 use Nextend\Framework\View\Html;
15 use Nextend\SmartSlider3\Application\ApplicationSmartSlider3;
16 use WP_HTTP_Proxy;
17
18 class Api {
19
20 private static $api = 'https://api.nextendweb.com/v1/';
21
22 public static function getApiUrl() {
23
24 return self::$api;
25 }
26
27 public static function api($posts, $returnUrl = false) {
28
29 $api = self::getApiUrl();
30
31 $posts_default = array(
32 'platform' => Platform::getName()
33 );
34
35 $posts = $posts + $posts_default;
36
37 if ($returnUrl) {
38 return $api . '?' . http_build_query($posts, '', '&');
39 }
40
41 if (!isset($data)) {
42 if (function_exists('curl_init') && function_exists('curl_exec') && Settings::get('curl', 1)) {
43 $ch = curl_init();
44 curl_setopt($ch, CURLOPT_URL, $api);
45
46 curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($posts, '', '&'));
47 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
48 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
49 curl_setopt($ch, CURLOPT_TIMEOUT, 30);
50 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');
51 curl_setopt($ch, CURLOPT_REFERER, $_SERVER['REQUEST_URI']);
52 $proxy = new WP_HTTP_Proxy();
53
54 if ($proxy->is_enabled() && $proxy->send_through_proxy($api)) {
55
56 curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
57
58 curl_setopt($ch, CURLOPT_PROXY, $proxy->host());
59
60 curl_setopt($ch, CURLOPT_PROXYPORT, $proxy->port());
61
62
63 if ($proxy->use_authentication()) {
64
65 curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
66
67 curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxy->authentication());
68 }
69 }
70
71
72 if (Settings::get('curl-clean-proxy', 0)) {
73 curl_setopt($ch, CURLOPT_PROXY, '');
74 }
75 $data = curl_exec($ch);
76 $errorNumber = curl_errno($ch);
77 if ($errorNumber == 60 || $errorNumber == 77) {
78 curl_setopt($ch, CURLOPT_CAINFO, HttpClient::getCacertPath());
79 $data = curl_exec($ch);
80 }
81 $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
82 $error = curl_error($ch);
83 $curlErrorNumber = curl_errno($ch);
84 curl_close($ch);
85
86 if ($curlErrorNumber) {
87 $href = ApplicationSmartSlider3::getInstance()
88 ->getApplicationTypeAdmin()
89 ->getUrlHelpCurl();
90 Notification::error(Html::tag('a', array(
91 'href' => $href . '#support-form'
92 ), n2_('Debug error')));
93
94 Notification::error($curlErrorNumber . $error);
95
96 return array(
97 'status' => 'ERROR_HANDLED'
98 );
99 }
100 } else {
101 $opts = array(
102 'http' => array(
103 'method' => 'POST',
104 'header' => 'Content-type: application/x-www-form-urlencoded',
105 'content' => http_build_query($posts, '', '&')
106 )
107 );
108 $context = stream_context_create($opts);
109 $data = file_get_contents($api, false, $context);
110 if ($data === false) {
111 Notification::error(n2_('CURL disabled in your php.ini configuration. Please enable it!'));
112
113 return array(
114 'status' => 'ERROR_HANDLED'
115 );
116 }
117 $headers = self::parseHeaders($http_response_header);
118 if ($headers['status'] != '200') {
119 Notification::error(n2_('Unable to contact with the licensing server, please try again later!'));
120
121 return array(
122 'status' => 'ERROR_HANDLED'
123 );
124 }
125 if (isset($headers['content-type'])) {
126 $contentType = $headers['content-type'];
127 }
128 }
129 }
130
131 switch ($contentType) {
132 case 'text/html; charset=UTF-8':
133
134 Notification::error(sprintf('Unexpected response from the API.<br>Contact us (support@nextendweb.com) with the following log:') . '<br><textarea style="width: 100%;height:200px;font-size:8px;">' . Base64::encode($data) . '</textarea>');
135
136 return array(
137 'status' => 'ERROR_HANDLED'
138 );
139 break;
140 case 'application/json':
141 return json_decode($data, true);
142 }
143
144 return $data;
145 }
146
147 private static function parseHeaders(array $headers, $header = null) {
148 $output = array();
149 if ('HTTP' === substr($headers[0], 0, 4)) {
150 list(, $output['status'], $output['status_text']) = explode(' ', $headers[0]);
151 unset($headers[0]);
152 }
153 foreach ($headers as $v) {
154 $h = preg_split('/:\s*/', $v);
155 if (count($h) >= 2) {
156 $output[strtolower($h[0])] = $h[1];
157 }
158 }
159 if (null !== $header) {
160 if (isset($output[strtolower($header)])) {
161 return $output[strtolower($header)];
162 }
163
164 return null;
165 }
166
167 return $output;
168 }
169 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Application;
5
6 use Nextend\Framework\Pattern\SingletonTrait;
7 use Nextend\Framework\Plugin;
8
9 abstract class AbstractApplication {
10
11 use SingletonTrait;
12
13 protected $key = '';
14
15 protected function init() {
16
17 //PluggableApplication\Nextend\SmartSlider3\Application\ApplicationSmartSlider3
18 Plugin::doAction('PluggableApplication\\' . get_class($this), array($this));
19 }
20
21 public function getKey() {
22 return $this->key;
23 }
24
25 public function enqueueAssets() {
26
27 }
28 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Application;
5
6
7 use Exception;
8 use Nextend\Framework\Controller\AbstractController;
9 use Nextend\Framework\Pattern\GetAssetsPathTrait;
10 use Nextend\Framework\Pattern\MVCHelperTrait;
11 use Nextend\Framework\Plugin;
12 use Nextend\Framework\Request\Request;
13 use Nextend\Framework\ResourceTranslator\ResourceTranslator;
14 use Nextend\Framework\Router\Router;
15 use Nextend\Framework\View\AbstractLayout;
16
17 abstract class AbstractApplicationType {
18
19 use GetAssetsPathTrait, MVCHelperTrait;
20
21 /** @var AbstractApplication */
22 protected $application;
23
24 /** @var Router */
25 protected $router;
26
27 protected $key = '';
28
29 /** @var AbstractLayout */
30 protected $layout;
31
32 protected $externalControllers = array();
33
34 /**
35 * AbstractApplicationType constructor.
36 *
37 * @param AbstractApplication $application
38 *
39 * @throws Exception
40 */
41 public function __construct($application) {
42
43 $this->setMVCHelper($this);
44
45 $this->application = $application;
46
47 ResourceTranslator::createResource('$' . $this->getKey() . '$', self::getAssetsPath(), self::getAssetsUri());
48
49 $this->createRouter();
50
51
52 //PluggableApplicationType\Nextend\SmartSlider3\Application\Admin\ApplicationTypeAdmin
53 Plugin::doAction('PluggableApplicationType\\' . get_class($this), array($this));
54 }
55
56 public function getKey() {
57 return $this->application->getKey() . '-' . $this->key;
58 }
59
60 protected function createRouter() {
61
62 }
63
64 public function processRequest($defaultControllerName, $defaultActionName, $ajax = false, $args = array()) {
65
66 $controllerName = trim(Request::$REQUEST->getCmd("nextendcontroller"));
67 if (empty($controllerName)) {
68 $controllerName = $defaultControllerName;
69 }
70
71 $actionName = trim(Request::$REQUEST->getCmd("nextendaction"));
72 if (empty($actionName)) {
73 $actionName = $defaultActionName;
74 }
75
76 $this->process($controllerName, $actionName, $ajax, $args);
77 }
78
79 public function process($controllerName, $actionName, $ajax = false, $args = array()) {
80
81 if ($ajax) {
82 Request::$isAjax = true;
83 }
84
85 /** @var AbstractController $controller */
86 $controller = $this->getController($controllerName, $ajax);
87
88 $controller->doAction($actionName, $args);
89
90 }
91
92 /**
93 * @param $controllerName
94 * @param bool $ajax
95 *
96 * @return AbstractController
97 */
98 protected function getController($controllerName, $ajax = false) {
99
100 $methodName = 'getController' . ($ajax ? 'Ajax' : '') . $controllerName;
101
102 if (method_exists($this, $methodName)) {
103
104 return call_user_func(array(
105 $this,
106 $methodName
107 ));
108 } else if (isset($this->externalControllers[$controllerName])) {
109
110 return call_user_func(array(
111 $this->externalControllers[$controllerName],
112 $methodName
113 ));
114 }
115
116 return $this->getDefaultController($controllerName, $ajax);
117 }
118
119 protected abstract function getDefaultController($controllerName, $ajax = false);
120
121 public function getApplication() {
122
123 return $this->application;
124 }
125
126 public function getApplicationType() {
127 return $this;
128 }
129
130 /**
131 * @return Router
132 */
133 public function getRouter() {
134 return $this->router;
135 }
136
137 public function enqueueAssets() {
138
139 $this->application->enqueueAssets();
140 }
141
142 /**
143 * @param AbstractLayout $layout
144 */
145 public function setLayout($layout) {
146 $this->layout = $layout;
147 }
148
149 public function addExternalController($name, $source) {
150
151 $this->externalControllers[$name] = $source;
152 }
153
154 public function getLogo() {
155
156 return file_get_contents(self::getAssetsPath() . '/images/logo.svg');
157 }
158 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset;
4
5 use Nextend\Framework\Misc\Base64;
6
7 class AbstractAsset {
8
9 /**
10 * @var AbstractCache
11 */
12 protected $cache;
13
14 protected $files = array();
15 protected $urls = array();
16 protected $codes = array();
17 protected $globalInline = array();
18 protected $firstCodes = array();
19 protected $inline = array();
20 protected $staticGroupPreload = array();
21 protected $staticGroup = array();
22
23 protected $groups = array();
24
25 public function addFile($pathToFile, $group) {
26 $this->addGroup($group);
27 $this->files[$group][] = $pathToFile;
28 }
29
30 public function addFiles($path, $files, $group) {
31 $this->addGroup($group);
32 foreach ($files as $file) {
33 $this->files[$group][] = $path . DIRECTORY_SEPARATOR . $file;
34 }
35 }
36
37 public function addStaticGroupPreload($file, $group) {
38 $this->staticGroupPreload[$group] = $file;
39 }
40
41 public function addStaticGroup($file, $group) {
42 $this->staticGroup[$group] = $file;
43 }
44
45 private function addGroup($group) {
46 if (!isset($this->files[$group])) {
47 $this->files[$group] = array();
48 }
49 }
50
51 public function addCode($code, $group, $unshift = false) {
52 if (!isset($this->codes[$group])) {
53 $this->codes[$group] = array();
54 }
55 if (!$unshift) {
56 $this->codes[$group][] = $code;
57 } else {
58 array_unshift($this->codes[$group], $code);
59 }
60 }
61
62 public function addUrl($url) {
63 $this->urls[] = $url;
64 }
65
66 public function addFirstCode($code, $unshift = false) {
67 if ($unshift) {
68 array_unshift($this->firstCodes, $code);
69 } else {
70 $this->firstCodes[] = $code;
71 }
72 }
73
74 public function addInline($code, $name = null, $unshift = false) {
75 if ($unshift) {
76 array_unshift($this->inline, $code);
77
78 } else {
79 if ($name) {
80 $this->inline[$name] = $code;
81 } else {
82 $this->inline[] = $code;
83 }
84 }
85 }
86
87 public function addGlobalInline($code, $unshift = false) {
88 if ($unshift) {
89 array_unshift($this->globalInline, $code);
90 } else {
91 $this->globalInline[] = $code;
92 }
93 }
94
95 public function loadedFilesEncoded() {
96 return Base64::encode(json_encode(call_user_func_array('array_merge', $this->files) + $this->urls));
97 }
98
99 protected function uniqueFiles() {
100 foreach ($this->files as $group => &$files) {
101 $this->files[$group] = array_values(array_unique($files));
102 }
103 $this->initGroups();
104 }
105
106 public function removeFiles($notNeededFiles) {
107 foreach ($this->files as $group => &$files) {
108 $this->files[$group] = array_diff($files, $notNeededFiles);
109 }
110 }
111
112 public function initGroups() {
113 $this->groups = array_unique(array_merge(array_keys($this->files), array_keys($this->codes)));
114
115 $skeleton = array_map(array(
116 AbstractAsset::class,
117 'emptyArray'
118 ), array_flip($this->groups));
119
120 $this->files += $skeleton;
121 $this->codes += $skeleton;
122 }
123
124 private static function emptyArray() {
125 return array();
126 }
127
128 public function getFiles() {
129 $this->uniqueFiles();
130
131 $files = array();
132
133 if (AssetManager::$cacheAll) {
134 foreach ($this->groups as $group) {
135 if (isset($this->staticGroup[$group])) continue;
136 $files[$group] = $this->cache->getAssetFile($group, $this->files[$group], $this->codes[$group]);
137 }
138 } else {
139 foreach ($this->groups as $group) {
140 if (isset($this->staticGroup[$group])) continue;
141 if (in_array($group, AssetManager::$cachedGroups)) {
142 $files[$group] = $this->cache->getAssetFile($group, $this->files[$group], $this->codes[$group]);
143 } else {
144 foreach ($this->files[$group] as $file) {
145 $files[] = $file;
146 }
147 foreach ($this->codes[$group] as $code) {
148 array_unshift($this->inline, $code);
149 }
150 }
151 }
152 }
153
154 if (isset($files['n2'])) {
155 return array('n2' => $files['n2']) + $this->staticGroup + $files;
156 }
157
158 return array_merge($files, $this->staticGroup);
159 }
160
161 public function serialize() {
162 return array(
163 'staticGroupPreload' => $this->staticGroupPreload,
164 'staticGroup' => $this->staticGroup,
165 'files' => $this->files,
166 'urls' => $this->urls,
167 'codes' => $this->codes,
168 'firstCodes' => $this->firstCodes,
169 'inline' => $this->inline,
170 'globalInline' => $this->globalInline
171 );
172 }
173
174 public function unSerialize($array) {
175 $this->staticGroupPreload = array_merge($this->staticGroupPreload, $array['staticGroupPreload']);
176 $this->staticGroup = array_merge($this->staticGroup, $array['staticGroup']);
177
178 foreach ($array['files'] as $group => $files) {
179 if (!isset($this->files[$group])) {
180 $this->files[$group] = $files;
181 } else {
182 $this->files[$group] = array_merge($this->files[$group], $files);
183 }
184 }
185 $this->urls = array_merge($this->urls, $array['urls']);
186
187 foreach ($array['codes'] as $group => $codes) {
188 if (!isset($this->codes[$group])) {
189 $this->codes[$group] = $codes;
190 } else {
191 $this->codes[$group] = array_merge($this->codes[$group], $codes);
192 }
193 }
194
195 $this->firstCodes = array_merge($this->firstCodes, $array['firstCodes']);
196 $this->inline = array_merge($this->inline, $array['inline']);
197 $this->globalInline = array_merge($this->globalInline, $array['globalInline']);
198 }
199 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset;
4
5 use Nextend\Framework\Cache\Manifest;
6 use Nextend\Framework\Filesystem\Filesystem;
7
8 abstract class AbstractCache {
9
10 public $outputFileType;
11
12 protected $group, $files, $codes;
13
14 public function getAssetFile($group, &$files = array(), &$codes = array()) {
15 $this->group = $group;
16 $this->files = $files;
17 $this->codes = $codes;
18
19 $cache = new Manifest($group, true, true);
20 $hash = $this->getHash();
21
22 return $cache->makeCache($group . "." . $this->outputFileType, $hash, array(
23 $this,
24 'getCachedContent'
25 ));
26 }
27
28 protected function getHash() {
29 $hash = '';
30 foreach ($this->files as $file) {
31 $hash .= $this->makeFileHash($file);
32 }
33 foreach ($this->codes as $code) {
34 $hash .= $code;
35 }
36
37 return md5($hash);
38 }
39
40 protected function getCacheFileName() {
41 $hash = '';
42 foreach ($this->files as $file) {
43 $hash .= $this->makeFileHash($file);
44 }
45 foreach ($this->codes as $code) {
46 $hash .= $code;
47 }
48
49 return md5($hash) . "." . $this->outputFileType;
50 }
51
52 /**
53 * @param Manifest $cache
54 *
55 * @return string
56 */
57 public function getCachedContent($cache) {
58 $fileContents = '';
59 foreach ($this->files as $file) {
60 $fileContents .= $this->parseFile($cache, Filesystem::readFile($file), $file) . "\n";
61 }
62
63 foreach ($this->codes as $code) {
64 $fileContents .= $code . "\n";
65 }
66
67 return $fileContents;
68 }
69
70 protected function makeFileHash($file) {
71 return $file . filemtime($file);
72 }
73
74 /**
75 * @param Manifest $cache
76 * @param $content
77 * @param $originalFilePath
78 *
79 * @return mixed
80 */
81 protected function parseFile($cache, $content, $originalFilePath) {
82 return $content;
83 }
84
85 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset;
4
5 use Nextend\Framework\Data\Data;
6 use Nextend\Framework\PageFlow;
7 use Nextend\Framework\Plugin;
8 use Nextend\Framework\View\Html;
9
10 /**
11 * Class Manager
12 *
13 */
14 class AssetManager {
15
16 /**
17 * Helper to safely store AssetManager related optimization data
18 *
19 * @var Data
20 */
21 public static $stateStorage;
22
23 /**
24 * @var CSS\Asset
25 */
26 public static $css;
27
28 private static $cssStack = array();
29
30 /**
31 * @var Css\Less\Asset
32 */
33 public static $less;
34
35 private static $lessStack = array();
36
37 /**
38 * @var Js\Asset
39 */
40 public static $js;
41
42 private static $jsStack = array();
43
44 /**
45 * @var Fonts\Google\Asset
46 */
47 public static $googleFonts;
48
49 /**
50 * @var Image\Asset
51 */
52 public static $image;
53
54 private static $imageStack = array();
55
56 private static $googleFontsStack = array();
57
58 public static $cacheAll = true;
59
60 public static $cachedGroups = array();
61
62 public static function getInstance() {
63 static $instance = null;
64 if (null === $instance) {
65 $instance = new self();
66 self::createStack();
67
68 Plugin::doAction('n2_assets_manager_started');
69 }
70
71 return $instance;
72 }
73
74 public static function createStack() {
75
76 self::$stateStorage = new Data();
77
78 self::$css = new Css\Asset();
79 array_unshift(self::$cssStack, self::$css);
80
81 self::$less = new Css\Less\Asset();
82 array_unshift(self::$lessStack, self::$less);
83
84 self::$js = new Js\Asset();
85 array_unshift(self::$jsStack, self::$js);
86
87 self::$googleFonts = new Fonts\Google\Asset();
88 array_unshift(self::$googleFontsStack, self::$googleFonts);
89
90 self::$image = new Image\Asset();
91 array_unshift(self::$imageStack, self::$image);
92 }
93
94 public static function removeStack() {
95 if (count(self::$cssStack) > 0) {
96
97 self::$stateStorage = new Data();
98
99 /**
100 * @var $previousCSS Css\Asset
101 * @var $previousLESS Css\Less\Asset
102 * @var $previousJS Js\Asset
103 * @var $previousGoogleFons Fonts\Google\Asset
104 * @var $previousImage Image\Asset
105 */
106 $previousCSS = array_shift(self::$cssStack);
107 self::$css = self::$cssStack[0];
108
109 $previousLESS = array_shift(self::$lessStack);
110 self::$less = self::$lessStack[0];
111
112 $previousJS = array_shift(self::$jsStack);
113 self::$js = self::$jsStack[0];
114
115 $previousGoogleFons = array_shift(self::$googleFontsStack);
116 self::$googleFonts = self::$googleFontsStack[0];
117
118 $previousImage = array_shift(self::$imageStack);
119 self::$image = self::$imageStack[0];
120
121 return array(
122 'css' => $previousCSS->serialize(),
123 'less' => $previousLESS->serialize(),
124 'js' => $previousJS->serialize(),
125 'googleFonts' => $previousGoogleFons->serialize(),
126 'image' => $previousImage->serialize()
127 );
128 }
129
130 echo "Too much remove stack on the asset manager...";
131 PageFlow::exitApplication();
132
133 }
134
135 public static function enableCacheAll() {
136 self::$cacheAll = true;
137 }
138
139 public static function disableCacheAll() {
140 self::$cacheAll = false;
141 }
142
143 public static function addCachedGroup($group) {
144 if (!in_array($group, self::$cachedGroups)) {
145 self::$cachedGroups[] = $group;
146 }
147 }
148
149 public static function loadFromArray($array) {
150
151 self::$css->unSerialize($array['css']);
152 self::$less->unSerialize($array['less']);
153 self::$js->unSerialize($array['js']);
154 self::$googleFonts->unSerialize($array['googleFonts']);
155 self::$image->unSerialize($array['image']);
156 }
157
158 public static function getCSS($path = false) {
159 if (self::$css) {
160 if ($path) {
161 return self::$css->get();
162 }
163
164 return self::$css->getOutput();
165 }
166
167 return '';
168 }
169
170 public static function getJs($path = false) {
171 if (self::$js) {
172 if ($path) {
173 return self::$js->get();
174 }
175
176 return self::$js->getOutput();
177 }
178
179 return '';
180 }
181
182 public static function generateAjaxCSS() {
183
184 return Html::style(self::$css->getAjaxOutput());
185 }
186
187
188 public static function generateAjaxJS() {
189
190 return self::$js->getAjaxOutput();
191 }
192
193 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset\Css;
4
5 use Nextend\Framework\Asset\AbstractAsset;
6 use Nextend\Framework\Asset\Fonts\Google\Google;
7 use Nextend\Framework\Platform\Platform;
8 use Nextend\Framework\Plugin;
9 use Nextend\Framework\Settings;
10 use Nextend\Framework\Url\Url;
11 use Nextend\Framework\View\Html;
12 use Nextend\SmartSlider3\SmartSlider3Info;
13
14 class Asset extends AbstractAsset {
15
16
17 public function __construct() {
18 $this->cache = new Cache();
19 }
20
21 public function getOutput() {
22
23 $headerPreload = !!Settings::get('header-preload', '0');
24
25 $needProtocol = !Settings::get('protocol-relative', '1');
26
27 Google::build();
28
29 Less\Less::build();
30
31 $output = "";
32
33 $this->urls = array_unique($this->urls);
34
35
36 foreach ($this->staticGroupPreload as $file) {
37 $url = $this->filterSrc(Url::pathToUri($file, $needProtocol) . '?ver=' . SmartSlider3Info::$revisionShort);
38 $output .= Html::style($url, true, array(
39 'media' => 'all'
40 )) . "\n";
41 if ($headerPreload) {
42 header('Link: <' . $url . '>; rel=preload; as=style', false);
43 }
44 }
45
46 $linkAttributes = array(
47 'media' => 'all'
48 );
49
50 if (!Platform::isAdmin() && Settings::get('async-non-primary-css', 0)) {
51 $linkAttributes = array(
52 'media' => 'print',
53 'onload' => "this.media='all'"
54 );
55 }
56
57 foreach ($this->urls as $url) {
58
59 $url = $this->filterSrc($url);
60
61 $output .= Html::style($url, true, $linkAttributes) . "\n";
62 }
63
64 foreach ($this->getFiles() as $file) {
65 if (substr($file, 0, 2) == '//') {
66 $url = $this->filterSrc($file);
67 } else {
68 $url = $this->filterSrc(Url::pathToUri($file, $needProtocol) . '?ver=' . SmartSlider3Info::$revisionShort);
69 }
70 $output .= Html::style($url, true, $linkAttributes) . "\n";
71 }
72
73 $inlineText = '';
74 foreach ($this->inline as $key => $value) {
75 if (!is_numeric($key)) {
76 $output .= Html::style($value, false, array(
77 'data-related' => $key
78 )) . "\n";
79 } else {
80 $inlineText .= $value;
81 }
82 }
83
84 if (!empty($inlineText)) {
85 $output .= Html::style($inlineText) . "\n";
86 }
87
88 return $output;
89 }
90
91 private function filterSrc($src) {
92 return Plugin::applyFilters('n2_style_loader_src', $src);
93 }
94
95 public function get() {
96 Google::build();
97 Less\Less::build();
98
99 return array(
100 'url' => $this->urls,
101 'files' => array_merge($this->staticGroupPreload, $this->getFiles()),
102 'inline' => implode("\n", $this->inline)
103 );
104 }
105
106 public function getAjaxOutput() {
107
108 $output = implode("\n", $this->inline);
109
110 return $output;
111 }
112 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset\Css;
4
5 use Nextend\Framework\Asset\AbstractCache;
6 use Nextend\Framework\Filesystem\Filesystem;
7 use Nextend\Framework\Url\Url;
8
9 class Cache extends AbstractCache {
10
11 public $outputFileType = "css";
12
13 private $baseUrl = '';
14
15 private $basePath = '';
16
17 public function getAssetFileFolder() {
18 return Filesystem::getWebCachePath() . DIRECTORY_SEPARATOR . $this->group . DIRECTORY_SEPARATOR;
19 }
20
21 protected function parseFile($cache, $content, $originalFilePath) {
22
23 $this->basePath = dirname($originalFilePath);
24 $this->baseUrl = Filesystem::pathToAbsoluteURL($this->basePath);
25
26 return preg_replace_callback('#url\([\'"]?([^"\'\)]+)[\'"]?\)#', array(
27 $this,
28 'makeAbsoluteUrl'
29 ), $content);
30 }
31
32 private function makeAbsoluteUrl($matches) {
33 if (substr($matches[1], 0, 5) == 'data:') return $matches[0];
34 if (substr($matches[1], 0, 4) == 'http') return $matches[0];
35 if (substr($matches[1], 0, 2) == '//') return $matches[0];
36
37 $exploded = explode('?', $matches[1]);
38
39 $realPath = realpath($this->basePath . '/' . $exploded[0]);
40 if ($realPath === false) {
41 return 'url(' . str_replace(array(
42 'http://',
43 'https://'
44 ), '//', $this->baseUrl) . '/' . $matches[1] . ')';
45 }
46
47 $realPath = Filesystem::convertToRealDirectorySeparator($realPath);
48
49 return 'url(' . Url::pathToUri($realPath, false) . (isset($exploded[1]) ? '?' . $exploded[1] : '') . ')';
50 }
51 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset\Css;
4
5 use Nextend\Framework\Asset\AssetManager;
6
7 class Css {
8
9 public static function addFile($pathToFile, $group) {
10 AssetManager::$css->addFile($pathToFile, $group);
11 }
12
13 public static function addFiles($path, $files, $group) {
14 AssetManager::$css->addFiles($path, $files, $group);
15 }
16
17 public static function addStaticGroupPreload($file, $group) {
18 AssetManager::$css->addStaticGroupPreload($file, $group);
19 }
20
21 public static function addStaticGroup($file, $group) {
22 AssetManager::$css->addStaticGroup($file, $group);
23 }
24
25 public static function addCode($code, $group, $unshift = false) {
26 AssetManager::$css->addCode($code, $group, $unshift);
27 }
28
29 public static function addUrl($url) {
30 AssetManager::$css->addUrl($url);
31 }
32
33 public static function addInline($code, $name = null) {
34 AssetManager::$css->addInline($code, $name);
35 }
36 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset\Css\Less;
4
5 use Nextend\Framework\Asset\AbstractAsset;
6
7 class Asset extends AbstractAsset {
8
9 public function __construct() {
10 $this->cache = new Cache();
11 }
12
13 protected function uniqueFiles() {
14 $this->initGroups();
15 }
16
17 public function getFiles() {
18 $this->uniqueFiles();
19
20 $files = array();
21 foreach ($this->groups as $group) {
22 $files[$group] = $this->cache->getAssetFile($group, $this->files[$group], $this->codes[$group]);
23 }
24
25 return $files;
26 }
27 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset\Css\Less;
4
5 use Exception;
6 use Nextend\Framework\Cache\Manifest;
7
8 class Cache extends \Nextend\Framework\Asset\Css\Cache {
9
10
11 public $outputFileType = "less.css";
12
13 public function getAssetFile($group, &$files = array(), &$codes = array()) {
14 $this->group = $group;
15 $this->files = $files;
16 $this->codes = $codes;
17
18 $cache = new Manifest($group, false, true);
19 $hash = $this->getHash();
20
21 return $cache->makeCache($group . "." . $this->outputFileType, $hash, array(
22 $this,
23 'getCachedContent'
24 ));
25 }
26
27 /**
28 * @param Manifest $cache
29 *
30 * @return string
31 * @throws Exception
32 */
33 public function getCachedContent($cache) {
34
35 $fileContents = '';
36
37 foreach ($this->files as $parameters) {
38 $compiler = new LessCompiler();
39
40 if (!empty($parameters['importDir'])) {
41 $compiler->addImportDir($parameters['importDir']);
42 }
43
44 $compiler->setVariables($parameters['context']);
45 $fileContents .= $compiler->compileFile($parameters['file']);
46 }
47
48 return $fileContents;
49 }
50
51 protected function makeFileHash($parameters) {
52 return json_encode($parameters) . filemtime($parameters['file']);
53 }
54
55 protected function parseFile($cache, $content, $lessParameters) {
56
57 return parent::parseFile($cache, $content, $lessParameters['file']);
58 }
59 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Asset\Css\Less\Formatter;
5
6
7 class Classic {
8
9 public $indentChar = " ";
10
11 public $break = "\n";
12 public $open = " {";
13 public $close = "}";
14 public $selectorSeparator = ", ";
15 public $assignSeparator = ":";
16
17 public $openSingle = " { ";
18 public $closeSingle = " }";
19
20 public $disableSingle = false;
21 public $breakSelectors = false;
22
23 public $compressColors = false;
24
25 public function __construct() {
26 $this->indentLevel = 0;
27 }
28
29 public function indentStr($n = 0) {
30 return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
31 }
32
33 public function property($name, $value) {
34 return $name . $this->assignSeparator . $value . ";";
35 }
36
37 protected function isEmpty($block) {
38 if (empty($block->lines)) {
39 foreach ($block->children as $child) {
40 if (!$this->isEmpty($child)) return false;
41 }
42
43 return true;
44 }
45
46 return false;
47 }
48
49 public function block($block) {
50 $ret = '';
51 if ($this->isEmpty($block)) return $ret;
52
53 $inner = $pre = $this->indentStr();
54
55 $isSingle = !$this->disableSingle && is_null($block->type) && count($block->lines) == 1;
56
57 if (!empty($block->selectors)) {
58 $this->indentLevel++;
59
60 if ($this->breakSelectors) {
61 $selectorSeparator = $this->selectorSeparator . $this->break . $pre;
62 } else {
63 $selectorSeparator = $this->selectorSeparator;
64 }
65
66 $ret .= $pre . implode($selectorSeparator, $block->selectors);
67 if ($isSingle) {
68 $ret .= $this->openSingle;
69 $inner = "";
70 } else {
71 $ret .= $this->open . $this->break;
72 $inner = $this->indentStr();
73 }
74
75 }
76
77 if (!empty($block->lines)) {
78 $glue = $this->break . $inner;
79 $ret .= $inner . implode($glue, $block->lines);
80 if (!$isSingle && !empty($block->children)) {
81 $ret .= $this->break;
82 }
83 }
84
85 foreach ($block->children as $child) {
86 $ret .= $this->block($child);
87 }
88
89 if (!empty($block->selectors)) {
90 if (!$isSingle && empty($block->children)) $ret .= $this->break;
91
92 if ($isSingle) {
93 $ret .= $this->closeSingle . $this->break;
94 } else {
95 $ret .= $pre . $this->close . $this->break;
96 }
97
98 $this->indentLevel--;
99 }
100
101 return $ret;
102 }
103 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Asset\Css\Less\Formatter;
5
6
7 class Compressed extends Classic {
8
9 public $disableSingle = true;
10 public $open = "{";
11 public $selectorSeparator = ",";
12 public $assignSeparator = ":";
13 public $break = "";
14 public $compressColors = true;
15
16 public function indentStr($n = 0) {
17 return "";
18 }
19 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Asset\Css\Less\Formatter;
5
6
7 class Debug extends Classic {
8
9 public $disableSingle = true;
10 public $breakSelectors = true;
11 public $assignSeparator = ": ";
12 public $selectorSeparator = ",";
13 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Asset\Css\Less;
5
6
7 use Nextend\Framework\Asset\AssetManager;
8 use Nextend\Framework\Asset\Css\Css;
9
10 class Less {
11
12 public static function addFile($pathToFile, $group, $context = array(), $importDir = null) {
13 AssetManager::$less->addFile(array(
14 'file' => $pathToFile,
15 'context' => $context,
16 'importDir' => $importDir
17 ), $group);
18 }
19
20 public static function build() {
21 foreach (AssetManager::$less->getFiles() as $group => $file) {
22 if (substr($file, 0, 2) == '//') {
23 Css::addUrl($file);
24 } else if (!realpath($file)) {
25 // For database cache the $file contains the content of the generated CSS file
26 Css::addCode($file, $group, true);
27 } else {
28 Css::addFile($file, $group);
29 }
30 }
31 }
32 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Asset\Fonts\Google;
5
6
7 use Nextend\Framework\Asset\AbstractAsset;
8 use Nextend\Framework\Asset\Css\Css;
9 use Nextend\Framework\Url\UrlHelper;
10
11 class Asset extends AbstractAsset {
12
13 public function getLoadedFamilies() {
14 return array_keys($this->files);
15 }
16
17 function addFont($family, $style = '400') {
18 $style = (string)$style;
19 if (!isset($this->files[$family])) {
20 $this->files[$family] = array();
21 }
22 if (!in_array($style, $this->files[$family])) {
23 $this->files[$family][] = $style;
24 }
25 }
26
27 public function loadFonts() {
28
29 if (!empty($this->files)) {
30 //https://fonts.googleapis.com/css?display=swap&family=Montserrat:400%7CRoboto:100italic,300,400
31
32 $families = array();
33 foreach ($this->files as $name => $styles) {
34 if (count($styles) && !in_array($name, Google::$excludedFamilies)) {
35 $families[] = $name . ':' . implode(',', $styles);
36 }
37 }
38
39 if (count($families)) {
40 $params = array(
41 'display' => 'swap',
42 'family' => urlencode(implode('|', $families))
43 );
44
45 Css::addUrl(UrlHelper::add_query_arg($params, 'https://fonts.googleapis.com/css'));
46 }
47
48 }
49
50 return true;
51 }
52 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Asset\Fonts\Google;
5
6
7 use Nextend\Framework\Asset\AssetManager;
8
9 class Google {
10
11 public static $enabled = false;
12
13 public static $excludedFamilies = array();
14
15 public static function addFont($family, $style = '400') {
16 AssetManager::$googleFonts->addFont($family, $style);
17 }
18
19 public static function addFontExclude($family) {
20 self::$excludedFamilies[] = $family;
21 }
22
23 public static function build() {
24 if (self::$enabled) {
25 AssetManager::$googleFonts->loadFonts();
26 }
27 }
28 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset\Image;
4
5 class Asset {
6
7 protected $images = array();
8
9 public function add($images) {
10 if (!is_array($images)) {
11 $images = array($images);
12 }
13
14 $this->images = array_unique(array_merge($this->images, $images));
15 }
16
17 public function get() {
18 return $this->images;
19 }
20
21 public function match($url) {
22 return in_array($url, $this->images);
23 }
24
25 public function serialize() {
26 return array(
27 'images' => $this->images
28 );
29 }
30
31 public function unSerialize($array) {
32 if (!empty($array['images'])) {
33 $this->add($array['images']);
34 }
35 }
36 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Asset\Js;
5
6 use Nextend\Framework\Asset\AbstractAsset;
7 use Nextend\Framework\Localization\Localization;
8 use Nextend\Framework\Platform\Platform;
9 use Nextend\Framework\Plugin;
10 use Nextend\Framework\Settings;
11 use Nextend\Framework\Url\Url;
12 use Nextend\Framework\View\Html;
13 use Nextend\SmartSlider3\SmartSlider3Info;
14
15 class Asset extends AbstractAsset {
16
17 public function __construct() {
18 $this->cache = new Cache();
19 }
20
21 public function getOutput() {
22
23 $output = "";
24
25 $needProtocol = !Settings::get('protocol-relative', '1');
26
27 $globalInline = $this->getGlobalInlineScripts();
28 if (!empty($globalInline)) {
29 $output .= Html::script(self::minify_js($globalInline . "\n"));
30 }
31
32 $async = !Platform::isAdmin();
33 $scriptAttributes = array();
34 if ($async) {
35 $scriptAttributes['defer'] = 1;
36 $scriptAttributes['async'] = 1;
37 }
38
39 foreach ($this->urls as $url) {
40 $output .= Html::scriptFile($this->filterSrc($url), $scriptAttributes) . "\n";
41 }
42
43 foreach ($this->getFiles() as $file) {
44 if (substr($file, 0, 2) == '//') {
45 $output .= Html::scriptFile($this->filterSrc($file), $scriptAttributes) . "\n";
46 } else {
47 $output .= Html::scriptFile($this->filterSrc(Url::pathToUri($file, $needProtocol) . '?ver=' . SmartSlider3Info::$revisionShort), $scriptAttributes) . "\n";
48 }
49 }
50
51 $output .= Html::script(self::minify_js(Localization::toJS() . "\n" . $this->getInlineScripts() . "\n"));
52
53 return $output;
54 }
55
56 private function filterSrc($src) {
57 return Plugin::applyFilters('n2_script_loader_src', $src);
58 }
59
60 public function get() {
61 return array(
62 'url' => $this->urls,
63 'files' => $this->getFiles(),
64 'inline' => $this->getInlineScripts(),
65 'globalInline' => $this->getGlobalInlineScripts()
66 );
67 }
68
69 public function getAjaxOutput() {
70
71 $output = $this->getInlineScripts();
72
73 return $output;
74 }
75
76 private function getGlobalInlineScripts() {
77 return implode('', $this->globalInline);
78 }
79
80 private function getInlineScripts() {
81 $scripts = '';
82
83 foreach ($this->firstCodes as $script) {
84 $scripts .= $script . "\n";
85 }
86
87 foreach ($this->inline as $script) {
88 $scripts .= $script . "\n";
89 }
90
91 return $this->serveJquery($scripts);
92 }
93
94 public static function serveJquery($script) {
95 if (empty($script)) {
96 return "";
97 }
98 $inline = "_N2.r('documentReady', function(){\n";
99 $inline .= $script;
100 $inline .= "});\n";
101
102 return $inline;
103 }
104
105 public static function minify_js($input) {
106 if (trim($input) === "") return $input;
107
108 return preg_replace(array(
109 // Remove comment(s)
110 '#\s*("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')\s*|\s*\/\*(?!\!|@cc_on)(?>[\s\S]*?\*\/)\s*|\s*(?<![\:\=])\/\/.*(?=[\n\r]|$)|^\s*|\s*$#',
111 // Remove white-space(s) outside the string and regex
112 '#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/)|\/(?!\/)[^\n\r]*?\/(?=[\s.,;]|[gimuy]|$))|\s*([!%&*\(\)\-=+\[\]\{\}|;:,.<>?\/])\s*#s',
113 // Remove the last semicolon
114 '#;+\}#',
115 // Minify object attribute(s) except JSON attribute(s). From `{'foo':'bar'}` to `{foo:'bar'}`
116 '#([\{,])([\'])(\d+|[a-z_][a-z0-9_]*)\2(?=\:)#i',
117 // --ibid. From `foo['bar']` to `foo.bar`
118 '#([a-z0-9_\)\]])\[([\'"])([a-z_][a-z0-9_]*)\2\]#i'
119 ), array(
120 '$1',
121 '$1$2',
122 '}',
123 '$1$3',
124 '$1.$3'
125 ), $input);
126 }
127 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset\Js;
4
5 use Nextend\Framework\Asset\AbstractCache;
6 use Nextend\Framework\Cache\Manifest;
7
8 class Cache extends AbstractCache {
9
10 public $outputFileType = "js";
11
12 /**
13 * @param Manifest $cache
14 *
15 * @return string
16 */
17 public function getCachedContent($cache) {
18
19 $content = '(function(){this._N2=this._N2||{_r:[],_d:[],r:function(){this._r.push(arguments)},d:function(){this._d.push(arguments)}}}).call(window);';
20 $content .= parent::getCachedContent($cache);
21 $content .= "_N2.d('" . $this->group . "');";
22
23 return $content;
24 }
25 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset\Js;
4
5 use Nextend\Framework\Asset\AssetManager;
6 use Nextend\Framework\Filesystem\Filesystem;
7
8 class Js {
9
10 public static function addFile($pathToFile, $group) {
11 AssetManager::$js->addFile($pathToFile, $group);
12 }
13
14 public static function addFiles($path, $files, $group) {
15 AssetManager::$js->addFiles($path, $files, $group);
16 }
17
18 public static function addStaticGroup($file, $group) {
19 AssetManager::$js->addStaticGroup($file, $group);
20 }
21
22 public static function addCode($code, $group) {
23 AssetManager::$js->addCode($code, $group);
24 }
25
26 public static function addUrl($url) {
27 AssetManager::$js->addUrl($url);
28 }
29
30 public static function addFirstCode($code, $unshift = false) {
31 AssetManager::$js->addFirstCode($code, $unshift);
32 }
33
34 public static function addInline($code, $unshift = false) {
35 AssetManager::$js->addInline($code, null, $unshift);
36 }
37
38 public static function addGlobalInline($code, $unshift = false) {
39 AssetManager::$js->addGlobalInline($code, $unshift);
40 }
41
42 public static function addInlineFile($path, $unshift = false) {
43 static $loaded = array();
44 if (!isset($loaded[$path])) {
45 AssetManager::$js->addInline(Filesystem::readFile($path), null, $unshift);
46 $loaded[$path] = 1;
47 }
48 }
49
50 public static function addGlobalInlineFile($path, $unshift = false) {
51 static $loaded = array();
52 if (!isset($loaded[$path])) {
53 AssetManager::$js->addGlobalInline(Filesystem::readFile($path), $unshift);
54 $loaded[$path] = 1;
55 }
56 }
57
58 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Asset;
4
5
6 use JHtml;
7 use Nextend\Framework\Asset\Css\Css;
8 use Nextend\Framework\Asset\Fonts\Google\Google;
9 use Nextend\Framework\Asset\Js\Js;
10 use Nextend\Framework\Font\FontSources;
11 use Nextend\Framework\Form\Form;
12 use Nextend\Framework\Platform\Platform;
13 use Nextend\Framework\Plugin;
14 use Nextend\Framework\ResourceTranslator\ResourceTranslator;
15 use Nextend\SmartSlider3\Application\Frontend\ApplicationTypeFrontend;
16 use Nextend\SmartSlider3\Settings;
17
18 class Predefined {
19
20 public static function backend($force = false) {
21 static $once;
22 if ($once != null && !$force) {
23 return;
24 }
25 $once = true;
26 wp_enqueue_script('jquery');
27 $jQueryFallback = site_url('wp-includes/js/jquery/jquery.js');
28
29 Js::addGlobalInline('_N2._jQueryFallback=\'' . $jQueryFallback . '\';');
30
31 $family = n2_x('Montserrat', 'Default Google font family for admin');
32 Google::addFont($family);
33
34 Js::addFirstCode("_N2.r(['AjaxHelper'],function(){_N2.AjaxHelper.addAjaxArray(" . json_encode(Form::tokenizeUrl()) . ");});");
35
36 Plugin::addAction('afterApplicationContent', array(
37 FontSources::class,
38 'onFontManagerLoadBackend'
39 ));
40 }
41
42 public static function frontend($force = false) {
43 static $once;
44 if ($once != null && !$force) {
45 return;
46 }
47 $once = true;
48 AssetManager::getInstance();
49 if (Platform::isAdmin()) {
50 Js::addGlobalInline('window.N2GSAP=' . N2GSAP . ';');
51 Js::addGlobalInline('window.N2PLATFORM="' . Platform::getName() . '";');
52 }
53
54 Js::addGlobalInline('(function(){this._N2=this._N2||{_r:[],_d:[],r:function(){this._r.push(arguments)},d:function(){this._d.push(arguments)}}}).call(window);');
55
56 /*
57 * +1px needed for Safari to fix: https://bugs.webkit.org/show_bug.cgi?id=225962
58 (function(ua){
59 if(ua.indexOf('Safari') > 0 && ua.indexOf('Chrome') === -1){
60 document.documentElement.style.setProperty('--ss-safari-fix-225962', '1px');
61 }
62 })(navigator.userAgent);
63 */
64 Js::addGlobalInline('!function(a){a.indexOf("Safari")>0&&-1===a.indexOf("Chrome")&&document.documentElement.style.setProperty("--ss-safari-fix-225962","1px")}(navigator.userAgent);');
65
66 Js::addStaticGroup(ApplicationTypeFrontend::getAssetsPath() . "/dist/n2.min.js", 'n2');
67
68 FontSources::onFontManagerLoad($force);
69 }
70
71 public static function loadLiteBox() {
72 }
73 }
74
1 <?php
2
3
4 namespace Nextend\Framework\Browse\Block\BrowseManager;
5
6
7 use Nextend\Framework\Asset\Js\Js;
8 use Nextend\Framework\View\AbstractBlock;
9 use Nextend\SmartSlider3\Application\Admin\TraitAdminUrl;
10
11 class BlockBrowseManager extends AbstractBlock {
12
13 use TraitAdminUrl;
14
15 public function display() {
16
17 Js::addFirstCode("new _N2.NextendBrowse('" . $this->getAjaxUrlBrowse() . "', " . (defined('N2_IMAGE_UPLOAD_DISABLE') ? 0 : 1) . ");");
18 }
19 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Browse;
5
6
7 use Nextend\Framework\Browse\Block\BrowseManager\BlockBrowseManager;
8 use Nextend\Framework\Pattern\VisualManagerTrait;
9
10 class BrowseManager {
11
12 use VisualManagerTrait;
13
14 public function display() {
15
16 $fontManagerBlock = new BlockBrowseManager($this->MVCHelper);
17 $fontManagerBlock->display();
18 }
19
20 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Browse\BulletProof;
5
6
7 class Exception extends \Exception {
8
9 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Browse;
4
5 use Exception;
6 use Nextend\Framework\Browse\BulletProof\BulletProof;
7 use Nextend\Framework\Controller\Admin\AdminAjaxController;
8 use Nextend\Framework\Filesystem\Filesystem;
9 use Nextend\Framework\Image\Image;
10 use Nextend\Framework\Notification\Notification;
11 use Nextend\Framework\Request\Request;
12 use Nextend\Framework\ResourceTranslator\ResourceTranslator;
13
14 class ControllerAjaxBrowse extends AdminAjaxController {
15
16 public function actionIndex() {
17 $this->validateToken();
18 $root = Filesystem::convertToRealDirectorySeparator(Filesystem::getImagesFolder());
19 $path = Filesystem::realpath($root . '/' . ltrim(rtrim(Request::$REQUEST->getVar('path', ''), '/'), '/'));
20 if (strpos($path, $root) !== 0) {
21 $path = $root;
22 }
23 $_directories = glob($path . '/*', GLOB_ONLYDIR);
24 $directories = array();
25 for ($i = 0; $i < count($_directories); $i++) {
26 $directories[basename($_directories[$i])] = Filesystem::toLinux($this->relative($_directories[$i], $root));
27 }
28
29 $extensions = array(
30 'jpg',
31 'jpeg',
32 'png',
33 'gif',
34 'mp4',
35 'mp3',
36 'svg',
37 'webp'
38 );
39 $_files = scandir($path);
40 $files = array();
41 for ($i = 0; $i < count($_files); $i++) {
42 $_files[$i] = $path . DIRECTORY_SEPARATOR . $_files[$i];
43 $ext = strtolower(pathinfo($_files[$i], PATHINFO_EXTENSION));
44 if (self::check_utf8($_files[$i]) && in_array($ext, $extensions)) {
45 $files[basename($_files[$i])] = ResourceTranslator::urlToResource(Filesystem::pathToAbsoluteURL($_files[$i]));
46 }
47 }
48 $relativePath = Filesystem::toLinux($this->relative($path, $root));
49 if (!$relativePath) {
50 $relativePath = '';
51 }
52 $this->response->respond(array(
53 'fullPath' => $path,
54 'path' => $relativePath,
55 'directories' => (object)$directories,
56 'files' => (object)$files
57 ));
58 }
59
60 private static function check_utf8($str) {
61 $len = strlen($str);
62 for ($i = 0; $i < $len; $i++) {
63 $c = ord($str[$i]);
64 if ($c > 128) {
65 if (($c > 247)) return false; elseif ($c > 239) $bytes = 4;
66 elseif ($c > 223) $bytes = 3;
67 elseif ($c > 191) $bytes = 2;
68 else return false;
69 if (($i + $bytes) > $len) return false;
70 while ($bytes > 1) {
71 $i++;
72 $b = ord($str[$i]);
73 if ($b < 128 || $b > 191) return false;
74 $bytes--;
75 }
76 }
77 }
78
79 return true;
80 }
81
82 public function actionUpload() {
83 if (defined('N2_IMAGE_UPLOAD_DISABLE')) {
84 Notification::error(n2_('You are not allowed to upload!'));
85 $this->response->error();
86 }
87
88 $this->validateToken();
89
90 $root = Filesystem::getImagesFolder();
91 $folder = ltrim(rtrim(Request::$REQUEST->getVar('path', ''), '/'), '/');
92 $path = Filesystem::realpath($root . '/' . $folder);
93
94 if ($path === false || $path == '') {
95 $folder = preg_replace("/[^A-Za-z0-9]/", '', $folder);
96 if (empty($folder)) {
97 Notification::error(n2_('Folder is missing!'));
98 $this->response->error();
99 } else {
100 Filesystem::createFolder($root . '/' . $folder);
101 $path = Filesystem::realpath($root . '/' . $folder);
102 }
103 }
104
105 $relativePath = Filesystem::toLinux($this->relative($path, $root));
106 if (!$relativePath) {
107 $relativePath = '';
108 }
109 $response = array(
110 'path' => $relativePath
111 );
112 try {
113 if (isset($_FILES) && isset($_FILES['image']) && isset($_FILES['image']['name'])) {
114 $info = pathinfo($_FILES['image']['name']);
115 $fileName = preg_replace('/[^a-zA-Z0-9_-]/', '', $info['filename']);
116 if (strlen($fileName) == 0) {
117 $fileName = '';
118 }
119
120 $upload = new BulletProof();
121 $file = $upload->uploadDir($path)
122 ->upload($_FILES['image'], $fileName);
123 $response['name'] = basename($file);
124 $response['url'] = ResourceTranslator::urlToResource(Filesystem::pathToAbsoluteURL($file));
125
126 Image::onImageUploaded($file);
127 }
128 } catch (Exception $e) {
129 Notification::error($e->getMessage());
130 $this->response->error();
131 }
132
133
134 $this->response->respond($response);
135 }
136
137 private function relative($path, $root) {
138 return substr(Filesystem::convertToRealDirectorySeparator($path), strlen($root));
139 }
140 }
1 <?php
2
3 namespace Nextend\Framework\Cache;
4
5
6 use Nextend\Framework\Cache\Storage\AbstractStorage;
7
8 abstract class AbstractCache {
9
10 protected $group = '';
11 protected $isAccessible = false;
12
13 /** @var AbstractStorage */
14 public $storage;
15
16 protected $_storageEngine = 'filesystem';
17
18 /**
19 * @param string $engine
20 *
21 * @return AbstractStorage
22 */
23 public static function getStorage($engine = "filesystem") {
24 static $storage = null;
25 if ($storage === null) {
26 $storage = array(
27 'filesystem' => new Storage\Filesystem(),
28 'database' => new Storage\Database()
29 );
30 }
31
32 return $storage[$engine];
33 }
34
35 public static function clearAll() {
36 self::getStorage('filesystem')
37 ->clearAll();
38 self::getStorage('filesystem')
39 ->clearAll('web');
40 }
41
42 public static function clearGroup($group) {
43 self::getStorage('filesystem')
44 ->clear($group);
45 self::getStorage('filesystem')
46 ->clear($group, 'web');
47 self::getStorage('database')
48 ->clear($group);
49 self::getStorage('database')
50 ->clear($group, 'web');
51 }
52
53 public function __construct($group, $isAccessible = false) {
54 $this->group = $group;
55 $this->isAccessible = $isAccessible;
56 $this->storage = self::getStorage($this->_storageEngine);
57 }
58
59 protected function clearCurrentGroup() {
60 $this->storage->clear($this->group, $this->getScope());
61 }
62
63 protected function getScope() {
64 if ($this->isAccessible) {
65 return 'web';
66 }
67
68 return 'notweb';
69 }
70
71 protected function exists($key) {
72 return $this->storage->exists($this->group, $key, $this->getScope());
73 }
74
75 protected function get($key) {
76 return $this->storage->get($this->group, $key, $this->getScope());
77 }
78
79 protected function set($key, $value) {
80 $this->storage->set($this->group, $key, $value, $this->getScope());
81 }
82
83 protected function getPath($key) {
84 return $this->storage->getPath($this->group, $key, $this->getScope());
85 }
86
87 protected function remove($key) {
88 return $this->storage->remove($this->group, $key, $this->getScope());
89 }
90 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Cache;
4
5 use DateTime;
6
7 class CacheImage extends AbstractCache {
8
9 protected $_storageEngine = 'filesystem';
10
11 protected $lazy = false;
12
13 public function __construct($group) {
14 parent::__construct($group, true);
15 }
16
17 protected function getScope() {
18 return 'image';
19 }
20
21 public function setLazy($lazy) {
22 $this->lazy = $lazy;
23 }
24
25 /**
26 * @param $fileExtension
27 * @param callable $callable
28 * @param array $parameters
29 * @param bool $hash
30 *
31 * @return mixed
32 */
33 public function makeCache($fileExtension, $callable, $parameters = array(), $hash = false) {
34
35 if (!$hash) {
36 $hash = $this->generateHash($fileExtension, $callable, $parameters);
37 }
38
39 if (strpos($parameters[1], '?') !== false) {
40 $fileNameParts = explode('?', $parameters[1]);
41 $keepFileName = pathinfo($fileNameParts[0], PATHINFO_FILENAME);
42 } else {
43 $keepFileName = pathinfo($parameters[1], PATHINFO_FILENAME);
44 }
45
46 $fileName = $hash . (!empty($keepFileName) ? '/' . $keepFileName : '');
47 $fileNameWithExtension = $fileName . '.' . $fileExtension;
48
49 $isCached = $this->exists($fileNameWithExtension);
50 if ($isCached) {
51 if (!$this->testManifestFile($fileName, $parameters[1])) {
52 $isCached = false;
53 }
54 }
55
56 if (!$isCached) {
57 if ($this->lazy) {
58 return $parameters[1];
59 }
60
61 array_unshift($parameters, $this->getPath($fileNameWithExtension));
62 call_user_func_array($callable, $parameters);
63
64 $this->createManifestFile($fileName, $parameters[2]);
65 }
66
67 return $this->getPath($fileNameWithExtension);
68 }
69
70 private function generateHash($fileExtension, $callable, $parameters) {
71 return md5(json_encode(array(
72 $fileExtension,
73 $callable,
74 $parameters
75 )));
76 }
77
78 protected function testManifestFile($fileName, $originalFile) {
79 $manifestKey = $this->getManifestKey($fileName);
80 if ($this->exists($manifestKey)) {
81
82 $manifestData = json_decode($this->get($manifestKey), true);
83
84 $newManifestData = $this->getManifestData($originalFile);
85 if ($manifestData['mtime'] == $newManifestData['mtime']) {
86 return true;
87 }
88 } else {
89 // Backward compatibility
90 $this->createManifestFile($fileName, $originalFile);
91
92 return true;
93 }
94
95 return false;
96 }
97
98 protected function createManifestFile($fileName, $originalFile) {
99
100 $this->set($this->getManifestKey($fileName), json_encode($this->getManifestData($originalFile)));
101 }
102
103 private function getManifestData($originalFile) {
104 $manifestData = array();
105 if (strpos($originalFile, '//') !== false) {
106 $manifestData['mtime'] = $this->getRemoteMTime($originalFile);
107 } else {
108 $manifestData['mtime'] = filemtime($originalFile);
109 }
110
111 return $manifestData;
112 }
113
114 private function getRemoteMTime($url) {
115 $h = get_headers($url, 1);
116 if (!$h || strpos($h[0], '200') !== false) {
117 foreach ($h as $k => $v) {
118 if (strtolower(trim($k)) == "last-modified") {
119 return (new DateTime($v))->getTimestamp();
120 }
121 }
122 }
123
124 return 0;
125 }
126
127 protected function getManifestKey($fileName) {
128 return $fileName . '.manifest';
129 }
130 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Cache;
4
5 class Manifest extends AbstractCache {
6
7 private $isRaw = false;
8
9 private $manifestData;
10
11 public function __construct($group, $isAccessible = false, $isRaw = false) {
12 parent::__construct($group, $isAccessible);
13 $this->isRaw = $isRaw;
14 }
15
16 protected function decode($data) {
17 return $data;
18 }
19
20 /**
21 * @param $fileName
22 * @param $hash
23 * @param callback $callable
24 *
25 * @return bool
26 */
27 public function makeCache($fileName, $hash, $callable) {
28 if (!$this->isCached($fileName, $hash)) {
29
30 $return = call_user_func($callable, $this);
31 if ($return === false) {
32 return false;
33 }
34
35 return $this->createCacheFile($fileName, $hash, $return);
36 }
37 if ($this->isAccessible) {
38 return $this->getPath($fileName);
39 }
40
41 return $this->decode($this->get($fileName));
42 }
43
44 private function isCached($fileName, $hash) {
45
46
47 $manifestKey = $this->getManifestKey($fileName);
48 if ($this->exists($manifestKey)) {
49
50 $this->manifestData = json_decode($this->get($manifestKey), true);
51
52 if (!$this->isCacheValid($this->manifestData) || $this->manifestData['hash'] != $hash || !$this->exists($fileName)) {
53 $this->clean($fileName);
54
55 return false;
56 }
57
58 return true;
59 }
60
61 return false;
62 }
63
64 protected function createCacheFile($fileName, $hash, $content) {
65
66 $this->manifestData = array();
67
68 $this->manifestData['hash'] = $hash;
69 $this->addManifestData($this->manifestData);
70
71 $this->set($this->getManifestKey($fileName), json_encode($this->manifestData));
72
73 $this->set($fileName, $this->isRaw ? $content : json_encode($content));
74
75 if ($this->isAccessible) {
76 return $this->getPath($fileName);
77 }
78
79 return $content;
80 }
81
82 protected function isCacheValid(&$manifestData) {
83 return true;
84 }
85
86 protected function addManifestData(&$manifestData) {
87
88 }
89
90 public function clean($fileName) {
91
92 $this->remove($this->getManifestKey($fileName));
93 $this->remove($fileName);
94 }
95
96 protected function getManifestKey($fileName) {
97 return $fileName . '.manifest';
98 }
99
100 public function getData($key, $default = 0) {
101 return isset($this->manifestData[$key]) ? $this->manifestData[$key] : $default;
102 }
103 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Cache\Storage;
5
6
7 abstract class AbstractStorage {
8
9 protected $paths = array();
10
11 public function isFilesystem() {
12 return false;
13 }
14
15 public abstract function clearAll($scope = 'notweb');
16
17 public abstract function clear($group, $scope = 'notweb');
18
19 public abstract function exists($group, $key, $scope = 'notweb');
20
21 public abstract function set($group, $key, $value, $scope = 'notweb');
22
23 public abstract function get($group, $key, $scope = 'notweb');
24
25 public abstract function remove($group, $key, $scope = 'notweb');
26
27 public abstract function getPath($group, $key, $scope = 'notweb');
28 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Cache\Storage;
4
5 use Nextend\Framework\Model\ApplicationSection;
6 use Nextend\Framework\Platform\Platform;
7
8 class Database extends AbstractStorage {
9
10 protected $db;
11
12 public function __construct() {
13
14 $this->paths['web'] = 'web';
15 $this->paths['notweb'] = 'notweb';
16 $this->paths['image'] = 'image';
17
18 $this->db = new ApplicationSection('cache');
19 }
20
21 public function clearAll($scope = 'notweb') {
22
23 }
24
25 public function clear($group, $scope = 'notweb') {
26
27 $this->db->delete($scope . '/' . $group);
28 }
29
30 public function exists($group, $key, $scope = 'notweb') {
31
32 if ($this->db->get($scope . '/' . $group, $key)) {
33 return true;
34 }
35
36 return false;
37 }
38
39 public function set($group, $key, $value, $scope = 'notweb') {
40
41 $this->db->set($scope . '/' . $group, $key, $value);
42 }
43
44 public function get($group, $key, $scope = 'notweb') {
45 return $this->db->get($scope . '/' . $group, $key);
46 }
47
48 public function remove($group, $key, $scope = 'notweb') {
49 $this->db->delete($scope . '/' . $group, $key);
50 }
51
52 public function getPath($group, $key, $scope = 'notweb') {
53
54 return Platform::getSiteUrl() . '?nextendcache=1&g=' . urlencode($group) . '&k=' . urlencode($key);
55 }
56 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Cache\Storage;
5
6
7 class Filesystem extends AbstractStorage {
8
9 public function __construct() {
10 $this->paths['web'] = \Nextend\Framework\Filesystem\Filesystem::getWebCachePath();
11 $this->paths['notweb'] = \Nextend\Framework\Filesystem\Filesystem::getNotWebCachePath();
12 $this->paths['image'] = \Nextend\Framework\Filesystem\Filesystem::getImagesFolder();
13 }
14
15 public function isFilesystem() {
16 return true;
17 }
18
19 public function clearAll($scope = 'notweb') {
20 if (\Nextend\Framework\Filesystem\Filesystem::existsFolder($this->paths[$scope])) {
21 \Nextend\Framework\Filesystem\Filesystem::deleteFolder($this->paths[$scope]);
22 }
23 }
24
25 public function clear($group, $scope = 'notweb') {
26
27 if (\Nextend\Framework\Filesystem\Filesystem::existsFolder($this->paths[$scope] . '/' . $group)) {
28 \Nextend\Framework\Filesystem\Filesystem::deleteFolder($this->paths[$scope] . '/' . $group);
29 }
30 }
31
32 public function exists($group, $key, $scope = 'notweb') {
33 if (\Nextend\Framework\Filesystem\Filesystem::existsFile($this->paths[$scope] . '/' . $group . '/' . $key)) {
34 return true;
35 }
36
37 return false;
38 }
39
40 public function set($group, $key, $value, $scope = 'notweb') {
41 $path = $this->paths[$scope] . '/' . $group . '/' . $key;
42 $dir = dirname($path);
43 if (!\Nextend\Framework\Filesystem\Filesystem::existsFolder($dir)) {
44 \Nextend\Framework\Filesystem\Filesystem::createFolder($dir);
45 }
46 \Nextend\Framework\Filesystem\Filesystem::createFile($path, $value);
47 }
48
49 public function get($group, $key, $scope = 'notweb') {
50 return \Nextend\Framework\Filesystem\Filesystem::readFile($this->paths[$scope] . '/' . $group . '/' . $key);
51 }
52
53 public function remove($group, $key, $scope = 'notweb') {
54 if ($this->exists($group, $key, $scope)) {
55 @unlink($this->paths[$scope] . '/' . $group . '/' . $key);
56 }
57 }
58
59 public function getPath($group, $key, $scope = 'notweb') {
60 return $this->paths[$scope] . DIRECTORY_SEPARATOR . $group . DIRECTORY_SEPARATOR . $key;
61 }
62 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Cache;
4
5 class StoreImage extends AbstractCache {
6
7 protected $_storageEngine = 'filesystem';
8
9 protected function getScope() {
10 return 'image';
11 }
12
13 public function makeCache($fileName, $content) {
14 if (!$this->isImage($fileName)) {
15 return false;
16 }
17
18 if (!$this->exists($fileName)) {
19 $this->set($fileName, $content);
20 }
21
22 return $this->getPath($fileName);
23 }
24
25 private function isImage($fileName) {
26 $supported_image = array(
27 'gif',
28 'jpg',
29 'jpeg',
30 'png',
31 'mp4',
32 'mp3',
33 'webp',
34 'svg'
35 );
36
37 $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
38 if (in_array($ext, $supported_image)) {
39 return true;
40 }
41
42 return false;
43 }
44 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework;
5
6
7 class Cast {
8
9 /**
10 * @param $number
11 *
12 * @return string the JavaScript float representation of the string
13 */
14 public static function floatToString($number) {
15
16 return json_encode(floatval($number));
17 }
18 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Content;
4
5 abstract class AbstractPlatformContent {
6
7 /**
8 * @param $keyword
9 *
10 * @return array links
11 * $links[] = array(
12 * 'title' => '',
13 * 'link' => '',
14 * 'info' => ''
15 * );
16 */
17 abstract public function searchLink($keyword);
18
19
20 /**
21 * @param $keyword
22 *
23 * @return array links
24 * $links[] = array(
25 * 'title' => '',
26 * 'description' => '',
27 * 'image' => '',
28 * 'link' => '',
29 * 'info' => ''
30 * );
31 */
32 abstract public function searchContent($keyword);
33 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Content;
4
5 use Nextend\Framework\Content\Joomla\JoomlaContent;
6 use Nextend\Framework\Content\WordPress\WordPressContent;
7
8 class Content {
9
10 /**
11 * @var AbstractPlatformContent
12 */
13 private static $platformContent;
14
15 public function __construct() {
16 self::$platformContent = new WordPressContent();
17 }
18
19 public static function searchLink($keyword) {
20 return self::$platformContent->searchLink($keyword);
21 }
22
23 public static function searchContent($keyword) {
24 return self::$platformContent->searchContent($keyword);
25 }
26 }
27
28 new Content();
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Content;
5
6
7 use Nextend\Framework\Controller\Admin\AdminAjaxController;
8 use Nextend\Framework\Request\Request;
9
10 class ControllerAjaxContent extends AdminAjaxController {
11
12 public function actionSearchLink() {
13 $this->validateToken();
14
15 $keyword = Request::$REQUEST->getVar('keyword', '');
16 $this->response->respond(Content::searchLink($keyword));
17 }
18
19 public function actionSearchContent() {
20 $this->validateToken();
21
22 $keyword = Request::$REQUEST->getVar('keyword', '');
23 $this->response->respond(Content::searchContent($keyword));
24 }
25 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Content\WordPress;
4
5 use Nextend\Framework\Content\AbstractPlatformContent;
6 use WP_Query;
7 use function get_post_thumbnail_id;
8 use function get_post_type;
9 use function get_post_type_object;
10 use function get_the_excerpt;
11 use function get_the_ID;
12 use function get_the_permalink;
13 use function get_the_title;
14 use function wp_get_attachment_url;
15
16 class WordPressContent extends AbstractPlatformContent {
17
18 public function searchLink($keyword) {
19
20 $the_query = new WP_Query('post_type=any&posts_per_page=20&post_status=publish&s=' . $keyword);
21
22 $links = array();
23 if ($the_query->have_posts()) {
24 while ($the_query->have_posts()) {
25 $the_query->the_post();
26
27 $link = array(
28 'title' => get_the_title(),
29 'link' => get_the_permalink(),
30 'info' => get_post_type_object(get_post_type())->labels->singular_name
31 );
32
33 $links[] = $link;
34
35 }
36 }
37 /* Restore original Post Data */
38 wp_reset_postdata();
39
40 return $links;
41 }
42
43 public function searchContent($keyword) {
44
45 $the_query = new WP_Query('post_type=any&posts_per_page=20&post_status=publish&s=' . $keyword);
46
47 $links = array();
48 if ($the_query->have_posts()) {
49 while ($the_query->have_posts()) {
50 $the_query->the_post();
51
52 $link = array(
53 'title' => get_the_title(),
54 'description' => get_the_excerpt(),
55 'image' => wp_get_attachment_url(get_post_thumbnail_id(get_the_ID())),
56 'link' => get_the_permalink(),
57 'info' => get_post_type_object(get_post_type())->labels->singular_name
58 );
59
60 $links[] = $link;
61
62 }
63 }
64 /* Restore original Post Data */
65 wp_reset_postdata();
66
67 return $links;
68 }
69 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Controller;
5
6
7 use Exception;
8 use Nextend\Framework\Acl\Acl;
9 use Nextend\Framework\Application\AbstractApplication;
10 use Nextend\Framework\Application\AbstractApplicationType;
11 use Nextend\Framework\Asset\AssetManager;
12 use Nextend\Framework\Asset\Predefined;
13 use Nextend\Framework\Form\Form;
14 use Nextend\Framework\Notification\Notification;
15 use Nextend\Framework\Pattern\GetPathTrait;
16 use Nextend\Framework\Pattern\MVCHelperTrait;
17 use Nextend\Framework\Plugin;
18 use Nextend\Framework\Request\Request;
19 use Nextend\SmartSlider3\Application\ApplicationSmartSlider3;
20
21 abstract class AbstractController {
22
23 use GetPathTrait;
24 use MVCHelperTrait;
25
26 /**
27 * @var AbstractApplicationType
28 */
29 protected $applicationType;
30
31 /** @var callback[] */
32 protected $externalActions = array();
33
34 /**
35 * AbstractController constructor.
36 *
37 * @param AbstractApplicationType $applicationType
38 */
39 public function __construct($applicationType) {
40
41 //PluggableController\Nextend\SmartSlider3\Application\Admin\Slider\ControllerSlider
42 Plugin::doAction('PluggableController\\' . get_class($this), array($this));
43
44
45 $this->applicationType = $applicationType;
46 $this->setMVCHelper($this->applicationType);
47
48 AssetManager::getInstance();
49
50 $this->initialize();
51 }
52
53 /**
54 * @param $actionName
55 * @param callback $callable
56 */
57 public function addExternalAction($actionName, $callable) {
58
59 $this->externalActions[$actionName] = $callable;
60 }
61
62 /**
63 * @return AbstractApplication
64 */
65 public function getApplication() {
66 return $this->applicationType->getApplication();
67 }
68
69 /**
70 * @return AbstractApplicationType
71 */
72 public function getApplicationType() {
73 return $this->applicationType;
74 }
75
76 public function getRouter() {
77 return $this->applicationType->getRouter();
78 }
79
80 /**
81 * @param $actionName
82 * @param array $args
83 *
84 * @throws Exception
85 */
86 final public function doAction($actionName, $args = array()) {
87
88 $originalActionName = $actionName;
89
90 if (method_exists($this, 'action' . $actionName)) {
91
92 call_user_func_array(array(
93 $this,
94 'action' . $actionName
95 ), $args);
96
97 } else if (isset($this->externalActions[$actionName]) && is_callable($this->externalActions[$actionName])) {
98
99 call_user_func_array($this->externalActions[$actionName], $args);
100
101 } else {
102
103 $actionName = $this->missingAction($this, $actionName);
104
105 if (method_exists($this, 'action' . $actionName)) {
106
107 call_user_func_array(array(
108 $this,
109 'action' . $actionName
110 ), $args);
111
112 } else {
113 throw new Exception(sprintf('Missing action (%s) for controller (%s)', $originalActionName, static::class));
114 }
115
116 }
117 }
118
119 protected function missingAction($controllerName, $actionName) {
120
121 return 'index';
122 }
123
124 public function initialize() {
125 Predefined::frontend();
126 }
127
128 /**
129 * Check ACL permissions
130 *
131 * @param $action
132 *
133 * @return bool
134 */
135 public function canDo($action) {
136 return Acl::canDo($action, $this);
137 }
138
139 public function redirect($url, $statusCode = 302, $terminate = true) {
140 Request::redirect($url, $statusCode, $terminate);
141 }
142
143 public function validatePermission($permission) {
144
145 if (!$this->canDo($permission)) {
146 Notification::error(n2_('You are not authorised to view this resource.'));
147
148 ApplicationSmartSlider3::getInstance()
149 ->getApplicationTypeAdmin()
150 ->process('sliders', 'index');
151
152 return false;
153 }
154
155 return true;
156 }
157
158 public function validateVariable($condition, $property) {
159
160 if (!$condition) {
161 Notification::error(sprintf(n2_('Missing parameter: %s'), $property));
162
163 ApplicationSmartSlider3::getInstance()
164 ->getApplicationTypeAdmin()
165 ->process('sliders', 'index');
166
167 return false;
168 }
169
170 return true;
171 }
172
173 public function validateDatabase($condition, $showError = true) {
174 if (!$condition) {
175 if ($showError) {
176 Notification::error(n2_('Database error'));
177
178 ApplicationSmartSlider3::getInstance()
179 ->getApplicationTypeAdmin()
180 ->process('sliders', 'index');
181 }
182
183 return false;
184 }
185
186 return true;
187 }
188
189 public function validateToken() {
190 if (!Form::checkToken()) {
191 Notification::error(n2_('Security token mismatch'));
192
193 return false;
194 }
195
196 return true;
197 }
198 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Controller\Admin;
5
6
7 use Nextend\Framework\Asset\Js\Js;
8 use Nextend\Framework\Asset\Predefined;
9 use Nextend\Framework\Controller\AbstractController;
10
11 abstract class AbstractAdminController extends AbstractController {
12
13 public function initialize() {
14 // Prevent browser from cache on backward button.
15 header("Cache-Control: no-store");
16
17 Js::addGlobalInline('window.N2DISABLESCHEDULER=1;');
18
19 parent::initialize();
20
21 Predefined::frontend();
22 Predefined::backend();
23 }
24 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Controller\Admin;
5
6
7 use Nextend\Framework\Controller\AjaxController;
8
9 class AdminAjaxController extends AjaxController {
10
11 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Controller\Admin;
5
6 use Nextend\Framework\Notification\Notification;
7 use Nextend\Framework\Request\Request;
8 use Nextend\Framework\Visual\ModelVisual;
9
10 abstract class AdminVisualManagerAjaxController extends AdminAjaxController {
11
12 protected $type = '';
13
14 /**
15 * @return ModelVisual
16 */
17 public abstract function getModel();
18
19 public function actionCreateSet() {
20 $this->validateToken();
21
22 $this->validatePermission('smartslider_edit');
23
24 $name = Request::$REQUEST->getVar('name');
25 $this->validateVariable(!empty($name), 'set name');
26
27 $model = $this->getModel();
28 if (($set = $model->createSet($name))) {
29 $this->response->respond(array(
30 'set' => $set
31 ));
32 }
33
34 Notification::error(n2_('Unexpected error'));
35 $this->response->error();
36 }
37
38 public function actionRenameSet() {
39 $this->validateToken();
40
41 $this->validatePermission('smartslider_edit');
42
43 $setId = Request::$REQUEST->getInt('setId');
44 $this->validateVariable($setId > 0, 'set');
45
46 $name = Request::$REQUEST->getVar('name');
47 $this->validateVariable(!empty($name), 'set name');
48
49 $model = $this->getModel();
50
51 if (($set = $model->renameSet($setId, $name))) {
52 $this->response->respond(array(
53 'set' => $set
54 ));
55 }
56
57 Notification::error(n2_('Set is not editable'));
58 $this->response->error();
59 }
60
61 public function actionDeleteSet() {
62 $this->validateToken();
63
64 $this->validatePermission('smartslider_delete');
65
66 $setId = Request::$REQUEST->getInt('setId');
67 $this->validateVariable($setId > 0, 'set');
68
69 $model = $this->getModel();
70
71 if (($set = $model->deleteSet($setId))) {
72 $this->response->respond(array(
73 'set' => $set
74 ));
75 }
76
77 Notification::error(n2_('Set is not editable'));
78 $this->response->error();
79 }
80
81 public function actionLoadVisualsForSet() {
82 $this->validateToken();
83
84
85 $setId = Request::$REQUEST->getInt('setId');
86 $this->validateVariable($setId > 0, 'set');
87
88 $model = $this->getModel();
89 $visuals = $model->getVisuals($setId);
90 if (is_array($visuals)) {
91 $this->response->respond(array(
92 'visuals' => $visuals
93 ));
94 }
95
96 Notification::error(n2_('Unexpected error'));
97 $this->response->error();
98 }
99
100 public function actionLoadSetByVisualId() {
101 $this->validateToken();
102
103 $visualId = Request::$REQUEST->getInt('visualId');
104 $this->validateVariable($visualId > 0, 'visual');
105
106 $model = $this->getModel();
107
108 $set = $model->getSetByVisualId($visualId);
109
110 if (is_array($set) && is_array($set['visuals'])) {
111 $this->response->respond(array(
112 'set' => $set
113 ));
114 }
115
116 Notification::error(n2_('Visual do not exists'));
117 $this->response->error();
118 }
119
120 public function actionAddVisual() {
121 $this->validateToken();
122
123 $this->validatePermission('smartslider_edit');
124
125 $setId = Request::$REQUEST->getInt('setId');
126 $this->validateVariable($setId > 0, 'set');
127
128 $model = $this->getModel();
129
130 if (($visual = $model->addVisual($setId, Request::$REQUEST->getVar('value')))) {
131 $this->response->respond(array(
132 'visual' => $visual
133 ));
134 }
135
136 Notification::error(n2_('Not editable'));
137 $this->response->error();
138 }
139
140 public function actionDeleteVisual() {
141 $this->validateToken();
142
143 $this->validatePermission('smartslider_delete');
144
145 $visualId = Request::$REQUEST->getInt('visualId');
146 $this->validateVariable($visualId > 0, 'visual');
147
148 $model = $this->getModel();
149
150 if (($visual = $model->deleteVisual($visualId))) {
151 $this->response->respond(array(
152 'visual' => $visual
153 ));
154 }
155
156 Notification::error(n2_('Not editable'));
157 $this->response->error();
158 }
159
160 public function actionChangeVisual() {
161 $this->validateToken();
162
163 $this->validatePermission('smartslider_edit');
164
165 $visualId = Request::$REQUEST->getInt('visualId');
166 $this->validateVariable($visualId > 0, 'visual');
167
168 $model = $this->getModel();
169
170 if (($visual = $model->changeVisual($visualId, Request::$REQUEST->getVar('value')))) {
171 $this->response->respond(array(
172 'visual' => $visual
173 ));
174 }
175
176 Notification::error(n2_('Unexpected error'));
177 $this->response->error();
178 }
179
180 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Controller;
4
5 use Nextend\Framework\Form\Form;
6 use Nextend\Framework\Notification\Notification;
7 use Nextend\Framework\PageFlow;
8 use Nextend\Framework\Response\ResponseAjax;
9
10 class AjaxController extends AbstractController {
11
12 /** @var ResponseAjax */
13 protected $response;
14
15 public function __construct($applicationType) {
16 PageFlow::cleanOutputBuffers();
17
18 $this->response = new ResponseAjax($applicationType);
19 parent::__construct($applicationType);
20 }
21
22 /**
23 * @return ResponseAjax
24 */
25 public function getResponse() {
26 return $this->response;
27 }
28
29 public function validateToken() {
30
31 if (!Form::checkToken()) {
32 Notification::error(n2_('Security token mismatch. Please refresh the page!'));
33 $this->response->error();
34 }
35 }
36
37 public function validatePermission($permission) {
38
39 if (!$this->canDo($permission)) {
40
41 Notification::error(n2_('You are not authorised to view this resource.'));
42
43 $this->response->error();
44 }
45 }
46
47 public function validateVariable($condition, $property) {
48
49 if (!$condition) {
50 Notification::error(sprintf(n2_('Missing parameter: %s'), $property));
51 $this->response->error();
52 }
53 }
54
55 public function validateDatabase($condition, $showError = true) {
56 if (!$condition) {
57 Notification::error(n2_('Database error'));
58 $this->response->error();
59 }
60 }
61
62 public function redirect($url, $statusCode = 302, $terminate = true) {
63 $this->response->redirect($url);
64 }
65
66 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Data;
4
5
6 class Data {
7
8 /**
9 * @var array
10 */
11 public $_data = array();
12
13 public function __construct($data = null, $json = false) {
14
15 if ($data) {
16 if (is_array($data)) {
17 $this->loadArray($data);
18 } else {
19 $this->loadJSON($data);
20 }
21 }
22 }
23
24 /**
25 * @param $json
26 */
27 public function loadJSON($json) {
28 $array = json_decode($json, true);
29 if (is_array($array)) $this->_data = array_merge($this->_data, $array);
30 }
31
32 /**
33 * @param $array
34 */
35 public function loadArray($array) {
36 if (!$this->_data) $this->_data = array();
37 if (is_array($array)) $this->_data = array_merge($this->_data, $array);
38 }
39
40 /**
41 * @return mixed|string
42 */
43 public function toJSON() {
44 return json_encode($this->_data);
45 }
46
47 /**
48 * @return array
49 */
50 public function toArray() {
51 return (array)$this->_data;
52 }
53
54 public function has($key) {
55
56 return isset($this->_data[$key]);
57 }
58
59 /**
60 * @param string $key
61 * @param string $default
62 *
63 * @return mixed
64 */
65 public function get($key, $default = '') {
66 if (isset($this->_data[$key])) return $this->_data[$key];
67
68 return $default;
69 }
70
71 public function getIfEmpty($key, $default = '') {
72 if (isset($this->_data[$key]) && !empty($this->_data[$key])) return $this->_data[$key];
73
74 return $default;
75 }
76
77 /**
78 * @param string $key
79 * @param mixed $value
80 */
81 public function set($key, $value) {
82 $this->_data[$key] = $value;
83 }
84
85 public function un_set($key) {
86 if (isset($this->_data[$key])) {
87 unset($this->_data[$key]);
88 }
89 }
90
91 public function fillDefault($defaults) {
92 $this->_data = array_merge($defaults, $this->_data);
93 }
94 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Database;
4
5 abstract class AbstractPlatformConnector {
6
7 protected $_prefixJoker = '#__';
8
9 protected $_prefix = '';
10
11 public function getPrefix() {
12 return $this->_prefix;
13 }
14
15 public function parsePrefix($query) {
16 return str_replace($this->_prefixJoker, $this->_prefix, $query);
17 }
18
19 abstract public function insertId();
20
21 abstract public function query($query, $attributes = false);
22
23 /**
24 * Return with one row by query string
25 *
26 * @param string $query
27 * @param array|bool $attributes for parameter binding
28 *
29 * @return mixed
30 */
31 abstract public function queryRow($query, $attributes = false);
32
33 abstract public function queryAll($query, $attributes = false, $type = "assoc", $key = null);
34
35
36 /**
37 * @param string $text
38 * @param bool $escape
39 *
40 * @return string
41 */
42 abstract public function quote($text, $escape = true);
43
44 /**
45 * @param string $name
46 * @param null $as
47 *
48 * @return mixed
49 */
50 abstract public function quoteName($name, $as = null);
51
52 public function checkError($result) {
53 return $result;
54 }
55
56 /**
57 * @return string
58 */
59 abstract public function getCharsetCollate();
60 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Database;
5
6
7 abstract class AbstractPlatformConnectorTable {
8
9 protected $primaryKeyColumn = "id";
10
11 /** @var AbstractPlatformConnector */
12 protected static $connector;
13
14 protected $tableName;
15
16 public function __construct($tableName) {
17
18 $this->tableName = self::$connector->getPrefix() . $tableName;
19 }
20
21 public function getTableName() {
22 return $this->tableName;
23 }
24
25 abstract public function findByPk($primaryKey);
26
27 abstract public function findByAttributes(array $attributes, $fields = false, $order = false);
28
29 abstract public function findAll($order = false);
30
31 /**
32 * Return with all row by attributes
33 *
34 * @param array $attributes
35 * @param bool|array $fields
36 * @param bool|string $order
37 *
38 * @return mixed
39 */
40 abstract public function findAllByAttributes(array $attributes, $fields = false, $order = false);
41
42 /**
43 * Insert new row
44 *
45 * @param array $attributes
46 *
47 * @return mixed|void
48 */
49 abstract public function insert(array $attributes);
50
51 abstract public function insertId();
52
53 /**
54 * Update row(s) by param(s)
55 *
56 * @param array $attributes
57 * @param array $conditions
58 *
59 * @return mixed
60 */
61 abstract public function update(array $attributes, array $conditions);
62
63 /**
64 * Update one row by primary key with $attributes
65 *
66 * @param mixed $primaryKey
67 * @param array $attributes
68 *
69 * @return mixed
70 */
71 abstract public function updateByPk($primaryKey, array $attributes);
72
73 /**
74 * Delete one with by primary key
75 *
76 * @param mixed $primaryKey
77 *
78 * @return mixed
79 */
80 abstract public function deleteByPk($primaryKey);
81
82 /**
83 * Delete all rows by attributes
84 *
85 * @param array $conditions
86 *
87 * @return mixed
88 */
89 abstract public function deleteByAttributes(array $conditions);
90 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Database;
4
5 use Nextend\Framework\Database\Joomla\JoomlaConnector;
6 use Nextend\Framework\Database\Joomla\JoomlaConnectorTable;
7 use Nextend\Framework\Database\WordPress\WordPressConnector;
8 use Nextend\Framework\Database\WordPress\WordPressConnectorTable;
9 use Nextend\Framework\Pattern\SingletonTrait;
10
11 class Database {
12
13 use SingletonTrait;
14
15 /**
16 * @var AbstractPlatformConnector
17 */
18 private static $platformConnector;
19
20 protected function init() {
21 self::$platformConnector = new WordPressConnector();
22 }
23
24 /**
25 * @param $tableName
26 *
27 * @return AbstractPlatformConnectorTable
28 */
29 public static function getTable($tableName) {
30 return new WordPressConnectorTable($tableName);
31 }
32
33 public static function getPrefix() {
34 return self::$platformConnector->getPrefix();
35 }
36
37 public static function parsePrefix($query) {
38 return self::$platformConnector->parsePrefix($query);
39 }
40
41 public static function insertId() {
42
43 return self::$platformConnector->insertId();
44 }
45
46 public static function query($query, $attributes = false) {
47
48 return self::$platformConnector->query($query, $attributes);
49 }
50
51 /**
52 * Return with one row by query string
53 *
54 * @param string $query
55 * @param array|bool $attributes for parameter binding
56 *
57 * @return mixed
58 */
59 public static function queryRow($query, $attributes = false) {
60
61 return self::$platformConnector->queryRow($query, $attributes);
62 }
63
64 public static function queryAll($query, $attributes = false, $type = "assoc", $key = null) {
65
66 return self::$platformConnector->queryAll($query, $attributes, $type, $key);
67 }
68
69
70 /**
71 * @param string $text
72 * @param bool $escape
73 *
74 * @return string
75 */
76 public static function quote($text, $escape = true) {
77
78 return self::$platformConnector->quote($text, $escape);
79 }
80
81 /**
82 * @param string $name
83 * @param null $as
84 *
85 * @return mixed
86 */
87 public static function quoteName($name, $as = null) {
88
89 return self::$platformConnector->quoteName($name, $as);
90 }
91
92 /**
93 * @return string
94 */
95 public static function getCharsetCollate() {
96
97 return self::$platformConnector->getCharsetCollate();
98 }
99 }
100
101 Database::getInstance();
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 namespace Nextend\Framework\Database\WordPress;
4
5 use Nextend\Framework\Database\AbstractPlatformConnector;
6 use Nextend\Framework\Notification\Notification;
7 use Nextend\SmartSlider3\Platform\SmartSlider3Platform;
8 use wpdb;
9
10 class WordPressConnector extends AbstractPlatformConnector {
11
12 /** @var wpdb $wpdb */
13 private $db;
14
15 public function __construct() {
16 /** @var wpdb $wpdb */ global $wpdb;
17 $this->db = $wpdb;
18 $this->_prefix = $wpdb->prefix;
19
20 WordPressConnectorTable::init($this, $this->db);
21 }
22
23 public function query($query, $attributes = false) {
24 if ($attributes) {
25 foreach ($attributes as $key => $value) {
26 $replaceTo = is_numeric($value) ? $value : $this->db->prepare('%s', $value);
27 $query = str_replace($key, $replaceTo, $query);
28 }
29 }
30
31 return $this->checkError($this->db->query($query));
32 }
33
34 public function insertId() {
35 return $this->db->insert_id;
36 }
37
38 private function _querySQL($query, $attributes = false) {
39
40 $args = array('');
41
42 if ($attributes) {
43 foreach ($attributes as $key => $value) {
44 $replaceTo = is_numeric($value) ? '%d' : '%s';
45 $query = str_replace($key, $replaceTo, $query);
46 $args[] = $value;
47 }
48 }
49
50
51 if (count($args) > 1) {
52 $args[0] = $query;
53
54 return call_user_func_array(array(
55 $this->db,
56 'prepare'
57 ), $args);
58 } else {
59 return $query;
60 }
61 }
62
63 public function queryRow($query, $attributes = false) {
64 return $this->checkError($this->db->get_row($this->_querySQL($query, $attributes), ARRAY_A));
65 }
66
67 public function queryAll($query, $attributes = false, $type = "assoc", $key = null) {
68 $result = $this->checkError($this->db->get_results($this->_querySQL($query, $attributes), $type == 'assoc' ? ARRAY_A : OBJECT_K));
69 if (!$key) {
70 return $result;
71 }
72 $realResult = array();
73
74 for ($i = 0; $i < count($result); $i++) {
75 $key = $type == 'assoc' ? $result[i][$key] : $result[i]->{$key};
76 $realResult[$key] = $result[i];
77 }
78
79 return $realResult;
80 }
81
82 public function quote($text, $escape = true) {
83 return '\'' . (esc_sql($text)) . '\'';
84 }
85
86 public function quoteName($name, $as = null) {
87 if (strpos($name, '.') !== false) {
88 return $name;
89 } else {
90 $q = '`';
91 if (strlen($q) == 1) {
92 return $q . $name . $q;
93 } else {
94 return $q[0] . $name . $q[1];
95 }
96 }
97 }
98
99 public function checkError($result) {
100 if (!empty($this->db->last_error)) {
101 if (is_admin()) {
102 $lastError = $this->db->last_error;
103 $lastQuery = $this->db->last_query;
104
105 $possibleErrors = array(
106 'Duplicate entry' => 'Your table column doesn\'t have auto increment, while it should have.',
107 'command denied' => 'Your database user has limited access and isn\'t able to run all commands which are necessary for our code to work.',
108 'Duplicate key name' => 'Your database user has limited access and isn\'t able to run DROP or ALTER database commands.',
109 'Can\'t DROP' => 'Your database user has limited access and isn\'t able to run DROP or ALTER database commands.'
110 );
111
112 $errorMessage = sprintf(n2_('If you see this message after the repair database process, please %1$scontact us%2$s with the log:'), '<a href="https://smartslider3.com/contact-us/support/" target="_blank">', '</a>');
113
114 foreach ($possibleErrors as $error => $cause) {
115 if (strpos($lastError, $error) !== false) {
116 $errorMessage = n2_($cause) . ' ' . n2_('Contact your server host and ask them to fix this for you!');
117 break;
118 }
119 }
120
121 $message = array(
122 n2_('Unexpected database error.'),
123 '',
124 '<a href="' . wp_nonce_url(add_query_arg(array('repairss3' => '1'), SmartSlider3Platform::getAdminUrl()), 'repairss3') . '" class="n2_button n2_button--big n2_button--blue">' . n2_('Try to repair database') . '</a>',
125 '',
126 $errorMessage,
127 '',
128 '<b>' . $lastError . '</b>',
129 $lastQuery
130 );
131 Notification::error(implode('<br>', $message), array(
132 'wide' => true
133 ));
134 }
135 }
136
137 return $result;
138 }
139
140 public function getCharsetCollate() {
141
142 return $this->db->get_charset_collate();
143 }
144 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3
4 namespace Nextend\Framework\Database\WordPress;
5
6 use Nextend\Framework\Database\AbstractPlatformConnector;
7 use Nextend\Framework\Database\AbstractPlatformConnectorTable;
8 use wpdb;
9
10 class WordPressConnectorTable extends AbstractPlatformConnectorTable {
11
12 /** @var wpdb */
13 protected static $db;
14
15 /**
16 * @param AbstractPlatformConnector $connector
17 * @param wpdb $db
18 */
19 public static function init($connector, $db) {
20 self::$connector = $connector;
21 self::$db = $db;
22 }
23
24 public function findByPk($primaryKey) {
25 $query = self::$db->prepare("SELECT * FROM " . $this->tableName . " WHERE " . self::$connector->quoteName($this->primaryKeyColumn) . " = %s", $primaryKey);
26
27 return self::$connector->checkError(self::$db->get_row($query, ARRAY_A));
28 }
29
30 public function findByAttributes(array $attributes, $fields = false, $order = false) {
31
32 return self::$connector->checkError(self::$db->get_row($this->_findByAttributesSQL($attributes, $fields, $order), ARRAY_A));
33 }
34
35
36 public function findAll($order = false) {
37
38 return self::$connector->checkError(self::$db->get_results($this->_findByAttributesSQL(array(), false, $order), ARRAY_A));
39 }
40
41 public function findAllByAttributes(array $attributes, $fields = false, $order = false) {
42
43 return self::$connector->checkError(self::$db->get_results($this->_findByAttributesSQL($attributes, $fields, $order), ARRAY_A));
44 }
45
46 public function insert(array $attributes) {
47 return self::$connector->checkError(self::$db->insert($this->tableName, $attributes));
48 }
49
50 public function insertId() {
51 return self::$db->insert_id;
52 }
53
54 public function update(array $attributes, array $conditions) {
55
56 return self::$connector->checkError(self::$db->update($this->tableName, $attributes, $conditions));
57 }
58
59 public function updateByPk($primaryKey, array $attributes) {
60
61 $where = array();
62 $where[$this->primaryKeyColumn] = $primaryKey;
63 self::$connector->checkError(self::$db->update($this->tableName, $attributes, $where));
64 }
65
66 public function deleteByPk($primaryKey) {
67 $where = array();
68 $where[$this->primaryKeyColumn] = $primaryKey;
69 self::$connector->checkError(self::$db->delete($this->tableName, $where));
70 }
71
72 public function deleteByAttributes(array $conditions) {
73 self::$connector->checkError(self::$db->delete($this->tableName, $conditions));
74 }
75
76 private function _findByAttributesSQL(array $attributes, $fields = array(), $order = false) {
77
78 $args = array('');
79
80 $query = 'SELECT ';
81 if (!empty($fields)) {
82
83 $fields = array_map(array(
84 self::$connector,
85 'quoteName'
86 ), $fields);
87
88 $query .= implode(', ', $fields);
89 } else {
90 $query .= '*';
91 }
92 $query .= ' FROM ' . $this->tableName;
93
94 $where = array();
95 foreach ($attributes as $key => $val) {
96 $where[] = self::$connector->quoteName($key) . ' = ' . (is_numeric($val) ? '%d' : '%s');
97 $args[] = $val;
98 }
99 if (count($where)) {
100 $query .= ' WHERE ' . implode(' AND ', $where);
101 }
102
103 if ($order) {
104 $query .= ' ORDER BY ' . $order;
105 }
106
107 if (count($args) > 1) {
108 $args[0] = $query;
109
110 return call_user_func_array(array(
111 self::$db,
112 'prepare'
113 ), $args);
114 } else {
115 return $query;
116 }
117 }
118 }
...\ No newline at end of file ...\ No newline at end of file
1 <?php
2
3 /**
4 * fast-image-size base class
5 *
6 * @package fast-image-size
7 * @copyright (c) Marc Alexander <admin@m-a-styles.de>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13 namespace Nextend\Framework\FastImageSize;
14
15 use Nextend\Framework\Pattern\SingletonTrait;
16 use Nextend\Framework\ResourceTranslator\ResourceTranslator;
17
18 class FastImageSize {
19
20 use SingletonTrait;
21
22 private static $cache = array();
23
24 /**
25 * @param string $image
26 * @param array $attributes
27 */
28 public static function initAttributes($image, &$attributes) {
29
30 $size = self::getSize($image);
31
32 if ($size) {
33 $attributes['width'] = $size['width'];
34 $attributes['height'] = $size['height'];
35 }
36 }
37
38 public static function getWidth($image) {
39
40 $size = self::getSize($image);
41
42 if ($size) {
43 return $size['width'];
44 }
45
46 return 0;
47 }
48
49 public static function getSize($image) {
50 $imagePath = ResourceTranslator::toPath($image);
51
52 if (!isset(self::$cache[$imagePath])) {
53 if (empty($imagePath)) {
54 self::$cache[$imagePath] = false;
55 } else {
56 self::$cache[$imagePath] = self::getInstance()
57 ->getImageSize($imagePath);
58 }
59 }
60
61 return self::$cache[$imagePath];
62 }
63
64 /** @var array Size info that is returned */
65 protected $size = array();
66
67 /** @var string Data retrieved from remote */
68 protected $data = '';
69
70 /** @var array List of supported image types and associated image types */
71 protected $supportedTypes = array(
72 'png' => array('png'),
73 'gif' => array('gif'),
74 'jpeg' => array(
75 'jpeg',
76 'jpg'
77 ),
78 'webp' => array(
79 'webp',
80 ),
81 'svg' => array(
82 'svg',
83 )
84 );
85
86 /** @var array Class map that links image extensions/mime types to class */
87 protected $classMap;
88
89 /** @var array An array containing the classes of supported image types */
90 protected $type;
91
92 /**
93 * Get image dimensions of supplied image
94 *
95 * @param string $file Path to image that should be checked
96 * @param string $type Mimetype of image
97 *
98 * @return array|bool Array with image dimensions if successful, false if not
99 */
100 public function getImageSize($file, $type = '') {
101 // Reset values
102 $this->resetValues();
103
104 // Treat image type as unknown if extension or mime type is unknown
105 if (!preg_match('/\.([a-z0-9]+)$/i', $file, $match) && empty($type)) {
106 $this->getImagesizeUnknownType($file);
107 } else {
108 $extension = (empty($type) && isset($match[1])) ? $match[1] : preg_replace('/.+\/([a-z0-9-.]+)$/i', '$1', $type);
109
110 $this->getImageSizeByExtension($file, $extension);
111 }
112
113 return sizeof($this->size) > 1 ? $this->size : false;
114 }
115
116 /**
117 * Get dimensions of image if type is unknown
118 *
119 * @param string $filename Path to file
120 */
121 protected function getImagesizeUnknownType($filename) {
122 // Grab the maximum amount of bytes we might need
123 $data = $this->getImage($filename, 0, Type\TypeJpeg::JPEG_MAX_HEADER_SIZE, false);
124
125 if ($data !== false) {
126 $this->loadAllTypes();
127 foreach ($this->type as $imageType) {
128 $imageType->getSize($filename);
129
130 if (sizeof($this->size) > 1) {
131 break;
132 }
133 }
134 }
135 }
136
137 /**
138 * Get image size by file extension
139 *
140 * @param string $file Path to image that should be checked
141 * @param string $extension Extension/type of image
142 */
143 protected function getImageSizeByExtension($file, $extension) {
144 $extension = strtolower($extension);
145 $this->loadExtension($extension);
146 if (isset($this->classMap[$extension])) {
147 $this->classMap[$extension]->getSize($file);
148 }
149 }
150
151 /**
152 * Reset values to default
153 */
154 protected function resetValues() {
155 $this->size = array();
156 $this->data = '';
157 }
158
159 /**
160 * Set mime type based on supplied image
161 *
162 * @param int $type Type of image
163 */
164 public function setImageType($type) {
165 $this->size['type'] = $type;
166 }
167
168 /**
169 * Set size info
170 *
171 * @param array $size Array containing size info for image
172 */
173 public function setSize($size) {
174 $this->size = $size;
175 }
176
177 /**
178 * Get image from specified path/source
179 *
180 * @param string $filename Path to image
181 * @param int $offset Offset at which reading of the image should start
182 * @param int $length Maximum length that should be read
183 * @param bool $forceLength True if the length needs to be the specified
184 * length, false if not. Default: true
185 *
186 * @return false|string Image data or false if result was empty
187 */
188 public function getImage($filename, $offset, $length, $forceLength = true) {
189 if (empty($this->data)) {
190 $this->data = @file_get_contents($filename, null, null, $offset, $length);
191 }
192
193 // Force length to expected one. Return false if data length
194 // is smaller than expected length
195 if ($forceLength === true) {
196 return (strlen($this->data) < $length) ? false : substr($this->data, $offset, $length);
197 }
198
199 return empty($this->data) ? false : $this->data;
200 }
201
202 /**
203 * Get return data
204 *
205 * @return array|bool Size array if dimensions could be found, false if not
206 */
207 protected function getReturnData() {
208 return sizeof($this->size) > 1 ? $this->size : false;
209 }
210
211 /**
212 * Load all supported types
213 */
214 protected function loadAllTypes() {
215 foreach ($this->supportedTypes as $imageType => $extension) {
216 $this->loadType($imageType);
217 }
218 }
219
220 /**
221 * Load an image type by extension
222 *
223 * @param string $extension Extension of image
224 */
225 protected function loadExtension($extension) {
226 if (isset($this->classMap[$extension])) {
227 return;
228 }
229 foreach ($this->supportedTypes as $imageType => $extensions) {
230 if (in_array($extension, $extensions, true)) {
231 $this->loadType($imageType);
232 }
233 }
234 }
235
236 /**
237 * Load an image type
238 *
239 * @param string $imageType Mimetype
240 */
241 protected function loadType($imageType) {
242 if (isset($this->type[$imageType])) {
243 return;
244 }
245
246 $className = '\\' . __NAMESPACE__ . '\Type\Type' . ucfirst($imageType);
247
248 $this->type[$imageType] = new $className($this);
249
250 // Create class map
251 foreach ($this->supportedTypes[$imageType] as $ext) {
252 /** @var Type\TypeInterface */
253 $this->classMap[$ext] = $this->type[$imageType];
254 }
255 }
256 }
1 <?php
2
3 /**
4 * fast-image-size image type base
5 *
6 * @package fast-image-size
7 * @copyright (c) Marc Alexander <admin@m-a-styles.de>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13 namespace Nextend\Framework\FastImageSize\Type;
14
15 use Nextend\Framework\FastImageSize\FastImageSize;
16
17 abstract class TypeBase implements TypeInterface {
18
19 /** @var FastImageSize */
20 protected $fastImageSize;
21
22 /**
23 * Base constructor for image types
24 *
25 * @param FastImageSize $fastImageSize
26 */
27 public function __construct(FastImageSize $fastImageSize) {
28 $this->fastImageSize = $fastImageSize;
29 }
30 }
1 <?php
2
3 /**
4 * fast-image-size image type gif
5 *
6 * @package fast-image-size
7 * @copyright (c) Marc Alexander <admin@m-a-styles.de>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13 namespace Nextend\Framework\FastImageSize\Type;
14
15 class TypeGif extends TypeBase {
16
17 /** @var string GIF87a header */
18 const GIF87A_HEADER = "\x47\x49\x46\x38\x37\x61";
19
20 /** @var string GIF89a header */
21 const GIF89A_HEADER = "\x47\x49\x46\x38\x39\x61";
22
23 /** @var int GIF header size */
24 const GIF_HEADER_SIZE = 6;
25
26 /**
27 * {@inheritdoc}
28 */
29 public function getSize($filename) {
30 // Get data needed for reading image dimensions as outlined by GIF87a
31 // and GIF89a specifications
32 $data = $this->fastImageSize->getImage($filename, 0, self::GIF_HEADER_SIZE + self::SHORT_SIZE * 2);
33
34 $type = substr($data, 0, self::GIF_HEADER_SIZE);
35 if ($type !== self::GIF87A_HEADER && $type !== self::GIF89A_HEADER) {
36 return;
37 }
38
39 $size = unpack('vwidth/vheight', substr($data, self::GIF_HEADER_SIZE, self::SHORT_SIZE * 2));
40
41 $this->fastImageSize->setSize($size);
42 $this->fastImageSize->setImageType(IMAGETYPE_GIF);
43 }
44 }
1 <?php
2
3 /**
4 * fast-image-size image type interface
5 *
6 * @package fast-image-size
7 * @copyright (c) Marc Alexander <admin@m-a-styles.de>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13 namespace Nextend\Framework\FastImageSize\Type;
14
15 interface TypeInterface {
16
17 /** @var int 4-byte long size */
18 const LONG_SIZE = 4;
19
20 /** @var int 2-byte short size */
21 const SHORT_SIZE = 2;
22
23 /**
24 * Get size of supplied image
25 *
26 * @param string $filename File name of image
27 *
28 * @return null
29 */
30 public function getSize($filename);
31 }
1 <?php
2
3 /**
4 * fast-image-size image type jpeg
5 *
6 * @package fast-image-size
7 * @copyright (c) Marc Alexander <admin@m-a-styles.de>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13 namespace Nextend\Framework\FastImageSize\Type;
14
15 class TypeJpeg extends TypeBase {
16
17 /** @var int JPEG max header size. Headers can be bigger, but we'll abort
18 * going through the header after this */
19 const JPEG_MAX_HEADER_SIZE = 786432; // = 768 kiB
20
21 /** @var string JPEG header */
22 const JPEG_HEADER = "\xFF\xD8";
23
24 /** @var string Start of frame marker */
25 const SOF_START_MARKER = "\xFF";
26
27 /** @var string End of image (EOI) marker */
28 const JPEG_EOI_MARKER = "\xD9";
29
30 /** @var array JPEG SOF markers */
31 protected $sofMarkers = array(
32 "\xC0",
33 "\xC1",
34 "\xC2",
35 "\xC3",
36 "\xC5",
37 "\xC6",
38 "\xC7",
39 "\xC9",
40 "\xCA",
41 "\xCB",
42 "\xCD",
43 "\xCE",
44 "\xCF"
45 );
46
47 /** @var string|bool JPEG data stream */
48 protected $data = '';
49
50 /** @var int Data length */
51 protected $dataLength = 0;
52
53 /**
54 * {@inheritdoc}
55 */
56 public function getSize($filename) {
57 // Do not force the data length
58 $this->data = $this->fastImageSize->getImage($filename, 0, self::JPEG_MAX_HEADER_SIZE, false);
59
60 // Check if file is jpeg
61 if ($this->data === false || substr($this->data, 0, self::SHORT_SIZE) !== self::JPEG_HEADER) {
62 return;
63 }
64
65 // Look through file for SOF marker
66 $size = $this->getSizeInfo();
67
68 $this->fastImageSize->setSize($size);
69 $this->fastImageSize->setImageType(IMAGETYPE_JPEG);
70 }
71
72 /**
73 * Get size info from image data
74 *
75 * @return array An array with the image's size info or an empty array if
76 * size info couldn't be found
77 */
78 protected function getSizeInfo() {
79 $size = array();
80 // since we check $i + 1 we need to stop one step earlier
81 $this->dataLength = strlen($this->data) - 1;
82
83 $sofStartRead = true;
84
85 // Look through file for SOF marker
86 for ($i = 2; $i < $this->dataLength; $i++) {
87 $marker = $this->getNextMarker($i, $sofStartRead);
88
89 if (in_array($marker, $this->sofMarkers)) {
90 // Extract size info from SOF marker
91 return $this->extractSizeInfo($i);
92 } else {
93 // Extract length only
94 $markerLength = $this->extractMarkerLength($i);
95
96 if ($markerLength < 2) {
97 return $size;
98 }
99
100 $i += $markerLength - 1;
101 continue;
102 }
103 }
104
105 return $size;
106 }
107
108 /**
109 * Extract marker length from data
110 *
111 * @param int $i Current index
112 *
113 * @return int Length of current marker
114 */
115 protected function extractMarkerLength($i) {
116 // Extract length only
117 list(, $unpacked) = unpack("H*", substr($this->data, $i, self::LONG_SIZE));
118
119 // Get width and height from unpacked size info
120 $markerLength = hexdec(substr($unpacked, 0, 4));
121
122 return $markerLength;
123 }
124
125 /**
126 * Extract size info from data
127 *
128 * @param int $i Current index
129 *
130 * @return array Size info of current marker
131 */
132 protected function extractSizeInfo($i) {
133 // Extract size info from SOF marker
134 list(, $unpacked) = unpack("H*", substr($this->data, $i - 1 + self::LONG_SIZE, self::LONG_SIZE));
135
136 // Get width and height from unpacked size info
137 $size = array(
138 'width' => hexdec(substr($unpacked, 4, 4)),
139 'height' => hexdec(substr($unpacked, 0, 4)),
140 );
141
142 return $size;
143 }
144
145 /**
146 * Get next JPEG marker in file
147 *
148 * @param int $i Current index
149 * @param bool $sofStartRead Flag whether SOF start padding was already read
150 *
151 * @return string Next JPEG marker in file
152 */
153 protected function getNextMarker(&$i, &$sofStartRead) {
154 $this->skipStartPadding($i, $sofStartRead);
155
156 do {
157 if ($i >= $this->dataLength) {
158 return self::JPEG_EOI_MARKER;
159 }
160 $marker = $this->data[$i];
161 $i++;
162 } while ($marker == self::SOF_START_MARKER);
163
164 return $marker;
165 }
166
167 /**
168 * Skip over any possible padding until we reach a byte without SOF start
169 * marker. Extraneous bytes might need to require proper treating.
170 *
171 * @param int $i Current index
172 * @param bool $sofStartRead Flag whether SOF start padding was already read
173 */
174 protected function skipStartPadding(&$i, &$sofStartRead) {
175 if (!$sofStartRead) {
176 while ($this->data[$i] !== self::SOF_START_MARKER) {
177 $i++;
178 }
179 }
180 }
181 }
1 <?php
2
3 /**
4 * fast-image-size image type png
5 *
6 * @package fast-image-size
7 * @copyright (c) Marc Alexander <admin@m-a-styles.de>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13 namespace Nextend\Framework\FastImageSize\Type;
14
15 class TypePng extends TypeBase {
16
17 /** @var string PNG header */
18 const PNG_HEADER = "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a";
19
20 /** @var int PNG IHDR offset */
21 const PNG_IHDR_OFFSET = 12;
22
23 /**
24 * {@inheritdoc}
25 */
26 public function getSize($filename) {
27 // Retrieve image data including the header, the IHDR tag, and the
28 // following 2 chunks for the image width and height
29 $data = $this->fastImageSize->getImage($filename, 0, self::PNG_IHDR_OFFSET + 3 * self::LONG_SIZE);
30
31 // Check if header fits expected format specified by RFC 2083
32 if (substr($data, 0, self::PNG_IHDR_OFFSET - self::LONG_SIZE) !== self::PNG_HEADER || substr($data, self::PNG_IHDR_OFFSET, self::LONG_SIZE) !== 'IHDR') {
33 return;
34 }
35
36 $size = unpack('Nwidth/Nheight', substr($data, self::PNG_IHDR_OFFSET + self::LONG_SIZE, self::LONG_SIZE * 2));
37 $this->fastImageSize->setSize($size);
38 $this->fastImageSize->setImageType(IMAGETYPE_PNG);
39 }
40 }
1 <?php
2
3 namespace Nextend\Framework\FastImageSize\Type;
4
5 class TypeSvg extends TypeBase {
6
7 /**
8 * {@inheritdoc}
9 */
10 public function getSize($filename) {
11
12 $data = $this->fastImageSize->getImage($filename, 0, 100);
13
14 preg_match('/width="([0-9]+)"/', $data, $matches);
15 if ($matches && $matches[1] > 0) {
16 $size = array();
17 $size['width'] = $matches[1];
18
19 preg_match('/height="([0-9]+)"/', $data, $matches);
20 if ($matches && $matches[1] > 0) {
21 $size['height'] = $matches[1];
22 $this->fastImageSize->setSize($size);
23
24 return;
25 }
26 }
27
28 preg_match('/viewBox=["\']([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)["\']/i', $data, $matches);
29
30 if ($matches) {
31 $this->fastImageSize->setSize(array(
32 'width' => $matches[3] - $matches[1],
33 'height' => $matches[4] - $matches[2],
34 ));
35 }
36
37 }
38 }
1 <?php
2
3 /**
4 * fast-image-size image type webp
5 *
6 * @package fast-image-size
7 * @copyright (c) Marc Alexander <admin@m-a-styles.de>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13 namespace Nextend\Framework\FastImageSize\Type;
14
15 use Nextend\Framework\FastImageSize\FastImageSize;
16
17 class TypeWebp extends TypeBase {
18
19 /** @var string RIFF header */
20 const WEBP_RIFF_HEADER = "RIFF";
21
22 /** @var string Webp header */
23 const WEBP_HEADER = "WEBP";
24
25 /** @var string VP8 chunk header */
26 const VP8_HEADER = "VP8";
27
28 /** @var string Simple(lossy) webp format */
29 const WEBP_FORMAT_SIMPLE = ' ';
30
31 /** @var string Lossless webp format */
32 const WEBP_FORMAT_LOSSLESS = 'L';
33
34 /** @var string Extended webp format */
35 const WEBP_FORMAT_EXTENDED = 'X';
36
37 /** @var int WEBP header size needed for retrieving image size */
38 const WEBP_HEADER_SIZE = 30;
39
40 /** @var array Size info array */
41 protected $size;
42
43 /**
44 * Constructor for webp image type. Adds missing constant if necessary.
45 *
46 * @param FastImageSize $fastImageSize
47 */
48 public function __construct(FastImageSize $fastImageSize) {
49 parent::__construct($fastImageSize);
50
51 if (!defined('IMAGETYPE_WEBP')) {
52 define('IMAGETYPE_WEBP', 18);
53 }
54 }
55
56 /**
57 * {@inheritdoc}
58 */
59 public function getSize($filename) {
60 // Do not force length of header
61 $data = $this->fastImageSize->getImage($filename, 0, self::WEBP_HEADER_SIZE);
62
63 $this->size = array();
64
65 $webpFormat = substr($data, 15, 1);
66
67 if (!$this->hasWebpHeader($data) || !$this->isValidFormat($webpFormat)) {
68 return;
69 }
70
71 $data = substr($data, 16, 14);
72
73 $this->getWebpSize($data, $webpFormat);
74
75 $this->fastImageSize->setSize($this->size);
76 $this->fastImageSize->setImageType(IMAGETYPE_WEBP);
77 }
78
79 /**
80 * Check if $data has valid WebP header
81 *
82 * @param string $data Image data
83 *
84 * @return bool True if $data has valid WebP header, false if not
85 */
86 protected function hasWebpHeader($data) {
87 $riffSignature = substr($data, 0, self::LONG_SIZE);
88 $webpSignature = substr($data, 8, self::LONG_SIZE);
89 $vp8Signature = substr($data, 12, self::SHORT_SIZE + 1);
90
91 return !empty($data) && $riffSignature === self::WEBP_RIFF_HEADER && $webpSignature === self::WEBP_HEADER && $vp8Signature === self::VP8_HEADER;
92 }
93
94 /**
95 * Check if $format is a valid WebP format
96 *
97 * @param string $format Format string
98 *
99 * @return bool True if format is valid WebP format, false if not
100 */
101 protected function isValidFormat($format) {
102 return in_array($format, array(
103 self::WEBP_FORMAT_SIMPLE,
104 self::WEBP_FORMAT_LOSSLESS,
105 self::WEBP_FORMAT_EXTENDED
106 ));
107 }
108
109 /**
110 * Get webp size info depending on format type and set size array values
111 *
112 * @param string $data Data string
113 * @param string $format Format string
114 */
115 protected function getWebpSize($data, $format) {
116 switch ($format) {
117 case self::WEBP_FORMAT_SIMPLE:
118 $this->size = unpack('vwidth/vheight', substr($data, 10, 4));
119 break;
120
121 case self::WEBP_FORMAT_LOSSLESS:
122 // Lossless uses 14-bit values so we'll have to use bitwise shifting
123 $this->size = array(
124 'width' => ord($data[5]) + ((ord($data[6]) & 0x3F) << 8) + 1,
125 'height' => (ord($data[6]) >> 6) + (ord($data[7]) << 2) + ((ord($data[8]) & 0xF) << 10) + 1,
126 );
127 break;
128
129 case self::WEBP_FORMAT_EXTENDED:
130 // Extended uses 24-bit values cause 14-bit for lossless wasn't weird enough
131 $this->size = array(
132 'width' => ord($data[8]) + (ord($data[9]) << 8) + (ord($data[10]) << 16) + 1,
133 'height' => ord($data[11]) + (ord($data[12]) << 8) + (ord($data[13]) << 16) + 1,
134 );
135 break;
136 }
137 }
138 }
1 <?php
2
3 namespace Nextend\Framework\Filesystem;
4
5 use Nextend\Framework\Url\Url;
6
7 if (!defined('NEXTEND_RELATIVE_CACHE_WEB')) {
8 define('NEXTEND_RELATIVE_CACHE_WEB', '/cache/nextend/web');
9 define('NEXTEND_CUSTOM_CACHE', 0);
10 } else {
11 define('NEXTEND_CUSTOM_CACHE', 1);
12 }
13 if (!defined('NEXTEND_RELATIVE_CACHE_NOTWEB')) {
14 define('NEXTEND_RELATIVE_CACHE_NOTWEB', '/cache/nextend/notweb');
15 }
16
17 abstract class AbstractPlatformFilesystem {
18
19 public $paths = array();
20
21 /**
22 * @var string Absolute path which match to the baseuri. It must not end with /
23 * @example /asd/xyz/wordpress
24 */
25 protected $_basepath;
26
27 protected $dirPermission = 0777;
28
29 protected $filePermission = 0666;
30
31
32 protected $translate = array();
33
34 public function init() {
35
36 }
37
38 public function getPaths() {
39
40 return $this->paths;
41 }
42
43 public function check($base, $folder) {
44 static $checked = array();
45 if (!isset($checked[$base . '/' . $folder])) {
46 $cacheFolder = $base . '/' . $folder;
47 if (!$this->existsFolder($cacheFolder)) {
48 if ($this->is_writable($base)) {
49 $this->createFolder($cacheFolder);
50 } else {
51 die('<div style="position:fixed;background:#fff;width:100%;height:100%;top:0;left:0;z-index:100000;">' . sprintf('<h2><b>%s</b> is not writable.</h2>', $base) . '</div>');
52 }
53 } else if (!$this->is_writable($cacheFolder)) {
54 die('<div style="position:fixed;background:#fff;width:100%;height:100%;top:0;left:0;z-index:100000;">' . sprintf('<h2><b>%s</b> is not writable.</h2>', $cacheFolder) . '</div>');
55 }
56 $checked[$base . '/' . $folder] = true;
57 }
58 }
59
60 public function measurePermission($testDir) {
61 while ('.' != $testDir && !is_dir($testDir)) {
62 $testDir = dirname($testDir);
63 }
64
65 if ($stat = @stat($testDir)) {
66 $this->dirPermission = $stat['mode'] & 0007777;
67 $this->filePermission = $this->dirPermission & 0000666;
68 }
69 }
70
71 /**
72 * @param $path
73 *
74 * @return mixed
75 */
76 public function toLinux($path) {
77 return str_replace(DIRECTORY_SEPARATOR, '/', $path);
78 }
79
80 /**
81 * @return string
82 */
83 public function getBasePath() {
84
85 return $this->_basepath;
86 }
87
88 /**
89 * @param $path
90 */
91 public function setBasePath($path) {
92
93 $this->_basepath = $path;
94 }
95
96 public function getWebCachePath() {
97
98 return $this->getBasePath() . NEXTEND_RELATIVE_CACHE_WEB;
99 }
100
101 public function getNotWebCachePath() {
102 return $this->getBasePath() . NEXTEND_RELATIVE_CACHE_NOTWEB;
103 }
104
105 /**
106 * @param $path
107 *
108 * @return string
109 */
110 public function pathToAbsoluteURL($path) {
111 return Url::pathToUri($path);
112 }
113
114 /**
115 * @param $path
116 *
117 * @return string
118 */
119 public function pathToRelativePath($path) {
120
121 return preg_replace('/^' . preg_quote($this->_basepath, '/') . '/', '', str_replace('/', DIRECTORY_SEPARATOR, $path));
122 }
123
124 /**
125 * @param $path
126 *
127 * @return string
128 */
129 public function pathToAbsolutePath($path) {
130
131 return $this->_basepath . str_replace('/', DIRECTORY_SEPARATOR, $path);
132 }
133
134 /**
135 * @param $url
136 *
137 * @return string
138 */
139 public function absoluteURLToPath($url) {
140
141 $fullUri = Url::getFullUri();
142 if (substr($url, 0, strlen($fullUri)) == $fullUri) {
143
144 return str_replace($fullUri, $this->_basepath, $url);
145 }
146
147 return $url;
148 }
149
150 /**
151 * @param $file
152 *
153 * @return bool
154 */
155 public function fileexists($file) {
156 return is_file($file);
157 }
158
159 /**
160 * @param $file
161 *
162 * @return bool
163 */
164 public function safefileexists($file) {
165 return realpath($file) && is_file($file);
166 }
167
168 /**
169 *
170 * @param $dir
171 *
172 * @return array Folder names without trailing slash
173 */
174 public function folders($dir) {
175 if (!is_dir($dir)) {
176 return array();
177 }
178 $folders = array();
179 foreach (scandir($dir) as $file) {
180 if ($file == '.' || $file == '..') continue;
181 if (is_dir($dir . DIRECTORY_SEPARATOR . $file)) $folders[] = $file;
182 }
183
184 return $folders;
185 }
186
187 /**
188 * @param $path
189 *
190 * @return bool
191 */
192 public function is_writable($path) {
193 return is_writable($path);
194 }
195
196 /**
197 * @param $path
198 *
199 * @return bool
200 */
201 public function createFolder($path) {
202
203 return mkdir($path, $this->dirPermission, true);
204 }
205
206 public function deleteFolder($dir) {
207 if (!is_dir($dir) || is_link($dir)) return unlink($dir);
208 foreach (scandir($dir) as $file) {
209 if ($file == '.' || $file == '..') continue;
210 if (!$this->deleteFolder($dir . DIRECTORY_SEPARATOR . $file)) {
211 chmod($dir . DIRECTORY_SEPARATOR . $file, $this->dirPermission);
212 if (!$this->deleteFolder($dir . DIRECTORY_SEPARATOR . $file)) return false;
213 }
214 }
215
216 return rmdir($dir);
217 }
218
219 public function existsFolder($path) {
220 return is_dir($path);
221 }
222
223 public function files($path) {
224 $files = array();
225 if (is_dir($path)) {
226 if ($dh = opendir($path)) {
227 while (($file = readdir($dh)) !== false) {
228 if ($file[0] != ".") {
229 $files[] = $file;
230 }
231 }
232 closedir($dh);
233 }
234 }
235
236 return $files;
237 }
238
239 /**
240 * @param $path
241 *
242 * @return bool
243 */
244 public function existsFile($path) {
245
246 return file_exists($path);
247 }
248
249 /**
250 * @param $path
251 * @param $buffer
252 *
253 * @return int
254 */
255 public function createFile($path, $buffer) {
256 return file_put_contents($path, $buffer);
257 }
258
259 /**
260 * @param $path
261 *
262 * @return string
263 */
264 public function readFile($path) {
265 return file_get_contents($path);
266 }
267
268 /**
269 * convert dir alias to normal format
270 *
271 * @param $pathName
272 *
273 * @return mixed
274 */
275 public function dirFormat($pathName) {
276 return str_replace(".", DIRECTORY_SEPARATOR, $pathName);
277 }
278
279 public function getImagesFolder() {
280 return '';
281 }
282
283 public function realpath($path) {
284 return rtrim(realpath($path), '/\\');
285 }
286
287 public function registerTranslate($from, $to) {
288 $this->translate[$from] = $to;
289 }
290
291 protected function trailingslashit($string) {
292 return $this->untrailingslashit($string) . '/';
293 }
294
295 protected function untrailingslashit($string) {
296 return rtrim($string, '/\\');
297 }
298
299 public function convertToRealDirectorySeparator($path) {
300 return str_replace(DIRECTORY_SEPARATOR == '/' ? '\\' : '/', DIRECTORY_SEPARATOR, $path);
301 }
302
303 public function get_temp_dir() {
304 static $temp = '';
305 if (defined('SS_TEMP_DIR')) return $this->trailingslashit(SS_TEMP_DIR);
306
307 if ($temp) return $this->trailingslashit($temp);
308
309 if (function_exists('sys_get_temp_dir')) {
310 $temp = sys_get_temp_dir();
311 if (@is_dir($temp) && $this->is_writable($temp)) return $this->trailingslashit($temp);
312 }
313
314 $temp = ini_get('upload_tmp_dir');
315 if (@is_dir($temp) && $this->is_writable($temp)) return $this->trailingslashit($temp);
316
317 $temp = $this->getNotWebCachePath() . '/';
318 if (is_dir($temp) && $this->is_writable($temp)) return $temp;
319
320 return '/tmp/';
321 }
322
323 public function tempnam($filename = '', $dir = '') {
324 if (empty($dir)) {
325 $dir = $this->get_temp_dir();
326 }
327
328 if (empty($filename) || '.' == $filename || '/' == $filename || '\\' == $filename) {
329 $filename = time();
330 }
331
332 // Use the basename of the given file without the extension as the name for the temporary directory
333 $temp_filename = basename($filename);
334 $temp_filename = preg_replace('|\.[^.]*$|', '', $temp_filename);
335
336 // If the folder is falsey, use its parent directory name instead.
337 if (!$temp_filename) {
338 return $this->tempnam(dirname($filename), $dir);
339 }
340
341 // Suffix some random data to avoid filename conflicts
342 $temp_filename .= '-' . md5(uniqid(rand() . time()));
343 $temp_filename .= '.tmp';
344 $temp_filename = $dir . $temp_filename;
345
346 $fp = @fopen($temp_filename, 'x');
347 if (!$fp && is_writable($dir) && file_exists($temp_filename)) {
348 return $this->tempnam($filename, $dir);
349 }
350 if ($fp) {
351 fclose($fp);
352 }
353
354 return $temp_filename;
355 }
356 }
...\ No newline at end of file ...\ No newline at end of file
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.