Version Description
- 04/19/2019 =
- Update - Ranking details in Squirrly SEO Rankings
- Update - Messages in Focus Pages when the page is not optimized for a keyword
- Update - Added the 14 Days Journey in case the user didn't start it
- Update - Facebook reactions count for Focus Pages and Audit
- Update - Focus Pages floating header if more Focus Pages were added
- Fix - Show the Live Assistant message when the user is not logged in to Squirrly
- Fix - Layout fix for Bulk Seo and Show All Button
- Fix - Show the Squirrly Snippet in Tags and custom tags
- Fix - Changed the description height in Squirrly SEO Snippet
- Fix - Show Squirrly Menu for Editors and Authors
- Fix - Update caps and roles for author and editors in Research section
- Fix - Don't show send keyword to Rankings if the keyword is already sent
- Fix - Show impressions column in the GSG Sync page
- Fix - Import keywords in Squirrly Briefcase from old Squirrly Briefcase backups
- Fix - The Keyword Research algorithm
Download this release
Release Info
Developer | cifi |
Plugin | SEO SQUIRRLY™ |
Version | 9.1.10 |
Comparing to | |
See all releases |
Code changes from version 8.4.07 to 9.1.10
- classes/{Action.php → ActionController.php} +33 -98
- classes/BlockController.php +23 -39
- classes/DisplayController.php +52 -35
- classes/Error.php +55 -31
- classes/FrontController.php +29 -51
- classes/HookController.php +3 -1
- classes/ObjController.php +82 -119
- classes/Ranking.php +0 -336
- classes/RemoteController.php +1021 -0
- classes/Tools.php +0 -1666
- classes/helpers/DevKit.php +80 -0
- classes/helpers/Sanitize.php +430 -0
- classes/helpers/Tools.php +1020 -0
- config.json +196 -0
- config/config.php +19 -40
- config/paths.php +21 -14
- controllers/Account.php +11 -0
- controllers/Api.php +0 -76
- controllers/Assistant.php +137 -0
- controllers/Audits.php +89 -0
- controllers/CheckSeo.php +114 -0
- controllers/Cron.php +22 -12
- controllers/Dashboard.php +33 -0
- controllers/Feed.php +0 -83
- controllers/FocusPages.php +261 -0
- controllers/FrontMenu.php +0 -104
- controllers/Frontend.php +70 -47
- controllers/Help.php +12 -0
- controllers/Menu.php +198 -420
- controllers/Onboarding.php +62 -0
- controllers/Patterns.php +144 -0
- controllers/Post.php +148 -74
- controllers/PostsList.php +100 -281
- controllers/Ranking.php +192 -0
- controllers/Research.php +588 -0
- controllers/SeoSettings.php +811 -0
- controllers/SerpChecker.php +0 -414
- controllers/Sitemaps.php +30 -20
- controllers/Snippet.php +247 -0
- core/BlockAccount.php +0 -12
- core/BlockAffiliate.php +0 -47
- core/BlockAnalytics.php +0 -9
- core/BlockAssistant.php +8 -0
- core/BlockAudit.php +0 -19
- core/BlockAudits.php +43 -0
- core/BlockBriefcaseKeywords.php +0 -329
- core/BlockCopyright.php +0 -11
- core/BlockCustomerService.php +0 -11
- core/BlockDashboard.php +0 -12
- core/BlockFocusPages.php +63 -0
- core/BlockHelp.php +0 -8
- core/BlockImport.php +0 -69
- core/BlockJorney.php +38 -0
- core/BlockKRFound.php +15 -0
- core/BlockKRHistory.php +15 -0
- core/BlockKeywordResearch.php +0 -12
- core/BlockLiveAssistant.php +0 -11
- core/BlockPatterns.php +0 -61
- core/BlockPostsAnalytics.php +0 -68
- core/BlockRanks.php +62 -0
- core/BlockSEOIssues.php +13 -0
- core/BlockSerpKeywords.php +0 -137
- core/BlockSettings.php +0 -92
- core/BlockSettingsSeo.php +0 -585
- core/BlockStats.php +20 -0
- core/BlockSupport.php +11 -47
- core/BlockToolbar.php +8 -1
- core/Blocklogin.php +76 -88
- core/Blockresearch.php +0 -8
- core/Blocksearch.php +0 -41
- core/Blockseo.php +0 -20
- core/Loading.php +0 -102
- core/config.json +0 -225
- debug/index.php +230 -0
- demo.json +8 -0
- languages/squirrly-seo-cs_CZ.mo +0 -0
- languages/squirrly-seo-cs_CZ.po +5013 -2205
- languages/squirrly-seo-de_DE.mo +0 -0
- languages/squirrly-seo-de_DE.po +4046 -1006
classes/{Action.php → ActionController.php}
RENAMED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Set the ajax action and call for wordpress
|
5 |
*/
|
6 |
-
class
|
7 |
|
8 |
/** @var array with all form and ajax actions */
|
9 |
var $actions = array();
|
@@ -11,22 +11,15 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
|
|
11 |
/** @var array from core config */
|
12 |
private static $config;
|
13 |
|
14 |
-
|
15 |
-
public function _isAjax() {
|
16 |
-
return (defined('DOING_AJAX') && DOING_AJAX);
|
17 |
-
}
|
18 |
-
|
19 |
/**
|
20 |
* The hookAjax is loaded as custom hook in hookController class
|
21 |
*
|
22 |
* @return void
|
23 |
*/
|
24 |
public function hookInit() {
|
25 |
-
|
26 |
/* Only if ajax */
|
27 |
-
if (
|
28 |
-
$this->
|
29 |
-
$this->getActions(((isset($_GET['action']) ? $_GET['action'] : (isset($_POST['action']) ? $_POST['action'] : ''))));
|
30 |
}
|
31 |
}
|
32 |
|
@@ -37,9 +30,8 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
|
|
37 |
*/
|
38 |
public function hookMenu() {
|
39 |
/* Only if post */
|
40 |
-
if (
|
41 |
-
$this->
|
42 |
-
$this->getActions(((isset($_GET['action']) ? $_GET['action'] : (isset($_POST['action']) ? $_POST['action'] : ''))));
|
43 |
}
|
44 |
}
|
45 |
|
@@ -50,7 +42,6 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
|
|
50 |
* @return void
|
51 |
*/
|
52 |
public function hookHead() {
|
53 |
-
|
54 |
echo '<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
55 |
<script type="text/javascript">
|
56 |
var sqQuery = {
|
@@ -64,7 +55,7 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
|
|
64 |
}
|
65 |
|
66 |
public function hookFronthead() {
|
67 |
-
if (
|
68 |
echo '<script type="text/javascript">
|
69 |
var sqQuery = {
|
70 |
"adminurl": "' . admin_url() . '",
|
@@ -78,14 +69,21 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
|
|
78 |
/**
|
79 |
* Get all actions from config.json in core directory and add them in the WP
|
80 |
*
|
81 |
-
* @return void
|
82 |
*/
|
83 |
-
public function getActions(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
//Let only the logged users to access the actions
|
85 |
-
if (
|
86 |
/* if config allready in cache */
|
87 |
if (!isset(self::$config)) {
|
88 |
-
$config_file =
|
89 |
if (!file_exists($config_file)) {
|
90 |
return;
|
91 |
}
|
@@ -99,21 +97,20 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
|
|
99 |
if (isset($block['active']) && $block['active'] == 1) {
|
100 |
/* if there is a single action */
|
101 |
if (isset($block['actions']['action']))
|
102 |
-
if (isset($block['admin']) &&
|
103 |
-
(($block['admin'] == 1 && is_user_logged_in()) ||
|
104 |
-
$block['admin'] == 0)
|
105 |
-
) {
|
106 |
/* if there are more actions for the current block */
|
107 |
if (!is_array($block['actions']['action'])) {
|
108 |
/* add the action in the actions array */
|
109 |
-
if ($block['actions']['action'] == $cur_action)
|
110 |
$this->actions[] = array('class' => $block['name']);
|
|
|
111 |
} else {
|
112 |
/* if there are more actions for the current block */
|
113 |
foreach ($block['actions']['action'] as $action) {
|
114 |
/* add the actions in the actions array */
|
115 |
-
if ($action == $cur_action)
|
116 |
$this->actions[] = array('class' => $block['name']);
|
|
|
117 |
}
|
118 |
}
|
119 |
}
|
@@ -121,82 +118,20 @@ class SQ_Classes_Action extends SQ_Classes_FrontController {
|
|
121 |
}
|
122 |
}
|
123 |
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
* @param string $module
|
136 |
-
* @param array $args
|
137 |
-
* @return json | string
|
138 |
-
*/
|
139 |
-
public static function apiCall($module, $args = array(), $timeout = 10) {
|
140 |
-
$parameters = "";
|
141 |
-
$scheme = "http:";
|
142 |
-
|
143 |
-
if (SQ_Classes_Tools::getOption('sq_api') == '' && $module <> 'sq/login' && $module <> 'sq/register') {
|
144 |
-
return false;
|
145 |
-
}
|
146 |
-
|
147 |
-
$extra = array(
|
148 |
-
'user_url' => home_url(),
|
149 |
-
'lang' => (defined('WPLANG') ? WPLANG : 'en_US'),
|
150 |
-
'versq' => SQ_VERSION_ID,
|
151 |
-
'verwp' => WP_VERSION_ID,
|
152 |
-
'verphp' => PHP_VERSION_ID,
|
153 |
-
'token' => SQ_Classes_Tools::getOption('sq_api'));
|
154 |
-
|
155 |
-
|
156 |
-
if (is_array($args)) {
|
157 |
-
$args = array_merge($args, $extra);
|
158 |
-
} else {
|
159 |
-
$args = $extra;
|
160 |
-
}
|
161 |
-
|
162 |
-
foreach ($args as $key => $value) {
|
163 |
-
if ($value <> '') {
|
164 |
-
$parameters .= ($parameters == "" ? "" : "&") . $key . "=" . urlencode($value);
|
165 |
-
}
|
166 |
-
}
|
167 |
-
|
168 |
-
/* If the call is for login on register then use base64 is exists */
|
169 |
-
if ($module == 'sq/login' || $module == 'sq/register') {
|
170 |
-
if (function_exists('base64_encode')) {
|
171 |
-
$parameters = 'q=' . base64_encode($parameters);
|
172 |
}
|
173 |
}
|
174 |
|
175 |
-
if ($module <> "") {
|
176 |
-
$module .= "/";
|
177 |
-
}
|
178 |
-
//call it with http to prevent curl issues with ssls
|
179 |
-
$url = self::cleanUrl($scheme . _SQ_API_URL_ . $module . "?" . $parameters);
|
180 |
-
try {
|
181 |
-
//echo $url;exit();
|
182 |
-
return SQ_Classes_Tools::sq_remote_get($url, array(), array('timeout' => $timeout));
|
183 |
-
} catch (Exception $e) {
|
184 |
-
return '';
|
185 |
-
}
|
186 |
-
|
187 |
-
}
|
188 |
-
|
189 |
-
/**
|
190 |
-
* Clear the url before the call
|
191 |
-
* @param string $url
|
192 |
-
* @return string
|
193 |
-
*/
|
194 |
-
private static function cleanUrl($url) {
|
195 |
-
return str_replace(array(' '), array('+'), $url);
|
196 |
-
}
|
197 |
-
|
198 |
-
public static function apiSaveSettings() {
|
199 |
-
self::apiCall('sq/user/settings', array('settings' => json_encode(SQ_Classes_Tools::getBriefOptions())), 10);
|
200 |
}
|
201 |
|
202 |
}
|
3 |
/**
|
4 |
* Set the ajax action and call for wordpress
|
5 |
*/
|
6 |
+
class SQ_Classes_ActionController extends SQ_Classes_FrontController {
|
7 |
|
8 |
/** @var array with all form and ajax actions */
|
9 |
var $actions = array();
|
11 |
/** @var array from core config */
|
12 |
private static $config;
|
13 |
|
|
|
|
|
|
|
|
|
|
|
14 |
/**
|
15 |
* The hookAjax is loaded as custom hook in hookController class
|
16 |
*
|
17 |
* @return void
|
18 |
*/
|
19 |
public function hookInit() {
|
|
|
20 |
/* Only if ajax */
|
21 |
+
if (SQ_Classes_Helpers_Tools::isAjax()) {
|
22 |
+
$this->getActions();
|
|
|
23 |
}
|
24 |
}
|
25 |
|
30 |
*/
|
31 |
public function hookMenu() {
|
32 |
/* Only if post */
|
33 |
+
if (!SQ_Classes_Helpers_Tools::isAjax()) {
|
34 |
+
$this->getActions();
|
|
|
35 |
}
|
36 |
}
|
37 |
|
42 |
* @return void
|
43 |
*/
|
44 |
public function hookHead() {
|
|
|
45 |
echo '<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
46 |
<script type="text/javascript">
|
47 |
var sqQuery = {
|
55 |
}
|
56 |
|
57 |
public function hookFronthead() {
|
58 |
+
if (SQ_Classes_Helpers_Tools::isFrontAdmin()) {
|
59 |
echo '<script type="text/javascript">
|
60 |
var sqQuery = {
|
61 |
"adminurl": "' . admin_url() . '",
|
69 |
/**
|
70 |
* Get all actions from config.json in core directory and add them in the WP
|
71 |
*
|
|
|
72 |
*/
|
73 |
+
public function getActions() {
|
74 |
+
$this->actions = array();
|
75 |
+
$cur_action = SQ_Classes_Helpers_Tools::getValue('action', false);
|
76 |
+
$sq_nonce = SQ_Classes_Helpers_Tools::getValue('sq_nonce', false);
|
77 |
+
|
78 |
+
if (!function_exists('is_user_logged_in')) {
|
79 |
+
return;
|
80 |
+
}
|
81 |
+
|
82 |
//Let only the logged users to access the actions
|
83 |
+
if ($cur_action <> '' && $sq_nonce <> '' && is_admin()) {
|
84 |
/* if config allready in cache */
|
85 |
if (!isset(self::$config)) {
|
86 |
+
$config_file = _SQ_ROOT_DIR_ . 'config.json';
|
87 |
if (!file_exists($config_file)) {
|
88 |
return;
|
89 |
}
|
97 |
if (isset($block['active']) && $block['active'] == 1) {
|
98 |
/* if there is a single action */
|
99 |
if (isset($block['actions']['action']))
|
100 |
+
if (isset($block['admin']) && (($block['admin'] == 1 && is_user_logged_in()) || $block['admin'] == 0)) {
|
|
|
|
|
|
|
101 |
/* if there are more actions for the current block */
|
102 |
if (!is_array($block['actions']['action'])) {
|
103 |
/* add the action in the actions array */
|
104 |
+
if ($block['actions']['action'] == $cur_action) {
|
105 |
$this->actions[] = array('class' => $block['name']);
|
106 |
+
}
|
107 |
} else {
|
108 |
/* if there are more actions for the current block */
|
109 |
foreach ($block['actions']['action'] as $action) {
|
110 |
/* add the actions in the actions array */
|
111 |
+
if ($action == $cur_action) {
|
112 |
$this->actions[] = array('class' => $block['name']);
|
113 |
+
}
|
114 |
}
|
115 |
}
|
116 |
}
|
118 |
}
|
119 |
}
|
120 |
|
121 |
+
if (!empty($this->actions)) {
|
122 |
+
/* add the actions in WP */
|
123 |
+
foreach ($this->actions as $actions) {
|
124 |
+
if (SQ_Classes_Helpers_Tools::isAjax()) {
|
125 |
+
check_ajax_referer(_SQ_NONCE_ID_, 'sq_nonce');
|
126 |
+
add_action('wp_ajax_' . $cur_action, array(SQ_Classes_ObjController::getClass($actions['class']), 'action'));
|
127 |
+
} else {
|
128 |
+
check_admin_referer($cur_action, 'sq_nonce');
|
129 |
+
SQ_Classes_ObjController::getClass($actions['class'])->action();
|
130 |
+
}
|
131 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
}
|
133 |
}
|
134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
}
|
136 |
|
137 |
}
|
classes/BlockController.php
CHANGED
@@ -15,7 +15,7 @@ class SQ_Classes_BlockController {
|
|
15 |
/** @var object of the view class */
|
16 |
protected $view;
|
17 |
|
18 |
-
/** @var name of the class */
|
19 |
private $name;
|
20 |
|
21 |
public function __construct() {
|
@@ -23,69 +23,63 @@ class SQ_Classes_BlockController {
|
|
23 |
$this->name = get_class($this);
|
24 |
|
25 |
/* create the model and view instances */
|
26 |
-
$
|
|
|
|
|
|
|
27 |
}
|
28 |
|
29 |
/**
|
30 |
* load sequence of classes
|
|
|
31 |
*
|
32 |
* @return mixed
|
33 |
*/
|
34 |
public function init() {
|
35 |
/* check if there is a hook defined in the block class */
|
36 |
SQ_Classes_ObjController::getClass('SQ_Classes_HookController')->setBlockHooks($this);
|
|
|
|
|
37 |
|
38 |
if ($this->flush) {
|
39 |
-
|
40 |
-
|
|
|
41 |
} else {
|
42 |
-
return $this->getView();
|
43 |
}
|
44 |
-
}
|
45 |
|
|
|
|
|
46 |
|
47 |
/**
|
48 |
* Get the block view
|
49 |
*
|
50 |
-
* @param
|
51 |
* @return mixed
|
52 |
*/
|
53 |
-
public function getView($view
|
54 |
-
|
55 |
-
if ($class = SQ_Classes_ObjController::getClassPath($this->name)) {
|
56 |
-
$view = $class['name'];
|
57 |
-
}
|
58 |
-
}
|
59 |
-
|
60 |
-
if (isset($view)) {
|
61 |
-
$this->view = SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController');
|
62 |
-
return $this->view->getView($view, $this);
|
63 |
-
}
|
64 |
-
|
65 |
-
return '';
|
66 |
}
|
67 |
|
68 |
-
|
69 |
/**
|
70 |
* Called as menu callback to show the block
|
71 |
*
|
72 |
*/
|
73 |
public function show() {
|
74 |
$this->flush = true;
|
|
|
75 |
echo $this->init();
|
76 |
}
|
77 |
|
78 |
-
|
79 |
public function preloadSettings() {
|
80 |
-
if(
|
81 |
echo '<script type="text/javascript">
|
82 |
var __blog_url = "' . get_bloginfo('url') . '";
|
83 |
-
var __token = "' .
|
84 |
var __language = "' . get_bloginfo('language') . '";
|
85 |
var __api_url = "' . _SQ_API_URL_ . '";
|
86 |
-
|
87 |
-
jQuery.sq_getHelp("' . str_replace(array("sq_core_block", "sq_controller_block_"), "", strtolower($this->name)) . '", "content");
|
88 |
-
});
|
89 |
</script>';
|
90 |
}
|
91 |
}
|
@@ -94,23 +88,13 @@ class SQ_Classes_BlockController {
|
|
94 |
* This function is called from Ajax class as a wp_ajax_action
|
95 |
*
|
96 |
*/
|
97 |
-
protected function action() {
|
98 |
-
// check to see if the submitted nonce matches with the
|
99 |
-
// generated nonce we created
|
100 |
-
if (function_exists('wp_verify_nonce'))
|
101 |
-
if (!wp_verify_nonce(SQ_Classes_Tools::getValue('nonce'), _SQ_NONCE_ID_))
|
102 |
-
die('Invalid request!');
|
103 |
-
}
|
104 |
|
105 |
/**
|
106 |
* This function will load the media in the header for each class
|
107 |
*
|
108 |
* @return void
|
109 |
*/
|
110 |
-
protected function hookHead() {
|
111 |
-
if ($class = SQ_Classes_ObjController::getClassPath($this->name)) {
|
112 |
-
SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia($class['name']);
|
113 |
-
}
|
114 |
-
}
|
115 |
|
116 |
}
|
15 |
/** @var object of the view class */
|
16 |
protected $view;
|
17 |
|
18 |
+
/** @var string name of the class */
|
19 |
private $name;
|
20 |
|
21 |
public function __construct() {
|
23 |
$this->name = get_class($this);
|
24 |
|
25 |
/* create the model and view instances */
|
26 |
+
$model_classname = str_replace('Core', 'Models', $this->name);
|
27 |
+
if(SQ_Classes_ObjController::getClassPath($model_classname)) {
|
28 |
+
$this->model = SQ_Classes_ObjController::getClass($model_classname);
|
29 |
+
}
|
30 |
}
|
31 |
|
32 |
/**
|
33 |
* load sequence of classes
|
34 |
+
* Function called usualy when the controller is loaded in WP
|
35 |
*
|
36 |
* @return mixed
|
37 |
*/
|
38 |
public function init() {
|
39 |
/* check if there is a hook defined in the block class */
|
40 |
SQ_Classes_ObjController::getClass('SQ_Classes_HookController')->setBlockHooks($this);
|
41 |
+
//get the class path
|
42 |
+
$class = SQ_Classes_ObjController::getClassPath($this->name);
|
43 |
|
44 |
if ($this->flush) {
|
45 |
+
SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia($class['name']);
|
46 |
+
|
47 |
+
echo $this->getView($class['name']);
|
48 |
} else {
|
49 |
+
return $this->getView($class['name']);
|
50 |
}
|
|
|
51 |
|
52 |
+
return '';
|
53 |
+
}
|
54 |
|
55 |
/**
|
56 |
* Get the block view
|
57 |
*
|
58 |
+
* @param string $view Class name
|
59 |
* @return mixed
|
60 |
*/
|
61 |
+
public function getView($view) {
|
62 |
+
return SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->getView($view, $this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
64 |
|
|
|
65 |
/**
|
66 |
* Called as menu callback to show the block
|
67 |
*
|
68 |
*/
|
69 |
public function show() {
|
70 |
$this->flush = true;
|
71 |
+
|
72 |
echo $this->init();
|
73 |
}
|
74 |
|
|
|
75 |
public function preloadSettings() {
|
76 |
+
if (SQ_Classes_Helpers_Tools::getOption('sq_api') <> '') {
|
77 |
echo '<script type="text/javascript">
|
78 |
var __blog_url = "' . get_bloginfo('url') . '";
|
79 |
+
var __token = "' . SQ_Classes_Helpers_Tools::getOption('sq_api') . '";
|
80 |
var __language = "' . get_bloginfo('language') . '";
|
81 |
var __api_url = "' . _SQ_API_URL_ . '";
|
82 |
+
var __apiv2_url = "' . _SQ_APIV2_URL_ . '";
|
|
|
|
|
83 |
</script>';
|
84 |
}
|
85 |
}
|
88 |
* This function is called from Ajax class as a wp_ajax_action
|
89 |
*
|
90 |
*/
|
91 |
+
protected function action() { }
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
|
93 |
/**
|
94 |
* This function will load the media in the header for each class
|
95 |
*
|
96 |
* @return void
|
97 |
*/
|
98 |
+
protected function hookHead() { }
|
|
|
|
|
|
|
|
|
99 |
|
100 |
}
|
classes/DisplayController.php
CHANGED
@@ -7,68 +7,69 @@ class SQ_Classes_DisplayController {
|
|
7 |
|
8 |
private static $cache;
|
9 |
|
10 |
-
public function init() {
|
11 |
-
/* Load the global CSS file */
|
12 |
-
self::loadMedia('global');
|
13 |
-
}
|
14 |
-
|
15 |
/**
|
16 |
* echo the css link from theme css directory
|
17 |
*
|
18 |
* @param string $uri The name of the css file or the entire uri path of the css file
|
19 |
* @param string $params : trigger, media
|
20 |
*
|
21 |
-
* @return
|
22 |
*/
|
23 |
-
public static function loadMedia($uri = '', $params = array(
|
24 |
-
if (
|
25 |
return;
|
26 |
}
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
$css_uri = '';
|
29 |
$js_uri = '';
|
30 |
|
31 |
-
if (!isset($params['media'])) {
|
32 |
-
$params['media'] = 'all';
|
33 |
-
}
|
34 |
-
|
35 |
if (isset(self::$cache[$uri]))
|
36 |
return;
|
|
|
37 |
self::$cache[$uri] = true;
|
38 |
|
39 |
/* if is a custom css file */
|
40 |
if (strpos($uri, '//') === false) {
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
$
|
45 |
-
}
|
46 |
-
if (strpos($uri, '.css') !== false && file_exists(_SQ_THEME_DIR_ . 'css/' . strtolower($uri))) {
|
47 |
-
$css_uri = _SQ_THEME_URL_ . 'css/' . strtolower($uri);
|
48 |
}
|
49 |
-
if (
|
50 |
-
$
|
51 |
}
|
52 |
|
53 |
-
if (file_exists(
|
54 |
-
$
|
55 |
}
|
56 |
-
if (file_exists(
|
57 |
-
$js_uri =
|
58 |
}
|
|
|
59 |
} else {
|
60 |
-
|
61 |
-
|
|
|
|
|
62 |
$css_uri = $uri;
|
63 |
-
elseif (strpos($uri, '.js') !== FALSE) {
|
64 |
$js_uri = $uri;
|
65 |
}
|
|
|
66 |
}
|
67 |
|
68 |
|
69 |
if ($css_uri <> '') {
|
70 |
if (!wp_style_is($name)) {
|
71 |
-
wp_enqueue_style($name, $css_uri, null,
|
|
|
72 |
if (is_admin() || (isset($params['trigger']) && $params['trigger'] === true)) { //load CSS for admin or on triggered
|
73 |
wp_print_styles(array($name));
|
74 |
}
|
@@ -79,7 +80,14 @@ class SQ_Classes_DisplayController {
|
|
79 |
|
80 |
if ($js_uri <> '') {
|
81 |
if (!wp_script_is($name)) {
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
if (is_admin() || isset($params['trigger']) && $params['trigger'] === true) {
|
84 |
wp_print_scripts(array($name));
|
85 |
}
|
@@ -97,12 +105,21 @@ class SQ_Classes_DisplayController {
|
|
97 |
* @return bool|string
|
98 |
*/
|
99 |
public function getView($block, $view) {
|
100 |
-
if (file_exists(_SQ_THEME_DIR_ . $block . '.php')) {
|
101 |
-
ob_start();
|
102 |
-
include(_SQ_THEME_DIR_ . $block . '.php');
|
103 |
-
return ob_get_clean();
|
104 |
-
}
|
105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
return false;
|
107 |
}
|
|
|
108 |
}
|
7 |
|
8 |
private static $cache;
|
9 |
|
|
|
|
|
|
|
|
|
|
|
10 |
/**
|
11 |
* echo the css link from theme css directory
|
12 |
*
|
13 |
* @param string $uri The name of the css file or the entire uri path of the css file
|
14 |
* @param string $params : trigger, media
|
15 |
*
|
16 |
+
* @return void
|
17 |
*/
|
18 |
+
public static function loadMedia($uri = '', $params = array()) {
|
19 |
+
if (SQ_Classes_Helpers_Tools::isAjax()) {
|
20 |
return;
|
21 |
}
|
22 |
|
23 |
+
if (empty($params)) {
|
24 |
+
$params = array(
|
25 |
+
'trigger' => false,
|
26 |
+
'media' => 'all'
|
27 |
+
);
|
28 |
+
}
|
29 |
+
|
30 |
$css_uri = '';
|
31 |
$js_uri = '';
|
32 |
|
|
|
|
|
|
|
|
|
33 |
if (isset(self::$cache[$uri]))
|
34 |
return;
|
35 |
+
|
36 |
self::$cache[$uri] = true;
|
37 |
|
38 |
/* if is a custom css file */
|
39 |
if (strpos($uri, '//') === false) {
|
40 |
+
$name = substr(md5($uri), 0, 10);
|
41 |
+
|
42 |
+
if (strpos($uri, '.css') !== false && file_exists(_SQ_ASSETS_DIR_ . 'css/' . strtolower($uri))) {
|
43 |
+
$css_uri = _SQ_ASSETS_URL_ . 'css/' . strtolower($uri);
|
|
|
|
|
|
|
44 |
}
|
45 |
+
if (file_exists(_SQ_ASSETS_DIR_ . 'css/' . strtolower($uri) . (SQ_DEBUG ? '' : '.min') . '.css')) {
|
46 |
+
$css_uri = _SQ_ASSETS_URL_ . 'css/' . strtolower($uri) . (SQ_DEBUG ? '' : '.min') . '.css';
|
47 |
}
|
48 |
|
49 |
+
if (strpos($uri, '.js') !== false && file_exists(_SQ_ASSETS_DIR_ . 'js/' . strtolower($uri))) {
|
50 |
+
$js_uri = _SQ_ASSETS_URL_ . 'js/' . strtolower($uri);
|
51 |
}
|
52 |
+
if (file_exists(_SQ_ASSETS_DIR_ . 'js/' . strtolower($uri) . (SQ_DEBUG ? '' : '.min') . '.js')) {
|
53 |
+
$js_uri = _SQ_ASSETS_URL_ . 'js/' . strtolower($uri) . (SQ_DEBUG ? '' : '.min') . '.js';
|
54 |
}
|
55 |
+
|
56 |
} else {
|
57 |
+
|
58 |
+
$name = substr(md5($uri), 0, 10);
|
59 |
+
|
60 |
+
if (strpos($uri, '.css') !== FALSE) {
|
61 |
$css_uri = $uri;
|
62 |
+
} elseif (strpos($uri, '.js') !== FALSE) {
|
63 |
$js_uri = $uri;
|
64 |
}
|
65 |
+
|
66 |
}
|
67 |
|
68 |
|
69 |
if ($css_uri <> '') {
|
70 |
if (!wp_style_is($name)) {
|
71 |
+
wp_enqueue_style($name, $css_uri, null, SQ_VERSION, $params['media']);
|
72 |
+
|
73 |
if (is_admin() || (isset($params['trigger']) && $params['trigger'] === true)) { //load CSS for admin or on triggered
|
74 |
wp_print_styles(array($name));
|
75 |
}
|
80 |
|
81 |
if ($js_uri <> '') {
|
82 |
if (!wp_script_is($name)) {
|
83 |
+
|
84 |
+
if (!wp_script_is('jquery')) {
|
85 |
+
wp_enqueue_script('jquery');
|
86 |
+
wp_print_scripts(array('jquery'));
|
87 |
+
}
|
88 |
+
|
89 |
+
wp_enqueue_script($name, $js_uri, null, SQ_VERSION);
|
90 |
+
|
91 |
if (is_admin() || isset($params['trigger']) && $params['trigger'] === true) {
|
92 |
wp_print_scripts(array($name));
|
93 |
}
|
105 |
* @return bool|string
|
106 |
*/
|
107 |
public function getView($block, $view) {
|
|
|
|
|
|
|
|
|
|
|
108 |
|
109 |
+
try {
|
110 |
+
$file = _SQ_THEME_DIR_ . $block . '.php';
|
111 |
+
|
112 |
+
if (file_exists($file)) {
|
113 |
+
|
114 |
+
ob_start();
|
115 |
+
include($file);
|
116 |
+
return ob_get_clean();
|
117 |
+
}
|
118 |
+
|
119 |
+
} catch (Exception $e) {
|
120 |
+
SQ_Debug::dump($file, $e->getMessage(), $e->getFile(), $e->getLine());
|
121 |
+
}
|
122 |
return false;
|
123 |
}
|
124 |
+
|
125 |
}
|
classes/Error.php
CHANGED
@@ -1,49 +1,51 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
class SQ_Classes_Error extends SQ_Classes_FrontController {
|
4 |
|
5 |
/** @var array */
|
6 |
-
private static $errors
|
|
|
7 |
|
8 |
-
/**
|
9 |
-
* The error controller for Squirrly
|
10 |
-
*/
|
11 |
public function __construct() {
|
12 |
parent::__construct();
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
self::setError(__('Function get_class does not exists! Is required for Squirrly to work properly.', _SQ_PLUGIN_NAME_));
|
17 |
-
}
|
18 |
-
if (!function_exists('file_exists')) {
|
19 |
-
self::setError(__('Function file_exists does not exists! Is required for Squirrly to work properly.', _SQ_PLUGIN_NAME_));
|
20 |
-
}
|
21 |
-
|
22 |
-
if (!defined('ABSPATH'))
|
23 |
-
self::setError(__('The home directory is not set!', _SQ_PLUGIN_NAME_), 'fatal');
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
28 |
}
|
|
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
* Show the error in wrodpress
|
33 |
*
|
34 |
* @param string $error
|
35 |
-
* @param
|
36 |
-
*
|
37 |
-
* @return void;
|
38 |
*/
|
39 |
public static function setError($error = '', $type = 'notice', $id = '') {
|
40 |
-
self::$errors[] = array(
|
|
|
41 |
'type' => $type,
|
42 |
'text' => $error);
|
43 |
}
|
44 |
|
|
|
|
|
|
|
|
|
45 |
public static function setMessage($message = '', $id = '') {
|
46 |
-
self::$errors[] = array(
|
|
|
47 |
'type' => 'success',
|
48 |
'text' => $message);
|
49 |
}
|
@@ -51,7 +53,7 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
|
|
51 |
/**
|
52 |
* This hook will show the error in WP header
|
53 |
*/
|
54 |
-
function hookNotices() {
|
55 |
if (is_array(self::$errors))
|
56 |
foreach (self::$errors as $error) {
|
57 |
|
@@ -62,29 +64,29 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
|
|
62 |
break;
|
63 |
case 'settings':
|
64 |
/* switch off option for notifications */
|
65 |
-
self::showError(
|
66 |
break;
|
67 |
|
68 |
case 'helpnotice':
|
69 |
-
if (!
|
70 |
self::$switch_off = "<a href=\"javascript:void(0);\" onclick=\"jQuery.post( ajaxurl, {action: 'sq_warnings_off', nonce: '" . wp_create_nonce(_SQ_NONCE_ID_) . "'}, function() {jQuery('#sq_ignore_warn').attr('checked', true); jQuery('.sq_message').hide(); jQuery('#toplevel_page_squirrly .awaiting-mod').fadeOut('slow'); });\" >" . __("Don't bother me!", _SQ_PLUGIN_NAME_) . "</a>";
|
71 |
-
self::showError(
|
72 |
}
|
73 |
break;
|
74 |
|
75 |
case 'success':
|
76 |
-
self::showError(
|
77 |
break;
|
78 |
|
79 |
case 'trial':
|
80 |
-
if (
|
81 |
self::$switch_off = "<a href=\"javascript:void(0);\" style=\"font-size: 12px;float:right;margin-right: 5px;color: #ddd;\" onclick=\"jQuery.post( ajaxurl, {action: 'sq_google_alert_trial', nonce: '" . wp_create_nonce(_SQ_NONCE_ID_) . "'}, function() {jQuery('.sq_message').fadeOut('slow');});\" >" . __("Don't bother me!", _SQ_PLUGIN_NAME_) . "</a>";
|
82 |
-
self::showError(
|
83 |
}
|
84 |
break;
|
85 |
default:
|
86 |
|
87 |
-
self::showError(
|
88 |
}
|
89 |
}
|
90 |
self::$errors = array();
|
@@ -93,10 +95,31 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
|
|
93 |
/**
|
94 |
* Show the notices to WP
|
95 |
*
|
|
|
|
|
96 |
* @return string
|
97 |
*/
|
98 |
-
public static function
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
if (file_exists(_SQ_THEME_DIR_ . 'Notices.php')) {
|
101 |
include(_SQ_THEME_DIR_ . 'Notices.php');
|
102 |
} else {
|
@@ -104,4 +127,5 @@ class SQ_Classes_Error extends SQ_Classes_FrontController {
|
|
104 |
}
|
105 |
}
|
106 |
|
|
|
107 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') || exit;
|
4 |
+
|
5 |
class SQ_Classes_Error extends SQ_Classes_FrontController {
|
6 |
|
7 |
/** @var array */
|
8 |
+
private static $errors = array();
|
9 |
+
private static $switch_off = array();
|
10 |
|
|
|
|
|
|
|
11 |
public function __construct() {
|
12 |
parent::__construct();
|
13 |
|
14 |
+
add_action('sq_notices', array('SQ_Classes_Error', 'hookNotices'));
|
15 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
+
/**
|
18 |
+
* Get the error message
|
19 |
+
* @return int
|
20 |
+
*/
|
21 |
+
public static function getError() {
|
22 |
+
if (count(self::$errors) > 0) {
|
23 |
+
return self::$errors[0]['text'];
|
24 |
}
|
25 |
+
return false;
|
26 |
}
|
27 |
|
28 |
/**
|
29 |
* Show the error in wrodpress
|
30 |
*
|
31 |
* @param string $error
|
32 |
+
* @param string $type
|
33 |
+
* @param string $id
|
|
|
34 |
*/
|
35 |
public static function setError($error = '', $type = 'notice', $id = '') {
|
36 |
+
self::$errors[] = array(
|
37 |
+
'id' => $id,
|
38 |
'type' => $type,
|
39 |
'text' => $error);
|
40 |
}
|
41 |
|
42 |
+
public static function isError() {
|
43 |
+
return (count(self::$errors) > 0);
|
44 |
+
}
|
45 |
+
|
46 |
public static function setMessage($message = '', $id = '') {
|
47 |
+
self::$errors[] = array(
|
48 |
+
'id' => $id,
|
49 |
'type' => 'success',
|
50 |
'text' => $message);
|
51 |
}
|
53 |
/**
|
54 |
* This hook will show the error in WP header
|
55 |
*/
|
56 |
+
public static function hookNotices() {
|
57 |
if (is_array(self::$errors))
|
58 |
foreach (self::$errors as $error) {
|
59 |
|
64 |
break;
|
65 |
case 'settings':
|
66 |
/* switch off option for notifications */
|
67 |
+
self::showError($error['text'] . " ", $error['id']);
|
68 |
break;
|
69 |
|
70 |
case 'helpnotice':
|
71 |
+
if (!SQ_Classes_Helpers_Tools::getOption('ignore_warn')) {
|
72 |
self::$switch_off = "<a href=\"javascript:void(0);\" onclick=\"jQuery.post( ajaxurl, {action: 'sq_warnings_off', nonce: '" . wp_create_nonce(_SQ_NONCE_ID_) . "'}, function() {jQuery('#sq_ignore_warn').attr('checked', true); jQuery('.sq_message').hide(); jQuery('#toplevel_page_squirrly .awaiting-mod').fadeOut('slow'); });\" >" . __("Don't bother me!", _SQ_PLUGIN_NAME_) . "</a>";
|
73 |
+
self::showError($error['text'] . " " . self::$switch_off, $error['id'], 'sq_helpnotice');
|
74 |
}
|
75 |
break;
|
76 |
|
77 |
case 'success':
|
78 |
+
self::showError($error['text'] . " ", $error['id'], 'sq_success');
|
79 |
break;
|
80 |
|
81 |
case 'trial':
|
82 |
+
if (SQ_Classes_Helpers_Tools::getOption('sq_google_alert_trial')) {
|
83 |
self::$switch_off = "<a href=\"javascript:void(0);\" style=\"font-size: 12px;float:right;margin-right: 5px;color: #ddd;\" onclick=\"jQuery.post( ajaxurl, {action: 'sq_google_alert_trial', nonce: '" . wp_create_nonce(_SQ_NONCE_ID_) . "'}, function() {jQuery('.sq_message').fadeOut('slow');});\" >" . __("Don't bother me!", _SQ_PLUGIN_NAME_) . "</a>";
|
84 |
+
self::showError($error['text'] . " " . self::$switch_off, $error['id'], 'sq_success');
|
85 |
}
|
86 |
break;
|
87 |
default:
|
88 |
|
89 |
+
self::showError($error['text'], $error['id']);
|
90 |
}
|
91 |
}
|
92 |
self::$errors = array();
|
95 |
/**
|
96 |
* Show the notices to WP
|
97 |
*
|
98 |
+
* @param $message
|
99 |
+
* @param string $type
|
100 |
* @return string
|
101 |
*/
|
102 |
+
public static function showNotices($message, $type = 'sq_notices') {
|
103 |
+
if (file_exists(_SQ_THEME_DIR_ . 'Notices.php')) {
|
104 |
+
ob_start();
|
105 |
+
include(_SQ_THEME_DIR_ . 'Notices.php');
|
106 |
+
$message = ob_get_contents();
|
107 |
+
ob_end_clean();
|
108 |
+
}
|
109 |
|
110 |
+
return $message;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Show the notices to WP
|
115 |
+
*
|
116 |
+
* @param $message
|
117 |
+
* @param string $id
|
118 |
+
* @param string $type
|
119 |
+
*
|
120 |
+
* return void
|
121 |
+
*/
|
122 |
+
public static function showError($message, $id = '', $type = 'sq_error') {
|
123 |
if (file_exists(_SQ_THEME_DIR_ . 'Notices.php')) {
|
124 |
include(_SQ_THEME_DIR_ . 'Notices.php');
|
125 |
} else {
|
127 |
}
|
128 |
}
|
129 |
|
130 |
+
|
131 |
}
|
classes/FrontController.php
CHANGED
@@ -12,40 +12,38 @@ class SQ_Classes_FrontController {
|
|
12 |
/** @var boolean */
|
13 |
public $flush = true;
|
14 |
|
15 |
-
/** @var object of the view class */
|
16 |
-
public $view;
|
17 |
-
|
18 |
/** @var name of the class */
|
19 |
private $name;
|
20 |
|
21 |
public function __construct() {
|
22 |
-
|
23 |
SQ_Classes_ObjController::getClass('SQ_Classes_Error');
|
24 |
-
/* Load Tools */
|
25 |
-
SQ_Classes_ObjController::getClass('SQ_Classes_Tools');
|
26 |
|
27 |
/* get the name of the current class */
|
28 |
$this->name = get_class($this);
|
29 |
|
30 |
/* load the model and hooks here for wordpress actions to take efect */
|
31 |
/* create the model and view instances */
|
32 |
-
$
|
|
|
|
|
|
|
33 |
|
34 |
//IMPORTANT TO LOAD HOOKS HERE
|
35 |
/* check if there is a hook defined in the controller clients class */
|
36 |
SQ_Classes_ObjController::getClass('SQ_Classes_HookController')->setHooks($this);
|
37 |
|
38 |
/* Load the Submit Actions Handler */
|
39 |
-
SQ_Classes_ObjController::getClass('
|
40 |
SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController');
|
41 |
|
42 |
-
//abstract classes
|
43 |
SQ_Classes_ObjController::getClass('SQ_Models_Abstract_Domain');
|
44 |
SQ_Classes_ObjController::getClass('SQ_Models_Abstract_Models');
|
45 |
SQ_Classes_ObjController::getClass('SQ_Models_Abstract_Seo');
|
46 |
}
|
47 |
|
48 |
-
public function getClass(){
|
49 |
return $this->name;
|
50 |
}
|
51 |
|
@@ -56,35 +54,27 @@ class SQ_Classes_FrontController {
|
|
56 |
* @return mixed
|
57 |
*/
|
58 |
public function init() {
|
59 |
-
|
60 |
-
SQ_Classes_ObjController::getClass('SQ_Classes_ObjController')->getBlocks($this->name);
|
61 |
|
62 |
if ($this->flush) {
|
63 |
-
|
|
|
|
|
64 |
} else {
|
65 |
-
return $this->getView();
|
66 |
}
|
|
|
|
|
67 |
}
|
68 |
|
69 |
/**
|
70 |
* Get the block view
|
71 |
*
|
72 |
-
* @param
|
73 |
* @return mixed
|
74 |
*/
|
75 |
-
public function getView($view
|
76 |
-
|
77 |
-
if ($class = SQ_Classes_ObjController::getClassPath($this->name)) {
|
78 |
-
$view = $class['name'];
|
79 |
-
}
|
80 |
-
}
|
81 |
-
|
82 |
-
if (isset($view)) {
|
83 |
-
$this->view = SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController');
|
84 |
-
return $this->view->getView($view, $this);
|
85 |
-
}
|
86 |
-
|
87 |
-
return '';
|
88 |
}
|
89 |
|
90 |
/**
|
@@ -93,6 +83,7 @@ class SQ_Classes_FrontController {
|
|
93 |
*/
|
94 |
public function show() {
|
95 |
$this->flush = true;
|
|
|
96 |
echo $this->init();
|
97 |
}
|
98 |
|
@@ -103,8 +94,14 @@ class SQ_Classes_FrontController {
|
|
103 |
* @return void
|
104 |
*/
|
105 |
public function runAdmin() {
|
106 |
-
|
|
|
|
|
|
|
|
|
107 |
SQ_Classes_ObjController::getClass('SQ_Controllers_Menu');
|
|
|
|
|
108 |
}
|
109 |
|
110 |
/**
|
@@ -115,10 +112,7 @@ class SQ_Classes_FrontController {
|
|
115 |
SQ_Classes_ObjController::getClass('SQ_Controllers_Frontend');
|
116 |
|
117 |
/* show the topbar admin menu and post actions */
|
118 |
-
SQ_Classes_ObjController::getClass('
|
119 |
-
|
120 |
-
/* call the API for save posts */
|
121 |
-
SQ_Classes_ObjController::getClass('SQ_Controllers_Api');
|
122 |
|
123 |
}
|
124 |
|
@@ -126,29 +120,13 @@ class SQ_Classes_FrontController {
|
|
126 |
* first function call for any class
|
127 |
*
|
128 |
*/
|
129 |
-
protected function action() {
|
130 |
-
|
131 |
-
// check to see if the submitted nonce matches with the
|
132 |
-
// generated nonce we created
|
133 |
-
if (function_exists('wp_verify_nonce'))
|
134 |
-
if (!wp_verify_nonce(SQ_Classes_Tools::getValue('nonce'), _SQ_NONCE_ID_))
|
135 |
-
die('Invalid request!');
|
136 |
-
}
|
137 |
|
138 |
/**
|
139 |
* This function will load the media in the header for each class
|
140 |
*
|
141 |
* @return void
|
142 |
*/
|
143 |
-
public function hookHead() {
|
144 |
-
if (!is_admin()) {
|
145 |
-
return;
|
146 |
-
}
|
147 |
-
|
148 |
-
SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->init();
|
149 |
-
if ($class = SQ_Classes_ObjController::getClassPath($this->name)) {
|
150 |
-
SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia($class['name']);
|
151 |
-
}
|
152 |
-
}
|
153 |
|
154 |
}
|
12 |
/** @var boolean */
|
13 |
public $flush = true;
|
14 |
|
|
|
|
|
|
|
15 |
/** @var name of the class */
|
16 |
private $name;
|
17 |
|
18 |
public function __construct() {
|
19 |
+
// Load error class
|
20 |
SQ_Classes_ObjController::getClass('SQ_Classes_Error');
|
|
|
|
|
21 |
|
22 |
/* get the name of the current class */
|
23 |
$this->name = get_class($this);
|
24 |
|
25 |
/* load the model and hooks here for wordpress actions to take efect */
|
26 |
/* create the model and view instances */
|
27 |
+
$model_classname = str_replace('Controllers', 'Models', $this->name);
|
28 |
+
if(SQ_Classes_ObjController::getClassPath($model_classname)) {
|
29 |
+
$this->model = SQ_Classes_ObjController::getClass($model_classname);
|
30 |
+
}
|
31 |
|
32 |
//IMPORTANT TO LOAD HOOKS HERE
|
33 |
/* check if there is a hook defined in the controller clients class */
|
34 |
SQ_Classes_ObjController::getClass('SQ_Classes_HookController')->setHooks($this);
|
35 |
|
36 |
/* Load the Submit Actions Handler */
|
37 |
+
SQ_Classes_ObjController::getClass('SQ_Classes_ActionController');
|
38 |
SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController');
|
39 |
|
40 |
+
// load the abstract classes
|
41 |
SQ_Classes_ObjController::getClass('SQ_Models_Abstract_Domain');
|
42 |
SQ_Classes_ObjController::getClass('SQ_Models_Abstract_Models');
|
43 |
SQ_Classes_ObjController::getClass('SQ_Models_Abstract_Seo');
|
44 |
}
|
45 |
|
46 |
+
public function getClass() {
|
47 |
return $this->name;
|
48 |
}
|
49 |
|
54 |
* @return mixed
|
55 |
*/
|
56 |
public function init() {
|
57 |
+
$class = SQ_Classes_ObjController::getClassPath($this->name);
|
|
|
58 |
|
59 |
if ($this->flush) {
|
60 |
+
SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->loadMedia($class['name']);
|
61 |
+
|
62 |
+
echo $this->getView($class['name']);
|
63 |
} else {
|
64 |
+
return $this->getView($class['name']);
|
65 |
}
|
66 |
+
|
67 |
+
return '';
|
68 |
}
|
69 |
|
70 |
/**
|
71 |
* Get the block view
|
72 |
*
|
73 |
+
* @param string $view Class name
|
74 |
* @return mixed
|
75 |
*/
|
76 |
+
public function getView($view) {
|
77 |
+
return SQ_Classes_ObjController::getClass('SQ_Classes_DisplayController')->getView($view, $this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
}
|
79 |
|
80 |
/**
|
83 |
*/
|
84 |
public function show() {
|
85 |
$this->flush = true;
|
86 |
+
|
87 |
echo $this->init();
|
88 |
}
|
89 |
|
94 |
* @return void
|
95 |
*/
|
96 |
public function runAdmin() {
|
97 |
+
// load the remote controller in admin
|
98 |
+
SQ_Classes_ObjController::getClass('SQ_Classes_RemoteController');
|
99 |
+
SQ_Classes_ObjController::getClass('SQ_Models_Abstract_Assistant');
|
100 |
+
|
101 |
+
// show the admin menu and post actions
|
102 |
SQ_Classes_ObjController::getClass('SQ_Controllers_Menu');
|
103 |
+
SQ_Classes_ObjController::getClass('SQ_Models_RoleManager');
|
104 |
+
|
105 |
}
|
106 |
|
107 |
/**
|
112 |
SQ_Classes_ObjController::getClass('SQ_Controllers_Frontend');
|
113 |
|
114 |
/* show the topbar admin menu and post actions */
|
115 |
+
SQ_Classes_ObjController::getClass('SQ_Controllers_Snippet');
|
|
|
|
|
|
|
116 |
|
117 |
}
|
118 |
|
120 |
* first function call for any class
|
121 |
*
|
122 |
*/
|
123 |
+
protected function action() { }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
|
125 |
/**
|
126 |
* This function will load the media in the header for each class
|
127 |
*
|
128 |
* @return void
|
129 |
*/
|
130 |
+
public function hookHead() {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
|
132 |
}
|
classes/HookController.php
CHANGED
@@ -104,8 +104,10 @@ class SQ_Classes_HookController {
|
|
104 |
|
105 |
/* for each admin action check if is defined in class and call it */
|
106 |
foreach ($this->block_hooks as $hook => $value)
|
107 |
-
if (is_callable(array($instance, 'hook' . ucfirst($hook))))
|
|
|
108 |
call_user_func_array(array($instance, 'hook' . ucfirst($hook)), $param_arr);
|
|
|
109 |
}
|
110 |
|
111 |
}
|
104 |
|
105 |
/* for each admin action check if is defined in class and call it */
|
106 |
foreach ($this->block_hooks as $hook => $value)
|
107 |
+
if (is_callable(array($instance, 'hook' . ucfirst($hook)))){
|
108 |
+
//call the WP add_action function
|
109 |
call_user_func_array(array($instance, 'hook' . ucfirst($hook)), $param_arr);
|
110 |
+
}
|
111 |
}
|
112 |
|
113 |
}
|
classes/ObjController.php
CHANGED
@@ -8,32 +8,34 @@ class SQ_Classes_ObjController {
|
|
8 |
/** @var array of instances */
|
9 |
public static $instances;
|
10 |
|
11 |
-
/**
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
15 |
public static function getClass($className, $args = array()) {
|
16 |
|
17 |
if ($class = self::getClassPath($className)) {
|
18 |
if (!isset(self::$instances[$className])) {
|
19 |
/* check if class is already defined */
|
20 |
if (!class_exists($className) || $className == get_class()) {
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
-
|
32 |
-
} else {
|
33 |
-
self::$instances[$className] = true;
|
34 |
}
|
35 |
-
} else {
|
36 |
-
|
37 |
}
|
38 |
} else
|
39 |
return self::$instances[$className];
|
@@ -41,30 +43,74 @@ class SQ_Classes_ObjController {
|
|
41 |
return false;
|
42 |
}
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
try {
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
} catch (Exception $e) {
|
50 |
-
|
51 |
}
|
|
|
|
|
|
|
52 |
}
|
53 |
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
|
|
|
|
|
|
|
|
66 |
}
|
67 |
-
|
|
|
68 |
}
|
69 |
|
70 |
|
@@ -104,7 +150,7 @@ class SQ_Classes_ObjController {
|
|
104 |
for ($i = 1; $i < sizeof($path) - 1; $i++)
|
105 |
$dir .= strtolower($path[$i]) . '/';
|
106 |
|
107 |
-
$class = array('dir' => _SQ_ROOT_DIR_ .
|
108 |
'name' => $path[sizeof($path) - 1]);
|
109 |
|
110 |
if (file_exists($class['dir'] . $class['name'] . '.php')) {
|
@@ -114,87 +160,4 @@ class SQ_Classes_ObjController {
|
|
114 |
return false;
|
115 |
}
|
116 |
|
117 |
-
|
118 |
-
/**
|
119 |
-
* Deprecated since 8.0.2
|
120 |
-
* Get the instance of the specified class
|
121 |
-
*
|
122 |
-
* @param string $className
|
123 |
-
* @param bool $core TRUE is the class is a core class or FALSE if it is from classes directory
|
124 |
-
*
|
125 |
-
* @return bool|object of the class
|
126 |
-
*/
|
127 |
-
public static function getController($className, $core = true) {
|
128 |
-
if (strpos($className, 'Controllers') === false) {
|
129 |
-
$className = _SQ_NAMESPACE_ . '_Controllers_' . str_replace(_SQ_NAMESPACE_ . '_', '', $className);
|
130 |
-
}
|
131 |
-
return self::getClass($className);
|
132 |
-
}
|
133 |
-
|
134 |
-
/**
|
135 |
-
* Deprecated since 8.0.2
|
136 |
-
* Get the instance of the specified model class
|
137 |
-
*
|
138 |
-
* @param string $className
|
139 |
-
*
|
140 |
-
* @return bool|object of the class
|
141 |
-
*/
|
142 |
-
public static function getModel($className) {
|
143 |
-
if (strpos($className, 'Model') === false) {
|
144 |
-
$className = _SQ_NAMESPACE_ . '_Models_' . str_replace(_SQ_NAMESPACE_ . '_', '', $className);
|
145 |
-
}
|
146 |
-
return self::getClass($className);
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* Get the instance of the specified block from core directory
|
151 |
-
*
|
152 |
-
* @param string $className
|
153 |
-
*
|
154 |
-
* @return bool|object of the class
|
155 |
-
*/
|
156 |
-
public static function getBlock($className) {
|
157 |
-
if (strpos($className, 'Core') === false) {
|
158 |
-
$className = _SQ_NAMESPACE_ . '_Core_' . str_replace(_SQ_NAMESPACE_ . '_', '', $className);
|
159 |
-
}
|
160 |
-
return self::getClass($className);
|
161 |
-
}
|
162 |
-
|
163 |
-
/**
|
164 |
-
* Get all core classes from config.json in core directory
|
165 |
-
* eg.SQ_Controllers_Post
|
166 |
-
* @param string $for
|
167 |
-
*/
|
168 |
-
public function getBlocks($for) {
|
169 |
-
/* if config allready in cache */
|
170 |
-
if (!isset(self::$config)) {
|
171 |
-
$config_file = _SQ_CORE_DIR_ . 'config.json';
|
172 |
-
if (!file_exists($config_file))
|
173 |
-
return;
|
174 |
-
|
175 |
-
/* load configuration blocks data from core config files */
|
176 |
-
self::$config = json_decode(file_get_contents($config_file), 1);;
|
177 |
-
}
|
178 |
-
//print_r(self::$config);
|
179 |
-
if (is_array(self::$config))
|
180 |
-
foreach (self::$config['blocks']['block'] as $block) {
|
181 |
-
if ($block['active'] == 1)
|
182 |
-
if (isset($block['controllers']['controller']))
|
183 |
-
if (!is_array($block['controllers']['controller'])) {
|
184 |
-
/* if the block should load for the current controller */
|
185 |
-
if ($for == $block['controllers']['controller']) {
|
186 |
-
SQ_Classes_ObjController::getClass($block['name'])->init();
|
187 |
-
}
|
188 |
-
} else {
|
189 |
-
foreach ($block['controllers']['controller'] as $controller) {
|
190 |
-
/* if the block should load for the current controller */
|
191 |
-
if ($for == $controller) {
|
192 |
-
SQ_Classes_ObjController::getClass($block['name'])->init();
|
193 |
-
}
|
194 |
-
}
|
195 |
-
}
|
196 |
-
}
|
197 |
-
|
198 |
-
}
|
199 |
-
|
200 |
}
|
8 |
/** @var array of instances */
|
9 |
public static $instances;
|
10 |
|
11 |
+
/**
|
12 |
+
* @param $className
|
13 |
+
* @param array $args
|
14 |
+
* @return bool|mixed
|
15 |
+
*/
|
16 |
public static function getClass($className, $args = array()) {
|
17 |
|
18 |
if ($class = self::getClassPath($className)) {
|
19 |
if (!isset(self::$instances[$className])) {
|
20 |
/* check if class is already defined */
|
21 |
if (!class_exists($className) || $className == get_class()) {
|
22 |
+
try {
|
23 |
+
self::includeClass($class['dir'], $class['name']);
|
24 |
+
|
25 |
+
//check if abstract
|
26 |
+
$check = new ReflectionClass($className);
|
27 |
+
$abstract = $check->isAbstract();
|
28 |
+
if (!$abstract) {
|
29 |
+
self::$instances[$className] = new $className();
|
30 |
+
if (!empty($args)) {
|
31 |
+
call_user_func_array(array(self::$instances[$className], '__construct'), $args);
|
32 |
+
}
|
33 |
+
return self::$instances[$className];
|
34 |
+
} else {
|
35 |
+
self::$instances[$className] = true;
|
36 |
}
|
37 |
+
} catch (Exception $e) {
|
|
|
|
|
38 |
}
|
|
|
|
|
39 |
}
|
40 |
} else
|
41 |
return self::$instances[$className];
|
43 |
return false;
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* Get a new instance of the class
|
48 |
+
* @param $className
|
49 |
+
* @param array $args
|
50 |
+
* @return bool|mixed
|
51 |
+
*/
|
52 |
+
public static function getNewClass($className, $args = array()) {
|
53 |
+
$instance = false;
|
54 |
+
if ($class = self::getClassPath($className)) {
|
55 |
+
/* check if class is already defined */
|
56 |
try {
|
57 |
+
if (!class_exists($className) || $className == get_class()) {
|
58 |
+
self::includeClass($class['dir'], $class['name']);
|
59 |
+
}
|
60 |
+
|
61 |
+
//check if abstract
|
62 |
+
$check = new ReflectionClass($className);
|
63 |
+
$abstract = $check->isAbstract();
|
64 |
+
if (!$abstract) {
|
65 |
+
$instance = new $className();
|
66 |
+
|
67 |
+
if (!empty($args)) {
|
68 |
+
call_user_func_array(array($instance, '__construct'), $args);
|
69 |
+
}
|
70 |
+
return $instance;
|
71 |
+
} else {
|
72 |
+
$instance = true;
|
73 |
+
}
|
74 |
} catch (Exception $e) {
|
75 |
+
SQ_Debug::dump($e->getMessage());
|
76 |
}
|
77 |
+
|
78 |
+
}
|
79 |
+
return $instance;
|
80 |
}
|
81 |
|
82 |
+
/**
|
83 |
+
* @param $classDir
|
84 |
+
* @param $className
|
85 |
+
* @throws Exception
|
86 |
+
*/
|
87 |
+
private static function includeClass($classDir, $className) {
|
88 |
+
$file = $classDir . $className . '.php';
|
89 |
+
try {
|
90 |
+
if (file_exists($file)) {
|
91 |
+
include_once($file);
|
92 |
+
}
|
93 |
+
} catch (Exception $e) {
|
94 |
+
throw new Exception('Controller Error: ' . $e->getMessage());
|
95 |
+
}
|
96 |
+
}
|
97 |
|
98 |
+
/**
|
99 |
+
* @param $className
|
100 |
+
* @param array $args
|
101 |
+
* @return stdClass
|
102 |
+
*/
|
103 |
+
public static function getDomain($className, $args = array()) {
|
104 |
+
try {
|
105 |
+
if ($class = self::getClassPath($className)) {
|
106 |
+
self::includeClass($class['dir'], $class['name']);
|
107 |
+
return new $className($args);
|
108 |
+
}
|
109 |
+
} catch (Exception $e) {
|
110 |
+
SQ_Debug::dump($e->getMessage());
|
111 |
}
|
112 |
+
|
113 |
+
return new stdClass();
|
114 |
}
|
115 |
|
116 |
|
150 |
for ($i = 1; $i < sizeof($path) - 1; $i++)
|
151 |
$dir .= strtolower($path[$i]) . '/';
|
152 |
|
153 |
+
$class = array('dir' => _SQ_ROOT_DIR_ . $dir,
|
154 |
'name' => $path[sizeof($path) - 1]);
|
155 |
|
156 |
if (file_exists($class['dir'] . $class['name'] . '.php')) {
|
160 |
return false;
|
161 |
}
|
162 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
}
|
classes/Ranking.php
DELETED
@@ -1,336 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class for Google Ranking Record
|
5 |
-
*/
|
6 |
-
class SQ_Classes_Ranking extends SQ_Classes_FrontController {
|
7 |
-
private $keyword;
|
8 |
-
private $post_id;
|
9 |
-
private $error;
|
10 |
-
|
11 |
-
//--
|
12 |
-
public function getCountry() {
|
13 |
-
if (SQ_Classes_Tools::getOption('sq_google_country') <> '') {
|
14 |
-
return SQ_Classes_Tools::getOption('sq_google_country');
|
15 |
-
}
|
16 |
-
return 'com';
|
17 |
-
}
|
18 |
-
|
19 |
-
public function getRefererCountry() {
|
20 |
-
$convert_refc = array('com' => 'us', '.off.ai' => 'ai', 'com.ag' => 'ag', 'com.ar' => 'ar', 'com.au' => 'au', 'com.br' => 'br', 'com.co' => 'co', 'co.cr' => 'cr', 'com.cu' => 'cu', 'com.do' => 'do', 'com.ec' => 'ec', 'com.sv' => 'sv', 'com.fj' => 'fj', 'com.gi' => 'gi', 'com.gr' => 'gr', 'com.hk' => 'hk', 'co.hu' => 'hu', 'co.in' => 'in', 'co.im' => 'im', 'co.il' => 'il', 'com.jm' => 'jm', 'co.jp' => 'jp', 'co.je' => 'je', 'co.kr' => 'kr', 'co.ls' => 'ls', 'com.my' => 'my', 'com.mt' => 'mt', 'com.mx' => 'mx', 'com.na' => 'na', 'com.np' => 'np', 'com.ni' => 'ni', 'com.nf' => 'nf', 'com.pk' => 'pk', 'com.pa' => 'pa', 'com.py' => 'py', 'com.pe' => 'pe', 'com.ph' => 'ph', 'com.pr' => 'pr', 'com.sg' => 'sg', 'co.za' => 'za', 'com.tw' => 'tw', 'com.th' => 'th', 'com.tr' => 'tr', 'com.ua' => 'ua', 'com.uk' => 'uk', 'com.uy' => 'uy',);
|
21 |
-
$country = $this->getCountry();
|
22 |
-
if (array_key_exists($country, $convert_refc)) {
|
23 |
-
return $convert_refc[$country];
|
24 |
-
}
|
25 |
-
return $country;
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Get the google language from settings
|
30 |
-
* @return string
|
31 |
-
*/
|
32 |
-
public function getLanguage() {
|
33 |
-
if (SQ_Classes_Tools::getOption('sq_google_language') <> '') {
|
34 |
-
return SQ_Classes_Tools::getOption('sq_google_language');
|
35 |
-
}
|
36 |
-
return 'en';
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Set the Post id
|
41 |
-
* @return type
|
42 |
-
*/
|
43 |
-
public function setPost($post_id) {
|
44 |
-
$this->post_id = $post_id;
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Get the current keyword
|
49 |
-
* @param type $keyword
|
50 |
-
*/
|
51 |
-
public function setKeyword($keyword) {
|
52 |
-
$this->keyword = str_replace(" ", "+", urlencode(strtolower($keyword)));
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Process Ranking on brief request
|
57 |
-
* @param type $return
|
58 |
-
*/
|
59 |
-
public function processRanking($post_id, $keyword) {
|
60 |
-
$this->setPost($post_id);
|
61 |
-
$this->setKeyword(trim($keyword));
|
62 |
-
|
63 |
-
if (isset($this->keyword) && $this->keyword <> '') {
|
64 |
-
return $this->getGoogleRank();
|
65 |
-
}
|
66 |
-
return false;
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Call google to get the keyword position
|
71 |
-
*
|
72 |
-
* @param integer $post_id
|
73 |
-
* @param string $keyword
|
74 |
-
* @param string $country : com | country extension
|
75 |
-
* @param string $language : en | local language
|
76 |
-
* @return boolean|int
|
77 |
-
*/
|
78 |
-
public function getGoogleRank() {
|
79 |
-
|
80 |
-
@ini_set('open_basedir', null);
|
81 |
-
$this->error = '';
|
82 |
-
|
83 |
-
if (trim($this->keyword) == '') {
|
84 |
-
$this->error = 'no keyword for post_id:' . $this->post_id;
|
85 |
-
return false;
|
86 |
-
}
|
87 |
-
|
88 |
-
if (!function_exists('preg_match_all')) {
|
89 |
-
return false;
|
90 |
-
}
|
91 |
-
|
92 |
-
$arg = array('timeout' => 10);
|
93 |
-
$arg['as_q'] = str_replace(" ", "+", strtolower(trim($this->keyword)));
|
94 |
-
$arg['hl'] = $this->getLanguage();
|
95 |
-
//$arg['gl'] = $this->getRefererCountry();
|
96 |
-
|
97 |
-
if (SQ_Classes_Tools::getOption('sq_google_country_strict')) {
|
98 |
-
$arg['cr'] = 'country' . strtoupper($this->getRefererCountry());
|
99 |
-
}
|
100 |
-
$arg['start'] = '0';
|
101 |
-
$arg['num'] = '100';
|
102 |
-
|
103 |
-
$arg['safe'] = 'active';
|
104 |
-
$arg['pws'] = '0';
|
105 |
-
$arg['as_epq'] = '';
|
106 |
-
$arg['as_oq'] = '';
|
107 |
-
$arg['as_nlo'] = '';
|
108 |
-
$arg['as_nhi'] = '';
|
109 |
-
$arg['as_qdr'] = 'all';
|
110 |
-
$arg['as_sitesearch'] = '';
|
111 |
-
$arg['as_occt'] = 'any';
|
112 |
-
$arg['tbs'] = '';
|
113 |
-
$arg['as_filetype'] = '';
|
114 |
-
$arg['as_rights'] = '';
|
115 |
-
|
116 |
-
$country = $this->getCountry();
|
117 |
-
|
118 |
-
if ($country == '' || $arg['hl'] == '') {
|
119 |
-
$this->error = 'no country (' . $country . ')';
|
120 |
-
return false;
|
121 |
-
}
|
122 |
-
|
123 |
-
$user_agents = array(
|
124 |
-
'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
|
125 |
-
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36',
|
126 |
-
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36',
|
127 |
-
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36',
|
128 |
-
'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2226.0 Safari/537.36',
|
129 |
-
'Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36',
|
130 |
-
'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36',
|
131 |
-
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2224.3 Safari/537.36',
|
132 |
-
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36',
|
133 |
-
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36',
|
134 |
-
'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36',
|
135 |
-
'Mozilla/5.0 (Windows NT 4.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36',
|
136 |
-
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36',
|
137 |
-
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36',
|
138 |
-
'Mozilla/5.0 (X11; OpenBSD i386) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36',
|
139 |
-
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1944.0 Safari/537.36',
|
140 |
-
'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36',
|
141 |
-
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A',
|
142 |
-
'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25',
|
143 |
-
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2',
|
144 |
-
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10',
|
145 |
-
'Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko ) Version/5.1 Mobile/9B176 Safari/7534.48.3',
|
146 |
-
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1',
|
147 |
-
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; da-dk) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1',
|
148 |
-
'Mozilla/5.0 (Windows; U; Windows NT 6.1; tr-TR) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27',
|
149 |
-
'Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201',
|
150 |
-
'Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:2.0b4) Gecko/20100818',
|
151 |
-
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a3pre) Gecko/20070330',
|
152 |
-
'Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.9.2a1pre) Gecko',
|
153 |
-
'Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.3) Gecko/20100401 Lightningquail/3.6.3',
|
154 |
-
'Mozilla/5.0 (X11; ; Linux i686; rv:1.9.2.20) Gecko/20110805',
|
155 |
-
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13; ) Gecko/20101203',
|
156 |
-
'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1b3) Gecko/20090305',
|
157 |
-
'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.0.9) Gecko/2009040821',
|
158 |
-
'Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.0.8) Gecko/2009032711',
|
159 |
-
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009032803',
|
160 |
-
'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.0.7) Gecko/2009021910 MEGAUPLOAD 1.0',
|
161 |
-
'Mozilla/5.0 (Windows; U; BeOS; en-US; rv:1.9.0.7) Gecko/2009021910',
|
162 |
-
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070321',
|
163 |
-
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Mozilla/4.8 [en] (Windows NT 5.1; U)',
|
164 |
-
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; nl-NL; rv:1.8.1.3) Gecko/20080722',
|
165 |
-
'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko',
|
166 |
-
'Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko',
|
167 |
-
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 7.0; InfoPath.3; .NET CLR 3.1.40767; Trident/6.0; en-IN)',
|
168 |
-
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)',
|
169 |
-
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)',
|
170 |
-
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)',
|
171 |
-
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/4.0; InfoPath.2; SV1; .NET CLR 2.0.50727; WOW64)',
|
172 |
-
'Mozilla/5.0 (compatible; MSIE 10.0; Macintosh; Intel Mac OS X 10_7_3; Trident/6.0)',
|
173 |
-
'Mozilla/4.0 (Compatible; MSIE 8.0; Windows NT 5.2; Trident/6.0)',
|
174 |
-
'Mozilla/4.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/5.0)',
|
175 |
-
'Mozilla/1.22 (compatible; MSIE 10.0; Windows 3.1)',
|
176 |
-
'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))',
|
177 |
-
'Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)',
|
178 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)',
|
179 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7)',
|
180 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7',
|
181 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; chromeframe/12.0.742.112)',
|
182 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0',
|
183 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; yie8)',
|
184 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; chromeframe/13.0.782.215)',
|
185 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; chromeframe/11.0.696.57)',
|
186 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) chromeframe/10.0.648.205',
|
187 |
-
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; chromeframe/11.0.696.57)',
|
188 |
-
'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
|
189 |
-
'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; SLCC1; .NET CLR 1.1.4322)',
|
190 |
-
'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.0; Trident/4.0; InfoPath.1; SV1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 3.0.04506.30)',
|
191 |
-
'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.0; Trident/4.0; FBSMTWB; .NET CLR 2.0.34861; .NET CLR 3.0.3746.3218; .NET CLR 3.5.33652; msn OptimizedIE8;ENUS)',
|
192 |
-
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)',
|
193 |
-
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8)',
|
194 |
-
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; Media Center PC 6.0; InfoPath.2; MS-RTC LM 8',
|
195 |
-
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; Media Center PC 6.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C)',
|
196 |
-
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.3; .NET4.0C; .NET4.0E; .NET CLR 3.5.30729; .NET CLR 3.0.30729; MS-RTC LM 8)',
|
197 |
-
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)',
|
198 |
-
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Zune 3.0)',
|
199 |
-
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; msn OptimizedIE8;ZHCN)',
|
200 |
-
|
201 |
-
);
|
202 |
-
|
203 |
-
$option = array();
|
204 |
-
$option['User-Agent'] = $user_agents[mt_rand(0, count($user_agents) - 1)];
|
205 |
-
$option['followlocation'] = true;
|
206 |
-
//Grab the remote informations from google
|
207 |
-
$response = utf8_decode(SQ_Classes_Tools::sq_remote_get("https://www.google.$country/search", $arg, $option));
|
208 |
-
|
209 |
-
//Check the values for block IP
|
210 |
-
if (strpos($response, "</h3>") === false) {
|
211 |
-
set_transient('google_blocked', time(), 3600);
|
212 |
-
return -2; //return error
|
213 |
-
}
|
214 |
-
|
215 |
-
//Get the permalink of the current post
|
216 |
-
$permalink = get_permalink($this->post_id);
|
217 |
-
if ($permalink == '') {
|
218 |
-
$this->error = 'no permalink for post_id:' . $this->post_id;
|
219 |
-
return false;
|
220 |
-
}
|
221 |
-
|
222 |
-
preg_match_all('/<h3.*?><a href="(.*?)".*?<\/h3>/is', $response, $matches);
|
223 |
-
|
224 |
-
if (!empty($matches[1])) {
|
225 |
-
$pos = -1;
|
226 |
-
foreach ($matches[1] as $index => $url) {
|
227 |
-
if (strpos($url, rtrim(str_replace(array('https:', 'http:'), array('', ''), $permalink), '/')) !== false) {
|
228 |
-
$pos = $index + 1;
|
229 |
-
break;
|
230 |
-
}
|
231 |
-
}
|
232 |
-
return $pos;
|
233 |
-
}
|
234 |
-
$this->error = 'no results returned by google';
|
235 |
-
return false;
|
236 |
-
}
|
237 |
-
|
238 |
-
/**
|
239 |
-
* Do google rank with cron
|
240 |
-
* @global type $wpdb
|
241 |
-
*/
|
242 |
-
public function processCron() {
|
243 |
-
global $wpdb;
|
244 |
-
|
245 |
-
if (get_transient('google_blocked') !== false || SQ_Classes_Tools::getOption('sq_google_ranksperhour') == 0) {
|
246 |
-
return;
|
247 |
-
}
|
248 |
-
|
249 |
-
set_time_limit(3000);
|
250 |
-
/* Load the Submit Actions Handler */
|
251 |
-
SQ_Classes_ObjController::getClass('SQ_Classes_Tools');
|
252 |
-
SQ_Classes_ObjController::getClass('SQ_Classes_Action');
|
253 |
-
|
254 |
-
//check 20 keyword at one time
|
255 |
-
$sql = "SELECT `post_id`, `meta_value`
|
256 |
-
FROM `" . $wpdb->postmeta . "`
|
257 |
-
WHERE (`meta_key` = '_sq_post_keyword')
|
258 |
-
ORDER BY `post_id` DESC";
|
259 |
-
|
260 |
-
if ($rows = $wpdb->get_results($sql)) {
|
261 |
-
$count = 0;
|
262 |
-
foreach ($rows as $row) {
|
263 |
-
if ($count > SQ_Classes_Tools::getOption('sq_google_ranksperhour')) {
|
264 |
-
break; //check only 10 keywords at the time
|
265 |
-
}
|
266 |
-
if ($row->meta_value <> '') {
|
267 |
-
$json = json_decode($row->meta_value);
|
268 |
-
//If keyword is set and no rank or last check is 2 days ago
|
269 |
-
if (isset($json->keyword) && $json->keyword <> '' &&
|
270 |
-
(!isset($json->rank) ||
|
271 |
-
(isset($json->update) && (time() - $json->update > (60 * 60 * 24 * 2))) || //if indexed then check every 2 days
|
272 |
-
(isset($json->update) && isset($json->rank) && $json->rank == -1 && (time() - $json->update > (60 * 60 * 24))) //if not indexed than check often
|
273 |
-
)
|
274 |
-
) {
|
275 |
-
|
276 |
-
$rank = $this->processRanking($row->post_id, $json->keyword);
|
277 |
-
|
278 |
-
//if there is a success response than save it
|
279 |
-
if (isset($rank) && $rank >= -1) {
|
280 |
-
$json->rank = $rank;
|
281 |
-
$json->country = $this->getCountry();
|
282 |
-
$json->language = $this->getLanguage();
|
283 |
-
SQ_Classes_ObjController::getClass('SQ_Models_Post')->saveKeyword($row->post_id, $json);
|
284 |
-
}
|
285 |
-
set_transient('sq_rank' . $row->post_id, $rank, (60 * 60 * 24));
|
286 |
-
//if rank proccess has no error
|
287 |
-
|
288 |
-
$args = array();
|
289 |
-
$args['post_id'] = $row->post_id;
|
290 |
-
$args['rank'] = (string)$rank;
|
291 |
-
$args['error'] = $this->error;
|
292 |
-
$args['country'] = $this->getCountry();
|
293 |
-
$args['language'] = $this->getLanguage();
|
294 |
-
|
295 |
-
SQ_Classes_Action::apiCall('sq/user-analytics/saveserp', $args);
|
296 |
-
|
297 |
-
$count++;
|
298 |
-
sleep(mt_rand(20, 40));
|
299 |
-
}
|
300 |
-
}
|
301 |
-
}
|
302 |
-
}
|
303 |
-
}
|
304 |
-
|
305 |
-
/**
|
306 |
-
* Get keyword from earlier version
|
307 |
-
*
|
308 |
-
*/
|
309 |
-
public function getKeywordHistory() {
|
310 |
-
global $wpdb;
|
311 |
-
//Check if ranks is saved in database
|
312 |
-
$sql = "SELECT a.`global_rank`, a.`keyword`, a.`post_id`
|
313 |
-
FROM `sq_analytics` as a
|
314 |
-
INNER JOIN (SELECT MAX(`id`) as id FROM `sq_analytics` WHERE `keyword` <> '' GROUP BY `post_id`) as a1 ON a1.id = a.id ";
|
315 |
-
|
316 |
-
if ($rows = $wpdb->get_results($sql)) {
|
317 |
-
foreach ($rows as $values) {
|
318 |
-
if ($json = SQ_Classes_ObjController::getClass('SQ_Models_Post')->getKeyword($values->post_id)) {
|
319 |
-
$json->keyword = urldecode($values->keyword);
|
320 |
-
if ($values->global_rank > 0) {
|
321 |
-
$json->rank = $values->global_rank;
|
322 |
-
}
|
323 |
-
SQ_Classes_ObjController::getClass('SQ_Models_Post')->saveKeyword($values->post_id, $json);
|
324 |
-
} else {
|
325 |
-
$args = array();
|
326 |
-
$args['keyword'] = urldecode($values->keyword);
|
327 |
-
if ($values->global_rank > 0) {
|
328 |
-
$json->rank = $values->global_rank;
|
329 |
-
}
|
330 |
-
SQ_Classes_ObjController::getClass('SQ_Models_Post')->saveKeyword($values->post_id, json_decode(json_encode($args)));
|
331 |
-
}
|
332 |
-
}
|
333 |
-
}
|
334 |
-
}
|
335 |
-
|
336 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/RemoteController.php
ADDED
@@ -0,0 +1,1021 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|