PageRenderTime 48ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/Wordpress/warp/systems/wordpress/helpers/system.php

https://github.com/dominikkucharski/Warp-Framework
PHP | 687 lines | 337 code | 149 blank | 201 comment | 75 complexity | 56aaff34c92847e45dd2605892078d13 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Warp Theme Framework
  4. * @author YOOtheme http://www.yootheme.com
  5. * @copyright Copyright (C) YOOtheme GmbH
  6. * @license http://www.gnu.org/licenses/gpl.html GNU/GPL
  7. */
  8. /*
  9. Class: SystemWarpHelper
  10. Wordpress system helper class, provides Wordpress 3.0 Blog integration (http://wordpress.org)
  11. */
  12. class SystemWarpHelper extends WarpHelper {
  13. /* system path */
  14. public $path;
  15. /* system url */
  16. public $url;
  17. /* cache path */
  18. public $cache_path;
  19. /* cache time */
  20. public $cache_time;
  21. /* configuration */
  22. public $config;
  23. /* theme xml */
  24. public $xml;
  25. /* query */
  26. public $query;
  27. /* all menu items options */
  28. public $menu_item_options;
  29. /*
  30. Function: Constructor
  31. Class Constructor.
  32. */
  33. public function __construct() {
  34. parent::__construct();
  35. // init vars
  36. $this->path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', ABSPATH), '/');
  37. $this->url = rtrim(site_url(), '/');
  38. $this->cache_path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', get_template_directory()), '/').'/cache';
  39. $this->cache_time = 86400;
  40. $this->menu_item_options = $this['option']->get('menu-items', array());
  41. // set config or load defaults
  42. if (defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE) {
  43. $settings = $this['option']->get('warp_theme_options', array());
  44. $settings = count($settings) ? $settings : file_get_contents($this['path']->path('template:config.default'));
  45. } else {
  46. $file = $this['path']->path('template:config');
  47. $settings = file_get_contents($file ? $file : $this['path']->path('template:config.default'));
  48. }
  49. $this->config = $this['data']->create($settings);
  50. // set cache directory
  51. if (!file_exists($this->cache_path)) {
  52. mkdir($this->cache_path, 0755);
  53. }
  54. }
  55. /*
  56. Function: init
  57. Initialize system configuration
  58. Returns:
  59. Void
  60. */
  61. public function init() {
  62. // set paths
  63. $this['path']->register($this->path.'/wp-admin', 'admin');
  64. $this['path']->register($this->path, 'site');
  65. $this['path']->register($this->cache_path, 'cache');
  66. $this['path']->register($this['path']->path('warp:systems/wordpress/menus'), 'menu');
  67. $this['path']->register($this['path']->path('warp:systems/wordpress/widgets'), 'widgets');
  68. $this['path']->register($this['path']->path('template:').'/widgets', 'widgets');
  69. // Enable thumbnail support for posts
  70. add_theme_support( 'post-thumbnails' );
  71. // set translations
  72. load_theme_textdomain('warp', $this['path']->path('template:languages'));
  73. // get theme xml
  74. $this->xml = $this['dom']->create($this['path']->path('template:template.xml'), 'xml');
  75. // get module positions
  76. foreach ($this->xml->find('positions > position') as $position) {
  77. $this['modules']->register($position->text());
  78. }
  79. // load widgets
  80. foreach ($this['path']->dirs('widgets:') as $name) {
  81. if ($file = $this['path']->path("widgets:{$name}/{$name}.php")) {
  82. require_once($file);
  83. }
  84. }
  85. // add actions
  86. add_action('wp_ajax_warp_search', array($this, 'ajaxSearch'));
  87. add_action('wp_ajax_nopriv_warp_search', array($this, 'ajaxSearch'));
  88. // register main menu
  89. register_nav_menus(array('main_menu' => 'Main Navigation Menu'));
  90. // is admin or site
  91. if (is_admin()) {
  92. // set paths
  93. $this['path']->register($this['path']->path('warp:config'), 'config');
  94. $this['path']->register($this['path']->path('warp:systems/wordpress/config'), 'config');
  95. // add actions
  96. add_action('admin_init', array($this, '_adminInit'));
  97. add_action('admin_menu', array($this, '_adminMenu'));
  98. // add notices
  99. if (isset($_GET['page']) && in_array($_GET['page'], array('warp', 'warp_widget'))) {
  100. add_action('admin_notices', array($this, '_adminNotices'));
  101. }
  102. } else {
  103. // add action
  104. add_action('wp', array($this, '_wp'));
  105. add_action("get_sidebar", array($this, '_get_sidebar'));
  106. // remove auto-linebreaks ?
  107. if (!$this->config->get('wpautop', 1)) {
  108. remove_filter('the_content', 'wpautop');
  109. }
  110. // set custom menu walker
  111. add_filter('wp_nav_menu_args', create_function('$args','if (empty($args["walker"])) $args["walker"] = new WarpMenuWalker();return $args;'));
  112. // filter widgets that should not be displayed
  113. add_filter('widget_display_callback', create_function('$instance,$widget,$args','$warp = Warp::getInstance(); return $warp["widgets"]->get($widget->id)->display ? $instance : false;'), 10, 3);
  114. // disable the admin bar for mobiles
  115. if ($this->config->get('mobile') && $this['browser']->isMobile()) {
  116. add_theme_support('admin-bar', array('callback' => '__return_false'));
  117. }
  118. }
  119. }
  120. /*
  121. Function: getQuery
  122. Get current query information
  123. Returns:
  124. Object
  125. */
  126. public function getQuery() {
  127. global $wp_query;
  128. // create, if not set
  129. if (empty($this->query)) {
  130. // init vars
  131. $obj = $wp_query->get_queried_object();
  132. $query = array();
  133. // find current page type
  134. foreach (array('home', 'front_page', 'archive', 'search', 'single', 'page', 'category') as $type) {
  135. if (call_user_func('is_'.$type)) {
  136. $query[] = $type;
  137. if ($type == 'page') {
  138. $query[] = 'page-'.$obj->ID;
  139. }
  140. if ($type == 'single') {
  141. $query[] = $obj->post_type;
  142. $query[] = $obj->post_type.'-'.$obj->ID;
  143. }
  144. if ($type == 'category') {
  145. $query[] = 'cat-'.$obj->cat_ID;
  146. }
  147. if ($type == 'archive') {
  148. $query[] = 'cat-'.$obj->term_id;
  149. }
  150. }
  151. }
  152. $this->query = $query;
  153. }
  154. return $this->query;
  155. }
  156. /*
  157. Function: getPostCount
  158. Retrieve current post count
  159. Returns:
  160. Int
  161. */
  162. public function getPostCount() {
  163. global $wp_query;
  164. return $wp_query->post_count;
  165. }
  166. /*
  167. Function: isBlog
  168. Returns:
  169. Boolean
  170. */
  171. public function isBlog() {
  172. return true;
  173. }
  174. /*
  175. Function: isPreview
  176. Checks for default widgets in theme preview
  177. Returns:
  178. Boolean
  179. */
  180. public function isPreview($position) {
  181. // preview postions
  182. $positions = array('logo', 'right');
  183. return is_preview() && in_array($position, $positions);
  184. }
  185. /*
  186. Function: ajaxSearch
  187. Ajax search callback
  188. Returns:
  189. String
  190. */
  191. public function ajaxSearch(){
  192. global $wp_query;
  193. $result = array('results' => array());
  194. $query = isset($_REQUEST['s']) ? $_REQUEST['s']:"";
  195. if (strlen($query)>=3) {
  196. $wp_query->query_vars['post_status'] = 'publish';
  197. $wp_query->query_vars['s'] = $query;
  198. $wp_query->is_search = true;
  199. foreach ($wp_query->get_posts() as $post) {
  200. $content = !empty($post->post_excerpt) ? strip_tags(do_shortcode($post->post_excerpt)) : strip_tags(do_shortcode($post->post_content));
  201. if (strlen($content) > 180) {
  202. $content = substr($content, 0, 179).'...';
  203. }
  204. $result['results'][] = array(
  205. 'title' => $post->post_title,
  206. 'text' => $content,
  207. 'url' => get_permalink($post->ID)
  208. );
  209. }
  210. }
  211. die(json_encode($result));
  212. }
  213. /*
  214. Function: _wp
  215. WP action callback
  216. Returns:
  217. Void
  218. */
  219. public function _wp() {
  220. // set config
  221. $this->config->set('language', get_bloginfo("language"));
  222. $this->config->set('direction', $GLOBALS['wp_locale']->is_rtl() ? 'rtl' : 'ltr');
  223. $this->config->set('site_url', rtrim(get_option('siteurl'), '/'));
  224. $this->config->set('site_name', get_option('blogname'));
  225. $this->config->set('datetime', date('Y-m-d'));
  226. $this->config->set('actual_date', date_i18n($this->config->get('date_format', 'l, j F Y')));
  227. $this->config->set('page_class', implode(' ', array_map(create_function('$element','return "wp-".$element;'), $this->getQuery())));
  228. // Outdated Browser page ?
  229. if (($this['config']->get('ie6page') && $this['browser']->isIE6()) || ($this['config']->get('outdated_browser') && $this['browser']->outdatedBrowser())) {
  230. $this['event']->bind('render.layouts:template', create_function('&$layout,&$args', '$args["title"] = __("Please update to a modern browser", "warp"); $args["error"] = "browser"; $args["message"] = __("outdatedBrowser_page_message", "warp"); $layout = "layouts:error";'));
  231. }
  232. // mobile theme ?
  233. if ($this['config']->get('mobile') && $this['browser']->isMobile()) {
  234. $this['config']->set('style', 'mobile');
  235. }
  236. // branding ?
  237. if ($this['config']->get('warp_branding')) {
  238. $this['template']->set('warp_branding', $this->warp->getBranding());
  239. }
  240. // set theme style paths
  241. if ($style = $this['config']->get('style')) {
  242. foreach (array('css' => 'template:styles/%s/css', 'js' => 'template:styles/%s/js', 'layouts' => 'template:styles/%s/layouts') as $name => $resource) {
  243. if ($p = $this['path']->path(sprintf($resource, $style))) {
  244. $this['path']->register($p, $name);
  245. }
  246. }
  247. }
  248. }
  249. /*
  250. Function: _adminInit
  251. Admin init action callback
  252. Returns:
  253. Void
  254. */
  255. public function _adminInit() {
  256. if (defined('DOING_AJAX') && DOING_AJAX && isset($_POST['task'], $_POST['warp-ajax-save'])) {
  257. $message = 'failed';
  258. $post = function_exists('wp_magic_quotes') ? array_map('stripslashes_deep', $_POST) : $_POST;
  259. switch ($post['task']) {
  260. case 'theme-options':
  261. // update theme config
  262. $config = isset($post['config']) ? $post['config'] : array();
  263. $config = array_merge($config, array('profile_data' => isset($post['profile_data']) ? $post['profile_data'] : array()));
  264. $config = array_merge($config, array('profile_map' => isset($post['profile_map']) ? $post['profile_map'] : array()));
  265. if (defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE) {
  266. if ($this['option']->set('warp_theme_options', (string) $this['data']->create($config))) {
  267. $message = 'success';
  268. }
  269. } else {
  270. if (file_put_contents($this['path']->path('template:').'/config', (string) $this['data']->create($config))) {
  271. $message = 'success';
  272. }
  273. }
  274. break;
  275. case 'widget-options':
  276. // update widget options
  277. if (update_option('warp_widget_options', $post['warp_widget_options'])) {
  278. $message = 'success';
  279. }
  280. break;
  281. }
  282. die(json_encode(compact('message')));
  283. }
  284. // add css/js
  285. $siteurl = sprintf('/%s/i', preg_quote(parse_url(site_url(), PHP_URL_PATH), '/'));
  286. if (isset($_GET['page']) && in_array($_GET['page'], array('warp', 'warp_widget'))) {
  287. wp_enqueue_style('warp-css-config', preg_replace($siteurl, '', $this['path']->url('config:css/config.css'), 1));
  288. wp_enqueue_script('warp-js-config', preg_replace($siteurl, '', $this['path']->url('config:js/config.js'), 1));
  289. wp_enqueue_script('warp-js-admin', preg_replace($siteurl, '', $this['path']->url('config:js/admin.js'), 1));
  290. }
  291. wp_enqueue_style('warp-css-admin', preg_replace($siteurl, '', $this['path']->url('config:css/admin.css'), 1));
  292. wp_enqueue_script('warp-js-wp-admin', preg_replace($siteurl, '', $this['path']->url('config:js/wp-admin.js'), 1));
  293. // add actions
  294. add_action('wp_ajax_save_nav_settings', array($this,'_save_nav_settings'));
  295. add_action('wp_ajax_get_nav_settings', array($this,'_get_nav_settings'));
  296. }
  297. /*
  298. Function: _adminNotices
  299. Admin notices action callback
  300. Returns:
  301. Void
  302. */
  303. public function _adminNotices() {
  304. // get warp xml
  305. $xml = $this['dom']->create($this['path']->path('warp:warp.xml'), 'xml');
  306. // cache writable ?
  307. if (!file_exists($this->cache_path) || !is_writable($this->cache_path)) {
  308. $update['cache'] = "Cache not writable, please check directory permissions ({$this->cache_path})";
  309. }
  310. // update check
  311. if ($url = $xml->first('updateUrl')->text()) {
  312. // create check urls
  313. $urls['tmpl'] = sprintf('%s?application=%s&version=%s&format=raw', $url, get_template(), $this->xml->first('version')->text());
  314. $urls['warp'] = sprintf('%s?application=%s&version=%s&format=raw', $url, 'warp', $xml->first('version')->text());
  315. foreach ($urls as $type => $url) {
  316. // only check once a day
  317. $hash = md5($url.date('Y-m-d'));
  318. if ($this['option']->get("{$type}_check") != $hash) {
  319. if ($request = $this['http']->get($url)) {
  320. $this['option']->set("{$type}_check", $hash);
  321. $this['option']->set("{$type}_data", $request['body']);
  322. }
  323. }
  324. // decode response and set message
  325. if (($data = json_decode($this['option']->get("{$type}_data"))) && $data->status == 'update-available') {
  326. $update[$type] = $data->message;
  327. }
  328. }
  329. }
  330. // show notice
  331. if (!empty($update)) {
  332. echo '<div class="update-nag">'.implode('<br>', $update).'</div>';
  333. }
  334. return false;
  335. }
  336. /*
  337. Function: _adminMenu
  338. Admin menu action callback
  339. Returns:
  340. Void
  341. */
  342. public function _adminMenu() {
  343. // init vars
  344. $name = $this->xml->first('name')->text();
  345. $icon = $this['path']->url('config:images/yoo_icon_16.png');
  346. if (function_exists('add_object_page')) {
  347. add_object_page('', $name, 8, 'warp', false, $icon);
  348. } else {
  349. add_menu_page('', $name, 8, 'warp', false, $icon);
  350. }
  351. add_submenu_page('warp', 'Theme Options', 'Theme Options', 8, 'warp', array($this, '_adminThemeOptions'));
  352. add_submenu_page('warp', 'Widget Options', 'Widget Options', 8, 'warp_widget', array($this, '_adminWidgetOptions'));
  353. }
  354. /*
  355. Function: _adminThemeOptions
  356. Render admin theme options layout
  357. Returns:
  358. Void
  359. */
  360. public function _adminThemeOptions() {
  361. echo $this['template']->render('config:layouts/theme_options', array('xml' => $this->xml));
  362. }
  363. /*
  364. Function: _adminWidgetOptions
  365. Render admin widget options layout
  366. Returns:
  367. Void
  368. */
  369. public function _adminWidgetOptions() {
  370. // get module settings
  371. $module_settings = $this->xml->find('modulesettings > setting');
  372. // get position settings
  373. $position_settings = array();
  374. foreach ($this->xml->find('positions > position') as $position) {
  375. $position_settings[$position->text()] = $position;
  376. }
  377. echo $this['template']->render('config:layouts/widget_options', compact('position_settings', 'module_settings'));
  378. }
  379. /*
  380. Function: getMenuItemOptions
  381. Retrieve menu by id
  382. Parameters:
  383. $id - Menu Item ID
  384. Returns:
  385. Array
  386. */
  387. public function getMenuItemOptions($id) {
  388. $menu_settings = array(
  389. 'columns' => 1,
  390. 'columnwidth' => -1,
  391. 'image' => ''
  392. );
  393. return isset($this->menu_item_options[$id]) ? $this->menu_item_options[$id] : array();
  394. }
  395. /*
  396. Function: _save_nav_settings
  397. Saves menu item settings
  398. Returns:
  399. Void
  400. */
  401. public function _save_nav_settings() {
  402. if (isset($_POST['menu-item'])) {
  403. $menu_item_settings = $this->menu_item_options;
  404. foreach ($_POST['menu-item'] as $itemId=>$settings) {
  405. $menu_item_settings[$itemId] = $settings;
  406. }
  407. $this['option']->set('menu-items', $menu_item_settings);
  408. $this->menu_item_options = $menu_item_settings;
  409. }
  410. die();
  411. }
  412. /*
  413. Function: _get_nav_settings
  414. Returns menu item settings as json
  415. Returns:
  416. Boolean
  417. */
  418. public function _get_nav_settings() {
  419. die(json_encode($this->menu_item_options));
  420. }
  421. /*
  422. Function: _get_sidebar
  423. Catches default sidebar content and makes it available for the sidebar widget
  424. Returns:
  425. Void
  426. */
  427. public function _get_sidebar($name=null) {
  428. $templates = isset($name) ? array("sidebar-{$name}.php", "sidebar.php") : array("sidebar.php");
  429. ob_start();
  430. if ("" == locate_template($templates, true, true)) {
  431. load_template(ABSPATH.WPINC."/theme-compat/sidebar.php", true);
  432. $clear = true;
  433. }
  434. $output = ob_get_clean();
  435. if (isset($clear)) {
  436. $output = "";
  437. }
  438. $this["template"]->set("sidebar.output", $output);
  439. }
  440. }
  441. /*
  442. Class: WarpMenuWalker
  443. Custom Menu Walker
  444. */
  445. class WarpMenuWalker extends Walker_Nav_Menu {
  446. public function start_lvl(&$output, $depth) {
  447. $output .= '<ul>';
  448. }
  449. public function end_lvl(&$output, $depth) {
  450. $output .= '</ul>';
  451. }
  452. public function start_el(&$output, $item, $depth, $args) {
  453. // get warp
  454. $warp = Warp::getInstance();
  455. // init vars
  456. $data = array();
  457. $classes = empty($item->classes) ? array() : (array) $item->classes;
  458. $options = $warp['system']->getMenuItemOptions($item->ID);
  459. // set id
  460. $data['data-id'] = $item->ID;
  461. // is current item ?
  462. if (in_array('current-menu-item', $classes) || in_array('current_page_item', $classes)) {
  463. $data['data-menu-active'] = 2;
  464. // home/fronpage item
  465. } elseif ($item->url == 'index.php' && (is_home() || is_front_page())) {
  466. $data['data-menu-active'] = 2;
  467. }
  468. // has columns ?
  469. if (!empty($options['columns'])) {
  470. $data['data-menu-columns'] = (int) $options['columns'];
  471. }
  472. // has columnwidth ?
  473. if (!empty($options['columnwidth'])) {
  474. $data['data-menu-columnwidth'] = (int) $options['columnwidth'];
  475. }
  476. // has image ?
  477. if (!empty($options['image'])) {
  478. $upload = wp_upload_dir();
  479. $data['data-menu-image'] = trailingslashit($upload['baseurl']).$options['image'];
  480. }
  481. // set item attributes
  482. $attributes = '';
  483. foreach ($data as $name => $value) {
  484. $attributes .= sprintf(' %s="%s"', $name, esc_attr($value));
  485. }
  486. // create item output
  487. $id = apply_filters('nav_menu_item_id', '', $item, $args);
  488. $output .= '<li'.(strlen($id) ? sprintf(' id="%s"', esc_attr($id)) : '').$attributes.'>';
  489. // set link attributes
  490. $attributes = '';
  491. foreach (array('attr_title' => 'title', 'target' => 'target', 'xfn' => 'rel', 'url' => 'href') as $var => $attr) {
  492. if (!empty($item->$var)) {
  493. $attributes .= sprintf(' %s="%s"', $attr, esc_attr($item->$var));
  494. }
  495. }
  496. // escape link title
  497. $item->title = htmlspecialchars($item->title, ENT_COMPAT, "UTF-8");
  498. // is separator ?
  499. if ($item->url == '#') {
  500. $format = '%s<span%s><span>%s</span></span>%s';
  501. $attributes = '';
  502. } else {
  503. $format = '%s<a%s><span>%s</span></a>%s';
  504. }
  505. // create link output
  506. $item_output = sprintf($format, $args->before, $attributes, $args->link_before.apply_filters('the_title', $item->title, $item->ID).$args->link_after, $args->after);
  507. $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
  508. }
  509. public function end_el(&$output, $item, $depth) {
  510. $output .= '</li>';
  511. }
  512. }
  513. /*
  514. Function: mb_strpos
  515. mb_strpos function for servers not using the multibyte string extension
  516. */
  517. if (!function_exists('mb_strpos')) {
  518. function mb_strpos($haystack, $needle, $offset = 0) {
  519. return strpos($haystack, $needle, $offset);
  520. }
  521. }