· 10 years ago · Jan 19, 2016, 02:21 AM
1<?php
2/**
3* Core Class
4*
5* @package Wordpress
6* @subpackage Local Pages
7* @author DA
8* @version 1.06
9* @copyright smp
10*/
11
12class SerpShakerCore {
13 /**
14 * Constructor.
15 */
16 function SerpShakerCore() {
17
18 // Plugin Details
19 @$this->plugin->name = 'serpshaker';
20 @$this->plugin->displayName = 'SERP Shaker';
21 @$this->plugin->url = WP_PLUGIN_URL.'/'.str_replace(basename( __FILE__),"",plugin_basename(__FILE__));
22 @$this->plugin->maxResultsPerAdminPage = 20;
23 @$this->plugin->maxPostsToBuild = 3; // If a number is not defined, fallback to this
24 @$this->counter = 0;
25
26 // Settings
27 $this->settings = get_option($this->plugin->name);
28
29
30 // Register and load JS and CSS files
31 if (is_admin()) {
32 @wp_register_script($this->plugin->name.'admin-js', $this->plugin->url.'js/admin.js');
33 @wp_enqueue_script($this->plugin->name.'admin-js');
34
35 @wp_register_style($this->plugin->name.'-admin-css', $this->plugin->url.'css/admin.css');
36 @wp_enqueue_style($this->plugin->name.'-admin-css');
37
38 }
39
40 // Hooks and filters if licensed
41 $status = get_option( 'serp_shaker_license_status' );
42 if( $status !== true && $status !== 'valid' ) {
43 add_action('init', array(&$this, 'RegisterCustomPostTypes')); // MUST be here for rewrites to work
44 if (is_admin()) {
45 // Admin
46 add_action('admin_notices', array(&$this, 'AdminNotices'));
47 add_action('save_post', array(&$this, 'Save'));
48 add_action('admin_menu', array(&$this, 'AddAdminPanels'), 99);
49 add_action('admin_init', array(&$this, 'AddMetaBoxes'), 99);
50 add_action('manage_posts_custom_column', array(&$this, 'ManageAdminColumns'), 10, 2);
51 add_action('manage_pages_custom_column', array(&$this, 'ManageAdminColumns'), 10, 2);
52 add_filter('manage_posts_columns', array(&$this, 'AddAdminColumns'));
53 add_filter('manage_pages_columns', array(&$this, 'AddAdminColumns'));
54 ss_preset_options();
55 }
56 add_action('admin_bar_menu', array(&$this, 'AddAdminBarMenu'), 95);
57 add_action('admin_menu', array(&$this, 'AddAdminMenu'));
58 add_action('init', array(&$this, 'setupTinyMCEPlugins'));
59 // Define sub pages for Admin Menus and Admin Bar
60 $this->subPages = array('Shortcodes');
61 }
62 else {
63 // Just display link to licensing screen
64 }
65 }
66 function setupTinyMCEPlugins() {
67 if (!current_user_can('edit_posts') && !current_user_can('edit_pages')) return;
68 if (get_user_option('rich_editing') == 'true') {
69 add_filter('mce_external_plugins', array(&$this, 'addTinyMCEPlugin'));
70 add_filter('mce_buttons', array(&$this, 'addTinyMCEButton'));
71 }
72 }
73 function addTinyMCEButton($buttons) {
74 array_push($buttons, "|", 'tinyShortCode', 'sslinknext', 'sslinkprev', 'ssweather', 'ssgoogle', 'ssyoutube', 'searchreplace', 'ssnextp', 'ssprevp', 'postsincat');
75
76 return $buttons;
77 }
78 /**
79 * Adds a plugin to the TinyMCE Editor for shortcode inserts
80 */
81 function addTinyMCEPlugin($plugin_array) {
82 $plugin_array['tinyShortCode'] = $this->plugin->url.'js/tinymce-ssShort.js.php';
83 $plugin_array['sslinkn'] = $this->plugin->url.'js/tinymce-linknext.js';
84 $plugin_array['sslinkp'] = $this->plugin->url.'js/tinymce-linkprev.js';
85 $plugin_array['ssweather'] = $this->plugin->url.'js/tinymce-weather.js';
86 $plugin_array['ssgoogle'] = $this->plugin->url.'js/tinymce-google-map.js';
87 $plugin_array['ssyoutube'] = $this->plugin->url.'js/tinymce-youtube1.js';
88 $plugin_array['searchreplace'] = $this->plugin->url.'js/searchreplace/plugin.min.js';
89 $plugin_array['ssnextp'] = $this->plugin->url.'js/tinymce-nexpage.js';
90 $plugin_array['ssprevp'] = $this->plugin->url.'js/tinymce-prevpage.js';
91 // $plugin_array['subpages'] = $this->plugin->url.'js/tinymce-subpages.js';
92 $plugin_array['postsincat'] = $this->plugin->url.'js/tinymce-postsincat.js';
93 return $plugin_array;
94 }
95 function AddAdminMenu() {
96 // Add menu page for licensing
97 }
98function serp_shaker_license_page() {
99 $license = get_option( 'serp_shaker_license_key' );
100 $status = get_option( 'serp_shaker_license_status' );
101 ?>
102 <div class="wrap">
103 <h2><?php _e('Plugin License Options'); ?></h2>
104 <p>Please enter your license key below and hit "Save Changes" and then "Activate License". Your plugin will not be eligible for auto upgrades until you've activated your license</p>
105 <form method="post" action="options.php">
106
107 <?php settings_fields('serp_shaker_license'); ?>
108
109 <table class="form-table">
110 <tbody>
111 <tr valign="top">
112 <th scope="row" valign="top">
113 <?php _e('License Key'); ?>
114 </th>
115 <td>
116 <input id="serp_shaker_license_key" name="serp_shaker_license_key" type="password" class="regular-text" value="<?php esc_attr_e( $license ); ?>" />
117 <label class="description" for="serp_shaker_license_key"><?php _e('Enter your license key'); ?></label>
118 </td>
119 </tr>
120 <?php if( false !== $license ) { ?>
121 <tr valign="top">
122 <th scope="row" valign="top">
123 <?php _e('Activate License'); ?>
124 </th>
125 <td>
126 <?php if( $status !== false && $status == 'valid' ) { ?>
127 <span style="color:green;"><?php _e('Your license key has been activated'); ?></span>
128 <?php wp_nonce_field( 'serp_shaker_nonce', 'serp_shaker_nonce' ); ?>
129 <input type="submit" class="button-secondary" name="edd_license_deactivate" value="<?php _e('Deactivate License'); ?>"/>
130 <?php } else {
131 wp_nonce_field( 'serp_shaker_nonce', 'serp_shaker_nonce' ); ?>
132 <input type="submit" class="button-secondary" name="edd_license_activate" value="<?php _e('Activate License'); ?>"/>
133 <?php } ?>
134 </td>
135 </tr>
136 <?php } ?>
137 </tbody>
138 </table>
139 <?php submit_button(); ?>
140
141 </form>
142 <?php
143}
144
145 /**
146 * Activation Routine. Runs when the Administrator activates the plugin.
147 *
148 * Creates database tables (if they do not exist)
149 */
150 function Activate() {
151 global $wpdb;
152
153 // Create database tables
154 $wpdb->query("CREATE TABLE IF NOT EXISTS ".$wpdb->prefix."ss_shortcodes (
155 shortcodeID int(10) NOT NULL AUTO_INCREMENT,
156 shortcode varchar(200) NOT NULL,
157 shortcodeData longtext,
158 PRIMARY KEY (`shortcodeID`),
159 UNIQUE KEY (`shortcode`)
160 )
161 ENGINE=innoDB
162 DEFAULT CHARSET=utf8
163 AUTO_INCREMENT=1");
164
165 $wpdb->query("CREATE TABLE IF NOT EXISTS ".$wpdb->prefix."ss_dynamicodes (
166 shortcodeID int(10) NOT NULL AUTO_INCREMENT,
167 shortcode varchar(200) NOT NULL,
168 shortcodeData longtext,
169 spinnable tinyint(1),
170 PRIMARY KEY (`shortcodeID`),
171 UNIQUE KEY (`shortcode`)
172 )
173 ENGINE=innoDB
174 DEFAULT CHARSET=utf8
175 AUTO_INCREMENT=1");
176
177 $wpdb->query("CREATE TABLE IF NOT EXISTS ".$wpdb->prefix."ss_ads (
178 adID int(10) NOT NULL AUTO_INCREMENT,
179 adname varchar(200) NOT NULL,
180 adData text,
181 PRIMARY KEY (`adID`),
182 UNIQUE KEY (`adname`)
183 )
184 ENGINE=innoDB
185 DEFAULT CHARSET=utf8
186 AUTO_INCREMENT=1");
187 $wpdb->query("ALTER TABLE ".$wpdb->prefix."ss_dynamicodes MODIFY shortcodeData longtext");
188 $wpdb->query("ALTER TABLE ".$wpdb->prefix."ss_shortcodes MODIFY shortcodeData longtext");
189 }
190
191 /**
192 * Registers custom post types for Local Pages
193 */
194 function RegisterCustomPostTypes() {
195 // Local Pages
196 register_post_type('shaker-page', array(
197 'labels' => array(
198 'name' => _x('Shaker Pages', 'post type general name'),
199 'singular_name' => _x('Shaker Page', 'post type singular name'),
200 'add_new' => _x('Add New', 'shaker-page'),
201 'add_new_item' => __('Add New Shaker Page'),
202 'edit_item' => __('Edit Shaker Page'),
203 'new_item' => __('New Shaker Page'),
204 'view_item' => __('View Shaker Page'),
205 'search_items' => __('Search Shaker Page'),
206 'not_found' => __('No shaker pages found'),
207 'not_found_in_trash' => __('No shaker pages found in Trash'),
208 'parent_item_colon' => ''
209 ),
210 'description' => 'Shaker Pages',
211 'public' => true,
212 'publicly_queryable' => true,
213 'exclude_from_search' => true,
214 'show_ui' => true,
215 'show_in_menu' => true,
216 'menu_position' => 20,
217 'menu_icon' => $this->plugin->url.'/images/icons/icon.png',
218 'capability_type' => 'post',
219 'hierarchical' => false,
220 'supports' => array('thumbnail', 'title', 'editor', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'post-formats', 'revisions'),//added revisions on 10-6. (test to see if it saves it)
221 'taxonomies' => array('post_tag'),
222 'has_archive' => false,
223 'show_in_nav_menus' => false
224 ));
225 }
226
227 /**
228 * If Local Pages is licensed, adds admin menus
229 */
230
231 function AddAdminPanels() {
232
233 add_submenu_page("edit.php?post_type=shaker-page", "Shortcodes", "Shortcodes", "activate_plugins", $this->plugin->name."-shortcodes", array(&$this, "AdminPanel"));
234 add_submenu_page("edit.php?post_type=shaker-page", "Dynamic Shortcodes", "Dynamic Shortcodes", "activate_plugins", $this->plugin->name. "-ss-shortcodes", "serp_shaker_shortcodes");
235 add_submenu_page("edit.php?post_type=shaker-page", "Ad Manager", "Ad Manager", "activate_plugins", $this->plugin->name. "-ss-ads", "serp_shaker_ads");
236 add_submenu_page("edit.php?post_type=shaker-page", "Shaker", "Shaker", "activate_plugins", $this->plugin->name. "-ss-shaker", "serp_shaker_shaker");
237 // add_submenu_page("edit.php?post_type=shaker-page", "Plugin License", "Plugin License & Updates", "activate_plugins", $this->plugin->name. "-ss-license", "serp_shaker_license_page");
238 // add_submenu_page("edit.php?post_type=shaker-page", "Shaker Interlink", "Shaker Interlink", "activate_plugins", $this->plugin->name. "-ss-silo", "serp_shaker_siloit");
239 // add_submenu_page("edit.php?post_type=shaker-page", "FITYMI", "FITYMI", "activate_plugins", $this->plugin->name. "-ss-fakeit", "serp_shaker_fakeit");
240 add_submenu_page('edit.php?post_type=shaker-page', 'Extract URLs', 'Extract URLs', 'activate_plugins', 'sscategorymapping_extract_urls', 'sscategorymapping_extract_urls');
241 // add_submenu_page("edit.php?post_type=shaker-page", "Updates", "Updates", "activate_plugins", $this->plugin->name. "-ss-updates", "serp_shaker_updates");
242 add_submenu_page("edit.php?post_type=shaker-page", "Add Ons", "Add Ons", "activate_plugins", $this->plugin->name. "-ss-addons", "serp_shaker_addons");
243 add_submenu_page("edit.php?post_type=shaker-page", 'SS Spinners Add On', 'Spinner Settings', 'activate_plugins', DIRNAME(__FILE__) . '/ss-spinners.php');
244 add_submenu_page("edit.php?post_type=shaker-page", 'Settings & Tools', 'Settings & Tools', 'activate_plugins', DIRNAME(__FILE__) . '/ss-tools.php');
245 add_submenu_page("edit.php?post_type=shaker-page", 'Advanced SILO Setup', 'Advanced SILO Setup', 'activate_plugins', DIRNAME(__FILE__) . '/ss-advancedsilo.php');
246
247 }
248
249
250
251
252 /**
253 * Adds meta boxes
254 */
255 function AddMetaBoxes() {
256 global $wp_meta_boxes;
257
258 // Add a meta box for Page/Post selection
259 add_meta_box($this->plugin->name.'-output', 'Output', array(&$this, 'DisplayOutputFields'), 'shaker-page', 'side', 'high');
260
261 // Registers all Page and Post meta boxes for Serp Shaker
262 if (@is_array($wp_meta_boxes['page']) AND count($wp_meta_boxes['page']) > 0) {
263 foreach ($wp_meta_boxes['page'] as $position=>$arr) {
264 foreach ($arr as $importance=>$metaBox) {
265 foreach ($metaBox as $pluginName=>$metaBoxAttributes) {
266 add_meta_box($pluginName, $metaBoxAttributes['title'], $metaBoxAttributes['callback'], 'shaker-page', $position, $importance);
267 }
268 }
269 }
270 }
271 if (@is_array($wp_meta_boxes['post']) AND count($wp_meta_boxes['post']) > 0) {
272 foreach ($wp_meta_boxes['post'] as $position=>$arr) {
273 foreach ($arr as $importance=>$metaBox) {
274 foreach ($metaBox as $pluginName=>$metaBoxAttributes) {
275 add_meta_box($pluginName, $metaBoxAttributes['title'], $metaBoxAttributes['callback'], 'shaker-page', $position, $importance);
276 }
277 }
278 }
279 }
280
281 // Register Page Attributes box. We do this here rather than in the register_post_type function as that function
282 // does not display the parent page or template dropdown options that we need.
283 add_meta_box($this->plugin->name.'-attributes', 'Page Attributes', array(&$this, 'DisplayPageAttributesFields'), 'shaker-page', 'side', 'low');
284 //MetaBox for spinner options
285 add_meta_box($this->plugin->name.'-spinner', 'SS Spinner', array(&$this, 'SpinnerOptions'), 'shaker-page', 'side', 'core');
286 add_meta_box( $this->plugin->name.'-title', 'Shaker Page SEO Settings', array(&$this, 'ss_title'),'shaker-page','normal','high');
287 add_meta_box( $this->plugin->name.'-newcategory', 'Shaker Page Category Shortcode', array(&$this, 'ss_category'),'shaker-page','side','high');
288 //add_meta_box( $this->plugin->name.'-page_parent', 'Set Page Parent', array(&$this, 'ss_page_parent'),'shaker-page','side','high');
289
290 }
291
292 /**
293 * If Local Pages is NOT licensed, this function is called to add options panels where the
294 * Local Pages Custom Post Type would otherwise appear, linking to the license screen.
295 */
296
297
298 /**
299 * Outputs a message when editing a Local Page custom post type to notify the
300 * user that this Local Page has already been marked as Generated and
301 * therefore produced the necessary Pages / Posts.
302 */
303 function AdminNotices() {
304 global $post;
305
306 if (@$_GET['action'] == 'edit') {
307 $this->meta = get_post_meta($post->ID, $this->plugin->name, true);
308 $type = get_post_type($post->ID);
309
310 if (@$this->meta['built'] && $type == 'shaker-page') {
311 echo (' <div class="error"><p>Pages / Posts have been built based on this Shaker Page. Making further changes to this Shaker Page is unecessary. Should you
312 wish to amend a specific Page or Post built based on this Shaker Page, please directly edit the Page or Post as necessary.</p></div>');
313 return false;
314 }
315 }
316 }
317
318 /**
319 * Adds menu entries to the Wordpress 3.1 Admin Bar linking to Administration Panels
320 */
321 function AddAdminBarMenu() {
322 global $wp_admin_bar;
323
324 $wp_admin_bar->add_menu(array('id' => $this->plugin->name, 'title' => $this->plugin->displayName, 'href' => get_admin_url('admin.php?page='.$this->plugin->name)));
325 foreach ($this->subPages as $key=>$subPage) {
326 $wp_admin_bar->add_menu(array('parent' => $this->plugin->name, 'id' => $this->plugin->name.'-'.strtolower($subPage), 'title' => $subPage, 'href' => get_admin_url('admin.php?page='.$this->plugin->name.'-'.strtolower($subPage))));
327 }
328 }
329
330 /**
331 * Adds columns to the Page and Post lists within Wordpress Administration
332 *
333 * @param array $defaults Default Columns
334 * @return array New Columns
335 */
336 function AddAdminColumns($defaults) {
337 $defaults['localPage'] = __('Shaker Page Generated');
338 return $defaults;
339 }
340
341 /**
342 * Manages the data to be displayed within a column on the Page and Post lists within Wordpress Administration
343 *
344 * @param string $columnName
345 * @param int $ID Post ID
346 */
347 function ManageAdminColumns($columnName, $ID) {
348 // Only run if on the lightbox column
349 if ($columnName == 'localPage') {
350 $meta = get_post_meta($ID, 'localPageID', true);
351 echo (($meta > 0) ? 'Yes' : 'No');
352 }
353 }
354
355 /**
356 * Displays output fields for the meta box for Local Pages custom post
357 */
358 function DisplayOutputFields() {
359 global $post;
360
361 $this->meta = get_post_meta($post->ID, $this->plugin->name, true);
362
363 // Start output
364 echo (' <div class="'.$this->plugin->name.'-meta-box">
365 <input type="hidden" name="'.$this->plugin->name.'_wpnonce" value="'.wp_create_nonce(plugin_basename(__FILE__)).'" />
366 <p>
367 <label for="'.$this->plugin->name.'[output]">'.__('Output Type', 'output').'</label>
368 <select name="'.$this->plugin->name.'[output]" size="1" id="output">
369 <option value="post"'.(@$this->meta['output'] == 'post' ? ' selected' : '').'>Posts</option>
370 <option value="page"'.(@$this->meta['output'] == 'page' ? ' selected' : '').'>Pages</option>
371 </select>
372 </p>
373 <p class="description">When <strong>Published</strong> is clicked below, this setting is used to define how the built
374 Shaker Pages should be stored: either as Wordpress Pages or Wordpress Posts.</p>
375
376 <p>
377 <label for="'.@$this->plugin->name.'[output]">'.__('Number of Posts or Pages (Optional)', 'numberOfPosts').'</label>
378 <input type="text" name="'.@$this->plugin->name.'[numberOfPosts]" value="'.@$this->meta['numberOfPosts'].'" />
379 </p>
380 <p class="description">The number of Pages / Posts to build from this Shaker Page. If blank it will determine the number of lines in the longest shortcode list</p>
381 <p>
382 <label for="'.@$this->plugin->name.'[randomdate]">'.__('Days in the Future or Past (Optional)', 'numberOfDays').'</label>
383 <input type="text" name="'.@$this->plugin->name.'[numberOfDays]" value="'.@$this->meta['numberOfDays'].'" />
384 </p>
385 <p class="description">The max number of days to future date or back date the posts. Choose below wether to future date or back date. If left blank it will use current date. <a href="http://members.serpshaker.com/members-area/video-18-new-date-feature/" style="color: red" target="_blank">(Help Video)</a></p>
386
387 <p>
388 <input type="radio" checked="checked" value="current" name="'.@$this->plugin->name.'[futuredate]">
389 <label>Current Date (default)</label>
390 <br>
391 <input type="radio" value="future" name="'.@$this->plugin->name.'[futuredate]">
392 <label>Future Date (scheduled)</label>
393 <br>
394 <input type="radio" value="past" name="'.@$this->plugin->name.'[futuredate]">
395 <label>Back Date (published)</label>
396 <br>');
397
398 // Output build button or message to say pages / posts already built
399 if (@$this->meta['built']) {
400 echo (' <p>
401 <input name="unbuild" type="submit" class="button-primary" id="unbuild" value="Delete Built Pages / Posts" />
402 </p>
403 <p class="description">Click this button if you wish to delete all Pages and Posts built based on this Shaker Page.');
404 } else {
405 if (isset($_GET['post'])) {
406 echo (' <p>
407 <input name="build" type="submit" class="button-primary" id="build" value="Build Pages / Posts" />
408 </p>
409 <p class="description"><strong>Check you are happy with your content first.</strong> This button will build the Pages / Posts
410 based on this Shaker Page. Once done, this cannot be done again for this Shaker Page.</p>
411 <p class="description"><img src="'.plugin_dir_url(__FILE__).'images/warning.png" width="16" height="16" align="absmiddle" /> Before building make sure you\'ve added the memory lines shown in <strong><a href="http://serp-shaker.s3.amazonaws.com/wp-config-changes.png" target="_blank">this image</a></strong> to the wp-config.php file <img src="'.plugin_dir_url(__FILE__).'/images/warning.png" width="16" height="16" align="absmiddle" /></p>');
412 } else {
413 echo (' <p>
414 <input name="build" type="submit" class="button-primary" id="build" value="Build Pages / Posts" disabled />
415 </p>
416 <p class="description"><strong>You can build Pages / Posts from this Shaker Page once it\'s saved.</strong></p>');
417 }
418 }
419 echo ' <h2>Shortcode Modifiers</h2>
420
421 <p class="description">
422 Using <em>Los Angeles</em> as an example:<br />
423 {city_upper} = LOS ANGELES<br />
424 {city_lower} = los angeles<br />
425 {city_word} = Los Angeles<br />
426 {city_url} = los-angeles<br /></p>';
427 if ( get_option( 'ss_youtube_api' ) == NULL ) {
428 echo '<h2>Youtube API</h2>
429 <p class="description">
430 You currently have not entered a Youtube API key. If you\'d like to take advantage of our built in Youtube function please enter your API key here:<br />
431 <a href="edit.php?post_type=shaker-page&page=serpshaker/ss-tools.php&tab=youtube" target="_blank">API Key Settings</a><br /></p>';
432 }
433 echo '<h2>Visual Editor Shortcuts</h2>
434 <p class="description">See <a href="http://members.serpshaker.com/members-area/video-9-visual-editor-shortcuts/" style="color: red" target="_blank">help video</a></p>';
435 echo (' </div>');
436 }
437
438 /**
439 * Displays Page Attribute fields for the meta box for Local Pages custom post
440 */
441 function DisplayPageAttributesFields() {
442 global $post;
443
444 $this->meta = get_post_meta($post->ID, $this->plugin->name, true);
445
446 $template = get_post_meta($post->ID, '_wp_page_template', true);
447 $templates = get_page_templates();
448
449
450 // Start output
451 echo (' <div class="'.$this->plugin->name.'-meta-box">
452 <input type="hidden" name="'.$this->plugin->name.'_wpnonce" value="'.wp_create_nonce(plugin_basename(__FILE__)).'" />
453 <p><strong>Parent</strong></p>'.
454 wp_dropdown_pages(array(
455 'post_type' => 'page',
456 'name' => 'parent_id',
457 'selected' => $post->post_parent,
458 'show_option_none' => '(no parent)' ,
459 'sort_column' => 'menu_order, post_title',
460 'echo' => 0
461 )).'
462
463 <p><strong>Template</strong></p>
464 <select name="page_template">
465 <option value="default"'.(($template == 'default' OR $template == '') ? ' selected' : '').'>Default Template</option>');
466
467 if (is_array($templates) AND count($templates) > 0) {
468 foreach ($templates as $name=>$file) {
469 echo (' <option value="'.$file.'"'.(($template == $file) ? ' selected' : '').'>'.$name.'</option>');
470 }
471 }
472
473 echo (' </select>
474 </div>');
475 }
476 function SpinnerOptions() {
477 global $post;
478
479 $this->meta = get_post_meta($post->ID, $this->plugin->name, true);
480
481 // Start output
482 echo (' <div class="'.$this->plugin->name.'-meta-box">
483 <input type="hidden" name="'.$this->plugin->name.'_wpnonce" value="'.wp_create_nonce(plugin_basename(__FILE__)).'" />
484
485 ');
486
487 // Output build button or message to say pages / posts already built
488 if (@$this->meta['alreadyspun']) {
489 echo ('
490 <p class="description">This content has already been used to create a new spun <strong><a href="edit.php?post_type=shaker-page">Shaker Page</a></strong>. If you\'d like to spin again just resave this Shaker Page');
491 } else {
492 if (isset($_GET['post'])) {
493 global $ss_wa_options;
494 global $ss_sr_options;
495 if($ss_wa_options['email'] === ''){
496 $disabledwa = "disabled";}
497 if($ss_sr_options['email'] === ''){
498 $disabledsr = "disabled";}
499 echo (' <p class="description"><strong>Make sure you\'ve added the settings for either <a href="edit.php?post_type=shaker-page&page=serpshaker/ss-spinners.php" target="_blank">SpinRewriter or WordAi</a>.</strong> The buttons below will spin the current content and create a new Shaker Page with spintax.<br />
500 <em><a href="http://members.serpshaker.com/members-area/video-14-advanced-spin-settings/" style="color: red" target="_blank">(Help Video)</a></em></p>
501 <p>
502 <img src="'.plugin_dir_url(__FILE__).'/images/wordai32.png" width="32" height="32" align="absmiddle" /> <input name="spin" type="submit" class="button-primary" id="spin" value="Spin It With WordAi" ' . $disabledwa . '/><BR><BR>
503 <img src="'.plugin_dir_url(__FILE__).'/images/spinrewriter32.png" width="32" height="32" align="absmiddle" /> <input name="spin" type="submit" class="button-primary" id="spin" value="Spin It With SpinRewriter" ' . $disabledsr . '/>
504 </p>
505 ');
506 } else {
507 echo (' <p>
508 <input name="spin" type="submit" class="button-primary" id="spin" value="Spin It" disabled />
509 </p>
510 <p class="description"><strong>You can spin this Shaker Page once it\'s saved.</strong></p>');
511 }
512 }
513
514 echo (' </div>');
515 }
516 function ss_title () {
517 // Get the post ID
518 global $post ;
519 $post_id = $post->ID;
520
521 $ss_title = trim(get_post_meta($post_id, 'ss_title', true));
522 $ss_yoast_seo_title = trim(get_post_meta($post_id, '_yoast_wpseo_title', true));
523 $ss_yoast_seo_description = trim(get_post_meta($post_id, '_yoast_wpseo_metadesc', true));
524
525 // The actual fields for data entry
526 echo '<label for="ss_title">';
527 echo 'Enter the title of your post/page below if you\'d like the <strong>Title</strong> and <strong>Permalink/slug</strong> to be different.<br />
528 This will be the <strong>H1 Page/Post Title</strong> <em><a href="http://members.serpshaker.com/members-area/video-15-advanced-different-title-url/" style="color: red" target="_blank">(Help Video)</a></em><br />';
529 echo '</label>';
530 echo '<input type="text" id="ss_title" class="large-text" name="ss_title" value="' . $ss_title . '" /><br /><br />';
531 $seooption = get_option( 'serp_shaker_platinum_seo' );
532 if( $seooption !== 'on' ) {
533 echo '<label for="ss_yoast_seo_title">';
534 echo 'If you\'re using <strong>YOAST SEO</strong> you can input the SEO Title and Description Below<br />
535 <strong>YOAST SEO Title:</strong><br />';
536 echo '</label>';
537 echo '<input type="text" id="ss_yoast_seo_title" class="large-text" name="ss_yoast_seo_title" value="' . $ss_yoast_seo_title . '" /><br />';
538 echo '<label for="ss_yoast_seo_description">';
539 echo '<strong>YOAST SEO Description:</strong>';
540 echo '</label><br />';
541 echo '<input type="text" id="ss_yoast_seo_description" class="large-text" name="ss_yoast_seo_description" value="' . $ss_yoast_seo_description . '" />';}
542}
543function ss_category () {
544 // Get the post ID
545 global $post ;
546 $post_id = $post->ID;
547
548 $ss_category = trim(get_post_meta($post_id, 'ss_category', true));
549
550 // The actual fields for data entry
551 echo '<label for="ss_category">';
552 echo 'Enter your category to use with the posts. Shortcodes can be used (eg, <strong>Keyword in {state}</strong>)';
553 echo '</label><br />';
554 echo '<input type="text" id="ss_category" name="ss_category" value="' . $ss_category . '" size="25" />';
555
556}
557 function ss_page_parent () {
558 // Get the post ID
559 global $post ;
560 $post_id = $post->ID;
561
562 $ss_page_parent = trim(get_post_meta($post_id, 'ss_page_parent', true));
563
564 // The actual fields for data entry
565 echo '<label for="ss_page_parent">';
566 echo 'If you are using pages to create your SILO, enter the page title that will be the <strong>Parent</strong> to this Shaker Page.<br /><br />
567 Keep in mind that in order for it to function correctly, the <strong>parent pages should have been previously created</strong>.<br/>
568 <br/>
569 Also if you used the <strong>Custom Title</strong> option make sure to put in the full title here.<br/>';
570 echo '</label><br />';
571 echo '<input type="text" id="ss_page_parent" name="ss_page_parent" value="' . $ss_page_parent . '" class="large-text" />';
572}
573
574
575
576 /**
577 * Saves Shaker Page Custom Post Type metadata
578 *
579 * @param int $post_id Post ID
580 */
581 function Save($post_id) {
582 global $ssShortCodes;
583
584 // Only continue if the post type is a shaker page
585 $type = get_post_type($post_id);
586 if ($type == 'shaker-page') {
587 if (@!wp_verify_nonce($_POST[$this->plugin->name.'_wpnonce'], plugin_basename(__FILE__))) return $post_id;
588 if (!current_user_can('edit_post', $post_id)) return $post_id;
589
590 // Save post meta for plugin
591 $data = $_POST[$this->plugin->name];
592 update_post_meta($post_id, $this->plugin->name, $data);
593 $ss_title = trim(@$_POST['ss_title']);
594 update_post_meta($post_id, 'ss_title', $ss_title);
595 $ss_yoast_seo_title = trim(@$_POST['ss_yoast_seo_title']);
596 update_post_meta($post_id, '_yoast_wpseo_title', $ss_yoast_seo_title);
597 $ss_yoast_seo_description = trim(@$_POST['ss_yoast_seo_description']);
598 update_post_meta($post_id, '_yoast_wpseo_metadesc', $ss_yoast_seo_description);
599 $ss_page_parent = trim(@$_POST['ss_page_parent']);
600 update_post_meta($post_id, 'ss_page_parent', $ss_page_parent);
601 $ss_post_category = trim(@$_POST['ss_category']);
602 update_post_meta($post_id, 'ss_category', $ss_post_category);
603
604 // Save post meta for Page Attributes
605 if ($_POST['page_template'] != '') update_post_meta($post_id, '_wp_page_template', $_POST['page_template']);
606
607 //CHeck if Spin It is pushed
608 if (isset($_POST['spin'])) {
609
610 if( !defined('SPUN_EXECUTED') ){
611 remove_action('save_post', array(&$this, 'Save'));
612 // Use WordAi or SpinRewriter to create a new post with spin syntax
613 if ($_POST['spin'] == 'Spin It With WordAi'){
614 $spun_content = ss_wordai($_POST['post_content']);}
615 elseif ($_POST['spin'] == 'Spin It With SpinRewriter'){
616 $spun_content = ss_spinrewriter($_POST['post_content']);}
617 $spunPost['post_title'] = $_POST['post_title'];
618 $spunPost['post_content'] = $spun_content;
619 $spunPost['post_category'] = $_POST['post_category'];
620 // Add some other basic details to the post
621 $spunPost['post_status'] = 'draft';
622 $spunPost['post_author'] = $_POST['post_author'];
623 $spunPost['post_type'] = 'shaker-page';
624 $spunPost['ping_status'] = 'closed';
625 $spunPostID = wp_insert_post($spunPost);
626 update_post_meta($spunPostID, 'ss_title', $ss_title);
627 switch ($_POST['serpshaker']['output']) {
628 case 'post':
629 if (trim($_POST['tax_input']['post_tag']) != '') wp_set_post_terms($spunPostID, $_POST['tax_input']['post_tag']); // Set tags, if defined
630 set_post_format($spunPostID, $_POST['post_format']); // Set post format
631 break;
632 case 'page':
633 update_post_meta($spunPostID, '_wp_page_template', $_POST['page_template']); // Set page template
634 break;
635 }
636 $data['alreadyspun'] = 1;
637 update_post_meta($post_id, $this->plugin->name, $data);
638 define('SPUN_EXECUTED', TRUE);
639 add_action('save_post', array(&$this, 'Save'));
640 }
641 }
642
643
644 // Check if build or unbuild buttons clicked.
645 if (isset($_POST['build']) AND $_POST['build'] == 'Build Pages / Posts') {
646 // Get shortcodes and spins used across all fields
647 $this->FindPostFields($_POST);
648
649 $maxDataEntries = 0;
650 $mypostcounter = 0;
651 // Get shortcode data for each shortcode found from above
652 foreach ($this->shortcodes as $key=>$shortcode) {
653 $scData = $ssShortCodes->GetByShortcode($shortcode);
654 $shortcodeData[$shortcode] = explode("\n", $scData['shortcodeData']);
655 $maxDataEntries = ((count($shortcodeData[$shortcode]) > $maxDataEntries) ? count($shortcodeData[$shortcode]) : $maxDataEntries);
656 $shortcodeDataCurrentIndex[$shortcode] = 0;
657 $shortcodeDataCeilingIndex[$shortcode] = count($shortcodeData[$shortcode]) - 1;
658 }
659 global $wp_version;
660 if ( $wp_version >= 4.2 ){
661 $terms = get_the_terms( $post_id, 'post_tag' );
662 $terms = wp_list_pluck( $terms, 'name' );}
663 if ($_POST['ss_title'] !== ''){
664 $post_title = $_POST['ss_title'];
665 }
666 else {
667 $post_title = $_POST['post_title'];}
668 if ($POST['ss_category'] === '') {
669 $post_category = $_POST['post_category'];}
670 else {
671 $post_category = $_POST['ss_category'];}
672 $customFields = get_post_custom_keys($post_id);
673 // Create a loop for the number of posts we need to build
674 $numberOfPosts = ($_POST[$this->plugin->name]['numberOfPosts'] != '' ? $_POST[$this->plugin->name]['numberOfPosts'] : $maxDataEntries);
675
676 @set_time_limit(0);
677 for ($i = 0; $i < $numberOfPosts; $i++) {
678 // Define the data to use for each shortcode for this Post
679 // Increment / reset index for next Post in loop
680 unset($replace); // Clear from last run
681 foreach ($this->shortcodes as $key=>$shortcode) {
682 $replace[$shortcode] = $shortcodeData[$shortcode][$shortcodeDataCurrentIndex[$shortcode]];
683 $shortcodeDataCurrentIndex[$shortcode] = (($shortcodeDataCurrentIndex[$shortcode]+1 > $shortcodeDataCeilingIndex[$shortcode]) ? 0 : $shortcodeDataCurrentIndex[$shortcode]+1);
684 }
685
686 // Generate new post array with shortcode replacements
687
688
689 $newPost = $this->ReplacePostFields(array(
690
691 'post_title' => $this->ConvertWordSpecialChars($post_title),
692 'post_name' => $this->ConvertWordSpecialChars($_POST['post_title']),
693 'post_content' => $this->ConvertWordSpecialChars($_POST['post_content']),
694 'post_category' => $this->ConvertWordSpecialChars($post_category),
695 'post_parent' => $_POST['ss_page_parent'],
696 'post_excerpt' => $_POST['post_excerpt']), $replace); // Replace shortcodes with given array of replacement content / words
697
698 // Spin the title and content
699 /* $spintax = new SS_Spintax();
700 $newPost['post_title'] = $spintax->process($newPost['post_title']);
701 $newPost['post_content'] = $spintax->process($newPost['post_content']);
702 $newPost['post_category'] = $spintax->process($newPost['post_category']);
703 // Add some other basic details to the post
704 $newPost['post_status'] = 'publish';
705 $newPost['post_author'] = $_POST['post_author'];
706 $newPost['post_name'] = strtolower(str_replace(" ", "-", $spintax->process($newPost['post_name'])));
707 $newPost['post_type'] = $_POST['serpshaker']['output'];
708 $newPost['ping_status'] = 'closed';*/
709 $spintax = new SS_Spintax();
710 $newPost['post_title'] = stripslashes($spintax->process($newPost['post_title']));
711 $newPost['post_content'] = stripslashes($spintax->process($newPost['post_content']));
712 $newPost['post_category'] = $spintax->process($newPost['post_category']);
713 // Add some other basic details to the post
714 $newPost['post_status'] = 'publish';
715 $newPost['post_author'] = $_POST['post_author'];
716 $newPost['post_name'] = stripslashes(strtolower(str_replace(" ", "-", $spintax->process($newPost['post_name']))));
717 $newPost['post_type'] = $_POST['serpshaker']['output'];
718 $newPost['ping_status'] = 'closed';
719 $newPost['post_excerpt'] = stripslashes($spintax->process($newPost['post_excerpt']));
720 // Depending on whether we are outputting Posts or Pages from this Shaker Page,
721 // set some additional fields.
722 if ($newPost['post_parent'] === ''){
723 $post_parent = $_POST['parent_id'];
724 }
725 else {
726 $page = get_page_by_title($newPost['post_parent']);
727 $post_parent = $page->ID;
728 }
729 switch ($_POST['serpshaker']['output']) {
730 case 'post':
731 // $newPost['post_category'] = $_POST['post_category']; // Set categories
732 break;
733 case 'page':
734 $newPost['post_parent'] = $post_parent; // Set optional parent Page
735 break;
736 }
737
738 // Create Page / Post
739 // added by don 7-22
740 // wp_defer_term_counting( true );
741 // wp_defer_comment_counting( true );
742 global $wpdb;
743 $wpdb->query( 'SET autocommit = 0;' );
744 /* $wpdb->query( 'SET unique_checks = 0;' );
745 $wpdb->query( 'SET foreign_key_checks = 0;' );*/
746 $defaults = array('to_ping' => '');
747 $user_ID = get_current_user_id();
748 $max_days = $_POST['serpshaker']['numberOfDays'];
749 if ($max_days != ''){
750 $day = rand(1, $max_days);
751 $hour = rand(0, 23);
752 $gmt_offset = '-5';}
753
754 if ($_POST['serpshaker']['futuredate'] == 'future' ) {
755 $new_post_status = 'future';
756 $new_date = date( 'Y-m-d H:i:s', strtotime("+$day day +$hour hour") );
757 $gmt_new_date = date( 'Y-m-d H:i:s', strtotime("+$day day +$hour hour +$gmt_offset hour") ); }
758
759 elseif ($_POST['serpshaker']['futuredate'] == 'past' ) {
760 $new_post_status = 'publish';
761 $new_date = date( 'Y-m-d H:i:s', strtotime("-$day day -$hour hour") );
762 $gmt_new_date = date( 'Y-m-d H:i:s', strtotime("-$day day -$hour hour -$gmt_offset hour") );}
763 else {
764 $new_post_status = 'publish';
765 $new_date = current_time('mysql');
766 $gmt_new_date = current_time('mysql');
767 }
768
769
770 // $newPostID = wp_insert_post($newPost);
771
772 $wpdb->query( $wpdb->prepare("INSERT IGNORE INTO `".$wpdb->prefix."posts`(post_author,post_content,post_title,comment_status,ping_status,post_name,post_type,post_date,post_date_gmt,post_status,post_parent,post_excerpt) VALUES(%s,%s,%s,'closed','closed',%s,%s,%s,%s,%s,%s,%s)", $user_ID,$newPost['post_content'],$newPost['post_title'],sanitize_title($newPost['post_name']),$newPost['post_type'],$new_date,$gmt_new_date,$new_post_status,$post_parent,$newPost['post_excerpt']));
773 $newPostID = $wpdb->insert_id;
774 if (!$newPostID) continue; // An error occured
775
776 // Depending on whether we are outputting Posts or Pages from this Local Page,
777 // set some additional fields. This is done after the Post / Page creation
778 // so we have a valid post ID
779 $spintax = new SS_Spintax();
780 switch ($_POST['serpshaker']['output']) {
781 case 'post':
782 /* if (trim($_POST['tax_input']['post_tag']) != '') wp_set_post_terms($newPostID, $spintax->process($this->ReplacePostFields($_POST['tax_input']['post_tag'], $replace))); // Set tags, if defined*/
783 $mytagcounter = 0;
784 if ( $wp_version >= 4.2 ){
785 $dotags = $spintax->process($this->ReplacePostFields($terms, $replace));}
786 else {
787 $dotags = array();
788 $dotags = explode(",",$spintax->process($this->ReplacePostFields($_POST['tax_input']['post_tag'], $replace)));
789 }
790// print_r($dotags);
791foreach($dotags as $thenewtag) {
792 $theslug = str_replace(" ","-",strtolower($thenewtag));
793 $theslug = str_replace("'","",$theslug);
794 $thenewtag = addslashes($thenewtag);
795 $wpdb->query( "INSERT IGNORE INTO `".$wpdb->prefix."terms`(name,slug) VALUES('" . $thenewtag . "','" . sanitize_title($theslug) . "')");
796$startpoint = $wpdb->insert_id;
797 $wpdb->query( "INSERT IGNORE INTO `".$wpdb->prefix."term_taxonomy`(term_taxonomy_id,term_id,taxonomy) VALUES(" . $startpoint . "," . $startpoint . ",'post_tag')");
798 $wpdb->query( "INSERT IGNORE INTO `".$wpdb->prefix."term_relationships`(object_id,term_taxonomy_id) VALUES(" . $newPostID . "," . $startpoint . ")");
799 $mytagcounter ++;
800 if($mytagcounter == 100) {
801 $wpdb->query( 'COMMIT;' );
802 $mytagcounter = 0;}}
803 set_post_format($newPostID, $_POST['post_format']); // Set post format
804 $catID = get_cat_ID( $newPost['post_category'] ) ;
805 if ($catID == 0) {
806 // Create the category
807 $catslug = str_replace(" ","-",strtolower($newPost['post_category']));
808 $catslug = str_replace("'","",$catslug);
809 $wpdb->query( "INSERT IGNORE INTO `".$wpdb->prefix."terms`(name,slug) VALUES('" . $newPost['post_category'] . "','" . sanitize_title($catslug) . "')");
810 //$catID = wp_create_category( $newPost['post_category'] );
811 $catID = $wpdb->insert_id;
812 }
813 // wp_set_post_categories( $newPostID, array($catID));
814 $wpdb->query( "INSERT IGNORE INTO `".$wpdb->prefix."term_relationships`(object_id,term_taxonomy_id) VALUES (" . $newPostID . "," . $catID . ")" );
815 $wpdb->query( "INSERT IGNORE INTO `".$wpdb->prefix."term_taxonomy`(term_taxonomy_id,term_id,taxonomy) VALUES (" . $catID . "," . $catID . ",'category')" );
816 break;
817 case 'page':
818 update_post_meta($newPostID, '_wp_page_template', $_POST['page_template']); // Set page template
819 break;
820 }
821
822 // Add meta to Post
823 //$startmeta = 1000;
824 if (is_array($customFields) AND count($customFields) > 0) {
825 foreach ($customFields as $k=>$metaKey) {
826 $meta = get_post_meta($post_id, $metaKey);
827 $spintax = new SS_Spintax();
828 $newMeta = $this->ReplacePostFields($meta, $replace); // Replace shortcodes with content
829 if (get_option( 'ss_double_agent_issue' ) !== 'on'){
830 $newMeta = $spintax->process($newMeta);} // Spin meta fields for meta title and description
831 // update_post_meta($newPostID, $metaKey, $newMeta[0]); // Add post meta to newly created post
832 $wpdb->query( "INSERT IGNORE INTO `".$wpdb->prefix."postmeta`(post_id,meta_key,meta_value) VALUES (" . $newPostID . ",'" . $metaKey . "','" . addslashes($newMeta[0]) . "')" );
833 // $startmeta = $startmeta + 1;
834 }
835 }
836 $featured_image = get_post_thumbnail_id($post_id);
837 set_post_thumbnail( $newPostID, $featured_image );
838
839
840 // Add this post ID to the newly created post, so we can reference it if we need to unbuild / delete later on
841 update_post_meta($newPostID, 'localPageID', $post_id);
842 $mypostcounter ++;
843 if($mypostcounter == 100) {
844 $wpdb->query( 'COMMIT;' );
845 $mypostcounter = 0;
846 }
847 }
848
849 $wpdb->query( 'COMMIT;' ); // added for uneven post numbers
850 // POST CATEGORY COUNTS UPDATE WAS HERE -- MOVED TO FUNCTION
851 serp_shaker_rebuild(); //calls the new rebuild post count function
852
853 $wpdb->query( 'COMMIT;' );
854 $wpdb->query( 'SET autocommit = 1;' );
855 //$wpdb->query( 'SET unique_checks = 1;' );
856 // $wpdb->query( 'SET foreign_key_checks = 1;' );
857 // Mark as built
858 $data['built'] = 1;
859 update_post_meta($post_id, $this->plugin->name, $data);
860 } elseif (isset($_POST['unbuild']) AND $_POST['unbuild'] == 'Delete Built Pages / Posts') {
861 // Delete Posts and Pages with localPageID matching this Local Page Custom Post ID
862 $query['post_type'] = 'any';
863 $query['meta_key'] = 'localPageID';
864 $query['meta_value'] = $post_id;
865 $query['posts_per_page'] = -1;
866 $q = new WP_Query($query);
867 foreach ($q->posts as $key=>$builtPost) wp_delete_post($builtPost->ID, true);
868 unset($q);
869
870 // Mark as not built
871 $data['built'] = 0;
872 update_post_meta($post_id, $this->plugin->name, $data);
873 }
874 // wp_defer_term_counting( false );
875 // wp_defer_comment_counting( false );
876 }
877
878 return $post_id;
879 }
880
881
882
883 /**
884 * Recursively goes through a POST array, replacing shortcodes
885 * with those specified in the replacement array.
886 *
887 * @param mixed $postArr Array or Single Value
888 * @param array $replaceArr Array of replacements
889 * @return mixed Array or Single Value (end of recursion will return same as put in i.e. array)
890 */
891 function ReplacePostFields($postArr, $replaceArr) {
892 if (!is_array($postArr)) {
893 foreach ($replaceArr as $shortcode=>$replacement) {
894 $postArr = str_replace('{'.$shortcode.'}', str_replace("\n", "", trim($replacement)), $postArr);
895 $postArr = str_replace('{'.$shortcode.'_upper}', strtoupper(str_replace("\n", "", trim($replacement))), $postArr);
896 $postArr = str_replace('{'.$shortcode.'_lower}', strtolower(str_replace("\n", "", trim($replacement))), $postArr);
897 $postArr = str_replace('{'.$shortcode.'_word}', ucwords(strtolower(str_replace("\n", "", trim($replacement)))), $postArr);
898 $createurls = array('\n', ' ');
899 $replaceurls = array('', '-');
900 $postArr = str_replace('{'.$shortcode.'_url}', sanitize_title(strtolower(str_replace($createurls, $replaceurls, trim($replacement)))), $postArr);
901 }
902 return $postArr;
903 }
904
905 foreach ($postArr as $key=>$value) {
906 $newArr[$key] = $this->ReplacePostFields($value, $replaceArr);
907 }
908
909 return $newArr;
910 }
911
912 /**
913 * Recursively goes through a POST array, finding shortcodes
914 * within the array content.
915 *
916 * @param mixed $postArr
917 */
918 function FindPostFields($postArr) {
919 if (!is_array($postArr)) {
920 preg_match_all("|{(.+?)}|", $postArr, $matches); // Get shortcodes and spins
921
922 // Build arrays of found shortcodes and spins
923 if (is_array($matches) AND count($matches[1]) > 0) {
924 foreach ($matches[0] as $mKey=>$shortcode) {
925 if (strpos($shortcode, "|") === false) { // Check this is a shortcode and not a spin
926 $shortcode = str_replace('_upper', '', $shortcode);
927 $shortcode = str_replace('_lower', '', $shortcode);
928 $shortcode = str_replace('_word', '', $shortcode);
929 $shortcode = str_replace('_url', '', $shortcode);
930 if (!is_array($this->shortcodes) OR (is_array($this->shortcodes) AND !in_array(trim($shortcode, "{}"), $this->shortcodes))) $this->shortcodes[] = trim($shortcode, "{}");
931 }
932 }
933 }
934
935 return $postArr;
936 }
937
938 foreach ($postArr as $key=>$value) {
939 $newArr[$key] = $this->FindPostFields($value);
940 }
941
942 return $newArr;
943 }
944
945 /**
946 * Converts Microsoft Word special characters without affecting the rest
947 * of the string (ensuring HTML elements are not encoded)
948 *
949 * @param string $string String to Convert
950 * @return string Converted String
951 */
952 function ConvertWordSpecialChars($string) {
953 $string = str_replace(chr(130), ',', $string); // baseline single quote
954 $string = str_replace(chr(132), '"', $string); // baseline double quote
955 $string = str_replace(chr(133), '...', $string); // ellipsis
956 $string = str_replace(chr(145), "'", $string); // left single quote
957 $string = str_replace(chr(146), "'", $string); // right single quote
958 $string = str_replace(chr(147), '"', $string); // left double quote
959 $string = str_replace(chr(148), '"', $string); // right double quote
960 $string = mb_convert_encoding($string, 'HTML-ENTITIES', 'UTF-8');
961 return $string;
962 }
963
964 /**
965 * Spins content.
966 *
967 * @param mixed $string
968 * @param mixed $seedPageName
969 * @param mixed $openingConstruct
970 * @param mixed $closingConstruct
971 */
972
973 function SpinContent($string, $openingConstruct = '{', $closingConstruct = '}') {
974 if(strpos($string, $openingConstruct) === false) return $string; // If we have nothing to spin return content
975
976 // Find all positions of the starting and opening braces
977 $startPositions = $this->strpos_all($string, $openingConstruct);
978 $endPositions = $this->strpos_all($string, $closingConstruct);
979
980 // There must be the same number of opening constructs to closing ones
981 if($startPositions === false OR count($startPositions) !== count($endPositions)) return $string;
982
983 $openingConstructLength = mb_strlen($openingConstruct);
984 $closingConstructLength = mb_strlen($closingConstruct);
985
986 // Organise the starting and opening values into a simple array showing orders
987 foreach($startPositions as $pos) $order[$pos] = 'open';
988 foreach($endPositions as $pos) $order[$pos] = 'close';
989 ksort($order);
990
991 // Go through the positions to get the depths
992 $depth = 0;
993 $chunk = 0;
994 foreach($order as $position => $state) {
995 if($state == 'open') {
996 $depth++;
997 $history[] = $position;
998 } else {
999 $lastPosition = end($history);
1000 $lastKey = key($history);
1001 unset($history[$lastKey]);
1002
1003 $store[$depth][] = mb_substr($string, $lastPosition + $openingConstructLength, $position - $lastPosition - $closingConstructLength);
1004 $depth--;
1005 }
1006 }
1007 krsort($store);
1008
1009 // Remove the old array and make sure we know what the original state of the top level spin blocks was
1010 unset($order);
1011 $original = $store[1];
1012
1013 // Move through all elements and spin them
1014 foreach($store as $depth => $values) {
1015 foreach($values as $key => $spin) {
1016 # Get the choices
1017 $choices = explode('|', $store[$depth][$key]);
1018 $replace = $choices[mt_rand(0, count($choices) - 1)];
1019
1020 # Move down to the lower levels
1021 $level = $depth;
1022 while($level > 0) {
1023 foreach($store[$level] as $k => $v) {
1024 $find = $openingConstruct.$store[$depth][$key].$closingConstruct;
1025 if($level == 1 AND $depth == 1)
1026 {
1027 $find = $store[$depth][$key];
1028 }
1029 $store[$level][$k] = $this->str_replace_first($find, $replace, $store[$level][$k]);
1030 }
1031 $level--;
1032 }
1033 }
1034 }
1035
1036 // Put the very lowest level back into the original string
1037 foreach($original as $key => $value) $string = $this->str_replace_first($openingConstruct.$value.$closingConstruct, $store[1][$key], $string);
1038
1039 return $string;
1040 }
1041
1042 /**
1043 * Similar to str_replace, but only replaces the first instance of the needle
1044 *
1045 * @param string $find Find
1046 * @param string $replace Replace
1047 * @param string $string Content
1048 * @return Amended String
1049 */
1050 function str_replace_first($find, $replace, $string) {
1051 if(!is_array($find)) $find = array($find); // Not an array
1052 if(!is_array($replace)) $replace = array($replace); // Not an array
1053
1054 foreach($find as $key => $value) {
1055 if(($pos = strpos($string, $value)) !== false) {
1056 if(!isset($replace[$key])) $replace[$key] = ''; // If we have no replacement make it empty
1057 $string = mb_substr($string, 0, $pos).$replace[$key].mb_substr($string, $pos + mb_strlen($value));
1058 }
1059 }
1060
1061 return $string;
1062 }
1063
1064 /**
1065 * Finds all instances of a needle in the haystack and returns the array.
1066 *
1067 * @param string $haystack Haystack
1068 * @param string $needle Needle
1069 * @return array Positions
1070 */
1071 function strpos_all($haystack, $needle) {
1072 $offset = 0;
1073 $i = 0;
1074 $return = false;
1075
1076 while(is_integer($i)) {
1077 $i = strpos($haystack, $needle, $offset);
1078
1079 if(is_integer($i)) {
1080 $return[] = $i;
1081 $offset = $i + mb_strlen($needle);
1082 }
1083 }
1084
1085 return $return;
1086 }
1087
1088 /**
1089 * Outputs the plugin Admin Panel in Wordpress Admin
1090 */
1091 function AdminPanel() {
1092 global $ssShortCodes;
1093
1094 // Get existing settings
1095 $this->data = get_option($this->plugin->name);
1096
1097 // Check command to determine what to output
1098 switch (strtolower(str_replace($this->plugin->name.'-', '', $_GET['page']))) {
1099 // Licensing / Updates
1100 case $this->plugin->name:
1101 $page = 'licensing';
1102
1103 // Save Settings
1104 if (isset($_POST['submit'])) {
1105 $this->data = is_array($this->data) ? array_merge($this->data, $_POST[$this->plugin->name]) : $_POST[$this->plugin->name];
1106 update_option($this->plugin->name, $this->data);
1107 $this->message = 'Licensing Settings Updated.';
1108 }
1109
1110 // Validate license key
1111 if (!$ssLum->CheckLicenseKeyIsValid(true)) {
1112 $this->errorMessage = $ssLum->licenseKeyCodeDescription; // Force License Key Check
1113 } else {
1114 $this->message .= 'License key is valid. ';
1115 }
1116
1117 // Download and Install Update, if requested
1118 if (isset($_GET['doUpdate']) AND $_GET['doUpdate'] == 1) {
1119 if ($ssLum->DownloadAndInstallUpdate()) {
1120 $this->message .= $this->plugin->displayName.' updated successfully. ';
1121 $ssLum->CheckForUpdates(); // Force re-check to ensure new version installed
1122 } else {
1123 $this->errorMessage .= 'An error occured when attempting to automatically update '.$this->plugin->displayName;
1124 }
1125 }
1126
1127 // Check for updates if required
1128 if (isset($_GET['checkUpdates']) AND $_GET['checkUpdates'] == 1) {
1129 $ssLum->CheckForUpdates(true); // Force Update Check
1130 }
1131
1132 break;
1133
1134 // Shortcodes
1135 case 'shortcodes':
1136 switch (@$_GET['cmd']) {
1137 case "add":
1138 case "edit":
1139 if (isset($_POST['submit'])) {
1140 // Check for required fields
1141 if (trim($_POST['shortcode']) == '') {
1142 $this->shortcode = $_POST;
1143 $this->errorMessage = 'Please specify a shortcode.';
1144 $page = 'shortcodes-form';
1145 }
1146 //elseif (trim($_POST['shortcodeData']) == '') {
1147 // $this->shortcode = $_POST;
1148 //$this->errorMessage = 'Please specify at least one word / phrase for this shortcode.';
1149 //$page = 'shortcodes-form';
1150 // }
1151 else {
1152 if ($ssShortCodes->Save($_POST)) {
1153 $this->message = 'Shortcode '.($_GET['cmd'] == 'add' ? 'created' : 'updated').'.';
1154 $this->shortcodes = $ssShortCodes->GetAll($_GET['paged']);
1155 $this->total = $ssShortCodes->GetTotal();
1156 $page = 'shortcodes';
1157 } else {
1158 $this->errorMessage = 'An error occured, please try again.';
1159 $page = 'shortcodes-form';
1160 }
1161 }
1162 } else {
1163 if (isset($_GET['pKey'])) {
1164 $this->shortcode = $ssShortCodes->GetByID($_GET['pKey']);
1165 }
1166 $page = 'shortcodes-form';
1167 }
1168 break;
1169 default:
1170 if (isset($_POST['doAction'])) {
1171 // Delete checked
1172 foreach ($_POST['shortcodeID'] as $shortcodeID=>$doDelete) $ssShortCodes->DeleteByID($shortcodeID);
1173 $this->message = 'Shortcode(s) deleted.';
1174 }
1175
1176 // Get shortcodes based on pagination
1177 $this->shortcodes = $ssShortCodes->GetAll(@$_GET['paged']);
1178 $this->total = $ssShortCodes->GetTotal();
1179 $page = 'shortcodes';
1180 break;
1181 }
1182 break;
1183 }
1184
1185 // Get most up to date data
1186 $this->data = get_option($this->plugin->name);
1187
1188 // Load form
1189 if (isset($this->errorMessage)) $this->message = '';
1190 include_once(WP_PLUGIN_DIR.'/'.$this->plugin->name.'/admin/'.$page.'.php');
1191 }
1192}
1193
1194function serp_shaker_shortcodes () {
1195 global $wpdb;
1196 if(isset($_GET['dynadel'])) {
1197 $deletedyna = $wpdb->query($wpdb->prepare("DELETE FROM " . $wpdb->prefix . "ss_dynamicodes WHERE shortcodeID = %s",$_GET['dynadel']));
1198 }
1199 if(isset($_POST['dynacodename']) && !empty($_POST['updateit'])) {
1200 $updatedyna = $wpdb->query($wpdb->prepare("UPDATE " . $wpdb->prefix . "ss_dynamicodes SET shortcode = '%s',shortcodeData = '%s',spinnable = %s WHERE shortcodeID = %s",$_POST['dynacodename'],stripslashes($_POST['dynacontent']),$_POST['spinnable'],$_POST['updateit']));
1201 } elseif(isset($_POST['dynacodename']) && empty($_POST['updateit'])) {
1202 $insertdyc = $wpdb->query($wpdb->prepare("INSERT INTO " . $wpdb->prefix . "ss_dynamicodes (shortcode,shortcodeData,spinnable) VALUES('%s','%s','%s')",$_POST['dynacodename'],stripslashes($_POST['dynacontent']),$_POST['spinnable']));
1203 // $wpdb->query($insertdyc);
1204 }
1205 $ssrows = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "ss_dynamicodes", ARRAY_A);
1206 // print_r($ssrows);
1207 $content = '';
1208 $editor_id = 'dynacontent';
1209 if(isset($_GET['dynaedit'])) {
1210 $editdyna = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "ss_dynamicodes WHERE shortcodeID = " . $_GET['dynaedit'], ARRAY_A);
1211 $shortname = $editdyna[0]['shortcode'];
1212 $content = $editdyna[0]['shortcodeData'];
1213 $shortspin = $editdyna[0]['spinnable'];
1214 }
1215 echo '<h1>Shortcodes</h1>';
1216 echo '<p>Dynamic Shortcodes are codes that are used to insert specific elements in content.<br />
1217 They can be static elements or they can be spinnable content.</p>
1218 <form id="form1" name="form1" method="post" action="">
1219 <p>Shotcode Name:
1220 <label for="textfield"></label>';
1221 if(isset($_GET['dynaedit'])) {
1222 echo '<input type="text" name="dynacodename" value="' . $shortname . '" />';
1223 } else {
1224 echo '<input type="text" name="dynacodename" />';
1225 }
1226 echo '</p>(When using a dynamic shortcode in your content, always use the shortcode shown in the table below.)<br />
1227 If inserting code snippets such as Youtube embeds, make sure you use the <strong>TEXT</strong> editor and not VISUAL<br /><br />';
1228 wp_editor(stripslashes($content), $editor_id, $settings = array('textarea_rows' => 5));
1229 echo'<p>
1230 <label for="select"></label>
1231 Spinnable:
1232 <select name="spinnable" id="select">';
1233 if($shortspin == 2) {
1234 echo '<option value="1">No</option><option value="2" selected="selected">Yes</option>';
1235 } else {
1236 echo '<option value="1" selected="selected">No</option><option value="2">Yes</option>';
1237 }
1238 echo '</select>
1239 </p>
1240 <p>
1241 <input type="hidden" name="updateit" value="' . $_GET['dynaedit'] . '">
1242 <input class="button-primary" type="submit" name="button" id="button" value="Create / Update" />';
1243 if(isset($_POST['dynacodename']) && !empty($_POST['updateit'])) {
1244 echo ' <a class="button" href="edit.php?post_type=shaker-page&page=serpshaker-ss-shortcodes">Add New</a>';
1245 }
1246 echo '</p>
1247 </form>';
1248 echo'<table width="80%" border="0" cellpadding="5" cellspacing="0"><tr style="background: #FFF;text-align: left;"><th scope="col">Shotcodes</th><th scope="col">Content Excerpt</th><th scope="col">Spinnable</th><th scope="col">Action</th></tr>';
1249
1250 foreach($ssrows as $ssdyna) {
1251 if($ssdyna['spinnable'] == 2) {
1252 $ssdyna['spinnable'] = "Yes";
1253 } else {
1254 $ssdyna['spinnable'] = "No";
1255 }
1256 echo '<tr><td nowrap width="20%">[dyna dynami="' . $ssdyna['shortcode'] . '"]</td><td width="40%">' . substr(strip_tags($ssdyna['shortcodeData']),0,50) . '</td><td width="20%">' . $ssdyna['spinnable'] . '</td><td width="20%"><a class="button button-primary" href="edit.php?post_type=shaker-page&page=serpshaker-ss-shortcodes&dynaedit=' . $ssdyna['shortcodeID'] . '"><b>Edit</b></a> <a style="color: red;" class="button" href="edit.php?post_type=shaker-page&page=serpshaker-ss-shortcodes&dynadel=' . $ssdyna['shortcodeID'] . '"><b>Delete</b></a></td></tr>';
1257 }
1258 echo '</table>';
1259}
1260
1261function serp_shaker_ads () {
1262 global $wpdb;
1263 $content = '';
1264 $editor_id = 'addata';
1265
1266 if(isset($_GET['addel'])) {
1267 $deletead = $wpdb->query($wpdb->prepare("DELETE FROM " . $wpdb->prefix . "ss_ads WHERE adID = %s",$_GET['addel']));
1268 }
1269 if(isset($_POST['adname']) && !empty($_POST['updateit'])) {
1270 $updatead = $wpdb->query($wpdb->prepare("UPDATE " . $wpdb->prefix . "ss_ads SET adname = '%s',adData = '%s' WHERE adID = %s",$_POST['adname'],$_POST['addata'],$_POST['updateit']));
1271
1272 } elseif(isset($_POST['adname']) && empty($_POST['updateit'])) {
1273 $insertad = $wpdb->query($wpdb->prepare("INSERT INTO " . $wpdb->prefix . "ss_ads (adname,addata) VALUES('%s','%s')",$_POST['adname'],$_POST['addata']));
1274 // $wpdb->query($insertdyc);
1275 }
1276 $ssrows = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "ss_ads", ARRAY_A);
1277 // print_r($ssrows);
1278 if(isset($_GET['adid'])) {
1279 $editadd = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "ss_ads WHERE adID = " . $_GET['adid'], ARRAY_A);
1280
1281 $addname = $editadd[0]['adname'];
1282 $content = $editadd[0]['adData'];
1283 $doupdate = 1;
1284 }
1285 echo '<h1>SERP Shaker Ads</h1>';
1286 echo '<form id="shakead" name="shakead" method="post" action="">
1287 <p>
1288 Ad Name:<br />';
1289 if(isset($_GET['adid'])) {
1290 echo '<input type="text" name="adname" id="adname" value="' . $addname . '" />';
1291 } else {
1292 echo '<input type="text" name="adname" id="adname" />';
1293 }
1294 echo '</p>';
1295 wp_editor( stripslashes($content), $editor_id, $settings = array('textarea_rows' => 7) );
1296
1297 echo ' <p>
1298 <input type="hidden" name="updateit" value="' . @$_GET['adid'] . '">
1299 <input class="button-primary" type="submit" name="button" id="button" value="Create/Edit Ad" />';
1300 if(isset($_POST['adname']) && !empty($_POST['updateit'])) {
1301 echo ' <a class="button" href="edit.php?post_type=shaker-page&page=serpshaker-ss-ads">Add New</a>';
1302 }
1303 echo '</p>
1304 </form>';
1305 echo '<table width="80%" border="0" cellpadding="5" cellspacing="0">';
1306 echo '<tr style="background: #FFF;text-align: left;">
1307 <th scope="col">Ad Name</th>
1308 <th scope="col">Ad Content</th>
1309 <th scope="col">Action</th>
1310 </tr>';
1311 foreach($ssrows as $ssads) {
1312 echo '<tr>
1313 <td width="20%" nowrap><b>[ssad ssadblk="' . $ssads['adname'] . '"]</b></td>
1314 <td width="60%">' . stripslashes($ssads['adData']) . '</td>
1315 <td width="20%"><a class="button button-primary" href="edit.php?post_type=shaker-page&page=serpshaker-ss-ads&adid=' . $ssads['adID'] . '"><b>Edit</b></a> <a style="color: red;" class="button" href="edit.php?post_type=shaker-page&page=serpshaker-ss-ads&addel=' . $ssads['adID'] . '"><b>Delete</b></a></td>
1316 </tr>';
1317 }
1318 echo '</table>';
1319
1320}
1321
1322class SS_Spintax
1323{
1324 public function process($text)
1325 {
1326 return preg_replace_callback(
1327 '/\{(((?>[^\{\}]+)|(?R))*)\}/x',
1328 array($this, 'replace'),
1329 $text
1330 );
1331 }
1332
1333 public function replace($text)
1334 {
1335 $text = $this->process($text[1]);
1336 $parts = explode('|', $text);
1337 return $parts[array_rand($parts)];
1338 }
1339}
1340
1341function ssrandomDate($start_date, $end_date)
1342{
1343 // Convert to timetamps
1344 $min = strtotime($start_date);
1345 $max = strtotime($end_date);
1346
1347 // Generate random number using above bounds
1348 $val = rand($min, $max);
1349
1350 // Convert back to desired date format
1351 return date('Y-m-d H:i:s', $val);
1352}
1353
1354
1355function serp_shaker_shaker () {
1356 global $wpdb;
1357 echo '<h1>The Shaker</h1>';
1358 echo 'The Shaker takes a start date you specify, and changes the dates of all posts to random dates.<br />These random dates start from the start date you select below.<br /><br />You can also prepend and append "<u>Text or HTML code</u>" to the beginning and end of every post.<br />These fields can take SpinTax';
1359 wp_enqueue_script('jquery-ui-datepicker');
1360 wp_enqueue_style('jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/themes/smoothness/jquery-ui.css');
1361 echo '<form id="shakeit" name="shakeit" method="post" action="">
1362 <p>Earliest Date:</p>
1363 <p><div class="dashicons dashicons-calendar"></div><input type="text" id="ShakeDate" name="ShakeDate" value=""/><br />(YEAR-MONTH-DATE) Click TextBox to Select Start Date</p>
1364 <p>Prepend:</p>
1365 <p>';
1366 wp_editor("", "ssprepend", $settings = array('textarea_rows' => 5));
1367 echo '</p>
1368 <p>Append:</p>
1369 <p>';
1370 wp_editor("", "ssappend", $settings = array('textarea_rows' => 5));
1371 echo '</p>
1372 <p>
1373 <input class="button-primary" type="submit" name="button" id="button" value="Submit" />
1374 </p>
1375 </form>';
1376
1377 $ssjs = <<< js_ss_date
1378 <script>
1379 jQuery(document).ready(function() {
1380 jQuery('#ShakeDate').datepicker({
1381 dateFormat : 'yy-mm-dd'
1382 });
1383 });</script>
1384js_ss_date;
1385 echo $ssjs;
1386 /*
1387 if(isset($_POST['ShakeDate'])) {
1388 $spintax = new SS_Spintax();
1389 $sshaker = $wpdb->get_results("SELECT ID FROM " . $wpdb->prefix . "posts WHERE post_status = 'publish' AND post_type='post'", ARRAY_A);
1390 // print_r($sshaker);
1391 } else {
1392 exit;
1393 }
1394 */
1395 $spintax = new SS_Spintax();
1396 $sshakerposts = $wpdb->get_results("SELECT ID FROM " . $wpdb->prefix . "posts WHERE post_status = 'publish' AND post_type='post'", ARRAY_A);
1397
1398 foreach($sshakerposts as $shakerid) {
1399 $newappend = "";
1400 $newprepend = "";
1401 if(isset($_POST['ShakeDate'])) {
1402
1403
1404 // print_r($sshaker);
1405
1406
1407
1408 if(isset($_POST['ssappend'])) {
1409 $newappend = $spintax->process("<br><br>" . $_POST['ssappend']);
1410 }
1411 if(isset($_POST['ssprepend'])) {
1412 $newprepend = $spintax->process($_POST['ssprepend'] . "<br><br>");
1413 }
1414 $startdate = $_POST['ShakeDate'] . " 00:00:00";
1415 $enddate = date('Y-m-d H:i:s');
1416 $ssgetdate = ssrandomDate($startdate,$enddate);
1417 $gmt_new_date = get_gmt_from_date($ssgetdate);
1418
1419 // echo $ssgetdate . "<br>" . $gmt_new_date . "<br>";
1420
1421 $query = "UPDATE " . $wpdb->prefix . "posts SET post_date = '" . $ssgetdate . "',post_modified = '" . $ssgetdate . "',post_date_gmt = '" . $gmt_new_date . "',post_modified_gmt= '" . $gmt_new_date . "',post_content = concat(post_content,'" . $newappend . "'),post_content = concat('" . $newprepend . "',post_content) WHERE ID = " . $shakerid['ID'];
1422
1423 $ssupdate = $wpdb->query($query);
1424
1425 @flush();
1426 @ob_flush();
1427 echo "Just updated POST #: " . $shakerid['ID'] . "<br />";
1428 }
1429 }
1430}
1431
1432
1433function serp_shaker_siloit () {
1434 echo '<h1>SERP Shaker Interlinking</h1>';
1435 echo 'The Serp Shaker interlinking option is coded directly into Serp Shaker.<br />
1436You do not need to change any settings to use it.<br /><br />
1437
1438<b>This is for POSTS only, not pages.</b><br /><br />
1439<span style="color: red;">DO NOT COPY/PASTE THESE EXAMPLES INTO THE VISUAL POST EDITOR!<br>
1440PLEASE PASTE THEM INTO THE TEXT TAB.</span><br><br>
1441
1442<a href="[linkprev]">Anchor text</a><br /><br />
1443
1444<a href="[linknext]">Anchor text</a><br /><br />
1445
1446<b>The anchor text can be in spintax format.</b><br /><br />
1447
1448<a href="[linkprev]">{Keyword1|Keyword2|Keyword3}</a><br /><br />
1449
1450Add this to your main Shaker Page content, anywhere you would<br />
1451like the contextual link to appear. We recommend adding it in the<br />
1452content body. Rather then at the beginning or end of the post.<br /><br />
1453
1454In future versions, we will be adding more complex interlinking<br />
1455structures.<br /><br />
1456
1457Why did we do it like this? Because it needs to be kept simple. This<br />
1458is how we do it, and it works. You need create relevance in search<br />
1459engines for an overall topic. Many people damage their own potential<br />
1460rankings, by not following the <b>"less is more"</b> way of doing things.';
1461
1462}
1463
1464/*function serp_shaker_cleanup () {
1465 global $wpdb;
1466 global $seooption;
1467 if (!empty($text)) {
1468 echo '<div id="message" class="updated fade"><p>' . $text . '</p></div>';
1469}
1470 echo '<h1>Base Install Cleanup</h1>';
1471echo '<span style="color: red">WARNING</span> The button below will delete all posts, pages, categories, and tags. This is usefull if you\'re working on a local install and need a fresh start.<br/>
1472Please be sure to <a href="export.php" target="_blank"><strong>export</strong></a> your pages and shaker page if you want to reuse them.<br />
1473<form id="Clean-Up" name="Clean-Up" method="post" action="">
1474 <p>
1475 <input class="button-primary" type="submit" name="Clean-Up" id="Clean-Up" value="Clean Up" />
1476 </p>
1477 </form>'; ?>
1478 <div class="wrap">
1479 <div class="metabox-holder postbox-container">
1480 <h1>SEO Options</h1>
1481 <form method="post" name="seo_settings">
1482 <table class="form-table">
1483 <tr>
1484 <th align="left">Use Platinum SEO</th>
1485 <td align="left"><input type="checkbox" name="serp_shaker_platinum_seo"
1486 <?php
1487 if ($seooption === 'on') {
1488 echo "checked";
1489 }
1490 ?> /> - enable it if you want to use Platinum SEO. If not you can use any other SEO Plugin but be aware that it may interfere with build time.
1491 </td>
1492 </tr>
1493 </table>
1494 <input class="button-primary" type="submit" name="SEO-Options" id="SEO-Options" value="Save SEO Options" />
1495 </form>
1496 </div>
1497 </div>
1498 <?php
1499
1500 if(isset($_POST['Clean-Up'])) {
1501 // $tables = array('posts','postmeta','terms','term_relationships','term_taxonomy');
1502 // foreach ($tables as $table){
1503 $wpdb->query("TRUNCATE TABLE $wpdb->posts");
1504 $wpdb->query("TRUNCATE TABLE $wpdb->postmeta");
1505 $wpdb->query("TRUNCATE TABLE $wpdb->terms");
1506 $wpdb->query("TRUNCATE TABLE $wpdb->term_relationships");
1507 $wpdb->query("TRUNCATE TABLE $wpdb->term_taxonomy");
1508 echo 'Deleted posts, pages, categories and tags. It\'s now ready for a new build<br/>';
1509 }
1510 if(isset($_POST['SEO-Options'])) {
1511 $update_ss_seo_query = update_option('serp_shaker_platinum_seo', $_POST['serp_shaker_platinum_seo']);
1512 if ($update_ss_seo_query) {
1513 $text = 'SEO Settings Updated<br />';
1514 } else {
1515 $text = __('No Option Updated');
1516 }
1517}
1518}*/
1519function serp_shaker_updates () {
1520 echo '<h1>SERP Shaker Updates</h1>';
1521 echo 'Serp Shaker will be adding Automatic Update ability soon. <br /><br />However, because of the nature of Serp Shaker, we are rolling<br />out updates manually for now. We will be adding the automatic<br />update ability in version 1.08 of Serp Shaker.<br /><br />Please be sure you are on the update list.<br /><br />Serp Shaker will be evolving at a rapid pace until we reach version 1.10.<br />After that, updates will become less frequent and scheduled.<br />We have many more features to add that take time.<br /><br /><b>Please make sure you are on the --> <a href="http://serpshaker.com/updates" target="_blank">Update Notification List</a></b>';
1522}
1523
1524
1525function serp_shaker_rebuild() { //Contributed by Fever
1526 //echo "<h1>Updating Category Post Counts</h1>";
1527 $username = DB_USER; //pulls username from wp-config
1528 $password = DB_PASSWORD; //pulls password from wp-config
1529 $server = DB_HOST; //pulls host address from wp-config
1530 $dB = DB_NAME; //pulls database id from wp-config
1531 global $wpdb;
1532
1533 if (function_exists("mysqli_connect")) {
1534 $connect = mysqli_connect($server, $username, $password,$dB);
1535 if (!$connect){ //outputs error info should connection fail
1536 die('Could not connect: ' . mysqli_error($connect));
1537 } else {
1538 mysqli_select_db($connect,$dB);
1539 }
1540 //DONE CONNECTING
1541 //Step 2. Recount Posts in Each Category
1542 $getTaxID = "SELECT * FROM ".$wpdb->prefix."term_taxonomy";
1543 $getTaxID = mysqli_query($connect,$getTaxID);
1544 if(!$getTaxID){
1545 print 'Error: '.mysqli_error($connect);
1546 }
1547 while($row = mysqli_fetch_array($getTaxID, MYSQLI_ASSOC)){
1548 $taxID = $row["term_id"];
1549 $countTaxPost = "SELECT * FROM ".$wpdb->prefix."term_relationships WHERE term_taxonomy_id = '$taxID'";
1550 $countTaxPost = mysqli_query($connect,$countTaxPost);
1551 //Modified to just count the posts using mysqli method.
1552 $count = mysqli_num_rows($countTaxPost);
1553 /* $count = 0;
1554 while($rowCount = mysqli_fetch_array($countTaxPost, MYSQLI_ASSOC)){
1555 $count++;
1556 }*/
1557 $getName = "SELECT * FROM ".$wpdb->prefix."terms WHERE term_id = '$taxID'";
1558 $getName = mysqli_query($connect,$getName);
1559 if(!$getName){
1560 print 'Error: '.mysqli_error($connect);
1561 }
1562 $termName;
1563 while($taxName = mysqli_fetch_array($getName, MYSQLI_ASSOC)){
1564 $termName = $taxName["name"];
1565 }
1566
1567 $updateCount = "UPDATE ".$wpdb->prefix."term_taxonomy SET count = '$count' WHERE term_id = '$taxID'";
1568 // echo " Category: $termName, $count posts. ";
1569 $updateCount = mysqli_query($connect,$updateCount);
1570 if(!$updateCount){
1571 print "Error: ".mysqli_error($connect);
1572 }
1573 }
1574 echo "<br><br>Update complete.";
1575 } else {
1576
1577 $connect = mysql_connect($server, $username, $password);
1578 if (!$connect){ //outputs error info should connection fail
1579 die('Could not connect: ' . mysql_error());
1580 } else {
1581 mysql_select_db($dB, $connect);
1582 }
1583 //DONE CONNECTING
1584 //Step 2. Recount Posts in Each Category
1585 $getTaxID = "SELECT * FROM ".$wpdb->prefix."term_taxonomy";
1586 $getTaxID = mysql_query($getTaxID);
1587 if(!$getTaxID){
1588 print 'Error: '.mysql_error();
1589 }
1590 while($row = mysql_fetch_array($getTaxID, MYSQL_ASSOC)){
1591 $taxID = $row["term_id"];
1592 $countTaxPost = "SELECT * FROM ".$wpdb->prefix."term_relationships WHERE term_taxonomy_id = '$taxID'";
1593 $countTaxPost = mysql_query($countTaxPost);
1594 $count = mysql_num_rows($countTaxPost);
1595 /*while($rowCount = mysql_fetch_array($countTaxPost, MYSQL_ASSOC)){
1596 $count++;
1597 } */
1598 $getName = "SELECT * FROM ".$wpdb->prefix."terms WHERE term_id = '$taxID'";
1599 $getName = mysql_query($getName);
1600 if(!$getName){
1601 print 'Error: '.mysql_error();
1602 }
1603 $termName;
1604 while($taxName = mysql_fetch_array($getName, MYSQL_ASSOC)){
1605 $termName = $taxName["name"];
1606 }
1607 //echo " Category: $termName, $count posts. ";
1608 $updateCount = "UPDATE ".$wpdb->prefix."term_taxonomy SET count = '$count' WHERE term_id = '$taxID'";
1609 $updateCount = mysql_query($updateCount);
1610 if(!$updateCount){
1611 print "Error: ".mysql_error();
1612 }
1613 }
1614 echo "<br><br>Update complete.";
1615 }
1616
1617}
1618
1619function serp_shaker_addons () {
1620 echo '<h1>SERP ADD ONs</h1>';
1621echo '<h1 style="color: red;text-align: center;font-size: 32px;">..:: Coming Soon ::..</h1><br /><br /><br />Serp Shaker is an evergreen product. Add-ons will become available after version 1.10.<br /><br />Serp Shaker is not your typical WordPress plugin...<br /><br />Serp Shaker is going through a process of evolution, to become the top predator in the food chain.';
1622}
1623
1624// Additional code contributed by Andrew Peacock to the original LPN plugin.
1625$sscategorymapping_catName = "";
1626$sscategorymapping_postId = 0;
1627$sscategorymapping_status = 'future';
1628
1629// Add an action to fix "missed schedule" posts
1630//add_action('init', 'sscategorymapping_init', 0);
1631
1632
1633// Add the meta box in the admin panel
1634add_action( 'add_meta_boxes', 'sscategorymapping_add_meta_box' );
1635
1636// On save, update the Local Page meta data (which is then used to populate into the individual posts).
1637add_action( 'save_post', 'sscategorymapping_save_post', 100);
1638
1639// On create SS pages, set the future published date
1640add_filter( 'save_post' , 'sscategorymapping_save_post' , 100, 2 );
1641//add_filter( 'save_post' , 'sscategorymapping_reset_time', 1, 2);
1642add_filter( 'wp_insert_post_data', 'sscategorymapping_wp_insert_post_data', 10, 2); // Only fires when page is manually created
1643
1644// Update the post meta data to put the shortcode-base content into each individual post.
1645add_action('added_post_meta', 'sscategorymapping_added_post_meta', 100, 4); // Priority 100 so it runs well after SS itself.
1646add_action('updated_post_meta', 'sscategorymapping_added_post_meta', 100, 4); // Priority 100 so it runs well after SS itself.
1647
1648//function sscategorymapping_init(){
1649// global $wpdb;
1650//
1651// $last = get_option('sscategorymapping_missedchedule', false);
1652// if(($last !== false) && ($last > (time() - (2 * 60)))) // Wait 2 minutes of missed schedule before running
1653// return;
1654//
1655// // Update current time
1656// update_option('sscategorymapping_missedchedule', time());
1657//
1658// $missedIDs = $wpdb->get_col(
1659// "SELECT `ID` FROM `{$wpdb->posts}` ".
1660// "WHERE ( ".
1661// " ((`post_date` > 0 )&& (`post_date` <= CURRENT_TIMESTAMP())) OR ".
1662// " ((`post_date_gmt` > 0) && (`post_date_gmt` <= UTC_TIMESTAMP())) ".
1663// ") AND `post_status` = 'future'"
1664// );
1665// if(!count($missedIDs)) return;
1666// foreach($missedIDs as $missedID){
1667// if(!$missedID) continue;
1668// wp_publish_post($missedID); //Let's publish missed schedule posts
1669// }
1670//}
1671
1672
1673
1674function sscategorymapping_extract_urls() {
1675 $txtfile = plugin_dir_path( __FILE__ ) . "output.txt";
1676 $htmlfile = plugin_dir_path( __FILE__ ) . "output.html";
1677 $txturl = plugin_dir_url( __FILE__ ) . "output.txt";
1678 $htmlurl = plugin_dir_url( __FILE__ ) . "output.html";
1679
1680 if (@$_REQUEST["sscategorymapping_paged"]) {
1681 $paged = $_REQUEST["sscategorymapping_paged"];
1682 } else {
1683 $paged = 1;
1684
1685 // Empty the output files
1686 $handle = fopen($txtfile, "w");
1687 fclose($handle);
1688 $handle = fopen($htmlfile, "w");
1689 fclose($handle);
1690 }
1691
1692 // Initialise
1693 $page = 1;
1694 $txtoutput = "";
1695 $htmloutput = "";
1696
1697 // Loop through all published URLs a page at a time till there are no posts.
1698 do {
1699 $nextBatch = new WP_Query(array('post_status'=>'publish', 'posts_per_page'=>100, 'paged'=>$page));
1700
1701 $postsFound = false;
1702 echo "<BR>Got links " . ((($page-1) * 100)) . " to " . ((($page-1) * 100)+99);
1703 while ($nextBatch->have_posts()) {
1704 $postsFound = true;
1705
1706 $nextBatch->the_post();
1707 $perm = get_permalink();
1708 $title = the_title('', '', false);
1709
1710 // Save the outputs
1711 $txtoutput .= $perm . "\n";
1712 $htmloutput .= '<a href="' . $perm . '">' . $title . '</a><br />'. "\n";
1713
1714 }
1715 @flush();
1716 @ob_flush();
1717 @set_time_limit(0);
1718 $page++;
1719 } while($postsFound === true);
1720
1721
1722 $handle = fopen($txtfile, "a");
1723 fputs($handle, $txtoutput);
1724 fclose($handle);
1725
1726 $handle = fopen($htmlfile, "a");
1727 fputs($handle, $htmloutput);
1728 fclose($handle);
1729
1730 // Echo a link to the file
1731 echo '<BR /><A href="' . $txturl . '" target="_blank">View results in text format</a>';
1732 echo '<BR /><A href="' . $htmlurl . '" target="_blank">View results in HTML format</a>';
1733 // echo '<input class="button-primary" type="submit" name="button" id="button" value="Promote" />';
1734/*if (isset($_POST['submit'])){
1735$debug = true;
1736//read in domain names from doms.txt file:
1737$lines = "";
1738$file = fopen("$txtfile", "r") or exit("Unable to open doms.txt file!");
1739//Output a line of the file until the end is reached:
1740$line_no=0;
1741 while(!feof($file)) {
1742 $line_no++;
1743 $line = fgets($file);
1744 $alllines .= $line."<br>";
1745 //code to later delete first 100 lines from doms.txt file:
1746 if($line_no < 100){//if over line 100, store in writelines var to write back to file later.
1747 /*$writelines .= $line;
1748 }else{//else line no is NOT over 100, so store line in dom array:*/
1749 // $uselines .= $line."<br>";
1750 /* $curURL = trim($line);
1751 //if cur URL doesn't conain a TLD, add .com
1752 if(strpos($curURL,".")===false){
1753 $curURL = $curURL.".com";
1754 }//end if curURL doesn't have a dot
1755 $dom_array[] = $curURL;*/
1756 // }//end else line is under 100 so put in dom array.
1757 // }//end while reading in lines from doms.txt file
1758//fclose($file);
1759//if($debug) echo"<h2>Domains taken from dom.txt file:</h2>$uselines<hr>";
1760
1761//now rewrite doms.txt file with all but first 100 lines:
1762/*$domFile = 'doms.txt';
1763$fh = fopen($domFile, 'w') or die("ERROR! Cannot open $domFile file for saving domains back to it!");
1764fwrite($fh, $writelines);
1765fclose($fh);*/
1766//if($debug) echo"Above Domains Deleted from doms.txt file!<hr>";}
1767}
1768
1769
1770
1771// Priority 1 task to reset the delay each time the "build" button is pressed.
1772//function sscategorymapping_reset_time($post_id, $post) {
1773// global $sscategorymapping_status;
1774//
1775// // Only continue if the post type is a local page
1776// $type = get_post_type($post_id);
1777// if ($type == 'shaker-page') {// Add the delay (in minutes)
1778// // Check if build or unbuild buttons clicked.
1779// if (isset($_POST['build']) AND $_POST['build'] == 'Build Pages / Posts') {
1780// // Get current time
1781// $nextPostTime = sscategorymapping_get_local_time(); // 1 minute ago
1782//
1783// // Save back to the parent localpage
1784// update_post_meta($post_id, "ssdelayedpublishlast", $nextPostTime);
1785//
1786// // Reset the scheduled status
1787// $sscategorymapping_status = 'publish';
1788// }
1789// }
1790//}
1791
1792
1793/* Adds a box to the main column on the Post and Page edit screens */
1794function sscategorymapping_add_meta_box() {
1795 /* add_meta_box(
1796 'sscategorymapping_add_meta_box_category',
1797 'SS Category Shortcode',
1798 'sscategorymapping_rendermetabox_category',
1799 'shaker-page',
1800 'side',
1801 'high'
1802 );*/
1803
1804// add_meta_box(
1805 // 'sscategorymapping_add_meta_box_delayedpublish',
1806 // 'SS Delayed Publish',
1807 // 'sscategorymapping_rendermetabox_delayedpublish',
1808 // 'shaker-page',
1809// 'side',
1810// 'high'
1811 // );
1812
1813 add_meta_box(
1814 'sscategorymapping_add_meta_box_deletetrash',
1815 'SS Delete Trash',
1816 'sscategorymapping_rendermetabox_deletetrash',
1817 'shaker-page',
1818 'side',
1819 'high'
1820 );
1821}
1822
1823// Save the SSshortcode-based category name and delayed post schedule into the meta data field (for the local page only).
1824function sscategorymapping_save_post($post_id, $post) {
1825 // Only continue if the post type is a local page
1826 $type = get_post_type($post_id);
1827
1828 if ($type == 'shaker-page') {
1829 // Save post meta for plugin
1830 /* $sscategorymapping_categoryname = trim(@$_POST['sscategorymapping_categoryname']);
1831 // $sscategorymapping_parentcategoryname = trim(@$_POST['sscategorymapping_parentcategoryname']);
1832 update_post_meta($post_id, 'sscategoryname', $sscategorymapping_categoryname);
1833 // update_post_meta($post_id, 'ssparentcategoryname', $sscategorymapping_parentcategoryname);
1834 //$sscategorymapping_delayedpublish = trim(@$_POST['sscategorymapping_delayedpublish']);
1835 //update_post_meta($post_id, 'ssdelayedpublish', $sscategorymapping_delayedpublish);*/
1836
1837 // Do we want to delete the trash?
1838 if (isset($_POST['deletetrash']) AND $_POST['deletetrash'] == 'Delete Trash') {
1839 global $wpdb;
1840
1841 //check_admin_referer('empty_trash_update');
1842 $result=$wpdb->query("DELETE FROM $wpdb->posts WHERE post_status = 'trash'");
1843
1844 }
1845 }
1846}
1847
1848
1849
1850/*function sscategorymapping_rendermetabox_category() {
1851 // Get the post ID
1852 global $post ;
1853 $post_id = $post->ID;
1854
1855 $sscategorymapping_categoryname = trim(get_post_meta($post_id, 'sscategoryname', true));
1856 //$sscategorymapping_parentcategoryname = trim(get_post_meta($post_id, 'ssparentcategoryname', true));
1857
1858 // The actual fields for data entry
1859 echo '<label for="sscategorymapping_categoryname">';
1860 echo 'Enter your shortcode for the category name (eg, <strong>{state}</strong>)';
1861 echo '</label><br />';
1862 echo '<input type="text" id="sscategorymapping_categoryname" name="sscategorymapping_categoryname" value="' . $sscategorymapping_categoryname . '" size="25" />';
1863 /*echo '<br /><br /><strong>Advanced: </strong>If you\'d like a more in-depth SILO, enter the parent category name as well';
1864 echo '</label><br />';
1865 echo '<input type="text" id="sscategorymapping_parentcategoryname" name="sscategorymapping_parentcategoryname" value="' . $sscategorymapping_parentcategoryname . '" size="25" />';
1866}*/
1867
1868
1869
1870//function sscategorymapping_rendermetabox_delayedpublish() {
1871// // Get the post ID
1872// global $post ;
1873// $post_id = $post->ID;
1874//
1875// $sscategorymapping_delayedpublish = trim(get_post_meta($post_id, 'ssdelayedpublish', true));
1876//
1877// // The actual fields for data entry
1878// echo '<label for="sscategorymapping_delayedpublish">';
1879// echo 'Enter the number of minutes delay between each post (eg enter 60 for one every hour)';
1880// echo '</label><br />';
1881// echo '<input type="text" id="sscategorymapping_delayedpublish" name="sscategorymapping_delayedpublish" value="' . $sscategorymapping_delayedpublish . '" size="25" />';
1882//}
1883
1884function sscategorymapping_rendermetabox_deletetrash() {
1885 // The actual fields for data entry
1886 echo '<label for="sscategorymapping_deletetrash">';
1887 echo 'Click here to delete the trash posts and pages.';
1888 echo '<p><input name="deletetrash" type="submit" class="button button-highlighted" id="deletetrash" value="Delete Trash" /></p>';
1889}
1890
1891
1892
1893
1894// This takes the data from the 'sscategoryname' meta data, which already has the shortcode value turned into the specific text, then
1895
1896// creates and/or assigns the category
1897
1898function sscategorymapping_added_post_meta($meta_id, $post_id, $meta_key, $meta_value) {
1899 // Ignore when saving local pages
1900 $type = get_post_type($post_id);
1901 if ($type == "shaker-page") return;
1902
1903 // Ignore if the meta key is not "lnpcategoryname"
1904
1905 switch ($meta_key) {
1906 case "sscategoryname":
1907 // Get the category name and delay
1908 $sscategorymapping_catName = $meta_value;
1909
1910 // Do nothing if there is no category name
1911 if (trim($sscategorymapping_catName) <> "") {
1912
1913 // Get category ID
1914 $catID = get_cat_ID( $sscategorymapping_catName ) ;
1915
1916 if ($catID == 0) {
1917 // Create the category
1918 $catID = wp_create_category( $sscategorymapping_catName );
1919 }
1920
1921 // Now assign the post to the category
1922 //wp_set_object_terms($post_id,$catID,'category');
1923 wp_set_post_categories( $post_id, array($catID));
1924 }
1925 break;
1926 }}
1927
1928
1929
1930function sscategorymapping_get_local_time() {
1931 return strtotime(current_time('mysql')) + 120; // 1 minute from now
1932}
1933
1934// Update the future scheduled date of newly-generated SS posts
1935function sscategorymapping_wp_insert_post_data($data, $postarr) {
1936 global $sscategorymapping_status;
1937
1938
1939 // Only continue if the current post type is a local page
1940 global $post;
1941 @$submittedPostId = $post->ID;
1942 $type = get_post_type($submittedPostId);
1943
1944 // If the user is creating a page, post, or other content, then exit
1945 if ($type != 'shaker-page') {
1946 return $data;
1947 }
1948
1949 // Check if build or unbuild buttons clicked.
1950 if (isset($_POST['build']) AND $_POST['build'] == 'Build Pages / Posts') {
1951 // Now exit if the submitted post is a post or page
1952 $type = $data["post_type"];
1953 if ( ($type != "post") && ($type != "page")) return $data;
1954
1955 // Check if a delay is enabled
1956// $sscategorymapping_delay = (int) $_POST["sscategorymapping_delayedpublish"];
1957// if ($sscategorymapping_delay > 0) {
1958//
1959// // Get the latest post time, or set it to now if not available
1960// $nextPostTime = get_post_meta($submittedPostId, "ssdelayedpublishlast", true);
1961// if ($nextPostTime == "") {
1962// $nextPostTime = sscategorymapping_get_local_time(); // time(); //strtotime(gmdate('Y-m-d H:i:s')); // strtotime($data['post_date']); // strtotime(current_time('mysql'));
1963// }
1964//
1965//
1966// // Update the actual post data
1967// $ds_gmt = get_gmt_from_date(date('Y-n-j G:i:s', $nextPostTime));
1968// $data['post_date'] = date_i18n('Y-n-j G:i:s', $nextPostTime);
1969// $data['post_date_gmt'] = $ds_gmt;
1970// $data['post_status'] = $sscategorymapping_status;
1971//
1972// // Save the new time back to the parent localpage
1973// // Add the delay (in minutes)
1974// $nextPostTime = $nextPostTime + ($sscategorymapping_delay * 60);
1975// update_post_meta($submittedPostId, "ssdelayedpublishlast", $nextPostTime);
1976//
1977// // And now we've done at least one post, set the post_status to 'future'
1978// $sscategorymapping_status = 'future';
1979//
1980// }
1981 }
1982 return $data;
1983}
1984// end Andrew Peacock Code
1985function ss_linknext() {
1986 $ssnextpost = get_permalink(ss_adjacent_post(true,'',true));
1987 return $ssnextpost;
1988}
1989
1990function ss_linkprev() {
1991 $ssprevpost = get_permalink(ss_adjacent_post(true,'',false));
1992 return $ssprevpost;
1993}
1994
1995function ss_ad_handler( $atts ) {
1996 global $wpdb;
1997 $query = "SELECT adData FROM " . $wpdb->prefix . "ss_ads WHERE adname = '" . $atts['ssadblk'] . "'";
1998 $getad = $wpdb->get_var($query);
1999
2000 // echo $getad;
2001 // echo $atts['ssadblk'];
2002
2003 return stripslashes($getad);
2004}
2005
2006function ss_dyna_handler( $atts ) {
2007 global $wpdb;
2008 $query = "SELECT shortcodeData FROM " . $wpdb->prefix . "ss_dynamicodes WHERE shortcode = '" . $atts['dynami'] . "'";
2009 $getdynamic = $wpdb->get_var($query);
2010 $spintax = new SS_Spintax();
2011 $newdynami = $spintax->process($getdynamic);
2012 return stripslashes($newdynami);
2013}
2014
2015 /**
2016 * Google Maps Shortcode
2017 */
2018 function SSmapcode($atts) {
2019$SScitystate = str_replace(" ", "+", $atts['location']);
2020$SSmapcode = <<< SSmap
2021<div style="float: left; padding: 10px;"><div style="width:250px;height:250px;margin-left: 10px; margin-right: 10px;"><iframe width="250" height="250" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=$SScitystate&ie=UTF8&z=12&t=m&iwloc=near&output=embed"></iframe><br></div></div>
2022SSmap;
2023return $SSmapcode;
2024}
2025function SSWeather( $atts ) {
2026
2027 // Attributes
2028 extract( shortcode_atts(
2029 array(
2030 'country' => 'us',
2031 'state' => '',
2032 'city' => '',
2033 ), $atts )
2034 );
2035
2036 // Code
2037$city = urlencode(ucwords($city));
2038$state = urlencode(ucwords($state));
2039$date = date("Y-m-d");
2040$weather = '<script type="text/javascript" src="http://www.showmyweather.com/weather_widget.php?int=0&type=js&country=' . $country . '&state=' . $state . '&city=' . $city . '&smallicon=1¤t=1&forecast=1&background_color=ffffff&color=000000&width=175&padding=10&border_width=1&border_color=000000&font_size=11&font_family=Verdana&showicons=1&measure=F&d=' . $date . '"></script>';
2041return $weather;
2042}
2043
2044
2045// Add Shortcode
2046function SSyoutube( $atts ) {
2047
2048 // Attributes
2049 extract( shortcode_atts(
2050 array(
2051 'keyword' => '',
2052 'title' => '',
2053 'width' => '420',
2054 'height' => '325',
2055 ), $atts )
2056 );
2057
2058 // Code
2059/*$youtubequery = urlencode(strtolower($keyword));
2060$youtuberesponse = file_get_contents("http://gdata.youtube.com/feeds/api/videos?q=" . $youtubequery);
2061$youtubefeed = simplexml_load_string($youtuberesponse);
2062$youtubeitemparts = explode("/",$youtubefeed->entry[rand(1,10)]->id);
2063$youtubevideoid = $youtubeitemparts[count($youtubeitemparts) - 1];*/
2064$youtube_api_search_url = "https://www.googleapis.com/youtube/v3/search";
2065$youtube_api_videos_url = "https://www.googleapis.com/youtube/v3/videos";
2066if (get_option( 'ss_youtube_api' ) != NULL ) {
2067$apikey = get_option( 'ss_youtube_api' );
2068$wp_remote_args = array(
2069 'user-agent' => 'Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0',
2070 'httpversion' => '1.1',
2071 );
2072
2073 # find new video
2074 $video_id = '';
2075
2076 # set params
2077 $params = array(
2078 'part' => 'id',
2079 'fields' => 'items/id/videoId',
2080 'q' => rawurlencode($keyword),
2081 'type' => 'video',
2082 'videoEmbeddable' => 'true',
2083 'maxResults' => 10,
2084 'key' => $apikey,
2085 );
2086
2087 $content = wp_remote_get(add_query_arg($params, $youtube_api_search_url), $wp_remote_args);
2088
2089 if (!is_wp_error($content))
2090 {
2091 $content = json_decode(wp_remote_retrieve_body($content));
2092
2093 # if we found video id
2094 if (isset($content->items[0]->id->videoId))
2095 {
2096 $video_id = $content->items[rand(0,10)]->id->videoId;
2097 }
2098 }
2099$video = '<div itemprop="video" itemscope="" itemtype="http://schema.org/VideoObject">
2100 <h2>Video: <span itemprop="name">' . $title . '</span></h2>
2101 <meta itemprop="thumbnailUrl" content="http://i.ytimg.com/vi/' . $video_id . '/hqdefault.jpg">
2102 <meta itemprop="embedUrl" content="http://www.youtube.com/v/' . $video_id . '">
2103 <embed src="http://www.youtube.com/v/' . $video_id . '" type="application/x-shockwave-flash" height="' . $height . '" width="' . $width . '">
2104
2105 <span itemprop="description"></span>
2106 </div>';
2107}
2108else {
2109$video = NULL;
2110}
2111
2112return $video;
2113}
2114
2115function next_page_shortcode($attributes) {
2116 extract(shortcode_atts(array(
2117 'anchor' => '',
2118 'loop' => 'cousin',
2119 'get_pages_query' => 'sort_column=menu_order&sort_order=asc'
2120 ), $attributes));
2121
2122 return next_ss_page($anchor,$loop, $get_pages_query);
2123 }
2124
2125 function previous_page_shortcode($attributes) {
2126 extract(shortcode_atts(array(
2127 'anchor' => '',
2128 'loop' => 'cousin',
2129 'get_pages_query' => 'sort_column=menu_order&sort_order=asc'
2130 ), $attributes));
2131
2132 return previous_ss_page($anchor,$loop, $get_pages_query);
2133 }
2134function SSsubpages(){
2135global $id;
2136$subpages = '<ul>' . wp_list_pages("title_li=&child_of=$id&show_date=modified
2137 &date_format=$date_format&echo=0") . '</ul>';
2138return $subpages;
2139}
2140
2141/*function SSrelatedpages($attributes){
2142extract(shortcode_atts(array(
2143 'parent' => ''), $attributes));
2144 $page = get_page_by_title($parent);
2145 $post_parent = $page->ID;
2146 $howmany = 5;
2147 $pages = wp_list_pages("title_li=&child_of=$post_parent&echo=0");
2148 $pages_arr = explode("\n", $pages);
2149 for($i=0;$i<$howmany;$i++){
2150$relatedpages .= $pages_arr[$i];
2151$pages_arr = explode("\n", $pages);
2152 for($i=0;$i<$howmany;$i++){
2153 $relatedpages .= $pages_arr[$i];
2154 }
2155 return $relatedpages;
2156$ss_page_view = $relatedpages
2157$content = $content . "<br><br>" . $ss_page_view;
2158return $content;
2159}
2160
2161}
2162add_filter('the_content','SSrelatedpages');*/
2163
2164function ss_get_pages($attributes) {
2165extract(shortcode_atts(array(
2166 'parent' => ''), $attributes));
2167 $page = get_page_by_title($parent);
2168 $post_parent = $page->ID;
2169 $howmany = 5;
2170 $pages = wp_list_pages("title_li=&child_of=$post_parent&exclude=$id&echo=0");
2171 $pages_arr = explode("\n", $pages);
2172 shuffle($pages_arr);
2173 for($i=0;$i<$howmany;$i++){
2174 $relatedpages .= $pages_arr[$i];
2175 }
2176 return $relatedpages;
2177}
2178/*function ss_get_pages($attributes) {
2179extract(shortcode_atts(array(
2180 'parent' => ''), $attributes));
2181 $page = get_page_by_title($parent);
2182 $post_parent = $page->ID;
2183 global $post;
2184$query = new WP_Query( array( 'orderby' => 'rand', 'posts_per_page' => 5, 'post_type' => 'page', 'post_parent' => $post_parent )) ;
2185if ( $query->have_posts() ) {
2186 echo '<ul>';
2187 while ( $query->have_posts() ) {
2188 $query->the_post();
2189 echo '<li>' . get_the_title() . '</li>';
2190 }
2191 echo '</ul>';
2192} else {
2193 //no posts found
2194}
2195}*/
2196/*function ss_child_pages($content) {
2197$ss_page_view = ss_get_pages();
2198$content = $content . "<br><br>" . $ss_page_view;
2199return $content;
2200}
2201
2202add_filter('the_content','ss_child_pages');*/
2203function ss_register_shortcodes() {
2204add_shortcode( 'linknext', 'ss_linknext' );
2205add_shortcode( 'linkprev', 'ss_linkprev' );
2206add_shortcode( 'ssad', 'ss_ad_handler' );
2207add_shortcode( 'dyna', 'ss_dyna_handler' );
2208add_shortcode('google-map', 'SSmapcode');
2209add_shortcode('subpages', 'SSsubpages');
2210add_shortcode('relatedpages', 'ss_get_pages');
2211add_shortcode( 'ssvideo', 'SSyoutube' );
2212add_shortcode('next_page', 'next_page_shortcode');
2213add_shortcode('previous_page', 'previous_page_shortcode');
2214add_shortcode('weather', 'SSWeather');
2215add_shortcode('sspostsincat', 'ssPagesByCategory');
2216}
2217
2218function ss_preset_options() {
2219 if (get_option(SS_WORDAI_OPTIONS) === false) {
2220 $options = array(
2221 'plan' => 'standard',
2222 'standard_quality' => '50',
2223 'turing_quality' => 'Readable',
2224 'email' => '',
2225 'pass' => '',
2226 'nonested' => '',
2227 'sentence' => 'on',
2228 'paragraph' => '',
2229 'returnspin' => 'true',
2230 'nooriginal' => 'on',
2231 'protected' => '',
2232 'synonyms' => '',
2233 );
2234 ss_set_option(SS_WORDAI_OPTIONS, $options, '', 'yes');
2235 }
2236 if (get_option(SS_SPIN_REWRITER_OPTIONS) === false) {
2237 $options = array(
2238 'confidence_level' => 'medium',
2239 'nested' => 'false',
2240 'sentence' => 'false',
2241 'email' => '',
2242 'apikey' => '',
2243 'paragraph' => 'false',
2244 'auto_new_paragraphs' => 'false',
2245 'auto_sentence_trees' => 'false',
2246 'capitalized' => 'false',
2247 'protected' => '',
2248 );
2249 ss_set_option(SS_SPIN_REWRITER_OPTIONS, $options, '', 'yes');
2250 }
2251
2252}
2253 function ss_set_option($option_name, $newvalue, $deprecated, $autoload) {
2254 if (get_option($option_name) === false) {
2255 add_option($option_name, $newvalue, $deprecated, $autoload);
2256 } else {
2257 update_option($option_name, $newvalue);
2258 }
2259}
2260
2261$ss_wa_options = get_option(SS_WORDAI_OPTIONS);
2262
2263function ss_wordai($content) {
2264 global $ss_wa_options;
2265
2266 $text = urlencode($content);
2267 if ($ss_wa_options['plan'] == 'turing') {
2268 $ch = curl_init('http://wordai.com/users/turing-api.php');
2269 $quality = $ss_wa_options['turing_quality'];
2270 } else {
2271 $ch = curl_init('http://wordai.com/users/regular-api.php');
2272 $quality = $ss_wa_options['standard_quality'];
2273 }
2274 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
2275 curl_setopt($ch, CURLOPT_POST, 1);
2276 curl_setopt($ch, CURLOPT_POSTFIELDS, "s=$text&quality=$quality&email=" . $ss_wa_options['email'] . "&pass=" . $ss_wa_options['pass'] . "&nonested=" . $ss_wa_options['nonested'] . "&sentence=" . $ss_wa_options['sentence'] . "¶graph=" . $ss_wa_options['returnspin'] .
2277 "&returnspin=false&nooriginal=" . $ss_wa_options['nooriginal'] .
2278 "&protected=" . urlencode($ss_wa_options['protected']) . "&synonyms=" . urlencode($ss_wa_options['synonyms']) . "&output=json");
2279 $response = trim(curl_exec($ch));
2280 curl_close($ch);
2281
2282 $api_response_interpreted = json_decode($response, true);
2283 if ($api_response_interpreted['status'] == 'Success') {
2284 return $api_response_interpreted['text'];
2285 }
2286
2287 return $content;
2288}
2289
2290$ss_sr_options = get_option(SS_SPIN_REWRITER_OPTIONS);
2291
2292add_action('init', 'userID');
2293
2294function userID(){
2295
2296 $user_ID= get_current_user_id();
2297}
2298
2299function ss_spinrewriter($content) {
2300 global $ss_sr_options;
2301
2302 $text = urlencode($content);
2303 $ch = curl_init('http://www.spinrewriter.com/action/api');
2304 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
2305 curl_setopt($ch, CURLOPT_POST, 1);
2306 curl_setopt($ch, CURLOPT_POSTFIELDS, "action=text_with_spintax&text=$text&email_address=" . $ss_sr_options['email'] . "&api_key=" . $ss_sr_options['apikey'] . "&confidence_level=" . $ss_sr_options['confidence_level'] . "&nested_spintax=" . $ss_sr_options['nested'] . "&auto_sentences=" . $ss_sr_options['sentence'] .
2307 "&auto_paragraphs=" . $ss_sr_options['paragraph'] ."&auto_new_paragraphs=" . $ss_sr_options['auto_new_paragraphs'] ."&auto_sentence_trees=" . $ss_sr_options['auto_sentence_trees'] ."&protected_terms=" . urlencode(str_replace("," , "\n" ,$ss_sr_options['protected'])) . "&auto_protected_terms=" . $ss_sr_options['capitalized'] . "");
2308 $response = trim(curl_exec($ch));
2309 curl_close($ch);
2310
2311 $api_response_interpreted = json_decode($response, true);
2312 if ($api_response_interpreted['status'] == 'OK') {
2313 return $api_response_interpreted['response'];
2314 }
2315
2316 return $content;
2317}
2318
2319
2320
2321
2322?>