Guest User

Untitled

a guest
Jan 9th, 2017
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 124.49 KB | None | 0 0
  1. <?php
  2. /**
  3. * Admin Page Class
  4. *
  5. * The Admin Page Class is used by including it in your plugin files and using its methods to
  6. * create custom Admin Pages. It is meant to be very simple and
  7. * straightforward.
  8. *
  9. * This class is derived from My-Meta-Box (https://github.com/bainternet/My-Meta-Box script) which is
  10. * a class for creating custom meta boxes for WordPress.
  11. *
  12. *
  13. * @version 1.3.0
  14. * @copyright 2012 - 2014
  15. * @author Ohad Raz (email: admin@bainternet.info)
  16. * @link http://en.bainternet.info
  17. *
  18. * @license GNU General Public LIcense v3.0 - license.txt
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. *
  27. * @package Admin Page Class
  28. *
  29. * @Last Revised
  30. */
  31.  
  32. if ( ! class_exists( 'BF_Admin_Page_Class') ) :
  33.  
  34. /**
  35. * Admin Page Class
  36. *
  37. * @package Admin Page Class
  38. * @since 0.1
  39. *
  40. * @todo Nothing.
  41. */
  42.  
  43. class BF_Admin_Page_Class {
  44.  
  45. /**
  46. * Contains all saved data for a page
  47. *
  48. * @access protected
  49. * @var array
  50. * @since 0.1
  51. */
  52. protected $_saved;
  53.  
  54. /**
  55. * Contains all arguments needed to build the page itself
  56. *
  57. * @access protected
  58. * @var array
  59. * @since 0.1
  60. */
  61. protected $args;
  62.  
  63. /**
  64. * Contains Options group name
  65. * @access protected
  66. * @var array
  67. * @since 0.1
  68. */
  69. protected $option_group;
  70.  
  71. /**
  72. * Contains all the information needed to build the form structure of the page
  73. *
  74. * @access public
  75. * @var array
  76. * @since 0.1
  77. */
  78. public $_fields;
  79.  
  80. /**
  81. * True if the table is opened, false if it is not opened
  82. *
  83. * @access protected
  84. * @var boolean
  85. * @since 0.1
  86. */
  87. protected $table = false;
  88.  
  89. /**
  90. * True if the tab div is opened, false if it is not opened
  91. *
  92. * @access protected
  93. * @var boolean
  94. * @since 0.1
  95. */
  96. protected $tab_div = false;
  97.  
  98. /**
  99. * Contains the menu_slug for the current TopLeve-Menu
  100. *
  101. * @access public
  102. * @var string
  103. * @since 0.1
  104. */
  105. public $Top_Slug;
  106.  
  107. /**
  108. * Contains the menu_slug for the current page
  109. *
  110. * @access public
  111. * @var string
  112. * @since 0.1
  113. */
  114. public $_Slug;
  115.  
  116. /**
  117. * Contains all the information needed to build the Help tabs
  118. *
  119. * @access public
  120. * @var array
  121. * @since 0.1
  122. */
  123. public $_help_tabs;
  124.  
  125. /**
  126. * Use html table row or div for each field, true for row, false for div
  127. *
  128. * @access public
  129. * @var boolean
  130. * @since 0.1
  131. */
  132. public $_div_or_row;
  133.  
  134. /**
  135. * saved flag
  136. * @var boolean
  137. * @since 0.6
  138. */
  139. public $saved_flag = false;
  140.  
  141. /**
  142. * use google fonts for typo filed?
  143. * @var boolean
  144. * @since 0.9.9
  145. * @access public
  146. */
  147. public $google_fonts = false;
  148.  
  149. /**
  150. * Holds used field types
  151. * @var boolean
  152. * @since 1.1.3
  153. * @access public
  154. */
  155. public $field_types = array();
  156.  
  157. /**
  158. * Holds validation Errors
  159. * @var boolean
  160. * @since 1.1.9
  161. * @access public
  162. */
  163. public $errors = array();
  164.  
  165. /**
  166. * Holds Errors flag
  167. * @var boolean
  168. * @since 1.1.9
  169. * @access public
  170. */
  171. public $errors_flag = false;
  172.  
  173. /**
  174. * data_type holds type of data (options, post_meta, tax_meta, user_meta)
  175. * @var string
  176. * @since
  177. */
  178. public $data_type = 'options';
  179. /**
  180. * Builds a new Page
  181. * @param $args (string|mixed array) -
  182. *
  183. * Possible keys within $args:
  184. * > menu (array|string) - (string) -> this the name of the parent Top-Level-Menu or a TopPage object to create
  185. * this page as a sub menu to.
  186. * (array) -> top - Slug for the New Top level Menu page to create.
  187. * > page_title (string) - The name of this page (good for Top level and sub menu pages)
  188. * > capability (string) (optional) - The capability needed to view the page (good for Top level and sub menu pages)
  189. * > menu_title (string) - The name of the Top-Level-Menu (Top level Only)
  190. * > menu_slug (string) - A unique string identifying your new menu (Top level Only)
  191. * > icon_url (string) (optional) - URL to the icon, decorating the Top-Level-Menu (Top level Only)
  192. * > position (string) (optional) - The position of the Menu in the ACP (Top level Only)
  193. * > option_group (string) (required) - the name of the option to create in the database
  194. *
  195. *
  196. */
  197. public function __construct($args) {
  198. if(is_array($args)) {
  199. if (isset($args['option_group'])){
  200. $this->option_group = $args['option_group'];
  201. }
  202. $this->args = $args;
  203. } else {
  204. $array['page_title'] = $args;
  205. $this->args = $array;
  206. }
  207.  
  208. //add hooks for export download
  209. add_action('template_redirect',array($this, 'admin_redirect_download_files'));
  210. add_filter('init', array($this,'add_query_var_vars'));
  211.  
  212. // If we are not in admin area exit.
  213. if ( ! is_admin() )
  214. return;
  215.  
  216. //load translation
  217. $this->load_textdomain();
  218.  
  219. //set defaults
  220. $this->_div_or_row = true;
  221. $this->saved = false;
  222. //store args
  223. $this->args = $args;
  224. //google_fonts
  225. $this->google_fonts = isset($args['google_fonts'])? true : false;
  226.  
  227. //sub $menu
  228. if(!is_array($args['menu'])) {
  229. if(is_object($args['menu'])) {
  230. $this->Top_Slug = $args['menu']->Top_Slug;
  231. }else{
  232. switch($args['menu']) {
  233. case 'posts':
  234. $this->Top_Slug = 'edit.php';
  235. break;
  236. case 'dashboard':
  237. $this->Top_Slug = 'index.php';
  238. break;
  239. case 'media':
  240. $this->Top_Slug = 'upload.php';
  241. break;
  242. case 'links':
  243. $this->Top_Slug = 'link-manager.php';
  244. break;
  245. case 'pages':
  246. $this->Top_Slug = 'edit.php?post_type=page';
  247. break;
  248. case 'comments':
  249. $this->Top_Slug = 'edit-comments.php';
  250. break;
  251. case 'theme':
  252. $this->Top_Slug = 'themes.php';
  253. break;
  254. case 'plugins':
  255. $this->Top_Slug = 'plugins.php';
  256. break;
  257. case 'users':
  258. $this->Top_Slug = 'users.php';
  259. break;
  260. case 'tools':
  261. $this->Top_Slug = 'tools.php';
  262. break;
  263. case 'settings':
  264. $this->Top_Slug = 'options-general.php';
  265. break;
  266. default:
  267. if(post_type_exists($args['menu'])) {
  268. $this->Top_Slug = 'edit.php?post_type='.$args['menu'];
  269. } else {
  270. $this->Top_Slug = $args['menu'];
  271. }
  272. }
  273. }
  274. add_action('admin_menu', array($this, 'AddMenuSubPage'));
  275. }else{
  276. //top page
  277. $this->Top_Slug = $args['menu']['top'];
  278. add_action('admin_menu', array($this, 'AddMenuTopPage'));
  279. }
  280.  
  281.  
  282. // Assign page values to local variables and add it's missed values.
  283. $this->_Page_Config = $args;
  284. $this->_fields = $this->_Page_Config['fields'];
  285. $this->_Local_images = (isset($args['local_images'])) ? true : false;
  286. $this->_div_or_row = (isset($args['div_or_row'])) ? $args['div_or_row'] : false;
  287. $this->add_missed_values();
  288. if (isset($args['use_with_theme'])){
  289. if ($args['use_with_theme'] === true){
  290. $this->SelfPath = get_stylesheet_directory_uri() . '/admin-page-class';
  291. }elseif($args['use_with_theme'] === false){
  292. $this->SelfPath = plugins_url( 'admin-page-class', plugin_basename( dirname( __FILE__ ) ) );
  293. }else{
  294. $this->SelfPath = $args['use_with_theme'];
  295. }
  296. }else{
  297. $this->SelfPath = plugins_url( 'admin-page-class', plugin_basename( dirname( __FILE__ ) ) );
  298. }
  299.  
  300. // Load common js, css files
  301. // Must enqueue for all pages as we need js for the media upload, too.
  302.  
  303.  
  304. //add_action('admin_head', array($this, 'loadScripts'));
  305. add_filter('attribute_escape',array($this,'edit_insert_to_post_text'),10,2);
  306.  
  307. // Delete file via Ajax
  308. add_action( 'wp_ajax_apc_delete_mupload', array( $this, 'wp_ajax_delete_image' ) );
  309. //import export
  310. add_action( 'wp_ajax_apc_import_'.$this->option_group, array( $this, 'import' ) );
  311. add_action( 'wp_ajax_apc_export_'.$this->option_group, array( $this, 'export' ) );
  312.  
  313. //plupload ajax
  314. add_action('wp_ajax_plupload_action', array( $this,"Handle_plupload_action"));
  315.  
  316. }
  317.  
  318.  
  319. /**
  320. * Does all the complicated stuff to build the menu and its first page
  321. *
  322. * @since 0.1
  323. * @access public
  324. */
  325. public function AddMenuTopPage() {
  326. $default = array(
  327. 'capability' => 'edit_themes',
  328. 'menu_title' => '',
  329. 'id' => 'id',
  330. 'icon_url' => '',
  331. 'position' => null
  332. );
  333.  
  334. $this->args = array_merge($default, $this->args);
  335. $id = add_menu_page($this->args['page_title'], $this->args['page_title'], $this->args['capability'], $this->args['id'], array($this, 'DisplayPage'), $this->args['icon_url'], $this->args['position']);
  336. $page = add_submenu_page($id, $this->args['page_title'], $this->args['page_title'], $this->args['capability'], $this->args['id'], array($this, 'DisplayPage'));
  337. if ($page){
  338. $this->_Slug = $page;
  339. // Adds my_help_tab when my_admin_page loads
  340. add_action('load-'.$page, array($this,'Load_page_hooker'));
  341. }
  342. }
  343.  
  344. /**
  345. * Does all the complicated stuff to build the page
  346. *
  347. * @since 0.1
  348. * @access public
  349. */
  350. public function AddMenuSubPage() {
  351. $default = array(
  352. 'capability' => 'edit_themes',
  353. );
  354. $this->args = array_merge($default, $this->args);
  355. $page = add_submenu_page($this->Top_Slug, $this->args['page_title'], $this->args['page_title'], $this->args['capability'], $this->createSlug(), array($this, 'DisplayPage'));
  356. if ($page){
  357. $this->_Slug = $page;
  358. add_action('load-'.$page, array($this,'Load_page_hooker'));
  359. }
  360. }
  361.  
  362. /**
  363. * loads scripts and styles for the page
  364. *
  365. * @author ohad raz
  366. * @since 0.1
  367. * @access public
  368. */
  369. public function Load_page_hooker(){
  370. $page = $this->_Slug;
  371. //help tabs
  372. add_action('admin_head-'.$page, array($this,'admin_add_help_tab'));
  373. //pluploader code
  374. add_action('admin_head-'.$page, array($this,'plupload_head_js'));
  375. //scripts and styles
  376. add_action( 'admin_print_styles', array( $this, 'load_scripts_styles' ) );
  377. //panel script
  378. add_action('admin_footer-' . $page, array($this,'panel_script'));
  379. //add mising scripts
  380. //add_action('admin_enqueue_scripts',array($this,'Finish'));
  381.  
  382. if(isset($_POST['action']) && $_POST['action'] == 'save') {
  383. do_action('WP_EX_before_save',$this);
  384. $this->save();
  385. $this->saved_flag = true;
  386. do_action('WP_EX_after_save',$this);
  387. }
  388. }
  389.  
  390. public function plupload_head_js(){
  391. if ($this->has_field('plupload')){
  392. $plupload_init = array(
  393. 'runtimes' => 'html5,silverlight,flash,html4',
  394. 'browse_button' => 'plupload-browse-button', // will be adjusted per uploader
  395. 'container' => 'plupload-upload-ui', // will be adjusted per uploader
  396. 'drop_element' => 'drag-drop-area', // will be adjusted per uploader
  397. 'file_data_name' => 'async-upload', // will be adjusted per uploader
  398. 'multiple_queues' => true,
  399. 'max_file_size' => wp_max_upload_size() . 'b',
  400. 'url' => admin_url('admin-ajax.php'),
  401. 'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'),
  402. 'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'),
  403. 'filters' => array(array('title' => __('Allowed Files','apc'), 'extensions' => '*')),
  404. 'multipart' => true,
  405. 'urlstream_upload' => true,
  406. 'multi_selection' => false, // will be added per uploader
  407. // additional post data to send to our ajax hook
  408. 'multipart_params' => array(
  409. '_ajax_nonce' => "", // will be added per uploader
  410. 'action' => 'plupload_action', // the ajax action name
  411. 'imgid' => 0 // will be added per uploader
  412. )
  413. );
  414. echo '<script type="text/javascript">'."\n".'var base_plupload_config=';
  415. echo json_encode($plupload_init)."\n".'</script>';
  416. }
  417. }
  418.  
  419. /**
  420. * Creates an unique slug out of the page_title and the current menu_slug
  421. *
  422. * @since 0.1
  423. * @access private
  424. */
  425. private function createSlug() {
  426. $slug = $this->args['page_title'];
  427. $slug = strtolower($slug);
  428. $slug = str_replace(' ','_',$slug);
  429. return $this->Top_Slug.'_'.$slug;
  430. }
  431.  
  432. /** add Help Tab
  433. *
  434. * @since 0.1
  435. * @access public
  436. * @param $args (mixed|array) contains everything needed to build the field
  437. *
  438. * Possible keys within $args:
  439. * > id (string) (required)- Tab ID. Must be HTML-safe and should be unique for this menu
  440. * > title (string) (required)- Title for the tab.
  441. * > content (string) (required)- Help tab content in plain text or HTML.
  442. *
  443.  
  444. *
  445. * Will only work on wordpres version 3.3 and up
  446. */
  447. public function HelpTab($args){
  448. $this->_help_tabs[] = $args;
  449. }
  450.  
  451. /* print Help Tabs for current screen
  452. *
  453. * @access public
  454. * @since 0.1
  455. * @author Ohad
  456. *
  457. * Will only work on wordpres version 3.3 and up
  458. */
  459. public function admin_add_help_tab(){
  460. $screen = get_current_screen();
  461. /*
  462. * Check if current screen is My Admin Page
  463. * Don't add help tab if it's not
  464. */
  465.  
  466. if ( $screen->id != $this->_Slug )
  467. return;
  468. // Add help_tabs for current screen
  469.  
  470. foreach((array)$this->_help_tabs as $tab){
  471.  
  472. $screen->add_help_tab($tab);
  473. }
  474. }
  475.  
  476. /* print out panel Script
  477. *
  478. * @access public
  479. * @since 0.1
  480. */
  481. public function panel_script(){
  482. ?>
  483. <script>
  484.  
  485. /* cookie stuff */
  486. function setCookie(name,value,days) {
  487. if (days) {
  488. var date = new Date();
  489. date.setTime(date.getTime()+(days*24*60*60*1000));
  490. var expires = "; expires="+date.toGMTString();
  491. }
  492. else var expires = "";
  493. document.cookie = name+"="+value+expires+"; path=/";
  494. }
  495.  
  496. function getCookie(name) {
  497. var nameEQ = name + "=";
  498.  
  499. var ca = document.cookie.split(";");
  500. for(var i=0;i < ca.length;i++) {
  501. var c = ca[i];
  502. while (c.charAt(0)==' ') c = c.substring(1,c.length);
  503. if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  504. }
  505. return null;
  506. }
  507.  
  508. function eraseCookie(name) {setCookie(name,"",-1);}
  509.  
  510. var last_tab = getCookie("apc_<?php echo $this->option_group; ?>last");
  511. if (last_tab) {
  512. var last_tab = last_tab;
  513. }else{
  514. var last_tab = null;
  515. }
  516. jQuery(document).ready(function() {
  517. function show_tab(li){
  518. if (!jQuery(li).hasClass("active_tab")){
  519. //hide all
  520. jQuery(".setingstab").hide("slow");
  521. jQuery(".panel_menu li").removeClass("active_tab");
  522. tab = jQuery(li).find("a").attr("href");
  523. jQuery(li).addClass("active_tab");
  524. jQuery(tab).show("fast");
  525. setCookie("apc_<?php echo $this->option_group; ?>last",tab);
  526. }
  527. }
  528. //hide all
  529. jQuery(".setingstab").hide();
  530.  
  531. //set first_tab as active if no cookie found
  532. if (last_tab == null){
  533. jQuery(".panel_menu li:first").addClass("active_tab");
  534. var tab = jQuery(".panel_menu li:first a").attr("href");
  535. jQuery(tab).show();
  536. }else{
  537. show_tab(jQuery('[href="' + last_tab + '"]').parent());
  538. }
  539.  
  540. //bind click on menu action to show the right tab.
  541. jQuery(".panel_menu li").bind("click", function(event){
  542. event.preventDefault()
  543. show_tab(jQuery(this));
  544.  
  545. });
  546. <?php
  547. if ($this->has_Field('upload')){
  548. ?>
  549. function load_images_muploader(){
  550. jQuery(".mupload_img_holder").each(function(i,v){
  551. if (jQuery(this).next().next().val() != ""){
  552. jQuery(this).append('<img src="' + jQuery(this).next().next().val() + '" style="height: 150px;width: 150px;" />');
  553. jQuery(this).next().next().next().val("Delete");
  554. jQuery(this).next().next().next().removeClass("apc_upload_image_button").addClass("apc_delete_image_button");
  555. }
  556. });
  557. }
  558. //upload button
  559. var formfield1;
  560. var formfield2;
  561. jQuery("#image_button").click(function(e){
  562. if(jQuery(this).hasClass("apc_upload_image_button")){
  563. formfield1 = jQuery(this).prev();
  564. formfield2 = jQuery(this).prev().prev();
  565. tb_show("", "media-upload.php?type=image&amp;apc=insert_file&amp;TB_iframe=true");
  566. return false;
  567. }else{
  568. var field_id = jQuery(this).attr("rel");
  569. var at_id = jQuery(this).prev().prev();
  570. var at_src = jQuery(this).prev();
  571. var t_button = jQuery(this);
  572. data = {
  573. action: "apc_delete_mupload",
  574. _wpnonce: $("#nonce-delete-mupload_" + field_id).val(),
  575. field_id: field_id,
  576. attachment_id: jQuery(at_id).val()
  577. };
  578.  
  579. $.post(ajaxurl, data, function(response) {
  580. if ("success" == response.status){
  581. jQuery(t_button).val("Upload Image");
  582. jQuery(t_button).removeClass("apc_delete_image_button").addClass("apc_upload_image_button");
  583. //clear html values
  584. jQuery(at_id).val("");
  585. jQuery(at_src).val("");
  586. jQuery(at_id).prev().html("");
  587. load_images_muploader();
  588. }else{
  589. alert(response.message);
  590. }
  591. }, "json");
  592. return false;
  593. }
  594. });
  595.  
  596.  
  597.  
  598. //store old send to editor function
  599. window.restore_send_to_editor = window.send_to_editor;
  600. //overwrite send to editor function
  601. window.send_to_editor = function(html) {
  602. imgurl = jQuery("img",html).attr("src");
  603. img_calsses = jQuery("img",html).attr("class").split(" ");
  604. att_id = "";
  605. jQuery.each(img_calsses,function(i,val){
  606. if (val.indexOf("wp-image") != -1){
  607. att_id = val.replace("wp-image-", "");
  608. }
  609. });
  610.  
  611. jQuery(formfield2).val(att_id);
  612. jQuery(formfield1).val(imgurl);
  613. load_images_muploader();
  614. tb_remove();
  615. //restore old send to editor function
  616. window.send_to_editor = window.restore_send_to_editor;
  617. }
  618. <?php
  619. }
  620. ?>
  621. });
  622. </script>
  623. <?php
  624. }
  625.  
  626.  
  627.  
  628. //rename insert to post button
  629. /**
  630. * edit_insert_to_post_text
  631. *
  632. * @author ohad raz
  633. * @since 0.1
  634. * @param string $input insert to post text
  635. * @return string
  636. */
  637. public function edit_insert_to_post_text( $safe_text, $text ) {
  638. if( is_admin() && 'Insert into Post' == $safe_text){
  639. if (isset($_REQUEST['apc']) && 'insert_file' == $_REQUEST['apc'] )
  640. return str_replace(__('Insert into Post'), __('Use this File','apc'), $safe_text);
  641. else
  642. return str_replace(__('Insert into Post'), __('Use this Image','apc'), $safe_text);
  643. }
  644. return $safe_text;
  645. }
  646.  
  647. /* print out panel Style (deprecated)
  648. *
  649. * @access public
  650. * @since 0.1
  651. */
  652. public function panel_style(){
  653. //echo '<style></style>';
  654. }
  655.  
  656. /**
  657. * Outputs all the HTML needed for the new page
  658. *
  659. * @access public
  660. * @param $args (mixed|array) contains everything needed to build the field
  661. * @param $repeater (boolean)
  662. * @since 0.1
  663. */
  664. public function DisplayPage() {
  665. do_action('admin_page_class_before_page');
  666. echo '<div class="wrap">'."\n";
  667. echo '<form method="post" name="'.apply_filters('apc_form_name', 'admin_page_class',$this).'" class="'.apply_filters('apc_form_class', 'admin_page_class',$this).'" id="'.apply_filters('apc_form_id', 'admin_page_class',$this).'" action="" enctype="multipart/form-data">
  668. '."\n".'<div class="header_wrap">'."\n".'
  669. <div style="float:left">'."\n";
  670. // echo apply_filters('admin_page_class_before_title','');
  671. echo '<h2>'.apply_filters('admin_page_class_h2',$this->args['page_title']).'</h2>'."\n".((isset($this->args['page_header_text']))? $this->args['page_header_text'] : '').'
  672. </div>'."\n".'
  673. <div class="header-save-button" style="float:right;margin:32px 0 0 0">'."\n".'
  674. <input type="submit" value="'.esc_attr(__('Save Changes','apc')).'" name="Submit" class="'.apply_filters('admin_page_class_submit_class', 'btn-info').' btn">
  675. </div>'. '
  676. </div>'."\n";
  677. wp_nonce_field( basename(__FILE__), 'BF_Admin_Page_Class_nonce' );
  678.  
  679. if ($this->saved_flag){
  680. echo '<div class="update-status">'."\n";
  681. $this->errors = apply_filters('admin_page_class_errors', $this->errors,$this);
  682. if (is_array($this->errors) && count($this->errors) > 0 ){
  683. $this->errors_flag = true;
  684. $this->displayErrors();
  685. }else{
  686. echo '<div class="alert alert-success"><button data-dismiss="alert" class="close" type="button">×</button><strong>'.__('Settings saved.','apc').'</strong></div>'."\n";
  687. }
  688. echo '</div>'."\n";
  689. }
  690.  
  691.  
  692. $saved = get_option($this->option_group);
  693. $this->_saved = $saved;
  694. $skip = array('title','paragraph','subtitle','TABS','CloseDiv','TABS_Listing','OpenTab','custom','import_export');
  695.  
  696. foreach($this->_fields as $field) {
  697. if (!in_array($field['type'],$skip)){
  698. if(!$this->table) {
  699. if ($this->_div_or_row){
  700. echo '<table class="form-table">'."\n";
  701. $this->table = true;
  702. }else{
  703. echo '<div class="form-table">'."\n";
  704. $this->table = true;
  705. }
  706. }
  707. }else{
  708. if($this->table) {
  709. if ($this->_div_or_row){echo '</table>'."\n";}else{echo '</div>'."\n";}
  710. $this->table = false;
  711. }
  712. }
  713. $data = '';
  714. if(!$this->saved_flag && $saved === false)
  715. $data = isset($field['std'])? $field['std'] : '';
  716.  
  717. if (isset($saved[$field['id']]))
  718. $data = $saved[$field['id']];
  719.  
  720. if (method_exists($this,'show_field_' . $field['type'])){
  721. if ($this->_div_or_row){echo '<td>'."\n";}else{echo apply_filters('admin_page_class_field_container_open','<div class="field">'."\n",$field);}
  722. call_user_func ( array( $this, 'show_field_' . $field['type'] ), $field, $data );
  723. if ($this->_div_or_row){echo '</td>'."\n";}else{echo apply_filters('admin_page_class_field_container_close','</div>'."\n",$field);}
  724. }else{
  725. switch($field['type']) {
  726. case 'TABS':
  727. echo '<div id="tabs">'."\n";
  728. break;
  729. case 'CloseDiv':
  730. $this->tab_div = false;
  731. echo '</div>'."\n";
  732. break;
  733. case 'TABS_Listing':
  734. echo '<div class="panel_menu">'."\n".'<ul>'."\n";
  735. echo apply_filters('admin_page_class_before_title','');
  736. foreach($field['links'] as $id => $name){
  737. $extra_classes = strtolower(str_replace(' ','-',$name)).' '.strtolower(str_replace(' ','-',$id));
  738. echo '<li class="'.apply_filters('APC_tab_li_extra_class',$extra_classes).'">'."\n\t".'<a class="nav_tab_link" href="#'.$id.'">'.$name.'</a>'."\n".'</li>'."\n";
  739. }
  740. echo '</ul>'."\n".'</div>'."\n".'<div class="sections">'."\n";
  741. break;
  742. case 'OpenTab':
  743. $this->tab_div = true;
  744. echo '<div class="setingstab" id="'.$field['id'].'">'."\n";
  745. do_action('admin_page_class_after_tab_open');
  746. break;
  747. case 'title':
  748. echo '<h2>'.$field['label'].'</h2>'."\n";
  749. break;
  750. case 'subtitle':
  751. echo '<h3>'.$field['label'].'</h3>'."\n";
  752. break;
  753. case 'paragraph':
  754. echo '<p>'.$field['text'].'</p>'."\n";
  755. break;
  756. case 'repeater':
  757. do_action('admin_page_class_before_repeater');
  758. $this->output_repeater_fields($field,$data);
  759. do_action('admin_page_class_after_repeater');
  760. break;
  761. case 'import_export':
  762. $this->show_import_export();
  763. do_action('admin_page_class_import_export_tab');
  764. break;
  765. }
  766. }
  767. if (!in_array($field['type'],$skip)){ echo '</tr>'."\n";}
  768. }
  769. if($this->table) echo '</table>'."\n";
  770. if($this->tab_div) echo '</div>'."\n";
  771. echo '</div>'."\n".'<div style="clear:both"></div>'."\n".'<div class="footer_wrap">'."\n".'
  772. <input type="submit" name="Submit" class="'.apply_filters('admin_page_class_submit_class', 'btn-info').' btn" value="'.esc_attr(__('Save Changes','apc')).'" />'.'
  773. </div>'."\n";
  774. echo '<input type="hidden" name="action" value="save" />'."\n";
  775. echo '</form>'."\n".'</div>'."\n".'</div>'."\n";
  776. do_action('admin_page_class_after_page');
  777. }
  778.  
  779. /**
  780. * Adds tabs current page
  781. *
  782. * @access public
  783. * @param $args (mixed|array) contains everything needed to build the field
  784. * @since 0.1
  785. */
  786. public function OpenTabs_container($text= null) {
  787. $args['type'] = 'TABS';
  788. $text = (null == $text)? '': $text;
  789. $args['text'] = $text;
  790. $args['id'] = 'TABS';
  791. $args['std'] = '';
  792. $this->SetField($args);
  793. }
  794.  
  795. /**
  796. * Close open Div
  797. *
  798. * @access public
  799. * @param $args (mixed|array) contains everything needed to build the field
  800. * @param $repeater (boolean)
  801. * @since 0.1
  802. */
  803. public function CloseDiv_Container() {
  804. $args['type'] = 'CloseDiv';
  805. $args['id'] = 'CloseDiv';
  806. $args['std'] = '';
  807. $this->SetField($args);
  808. }
  809.  
  810. /**
  811. * Adds tabs listing in ul li
  812. *
  813. * @access public
  814. * @param $args (mixed|array) contains everything needed to build the field
  815. * @param $repeater (boolean)
  816. * @since 0.1
  817. */
  818. public function TabsListing($args) {
  819. $args['type'] = 'TABS_Listing';
  820. $args['id'] = 'TABS_Listing';
  821. $args['std'] = '';
  822. $this->SetField($args);
  823. }
  824.  
  825. /**
  826. * Opens a Div
  827. *
  828. * @access public
  829. * @param $args (mixed|array) contains everything needed to build the field
  830. * @param $repeater (boolean)
  831. * @since 0.1
  832. */
  833. public function OpenTab($name) {
  834. $args['type'] = 'OpenTab';
  835. $args['id'] = $name;
  836. $args['std'] = '';
  837. $this->SetField($args);
  838. }
  839.  
  840. /**
  841. * close a Div
  842. *
  843. * @access public
  844. * @since 0.1
  845. */
  846. public function CloseTab() {
  847. $args['type'] = 'CloseDiv';
  848. $args['id'] = 'CloseDiv';
  849. $args['std'] = '';
  850. $this->SetField($args);
  851. }
  852.  
  853. /**
  854. * Does the repetive tasks of adding a field
  855. *
  856. * @param $args (mixed|array) contains everything needed to build the field
  857. * @param $repeater (boolean)
  858. * @since 0.1
  859. *
  860. * @access private
  861. */
  862. private function SetField($args) {
  863. $default = array(
  864. 'std' => '',
  865. 'id' => ''
  866. );
  867. $args = array_merge($default, $args);
  868. $this->buildOptions($args);
  869. $this->_fields[] = $args;
  870. }
  871.  
  872. /**
  873. * Builds all the options with their std values
  874. *
  875. * @access public
  876. * @param $args (mixed|array) contains everything needed to build the field
  877. * @since 0.1
  878. * @access private
  879. */
  880. private function buildOptions($args) {
  881. $default = array(
  882. 'std' => '',
  883. 'id' => ''
  884. );
  885. $args = array_merge($default, $args);
  886. $saved = get_option($this->option_group);
  887. if (isset($saved[$args['id']])){
  888. if($saved[$args['id']] === false) {
  889. $saved[$args['id']] = $args['std'];
  890. update_option($this->args['option_group'],$saved);
  891. }
  892. }
  893. }
  894.  
  895. /**
  896. * Adds a heading to the current page
  897. *
  898. * @access public
  899. * @param $args (mixed|array) contains everything needed to build the field
  900. * @param $repeater (boolean)
  901. * @since 0.1
  902. *
  903. * @param string $label simply the text for your heading
  904. */
  905. public function Title($label,$repeater = false) {
  906. $args['type'] = 'title';
  907. $args['std'] = '';
  908. $args['label'] = $label;
  909. $args['id'] = 'title'.$label;
  910. $this->SetField($args);
  911. }
  912.  
  913. /**
  914. * Adds a sub-heading to the current page
  915. *
  916. * @access public
  917. * @param $args (mixed|array) contains everything needed to build the field
  918. * @param $repeater (boolean)
  919. * @since 0.1
  920. *
  921. * @param string $label simply the text for your heading
  922. */
  923. public function Subtitle($label,$repeater = false) {
  924. $args['type'] = 'subtitle';
  925. $args['label'] = $label;
  926. $args['id'] = 'title'.$label;
  927. $args['std'] = '';
  928. $this->SetField($args);
  929. }
  930.  
  931. /**
  932. * Adds a paragraph to the current page
  933. *
  934. * @access public
  935. * @param $args (mixed|array) contains everything needed to build the field
  936. * @param $repeater (boolean)
  937. * @since 0.1
  938. *
  939. * @param string $text the text you want to display
  940. */
  941. public function Paragraph($text,$repeater = false) {
  942. $args['type'] = 'paragraph';
  943. $args['text'] = $text;
  944. $args['id'] = 'paragraph';
  945. $args['std'] = '';
  946. $this->SetField($args);
  947. }
  948.  
  949.  
  950. /**
  951. * Load all Javascript and CSS
  952. *
  953. * @since 0.1
  954. * @access public
  955. */
  956. public function load_scripts_styles() {
  957.  
  958. // Get Plugin Path
  959. $plugin_path = $this->SelfPath;
  960.  
  961. //this replaces the ugly check fields methods calls
  962. foreach (array('upload','color','date','time','code','select','editor','plupload') as $type) {
  963. call_user_func ( array( $this, 'check_field_' . $type ));
  964. }
  965.  
  966. wp_enqueue_script('common');
  967. if ($this->has_Field('TABS')){
  968. wp_print_scripts('jquery-ui-tabs');
  969. }
  970.  
  971. // Enqueue admin page Style
  972. wp_enqueue_style( 'Admin_Page_Class', $plugin_path . '/css/Admin_Page_Class.css' );
  973. wp_enqueue_style('iphone_checkbox',$plugin_path. '/js/FancyCheckbox/FancyCheckbox.css');
  974.  
  975. // Enqueue admin page Scripts
  976. wp_enqueue_script( 'Admin_Page_Class', $plugin_path . '/js/Admin_Page_Class.js', array( 'jquery' ), null, true );
  977. wp_enqueue_script('iphone_checkbox',$plugin_path. '/js/FancyCheckbox/FancyCheckbox.js',array('jquery'),null,true);
  978.  
  979. wp_enqueue_script('utils');
  980. wp_enqueue_script( 'jquery-ui-sortable' );
  981. wp_enqueue_script( 'jquery-ui-dialog' );
  982. }
  983.  
  984.  
  985. /**
  986. * Check Field code editor
  987. *
  988. * @since 0.1
  989. * @access public
  990. */
  991. public function check_field_code() {
  992.  
  993. if ( $this->has_field( 'code' ) && $this->is_edit_page() ) {
  994. $plugin_path = $this->SelfPath;
  995. // Enqueu codemirror js and css
  996. wp_enqueue_style( 'at-code-css', $plugin_path .'/js/codemirror/codemirror.css',array(),null);
  997. wp_enqueue_style( 'at-code-css-dark', $plugin_path .'/js/codemirror/solarizedDark.css',array(),null);
  998. wp_enqueue_style( 'at-code-css-light', $plugin_path .'/js/codemirror/solarizedLight.css',array(),null);
  999. wp_enqueue_script('at-code-js',$plugin_path .'/js/codemirror/codemirror.js',array('jquery'),false,true);
  1000. wp_enqueue_script('at-code-js-xml',$plugin_path .'/js/codemirror/xml.js',array('jquery'),false,true);
  1001. wp_enqueue_script('at-code-js-javascript',$plugin_path .'/js/codemirror/javascript.js',array('jquery'),false,true);
  1002. wp_enqueue_script('at-code-js-css',$plugin_path .'/js/codemirror/css.js',array('jquery'),false,true);
  1003. wp_enqueue_script('at-code-js-clike',$plugin_path .'/js/codemirror/clike.js',array('jquery'),false,true);
  1004. wp_enqueue_script('at-code-js-php',$plugin_path .'/js/codemirror/php.js',array('jquery'),false,true);
  1005. }
  1006. }
  1007.  
  1008.  
  1009.  
  1010. /**
  1011. * Check For editor field to enqueue editor scripts
  1012. * @since 1.1.3
  1013. * @access public
  1014. */
  1015. public function check_field_editor(){
  1016. if ($this->has_Field('editor')){
  1017. global $wp_version;
  1018. if ( version_compare( $wp_version, '3.2.1' ) < 1 ) {
  1019. wp_print_scripts('tiny_mce');
  1020. wp_print_scripts('editor');
  1021. wp_print_scripts('editor-functions');
  1022. }
  1023. }
  1024. }
  1025.  
  1026. /**
  1027. * Check For select field to enqueue Select2 #see http://goo.gl/3pjY8
  1028. * @since 1.1.3
  1029. * @access public
  1030. */
  1031. public function check_field_select(){
  1032. if ($this->has_field_any(array('select','typo')) && $this->is_edit_page()) {
  1033. $plugin_path = $this->SelfPath;
  1034. // Enqueu JQuery chosen library, use proper version.
  1035. wp_enqueue_style('at-multiselect-chosen-css', $plugin_path . '/js/select2/select2.css', array(), null);
  1036.  
  1037. wp_enqueue_script('at-multiselect-chosen-js', $plugin_path . '/js/select2/select2.js', array('jquery'), false, true);
  1038. }
  1039. }
  1040.  
  1041. /**
  1042. * Check Field Plupload
  1043. *
  1044. * @since 0.9.7
  1045. * @access public
  1046. */
  1047. public function check_field_plupload(){
  1048. if ( $this->has_field( 'plupload' ) && $this->is_edit_page() ) {
  1049. $plugin_path = $this->SelfPath;
  1050. wp_enqueue_script('plupload-all');
  1051. wp_register_script('myplupload', $plugin_path .'/js/plupload/myplupload.js', array('jquery'));
  1052. wp_enqueue_script('myplupload');
  1053. wp_register_style('myplupload', $plugin_path .'/js/plupload/myplupload.css');
  1054. wp_enqueue_style('myplupload');
  1055. }
  1056. }
  1057.  
  1058.  
  1059. /**
  1060. * Check the Field Upload, Add needed Actions
  1061. *
  1062. * @since 0.1
  1063. * @access public
  1064. */
  1065. public function check_field_upload() {
  1066.  
  1067. // Check if the field is an image or file. If not, return.
  1068. if ( ! $this->has_field_any(array('image','file')) )
  1069. return;
  1070.  
  1071. // Add data encoding type for file uploading.
  1072. add_action( 'post_edit_form_tag', array( $this, 'add_enctype' ) );
  1073.  
  1074. if( wp_style_is( 'wp-color-picker', 'registered' ) ){ //since WordPress 3.5
  1075. wp_enqueue_media();
  1076. wp_enqueue_script('media-upload');
  1077. }else{
  1078. // Make upload feature work event when custom post type doesn't support 'editor'
  1079. wp_enqueue_script( 'media-upload' );
  1080. add_thickbox();
  1081. wp_enqueue_script( 'jquery-ui-core' );
  1082. wp_enqueue_script( 'jquery-ui-sortable' );
  1083. }
  1084.  
  1085.  
  1086. // Add filters for media upload.
  1087. add_filter( 'media_upload_gallery', array( $this, 'insert_images' ) );
  1088. add_filter( 'media_upload_library', array( $this, 'insert_images' ) );
  1089. add_filter( 'media_upload_image', array( $this, 'insert_images' ) );
  1090.  
  1091. // Delete all attachments when delete custom post type.
  1092. add_action( 'wp_ajax_at_delete_file', array( $this, 'delete_file' ) );
  1093. add_action( 'wp_ajax_at_reorder_images', array( $this, 'reorder_images' ) );
  1094. // Delete file via Ajax
  1095. add_action( 'wp_ajax_at_delete_mupload', array( $this, 'wp_ajax_delete_image' ) );
  1096. }
  1097.  
  1098. /**
  1099. * Add data encoding type for file uploading
  1100. *
  1101. * @since 0.1
  1102. * @access public
  1103. */
  1104. public function add_enctype () {
  1105. echo ' enctype="multipart/form-data"';
  1106. }
  1107.  
  1108. /**
  1109. * Process images added to meta field.
  1110. *
  1111. * Modified from Faster Image Insert plugin.
  1112. *
  1113. * @return void
  1114. * @author Cory Crowley
  1115. */
  1116. public function insert_images() {
  1117.  
  1118. // If post variables are empty, return.
  1119. if ( ! isset( $_POST['at-insert'] ) || empty( $_POST['attachments'] ) )
  1120. return;
  1121.  
  1122. // Security Check
  1123. check_admin_referer( 'media-form' );
  1124.  
  1125. // Create Security Nonce
  1126. $nonce = wp_create_nonce( 'at_ajax_delete' );
  1127.  
  1128. // Get Post Id and Field Id
  1129. $id = $_POST['field_id'];
  1130.  
  1131. // Modify the insertion string
  1132. $html = '';
  1133. foreach( $_POST['attachments'] as $attachment_id => $attachment ) {
  1134.  
  1135. // Strip Slashes
  1136. $attachment = stripslashes_deep( $attachment );
  1137.  
  1138. // If not selected or url is empty, continue in loop.
  1139. if ( empty( $attachment['selected'] ) || empty( $attachment['url'] ) )
  1140. continue;
  1141.  
  1142. $li = "<li id='item_{$attachment_id}'>";
  1143. $li .= "<img src='{$attachment['url']}' alt='image_{$attachment_id}' />";
  1144. //$li .= "<a title='" . __( 'Delete this image' ) . "' class='at-delete-file' href='#' rel='{$nonce}|{$post_id}|{$id}|{$attachment_id}'>" . __( 'Delete' ) . "</a>";
  1145. $li .= "<a title='" . __( 'Delete this image','apc' ) . "' class='at-delete-file' href='#' rel='{$nonce}|{$post_id}|{$id}|{$attachment_id}'><img src='" . $this->SelfPath. "/images/delete-16.png' alt='" . __( 'Delete' ,'apc') . "' /></a>";
  1146. $li .= "<input type='hidden' name='{$id}[]' value='{$attachment_id}' />";
  1147. $li .= "</li>";
  1148. $html .= $li;
  1149.  
  1150. } // End For Each
  1151.  
  1152. return media_send_to_editor( $html );
  1153.  
  1154. }
  1155.  
  1156. /**
  1157. * Delete attachments associated with the post.
  1158. *
  1159. * @since 0.1
  1160. * @access public
  1161. *
  1162. */
  1163. public function delete_attachments( $post_id ) {
  1164.  
  1165. // Get Attachments
  1166. $attachments = get_posts( array( 'numberposts' => -1, 'post_type' => 'attachment', 'post_parent' => $post_id ) );
  1167.  
  1168. // Loop through attachments, if not empty, delete it.
  1169. if ( ! empty( $attachments ) ) {
  1170. foreach ( $attachments as $att ) {
  1171. wp_delete_attachment( $att->ID );
  1172. }
  1173. }
  1174.  
  1175. }
  1176.  
  1177.  
  1178. /**
  1179. * Ajax callback for deleting files.
  1180. * Modified from a function used by "Verve Meta Boxes" plugin (http://goo.gl/LzYSq)
  1181. * @since 0.1
  1182. * @access public
  1183. */
  1184. public function wp_ajax_delete_image() {
  1185. $field_id = isset( $_GET['field_id'] ) ? $_GET['field_id'] : 0;
  1186. $attachment_id = isset( $_GET['attachment_id'] ) ? intval( $_GET['attachment_id'] ) : 0;
  1187. $ok = false;
  1188. $remove_meta_only = apply_filters("apc_delete_image",true);
  1189. if (strpos($field_id, '[') === false){
  1190. check_admin_referer( "at-delete-mupload_".urldecode($field_id));
  1191. $temp = get_option($this->args['option_group']);
  1192. unset($temp[$field_id]);
  1193. update_option($this->args['option_group'],$temp);
  1194. if (!$remove_meta_only)
  1195. $ok = wp_delete_attachment( $attachment_id );
  1196. else
  1197. $ok = true;
  1198. }else{
  1199. $f = explode('[',urldecode($field_id));
  1200. $f_fiexed = array();
  1201. foreach ($f as $k => $v){
  1202. $f[$k] = str_replace(']','',$v);
  1203. }
  1204. $temp = get_option($this->args['option_group']);
  1205.  
  1206. /**
  1207. * repeater block
  1208. * $f[0] = repeater id
  1209. * $f[1] = repeater item number
  1210. * $f[2] = actuall in repeater item image field id
  1211. *
  1212. * conditional block
  1213. * $f[0] = conditional id
  1214. * $f[1] = actuall in conditional block image field id
  1215. */
  1216. $saved = $temp[$f[0]];
  1217. if (isset($f[2]) && isset($saved[$f[1]][$f[2]])){ //delete from repeater block
  1218. unset($saved[$f[1]][$f[2]]);
  1219. $temp[$f[0]] = $saved;
  1220. update_option($this->args['option_group'],$temp);
  1221. if (!$remove_meta_only)
  1222. $ok = wp_delete_attachment( $attachment_id );
  1223. else
  1224. $ok = true;
  1225. }elseif(isset($saved[$f[1]]['src'])){ //delete from conditional block
  1226. unset($saved[$f[1]]);
  1227. $temp[$f[0]] = $saved;
  1228. update_option($this->args['option_group'],$temp);
  1229. if (!$remove_meta_only)
  1230. $ok = wp_delete_attachment( $attachment_id );
  1231. else
  1232. $ok = true;
  1233. }
  1234. }
  1235.  
  1236. if ( $ok ){
  1237. echo json_encode( array('status' => 'success' ));
  1238. die();
  1239. }else{
  1240. echo json_encode(array('message' => __( 'Cannot delete file. Something\'s wrong.','apc')));
  1241. die();
  1242. }
  1243. }
  1244.  
  1245. /**
  1246. * Ajax callback for reordering Images.
  1247. *
  1248. * @since 0.1
  1249. * @access public
  1250. */
  1251. public function reorder_images() {
  1252.  
  1253. if ( ! isset( $_POST['data'] ) )
  1254. die();
  1255.  
  1256. list( $order, $post_id, $key, $nonce ) = explode( '|', $_POST['data'] );
  1257.  
  1258. if ( ! wp_verify_nonce( $nonce, 'at_ajax_reorder' ) )
  1259. die( '1' );
  1260.  
  1261. parse_str( $order, $items );
  1262. $items = $items['item'];
  1263. $order = 1;
  1264. foreach ( $items as $item ) {
  1265. wp_update_post( array( 'ID' => $item, 'post_parent' => $post_id, 'menu_order' => $order ) );
  1266. $order++;
  1267. }
  1268.  
  1269. die( '0' );
  1270.  
  1271. }
  1272.  
  1273. /**
  1274. * Check Field Color
  1275. *
  1276. * @since 0.1
  1277. * @access public
  1278. */
  1279. public function check_field_color() {
  1280.  
  1281. if ( $this->has_field_any(array('color' ,'typo' )) && $this->is_edit_page() ) {
  1282. if( wp_style_is( 'wp-color-picker', 'registered' ) ) {
  1283. wp_enqueue_style( 'wp-color-picker' );
  1284. wp_enqueue_script( 'wp-color-picker' );
  1285. }else{
  1286. // Enqueu built-in script and style for color picker.
  1287. wp_enqueue_style( 'farbtastic' );
  1288. wp_enqueue_script( 'farbtastic' );
  1289. }
  1290. }
  1291.  
  1292. }
  1293.  
  1294. /**
  1295. * Check Field Date
  1296. *
  1297. * @since 0.1
  1298. * @access public
  1299. */
  1300. public function check_field_date() {
  1301.  
  1302. if ( $this->has_field( 'date' ) && $this->is_edit_page() ) {
  1303. $plugin_path = $this->SelfPath;
  1304. // Enqueu JQuery UI, use proper version.
  1305. wp_enqueue_style( 'jquery-ui-css', $plugin_path.'/css/jquery-ui.css' );
  1306. wp_enqueue_script( 'jquery-ui');
  1307. wp_enqueue_script( 'jquery-ui-datepicker');
  1308. }
  1309.  
  1310. }
  1311.  
  1312. /**
  1313. * Check Field Time
  1314. *
  1315. * @since 0.1
  1316. * @access public
  1317. */
  1318. public function check_field_time() {
  1319.  
  1320. if ( $this->has_field( 'time' ) && $this->is_edit_page() ) {
  1321. $plugin_path = $this->SelfPath;
  1322.  
  1323. wp_enqueue_style( 'jquery-ui-css', $plugin_path.'/css/jquery-ui.css' );
  1324. wp_enqueue_script( 'jquery-ui');
  1325. wp_enqueue_script( 'at-timepicker', $plugin_path . '/js/time-and-date/jquery-ui-timepicker-addon.js', array( 'jquery-ui-slider','jquery-ui-datepicker' ), null, true );
  1326.  
  1327. }
  1328.  
  1329. }
  1330.  
  1331. /**
  1332. * Add Meta Box for multiple post types.
  1333. *
  1334. * @since 0.1
  1335. * @access public
  1336. */
  1337. public function add() {
  1338.  
  1339. // Loop through array
  1340. foreach ( $this->_meta_box['pages'] as $page ) {
  1341. add_meta_box( $this->_meta_box['id'], $this->_meta_box['title'], array( $this, 'show' ), $page, $this->_meta_box['context'], $this->_meta_box['priority'] );
  1342. }
  1343.  
  1344. }
  1345.  
  1346. /**
  1347. * Callback function to show fields in Page.
  1348. *
  1349. * @since 0.1
  1350. * @access public
  1351. */
  1352. public function show() {
  1353.  
  1354. global $post;
  1355. wp_nonce_field( basename(__FILE__), 'BF_Admin_Page_Class_nonce' );
  1356. echo '<table class="form-table">'."\n";
  1357. foreach ( $this->_fields as $field ) {
  1358. $meta = get_post_meta( $post->ID, $field['id'], !$field['multiple'] );
  1359. $meta = ( $meta !== '' ) ? $meta : $field['std'];
  1360. if ('image' != $field['type'] && $field['type'] != 'repeater')
  1361. $meta = is_array( $meta ) ? array_map( 'esc_attr', $meta ) : esc_attr( $meta );
  1362. echo '<tr>'."\n";
  1363.  
  1364. // Call Separated methods for displaying each type of field.
  1365. call_user_func ( array( $this, 'show_field_' . $field['type'] ), $field, $meta );
  1366. echo '</tr>'."\n";
  1367. }
  1368. echo '</table>'."\n";
  1369. }
  1370.  
  1371. /**
  1372. * Show Repeater Fields.
  1373. *
  1374. * @param string $field
  1375. * @param string $meta
  1376. * @since 0.1
  1377. * @modified at 0.4 added sortable option
  1378. * @access public
  1379. */
  1380. public function show_field_repeater( $field, $meta ) {
  1381. // Get Plugin Path
  1382. $plugin_path = $this->SelfPath;
  1383. $this->show_field_begin( $field, $meta );
  1384. $class = '';
  1385. if ($field['sortable'])
  1386. $class = " repeater-sortable";
  1387. $jsid = ltrim(strtolower(str_replace(' ','',$field['id'])), '0123456789');
  1388. echo "<div class='at-repeat".$class."' id='{$jsid}'>\n";
  1389.  
  1390. $c = 0;
  1391. $temp_div_row = $this->_div_or_row;
  1392. $this->_div_or_row = true;
  1393. $meta = isset($this->_saved[$field['id']])? $this->_saved[$field['id']]: '';
  1394.  
  1395. if (count($meta) > 0 && is_array($meta) ){
  1396. foreach ($meta as $me){
  1397. //for labling toggles
  1398. $mmm = isset($me[$field['fields'][0]['id']])? $me[$field['fields'][0]['id']]: "";
  1399. $mmm = (in_array($field['fields'][0]['type'],array('image','file'))? '' : $mmm);
  1400. echo '<div class="at-repater-block">'.$mmm.'<br/><table class="repeater-table" style="display: none;">';
  1401. if ($field['inline']){
  1402. echo '<tr class="at-inline" VALIGN="top">';
  1403. }
  1404. foreach ($field['fields'] as $f){
  1405. //reset var $id for repeater
  1406. $id = '';
  1407. $id = $field['id'].'['.$c.']['.$f['id'].']';
  1408. $m = isset($me[$f['id']])? $me[$f['id']]: '';
  1409. if ( $m !== '' ) {
  1410. $m = $m;
  1411. }else{
  1412. $m = isset($f['std'])? $f['std'] : '';
  1413. }
  1414. if ('image' != $f['type'] && $f['type'] != 'repeater')
  1415. $m = is_array( $m) ? array_map( 'esc_attr', $m ) : esc_attr( $m);
  1416. if (in_array($f['type'],array('text','textarea')))
  1417. $m = stripslashes($m);
  1418. //set new id for field in array format
  1419. $f['id'] = $id;
  1420. if (!$field['inline']){
  1421. echo '<tr>';
  1422. }
  1423. call_user_func ( array( $this, 'show_field_' . $f['type'] ), $f, $m);
  1424. if (!$field['inline']){
  1425. echo '</tr>';
  1426. }
  1427. }
  1428. if ($field['inline']){
  1429. echo '</tr>';
  1430. }
  1431. echo '</table>
  1432. <span class="at-re-toggle"><img src="';
  1433. if ($this->_Local_images){
  1434. echo $plugin_path.'/images/edit.png';
  1435. }else{
  1436. echo 'http://i.imgur.com/ka0E2.png';
  1437. }
  1438. echo '" alt="Edit" title="Edit"/></span>
  1439. <img src="';
  1440. if ($this->_Local_images){
  1441. echo $plugin_path.'/images/remove.png';
  1442. }else{
  1443. echo 'http://i.imgur.com/g8Duj.png';
  1444. }
  1445. echo '" alt="'.__('Remove','apc').'" title="'.__('Remove','apc').'" id="remove-'.$field['id'].'"></div>';
  1446. $c = $c + 1;
  1447.  
  1448. }
  1449. }
  1450.  
  1451. echo '<img src="';
  1452. if ($this->_Local_images){
  1453. echo $plugin_path.'/images/add.png';
  1454. }else{
  1455. echo 'http://i.imgur.com/w5Tuc.png';
  1456. }
  1457. echo '" alt="'.__('Add','apc').'" title="'.__('Add','apc').'" id="add-'.$jsid.'"><br/></div>';
  1458.  
  1459. //create all fields once more for js function and catch with object buffer
  1460. ob_start();
  1461. echo '<div class="at-repater-block"><table class="repeater-table">'."\n";
  1462. if ($field['inline']){
  1463. echo '<tr class="at-inline" VALIGN="top">'."\n";
  1464. }
  1465. foreach ($field['fields'] as $f){
  1466. //reset var $id for repeater
  1467. $id = '';
  1468.  
  1469. $id = $field['id'].'[CurrentCounter]['.$f['id'].']';
  1470. $f['id'] = $id;
  1471. if (!$field['inline']){
  1472. echo '<tr>'."\n";
  1473. }
  1474. $m = isset($f['std'])? $f['std'] : '';
  1475. call_user_func ( array( $this, 'show_field_' . $f['type'] ), $f, $m);
  1476. if (!$field['inline']){
  1477. echo '</tr>'."\n";
  1478. }
  1479. }
  1480. if ($field['inline']){
  1481. echo '</tr>'."\n";
  1482. }
  1483. echo '</table><img src="';
  1484. if ($this->_Local_images){
  1485. echo $plugin_path.'/images/remove.png';
  1486. }else{
  1487. echo 'http://i.imgur.com/g8Duj.png';
  1488. }
  1489.  
  1490. echo '" alt="'.__('Remove','apc').'" title="'.__('Remove','apc').'" id="remove-'.$jsid.'"></div>'."\n";
  1491. $counter = 'countadd_'.$jsid;
  1492. $js_code = ob_get_clean ();
  1493. $js_code = str_replace("'","\"",$js_code);
  1494. //$js_code = str_replace("CurrentCounter","' + ".$counter." + '",$js_code);
  1495. echo "\n".'<script type="text/template" id="'.$jsid.'-template">'.$js_code.'</script>'."\n";
  1496. echo '<script>
  1497. jQuery(document).ready(function($) {
  1498. var '.$counter.' = '.$c.';
  1499. $(document).on("click","#add-'.$jsid.'", function() {
  1500. '.$counter.' = '.$counter.' + 1;
  1501. var rep = $("#'.$jsid.'-template").html().replace(new RegExp("CurrentCounter", "g"), '.$counter.');
  1502. $(this).before(rep);
  1503. apc_init();
  1504. });
  1505. $(document).on("click","#remove-'.$jsid.'", function() {
  1506. $(this).parent().remove();
  1507. });
  1508. });
  1509. </script>'."\n";
  1510. echo '<br/><style>
  1511. .at-inline{line-height: 1 !important;}
  1512. .at-inline .at-field{border: 0px !important;}
  1513. .at-inline .at-label{margin: 0 0 1px !important;}
  1514. .at-inline .at-text{width: 70px;}
  1515. .at-inline .at-textarea{width: 100px; height: 75px;}
  1516. .at-repater-block{background-color: #FFFFFF;border: 1px solid;margin: 2px;}
  1517. </style>';
  1518.  
  1519. $this->_div_or_row = $temp_div_row;
  1520. $this->show_field_end($field, $meta);
  1521. }
  1522.  
  1523. /**
  1524. * Begin Field.
  1525. *
  1526. * @param string $field
  1527. * @param string $meta
  1528. * @since 0.1
  1529. * @access public
  1530. */
  1531. public function show_field_begin( $field, $meta) {
  1532. if ($this->_div_or_row){
  1533. echo "<td class='at-field'>\n";
  1534. }
  1535.  
  1536. //check for errors
  1537. if ($this->saved_flag && $this->errors_flag && isset($field['validate']) && isset($field['id']) && $this->has_error($field['id'])){
  1538. echo '<div class="alert alert-error field-validation-error"><button data-dismiss="alert" class="close" type="button">×</button>';
  1539. $ers = $this->getFieldErrors($field['id']);
  1540. foreach ((array)$ers['m'] as $m) {
  1541. echo "{$m}</br />";
  1542. }
  1543. echo '</div>'."\n";
  1544. }
  1545.  
  1546. if ( $field['name'] != '' || $field['name'] != FALSE )
  1547. echo "<div class='at-label'><label for='{$field['id']}'>{$field['name']}</label></div>\n";
  1548. }
  1549.  
  1550. /**
  1551. * End Field.
  1552. *
  1553. * @param string $field
  1554. * @param string $meta
  1555. * @since 0.1
  1556. * @access public
  1557. */
  1558. public function show_field_end( $field, $meta=NULL ,$group = false) {
  1559. if ( isset($field['desc']) && $field['desc'] != '' )
  1560. echo "<div class='desc-field'>{$field['desc']}</div>\n";
  1561.  
  1562. if ($this->_div_or_row)
  1563. echo "</td>\n";
  1564.  
  1565.  
  1566. }
  1567.  
  1568. /**
  1569. * Show Sortable Field
  1570. * @author Ohad Raz
  1571. * @since 0.4
  1572. * @access public
  1573. * @param (array) $field
  1574. * @param (array) $meta
  1575. * @return void
  1576. */
  1577. public function show_field_sortable( $field, $meta ) {
  1578.  
  1579. $this->show_field_begin( $field, $meta );
  1580. $re = '<div class="at-sortable-con"><ul class="at-sortable">'."\n";
  1581. $i = 0;
  1582. if ( ! is_array( $meta ) || empty($meta) ){
  1583. foreach ( $field['options'] as $value => $label ) {
  1584. $re .= '<li class="widget-sort at-sort-item_'.$i.'">'.$label.'<input type="hidden" value="'.$label.'" name="'.$field['id'].'['.$value.']">'."\n";
  1585. }
  1586. }
  1587. else{
  1588. foreach ( $meta as $value => $label ) {
  1589. $re .= '<li class="widget-sort at-sort-item_'.$i.'">'.$label.'<input type="hidden" value="'.$label.'" name="'.$field['id'].'['.$value.']">'."\n";
  1590. }
  1591. }
  1592. $re .= '</ul>'."\n".'</div>'."\n";
  1593. echo $re;
  1594. $this->show_field_end( $field, $meta );
  1595. }
  1596.  
  1597. /**
  1598. * Show Field Text.
  1599. *
  1600. * @param string $field
  1601. * @param string $meta
  1602. * @since 0.1
  1603. * @access public
  1604. */
  1605. public function show_field_text( $field, $meta) {
  1606. ?><div class="<?php echo $field['id']; ?>"><?php
  1607.  
  1608. $this->show_field_begin( $field, $meta );
  1609. echo "<input type='text' class='at-text".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' value='".stripslashes($meta)."' size='30' />"."\n";
  1610. $this->show_field_end( $field, $meta );
  1611.  
  1612. ?></div><?php
  1613. }
  1614.  
  1615. /**
  1616. * Show Field Plupload.
  1617. *
  1618. * @param string $field
  1619. * @param string $meta
  1620. * @since 0.9.7
  1621. * @access public
  1622. */
  1623. public function show_field_plupload( $field, $meta) {
  1624.  
  1625. $this->show_field_begin($field,$meta);
  1626. $id = $field['id']; // this will be the name of form field. Image url(s) will be submitted in $_POST using this key. So if $id == “img1” then $_POST[“img1”] will have all the image urls
  1627. $multiple = $field['multiple']; // allow multiple files upload
  1628. $m1 = ($multiple)? 'plupload-upload-uic-multiple':'';
  1629. $m2 = ($multiple)? 'plupload-thumbs-multiple':'';
  1630. $width = $field['width']; // If you want to automatically resize all uploaded images then provide width here (in pixels)
  1631. $height = $field['height']; // If you want to automatically resize all uploaded images then provide height here (in pixels)
  1632. $html = '
  1633. <input type="hidden" name="'.$id.'" id="'. $id.'" value="'.$meta .'" />
  1634. <div class="plupload-upload-uic hide-if-no-js '.$m1.'" id="'.$id.'plupload-upload-ui">
  1635. <input id="'.$id.'plupload-browse-button" type="button" value="'.__('Select Files','apc').'" class="button" />
  1636. <span class="ajaxnonceplu" id="ajaxnonceplu'.wp_create_nonce($id . 'pluploadan').'"></span>';
  1637. if ($width && $height){
  1638. $html .= '<span class="plupload-resize"></span><span class="plupload-width" id="plupload-width'.$width.'"></span>
  1639. <span class="plupload-height" id="plupload-height'.$height.'"></span>';
  1640. }
  1641. $html .= '<div class="filelist"></div>
  1642. </div>
  1643. <div class="plupload-thumbs '.$m2.'" id="'.$id.'plupload-thumbs">
  1644. </div>
  1645. <div class="clear"></div>';
  1646. echo $html;
  1647. $this->show_field_end($field,$meta);
  1648. }
  1649.  
  1650. /**
  1651. * Show Field code editor.
  1652. *
  1653. * @param string $field
  1654. * @author Ohad Raz
  1655. * @param string $meta
  1656. * @since 0.1
  1657. * @access public
  1658. */
  1659. public function show_field_code( $field, $meta) {
  1660. $this->show_field_begin( $field, $meta );
  1661. echo "<textarea class='code_text".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' data-lang='{$field['syntax']}' data-theme='{$field['theme']}'>".stripslashes($meta)."</textarea>";
  1662. $this->show_field_end( $field, $meta );
  1663. }
  1664.  
  1665.  
  1666. /**
  1667. * Show Field hidden.
  1668. *
  1669. * @param string $field
  1670. * @param string|mixed $meta
  1671. * @since 0.1
  1672. * @access public
  1673. */
  1674. public function show_field_hidden( $field, $meta) {
  1675. echo "<input type='hidden' class='at-hidden".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' value='{$meta}'/>";
  1676. }
  1677.  
  1678. /**
  1679. * Show Field Paragraph.
  1680. *
  1681. * @param string $field
  1682. * @since 0.1
  1683. * @access public
  1684. */
  1685. public function show_field_paragraph( $field) {
  1686. echo '<p>'.$field['value'].'</p>'."\n";
  1687. }
  1688.  
  1689. /**
  1690. * Show Field Textarea.
  1691. *
  1692. * @param string $field
  1693. * @param string $meta
  1694. * @since 0.1
  1695. * @access public
  1696. */
  1697. public function show_field_textarea( $field, $meta ) {
  1698. $this->show_field_begin( $field, $meta );
  1699. echo "<textarea class='at-textarea large-text".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' cols='60' rows='10'>".stripslashes($meta)."</textarea>"."\n";
  1700. $this->show_field_end( $field, $meta );
  1701. }
  1702.  
  1703. /**
  1704. * Show Field Select.
  1705. *
  1706. * @param string $field
  1707. * @param string $meta
  1708. * @since 0.1
  1709. * @access public
  1710. */
  1711. public function show_field_select( $field, $meta ) {
  1712.  
  1713. if ( ! is_array( $meta ) )
  1714. $meta = (array) $meta;
  1715. ?><div class="<?php echo $field['id']; ?>"><?php
  1716. $this->show_field_begin( $field, $meta );
  1717. echo "<select class='at-select".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}" . ((isset($field['multiple']) && $field['multiple']) ? "[]' id='{$field['id']}' multiple='multiple'" : "'" ) . ">\n";
  1718. foreach ( $field['options'] as $key => $value ) {
  1719. echo "\t<option value='{$key}'" . selected( in_array( $key, $meta ), true, false ) . ">{$value}</option>\n";
  1720. }
  1721. echo "</select>"."\n";
  1722. $this->show_field_end( $field, $meta );
  1723. ?></div><?php
  1724. }
  1725.  
  1726. /**
  1727. * Show Radio Field.
  1728. *
  1729. * @param string $field
  1730. * @param string $meta
  1731. * @since 0.1
  1732. * @access public
  1733. */
  1734. public function show_field_radio( $field, $meta ) {
  1735.  
  1736. if ( ! is_array( $meta ) )
  1737. $meta = (array) $meta;
  1738.  
  1739. $this->show_field_begin( $field, $meta );
  1740. foreach ( $field['options'] as $key => $value ) {
  1741. echo "<input type='radio' class='at-radio".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' value='{$key}'" . checked( in_array( $key, $meta ), true, false ) . " /> <span class='at-radio-label'>{$value}</span>"."\n";
  1742. }
  1743. $this->show_field_end( $field, $meta );
  1744. }
  1745.  
  1746. /**
  1747. * Show Checkbox Field.
  1748. *
  1749. * @param string $field
  1750. * @param string $meta
  1751. * @since 0.1
  1752. * @access public
  1753. */
  1754. public function show_field_checkbox( $field, $meta ) {
  1755.  
  1756. $this->show_field_begin($field, $meta);
  1757. $meta = ($meta == 'on')? true: $meta;
  1758. echo "<input type='checkbox' class='rw-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}'" . checked($meta, true, false) . " />"."\n";
  1759. $this->show_field_end( $field, $meta );
  1760. }
  1761.  
  1762. /**
  1763. * Show conditinal Checkbox Field.
  1764. *
  1765. * @param string $field
  1766. * @param string $meta
  1767. * @since 0.5
  1768. * @access public
  1769. */
  1770. public function show_field_cond( $field, $meta ) {
  1771.  
  1772. $this->show_field_begin($field, $meta);
  1773. $checked = false;
  1774. if (is_array($meta) && isset($meta['enabled']) && $meta['enabled'] == 'on'){
  1775. $checked = true;
  1776. }
  1777. echo "<input type='checkbox' class='conditinal_control' name='{$field['id']}[enabled]' id='{$field['id']}'" . checked($checked, true, false) . " />";
  1778. //start showing the fields
  1779. $display = ($checked)? '' : ' style="display: none;"';
  1780.  
  1781. echo '<div class="conditinal_container"'.$display.'>';
  1782. foreach ((array)$field['fields'] as $f){
  1783. //reset var $id for cond
  1784. $id = '';
  1785. $id = $field['id'].'['.$f['id'].']';
  1786. $m = '';
  1787. $m = (isset($meta[$f['id']])) ? $meta[$f['id']]: '';
  1788. $m = ( $m !== '' ) ? $m : (isset($f['std'])? $f['std'] : '');
  1789. if ('image' != $f['type'] && $f['type'] != 'repeater')
  1790. $m = is_array( $m) ? array_map( 'esc_attr', $m ) : esc_attr( $m);
  1791. //set new id for field in array format
  1792. $f['id'] = $id;
  1793. call_user_func ( array( $this, 'show_field_' . $f['type'] ), $f, $m);
  1794. }
  1795. echo '</div>';
  1796. $this->show_field_end( $field, $meta );
  1797. }
  1798.  
  1799. /**
  1800. * Show Wysiwig Field.
  1801. *
  1802. * @param string $field
  1803. * @param string $meta
  1804. * @since 0.1
  1805. * @access public
  1806. */
  1807. public function show_field_wysiwyg( $field, $meta ) {
  1808. $this->show_field_begin( $field, $meta );
  1809. // Add TinyMCE script for WP version < 3.3
  1810. global $wp_version;
  1811.  
  1812. if ( version_compare( $wp_version, '3.2.1' ) < 1 ) {
  1813. echo "<textarea class='at-wysiwyg theEditor large-text".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' cols='60' rows='10'>{$meta}</textarea>";
  1814. }else{
  1815. // Use new wp_editor() since WP 3.3
  1816. wp_editor( stripslashes(stripslashes(html_entity_decode($meta))), $field['id'], array( 'editor_class' => 'at-wysiwyg'.(isset($field['class'])? " {$field['class']}": "")) );
  1817. }
  1818. $this->show_field_end( $field, $meta );
  1819. }
  1820.  
  1821. /**
  1822. * Show File Field.
  1823. *
  1824. * @param string $field
  1825. * @param string $meta
  1826. * @since 0.1
  1827. * @access public
  1828. */
  1829. public function show_field_file( $field, $meta ) {
  1830.  
  1831. global $post;
  1832.  
  1833. if ( ! is_array( $meta ) )
  1834. $meta = (array) $meta;
  1835.  
  1836. $this->show_field_begin( $field, $meta );
  1837. echo "{$field['desc']}<br />";
  1838.  
  1839. if ( ! empty( $meta ) ) {
  1840. $nonce = wp_create_nonce( 'at_ajax_delete' );
  1841. echo '<div style="margin-bottom: 10px"><strong>' . __('Uploaded files','apc') . '</strong></div>';
  1842. echo '<ol class="at-upload">';
  1843. foreach ( $meta as $att ) {
  1844. // if (wp_attachment_is_image($att)) continue; // what's image uploader for?
  1845. echo "<li>" . wp_get_attachment_link( $att, '' , false, false, ' ' ) . " (<a class='at-delete-file' href='#' rel='{$nonce}|{$post->ID}|{$field['id']}|{$att}'>" . __( 'Delete' ,'apc') . "</a>)</li>";
  1846. }
  1847. echo '</ol>';
  1848. }
  1849.  
  1850. // show form upload
  1851. echo "<div class='at-file-upload-label'>";
  1852. echo "<strong>" . __( 'Upload new files' ,'apc') . "</strong>";
  1853. echo "</div>";
  1854. echo "<div class='new-files'>";
  1855. echo "<div class='file-input'>";
  1856. echo "<input type='file' name='{$field['id']}[]' />";
  1857. echo "</div><!-- End .file-input -->";
  1858. echo "<a class='at-add-file button' href='#'>" . __( 'Add more files','apc' ) . "</a>";
  1859. echo "</div><!-- End .new-files -->";
  1860. echo "</td>";
  1861. }
  1862.  
  1863.  
  1864. public function show_field_media_manager($field,$meta){
  1865. $this->show_field_begin( $field, $meta );
  1866. $html = wp_nonce_field( "at-delete-mupload_{$field['id']}", "nonce-delete-mupload_".$field['id'], false, false );
  1867. $height = (isset($field['preview_height']))? $field['preview_height'] : '150px';
  1868. $width = (isset($field['preview_width']))? $field['preview_width'] : '150px';
  1869. $multi = (isset($field['multiple']) && $field['multiple'] == true) ? 'true' : 'false';
  1870. if (is_array($meta)){
  1871. if(isset($meta[0]) && is_array($meta[0]))
  1872. $meta = $meta[0];
  1873. }
  1874. if (is_array($meta) && isset($meta['src']) && $meta['src'] != ''){
  1875. $html .= "<span class='mupload_img_holder' data-wi='".$width."' data-he='".$height."'><img src='".$meta['src']."' style='height: ".$height.";width: ".$width.";' /></span>"."\n";
  1876. $html .= "<input type='hidden' name='".$field['id']."[id]' id='".$field['id']."[id]' value='".$meta['id']."' />"."\n";
  1877. $html .= "<input type='hidden' name='".$field['id']."[src]' id='".$field['id']."[src]' value='".$meta['src']."' />"."\n";
  1878. $html .= "<input class='at-delete_image_button button' type='button' rel='".$field['id']."' value='".__('Delete Image','apc')."' />"."\n";
  1879. }else{
  1880. $html .= "<span class='mupload_img_holder' data-wi='".$width."' data-he='".$height."' data-multi='".$multi."'></span>"."\n";
  1881. $html .= "<input type='hidden' name='".$field['id']."[id]' id='".$field['id']."[id]' value='' />"."\n";
  1882. $html .= "<input type='hidden' name='".$field['id']."[src]' id='".$field['id']."[src]' value='' />"."\n";
  1883. $html .= "<input class='at-mm-upload_image_button button' type='button' rel='".$field['id']."' value='".__('Upload Image','apc')."' />"."\n";
  1884. }
  1885. echo $html;
  1886. $this->show_field_end( $field, $meta );
  1887. }
  1888.  
  1889. /**
  1890. * Show Image Field.
  1891. *
  1892. * @param array $field
  1893. * @param array $meta
  1894. * @since 0.1
  1895. * @access public
  1896. */
  1897. public function show_field_image( $field, $meta ) {
  1898. $this->show_field_begin( $field, $meta );
  1899. $html = wp_nonce_field( "at-delete-mupload_{$field['id']}", "nonce-delete-mupload_".$field['id'], false, false );
  1900. $height = (isset($field['preview_height']))? $field['preview_height'] : '150px';
  1901. $width = (isset($field['preview_width']))? $field['preview_width'] : '150px';
  1902. $upload_type = (!function_exists('wp_enqueue_media')) ? 'tk' : 'mm';
  1903. if (is_array($meta)){
  1904. if(isset($meta[0]) && is_array($meta[0]))
  1905. $meta = $meta[0];
  1906. }
  1907. if (is_array($meta) && isset($meta['src']) && $meta['src'] != ''){
  1908. $html .= "<span class='mupload_img_holder' data-wi='".$width."' data-he='".$height."'><img src='".$meta['src']."' style='height: ".$height.";width: ".$width.";' /></span>";
  1909. $html .= "<input type='hidden' name='".$field['id']."[id]' id='".$field['id']."[id]' value='".$meta['id']."' />";
  1910. $html .= "<input type='hidden' name='".$field['id']."[src]' id='".$field['id']."[src]' value='".$meta['src']."' />";
  1911. $html .= "<input class='at-delete_image_button button' type='button' data-u='".$upload_type."' rel='".$field['id']."' value='".__('Delete Image','apc')."' />";
  1912. }else{
  1913. $html .= "<span class='mupload_img_holder' data-wi='".$width."' data-he='".$height."'></span>";
  1914. $html .= "<input type='hidden' name='".$field['id']."[id]' id='".$field['id']."[id]' value='' />";
  1915. $html .= "<input type='hidden' name='".$field['id']."[src]' id='".$field['id']."[src]' value='' />";
  1916. $html .= "<input class='at-upload_image_button button' type='button' data-u='".$upload_type."' rel='".$field['id']."' value='".__('Upload Image','apc')."' />";
  1917. }
  1918. echo $html;
  1919. $this->show_field_end( $field, $meta );
  1920. }
  1921.  
  1922. /**
  1923. * Show Typography Field.
  1924. *
  1925. * @author Ohad Raz
  1926. * @param array $field
  1927. * @param array $meta
  1928. * @since 0.3
  1929. * @access public
  1930. *
  1931. * @last modified 0.4 - faster better selected handeling
  1932. */
  1933. public function show_field_typo( $field, $meta ) {
  1934. $this->show_field_begin( $field, $meta );
  1935. if (!is_array($meta)){
  1936. $meta = array(
  1937. 'size' => '',
  1938. 'face' => '',
  1939. 'style' => '',
  1940. 'color' => '#',
  1941. 'weight' => '',
  1942. );
  1943. }
  1944. $html = '<select class="at-typography at-typography-size" name="' . esc_attr( $field['id'] . '[size]' ) . '" id="' . esc_attr( $field['id'] . '_size' ) . '">'."\n";
  1945. $op = '';
  1946. for ($i = 9; $i < 71; $i++) {
  1947. $size = $i . 'px';
  1948. $op .= "\t".'<option value="' . esc_attr( $size ) . '">' . esc_html( $size ) . '</option>'."\n";
  1949. }
  1950. if (isset($meta['size']))
  1951. $op = str_replace('value="'.$meta['size'].'"', 'value="'.$meta['size'].'" selected="selected"', $op);
  1952. $html .=$op. '</select>'."\n";
  1953.  
  1954. // Font Face
  1955. $html .= '<select class="at-typography at-typography-face" name="' . esc_attr( $field['id'] .'[face]' ) . '" id="' . esc_attr( $field['id'] . '_face' ) . '">'."\n";
  1956.  
  1957. $faces = $this->get_fonts_family();
  1958. $op = '';
  1959. foreach ( $faces as $key => $face ) {
  1960. $op .= "\t".'<option value="' . esc_attr( $key ) . '">' . esc_html( $face['name'] ) . '</option>'."\n";
  1961. }
  1962. if (isset($meta['face']))
  1963. $op = str_replace('value="'.$meta['face'].'"', 'value="'.$meta['face'].'" selected="selected"', $op);
  1964. $html .= $op. '</select>'."\n";
  1965.  
  1966. // Font Weight
  1967. $html .= '<select class="at-typography at-typography-weight" name="' . esc_attr( $field['id'] .'[weight]' ) . '" id="' . esc_attr( $field['id'] . '_weight' ) . '">'."\n";
  1968. $weights = $this->get_font_weight();
  1969. $op = '';
  1970. foreach ( $weights as $key => $label ) {
  1971. $op .= "\t".'<option value="' . esc_attr( $key ) . '">' . esc_html( $label ) . '</option>'."\n";
  1972. }
  1973. if (isset($meta['weight']))
  1974. $op = str_replace('value="'.$meta['weight'].'"', 'value="'.$meta['weight'].'" selected="selected"', $op);
  1975. $html .= $op. '</select>'."\n";
  1976.  
  1977. /* Font Style */
  1978. $html .= '<select class="at-typography at-typography-style" name="'.$field['id'].'[style]" id="'. $field['id'].'_style">'."\n";
  1979. $styles = $this->get_font_style();
  1980. $op = '';
  1981. foreach ( $styles as $key => $style ) {
  1982. $op .= "\t".'<option value="' . esc_attr( $key ) . '">'. $style .'</option>'."\n";
  1983. }
  1984. if (isset($meta['style']))
  1985. $op = str_replace('value="'.$meta['style'].'"', 'value="'.$meta['style'].'" selected="selected"', $op);
  1986. $html .= $op. '</select>'."\n";
  1987.  
  1988. // Font Color
  1989. if( wp_style_is( 'wp-color-picker', 'registered' ) ) { //iris color picker since 3.5
  1990. $html .= "<input class='at-color-iris' type='text' name='{$field['id']}[color]' id='{$field['id']}[color]' value='".$meta['color']."' size='8' />"."\n";
  1991. }else{
  1992. $html .= "<input class='at-color' type='text' name='".$field['id']."[color]' id='".$field['id']."[color]' value='".$meta['color'] ."' size='6' />"."\n";
  1993. $html .= "<input type='button' class='at-color-select button' rel='".$field['id']."[color]' value='" . __( 'Select a color' ,'apc') . "'/>"."\n";
  1994. $html .= "<div style='display:none' class='at-color-picker' rel='".$field['id']."[color]'></div>"."\n";
  1995. }
  1996.  
  1997. echo $html;
  1998. $this->show_field_end( $field, $meta );
  1999. }
  2000.  
  2001. /**
  2002. * Show Color Field.
  2003. *
  2004. * @param string $field
  2005. * @param string $meta
  2006. * @since 0.1
  2007. * @access public
  2008. */
  2009. public function show_field_color( $field, $meta ) {
  2010. if ( empty( $meta ) )
  2011. $meta = '#';
  2012. ?>
  2013. <div class="<?php echo $field['id']; ?>">
  2014. <?php
  2015. $this->show_field_begin( $field, $meta );
  2016. if( wp_style_is( 'wp-color-picker', 'registered' ) ) { //iris color picker since 3.5
  2017. echo "<input class='at-color-iris".(isset($field['class'])? " {$field['class']}": "")."' type='text' name='{$field['id']}' id='{$field['id']}' value='{$meta}' size='8' />";
  2018. }else{
  2019. echo "<input class='at-color".(isset($field['class'])? " {$field['class']}": "")."' type='text' name='{$field['id']}' id='{$field['id']}' value='{$meta}' size='8' />";
  2020. echo "<input type='button' class='at-color-select button' rel='{$field['id']}' value='" . __( 'Select a color' ,'apc') . "'/>";
  2021. echo "<div style='display:none' class='at-color-picker' rel='{$field['id']}'></div>";
  2022. }
  2023. $this->show_field_end($field, $meta);
  2024.  
  2025. ?>
  2026. </div>
  2027. <?php
  2028.  
  2029. }
  2030.  
  2031. /**
  2032. * Show Checkbox List Field
  2033. *
  2034. * @param string $field
  2035. * @param string $meta
  2036. * @since 0.1
  2037. * @access public
  2038. */
  2039. public function show_field_checkbox_list( $field, $meta ) {
  2040.  
  2041. if ( ! is_array( $meta ) )
  2042. $meta = (array) $meta;
  2043.  
  2044. $this->show_field_begin($field, $meta);
  2045.  
  2046. $html = array();
  2047.  
  2048. foreach ($field['options'] as $key => $value) {
  2049. $html[] = "<label class='at-checkbox_list-label'><input type='checkbox' class='at-checkbox_list".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='{$key}'" . checked( in_array( $key, $meta ), true, false ) . " />{$value}</label>";
  2050. }
  2051.  
  2052. echo implode( '<br />' , $html );
  2053.  
  2054. $this->show_field_end($field, $meta);
  2055.  
  2056. }
  2057.  
  2058. /**
  2059. * Show Date Field.
  2060. *
  2061. * @param string $field
  2062. * @param string $meta
  2063. * @since 0.1
  2064. * @access public
  2065. */
  2066. public function show_field_date( $field, $meta ) {
  2067. $this->show_field_begin( $field, $meta );
  2068. echo "<input type='text' class='at-date".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' rel='{$field['format']}' value='{$meta}' size='30' />";
  2069. $this->show_field_end( $field, $meta );
  2070. }
  2071.  
  2072. /**
  2073. * Show time field.
  2074. *
  2075. * @param string $field
  2076. * @param string $meta
  2077. * @since 0.1
  2078. * @access public
  2079. */
  2080. public function show_field_time( $field, $meta ) {
  2081. $this->show_field_begin( $field, $meta );
  2082. echo "<input type='text' class='at-time".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' rel='{$field['format']}' value='{$meta}' size='30' />";
  2083. $this->show_field_end( $field, $meta );
  2084. }
  2085.  
  2086. /**
  2087. * Show Posts field.
  2088. * used creating a posts/pages/custom types checkboxlist or a select dropdown
  2089. * @param string $field
  2090. * @param string $meta
  2091. * @since 0.1
  2092. * @access public
  2093. */
  2094. public function show_field_posts($field, $meta) {
  2095. global $post;
  2096. if (!is_array($meta)) $meta = (array) $meta;
  2097. $this->show_field_begin($field, $meta);
  2098. $options = $field['options'];
  2099. $posts = get_posts($options['args']);
  2100.  
  2101. // checkbox_list
  2102. if ('checkbox_list' == $options['type']) {
  2103. foreach ($posts as $p) {
  2104. if (isset($field['class']) && $field['class']== 'no-toggle')
  2105. echo "<label class='at-posts-checkbox-label'><input type='checkbox' class='at-posts-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$p->ID'" . checked(in_array($p->ID, $meta), true, false) . " /> {$p->post_title}</label>";
  2106. else
  2107. echo "{$p->post_title}<input type='checkbox' class='at-posts-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$p->ID'" . checked(in_array($p->ID, $meta), true, false) . " />";
  2108. }
  2109. }
  2110. // select
  2111. else {
  2112. echo "<select class='at-posts-select".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}" . ($field['multiple'] ? "[]' multiple='multiple' style='height:auto'" : "'") . ">";
  2113. foreach ($posts as $p) {
  2114. echo "<option value='$p->ID'" . selected(in_array($p->ID, $meta), true, false) . ">$p->post_title</option>";
  2115. }
  2116. echo "</select>";
  2117. }
  2118.  
  2119. $this->show_field_end($field, $meta);
  2120. }
  2121.  
  2122. /**
  2123. * Show Taxonomy field.
  2124. * used creating a category/tags/custom taxonomy checkboxlist or a select dropdown
  2125. * @param string $field
  2126. * @param string $meta
  2127. * @since 0.1
  2128. * @access public
  2129. *
  2130. * @uses get_terms()
  2131. */
  2132. public function show_field_taxonomy($field, $meta) {
  2133. global $post;
  2134.  
  2135. if (!is_array($meta)) $meta = (array) $meta;
  2136. $this->show_field_begin($field, $meta);
  2137. $options = $field['options'];
  2138. $terms = get_terms($options['taxonomy'], $options['args']);
  2139.  
  2140. // checkbox_list
  2141. if ('checkbox_list' == $options['type']) {
  2142. foreach ($terms as $term) {
  2143. if (isset($field['class']) && $field['class'] == 'no-toggle')
  2144. echo "<label class='at-tax-checkbox-label'><input type='checkbox' class='at-tax-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$term->slug'" . checked(in_array($term->slug, $meta), true, false) . " /> {$term->name}</label>";
  2145. else
  2146. echo "{$term->name} <input type='checkbox' class='at-tax-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$term->slug'" . checked(in_array($term->slug, $meta), true, false) . " />";
  2147. }
  2148. }
  2149. // select
  2150. else {
  2151. echo "<select class='at-tax-select".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}" . ($field['multiple'] ? "[]' multiple='multiple' style='height:auto'" : "'") . ">";
  2152. foreach ($terms as $term) {
  2153. echo "<option value='$term->slug'" . selected(in_array($term->slug, $meta), true, false) . ">$term->name</option>";
  2154. }
  2155. echo "</select>";
  2156. }
  2157.  
  2158. $this->show_field_end($field, $meta);
  2159. }
  2160.  
  2161. /**
  2162. * Show Role field.
  2163. * used creating a Wordpress roles list checkboxlist or a select dropdown
  2164. * @param string $field
  2165. * @param string $meta
  2166. * @since 0.1
  2167. * @access public
  2168. *
  2169. * @uses global $wp_roles;
  2170. * @uses checked();
  2171. */
  2172. public function show_field_WProle($field, $meta) {
  2173. if (!is_array($meta)) $meta = (array) $meta;
  2174. $this->show_field_begin($field, $meta);
  2175. $options = $field['options'];
  2176. global $wp_roles;
  2177. if ( ! isset( $wp_roles ) )
  2178. $wp_roles = new WP_Roles();
  2179. $names = $wp_roles->get_names();
  2180. if ($names){
  2181. // checkbox_list
  2182. if ('checkbox_list' == $options['type']) {
  2183. foreach ($names as $n) {
  2184. if (isset($field['class']) && $field['class'] == 'no-toggle')
  2185. echo "<label class='at-posts-checkbox-label'><input type='checkbox' class='at-role-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$n'" . checked(in_array($n, $meta), true, false) . " /> ".$n."</label>";
  2186. else
  2187. echo "{$n} <input type='checkbox' class='at-role-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$n'" . checked(in_array($n, $meta), true, false) . " />";
  2188. }
  2189. }
  2190. // select
  2191. else {
  2192. echo "<select class='at-role-select".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}" . ($field['multiple'] ? "[]' multiple='multiple' style='height:auto'" : "'") . ">";
  2193. foreach ($names as $n) {
  2194. echo "<option value='$n'" . selected(in_array($n, $meta), true, false) . ">$n</option>";
  2195. }
  2196. echo "</select>";
  2197. }
  2198. }
  2199. $this->show_field_end($field, $meta);
  2200. }
  2201.  
  2202. /**
  2203. * Save Data from page
  2204. *
  2205. * @param string $repeater (false )
  2206. * @since 0.1
  2207. * @access public
  2208. */
  2209. public function save($repeater = false) {
  2210. $saved = get_option($this->option_group);
  2211. $this->_saved = $saved;
  2212.  
  2213. $post_data = isset($_POST)? $_POST : NULL;
  2214.  
  2215. If ($post_data == NULL) return;
  2216.  
  2217. $skip = array('title','paragraph','subtitle','TABS','CloseDiv','TABS_Listing','OpenTab','import_export');
  2218.  
  2219. //check nonce
  2220. if ( ! check_admin_referer( basename( __FILE__ ), 'BF_Admin_Page_Class_nonce') )
  2221. return;
  2222.  
  2223. foreach ( $this->_fields as $field ) {
  2224. if(!in_array($field['type'],$skip)){
  2225.  
  2226. $name = $field['id'];
  2227. $type = $field['type'];
  2228. $old = isset($saved[$name])? $saved[$name]: NULL;
  2229. $new = ( isset( $_POST[$name] ) ) ? $_POST[$name] : ( ( isset($field['multiple']) && $field['multiple']) ? array() : '' );
  2230.  
  2231.  
  2232. //Validate and senitize meta value
  2233. //issue #27
  2234. $validationClass = apply_filters('apc_validattion_class_name', 'BF_Admin_Page_Class_Validate',$this);
  2235. if ( class_exists( $validationClass ) && isset($field['validate_func']) && method_exists( $validationClass, $field['validate_func'] ) ) {
  2236. $new = call_user_func( array( $validationClass, $field['validate_func'] ), $new ,$this);
  2237. }
  2238.  
  2239. //native validation
  2240. if (isset($field['validate'])){
  2241. if (!$this->validate_field($field,$new))
  2242. $new = $old;
  2243. }
  2244.  
  2245.  
  2246. // Call defined method to save meta value, if there's no methods, call common one.
  2247. $save_func = 'save_field_' . $type;
  2248. if ( method_exists( $this, $save_func ) ) {
  2249. call_user_func( array( $this, 'save_field_' . $type ), $field, $old, $new );
  2250. } else {
  2251. $this->save_field( $field, $old, $new );
  2252. }
  2253.  
  2254. }//END Skip
  2255. } // End foreach
  2256. update_option($this->args['option_group'],$this->_saved);
  2257. }
  2258.  
  2259. /**
  2260. * Common function for saving fields.
  2261. *
  2262. * @param string $field
  2263. * @param string $old
  2264. * @param string|mixed $new
  2265. * @since 0.1
  2266. * @access public
  2267. */
  2268. public function save_field( $field, $old, $new ) {
  2269. $name = $field['id'];
  2270. unset($this->_saved[$name]);
  2271. if ( $new === '' || $new === array() && ( !in_array($field['type'],array('text','textarea')) ) )
  2272. return;
  2273. if ( isset($field['multiple'] ) && $field['multiple'] && $field['type'] != 'plupload') {
  2274. foreach ( $new as $add_new ) {
  2275. $temp[] = $add_new;
  2276. }
  2277. $this->_saved[$name] = $temp;
  2278. } else {
  2279. $this->_saved[$name] = $new;
  2280. }
  2281. }
  2282.  
  2283. /**
  2284. * function for saving image field.
  2285. *
  2286. * @param string $field
  2287. * @param string $old
  2288. * @param string|mixed $new
  2289. * @since 0.1
  2290. * @access public
  2291. */
  2292. public function save_field_image( $field, $old, $new ) {
  2293. $name = $field['id'];
  2294. unset($this->_saved[$name]);
  2295. if ( $new === '' || $new === array() || $new['id'] == '' || $new['src'] == '')
  2296. return;
  2297.  
  2298. $this->_saved[$name] = $new;
  2299. }
  2300.  
  2301. /*
  2302. * Save Wysiwyg Field.
  2303. *
  2304. * @param string $field
  2305. * @param string $old
  2306. * @param string $new
  2307. * @since 0.1
  2308. * @access public
  2309. */
  2310. public function save_field_wysiwyg( $field, $old, $new ) {
  2311. $this->save_field( $field, $old, htmlentities($new) );
  2312. }
  2313.  
  2314. /*
  2315. * Save checkbox Field.
  2316. *
  2317. * @param string $field
  2318. * @param string $old
  2319. * @param string $new
  2320. * @since 0.9
  2321. * @access public
  2322. */
  2323. public function save_field_checkbox( $field, $old, $new ) {
  2324. if ( $new === '' )
  2325. $this->save_field( $field, $old, false );
  2326. else
  2327. $this->save_field( $field, $old, true );
  2328. }
  2329.  
  2330. /**
  2331. * Save repeater Fields.
  2332. *
  2333. * @param string $field
  2334. * @param string|mixed $old
  2335. * @param string|mixed $new
  2336. * @since 0.1
  2337. * @access public
  2338. */
  2339. public function save_field_repeater( $field, $old, $new ) {
  2340. if (is_array($new) && count($new) > 0){
  2341. foreach ($new as $n){
  2342. foreach ( $field['fields'] as $f ) {
  2343. $type = $f['type'];
  2344. switch($type) {
  2345. case 'wysiwyg':
  2346. $n[$f['id']] = wpautop( $n[$f['id']] );
  2347. break;
  2348. case 'file':
  2349. $n[$f['id']] = $this->save_field_file_repeater($f,'',$n[$f['id']]);
  2350. break;
  2351. default:
  2352. break;
  2353. }
  2354. }
  2355. if(!$this->is_array_empty($n))
  2356. $temp[] = $n;
  2357. }
  2358. if (isset($temp) && count($temp) > 0 && !$this->is_array_empty($temp)){
  2359. $this->_saved[$field['id']] = $temp;
  2360. }else{
  2361. if (isset($this->_saved[$field['id']]))
  2362. unset($this->_saved[$field['id']]);
  2363. }
  2364. }else{
  2365. // remove old meta if exists
  2366. if (isset($this->_saved[$field['id']]))
  2367. unset($this->_saved[$field['id']]);
  2368. }
  2369. }
  2370.  
  2371.  
  2372.  
  2373. /**
  2374. * Add missed values for Page.
  2375. *
  2376. * @since 0.1
  2377. * @access public
  2378. */
  2379. public function add_missed_values() {
  2380.  
  2381. // Default values for admin
  2382. //$this->_meta_box = array_merge( array( 'context' => 'normal', 'priority' => 'high', 'pages' => array( 'post' ) ), $this->_meta_box );
  2383.  
  2384. // Default values for fields
  2385. foreach ( $this->_fields as &$field ) {
  2386.  
  2387. $multiple = in_array( $field['type'], array( 'checkbox_list', 'file', 'image' ) );
  2388. $std = $multiple ? array() : '';
  2389. $format = 'date' == $field['type'] ? 'yy-mm-dd' : ( 'time' == $field['type'] ? 'hh:mm' : '' );
  2390.  
  2391. $field = array_merge( array( 'multiple' => $multiple, 'std' => $std, 'desc' => '', 'format' => $format, 'validate_func' => '' ), $field );
  2392.  
  2393. } // End foreach
  2394.  
  2395. }
  2396.  
  2397. /**
  2398. * Check if field with $type exists.
  2399. *
  2400. * @param string $type
  2401. * @since 0.1
  2402. * @access public
  2403. */
  2404. public function has_field( $type ) {
  2405. //faster search in single array.
  2406. if (count($this->field_types) > 0){
  2407. return in_array($type, $this->field_types);
  2408. }
  2409.  
  2410. //run once over all fields and store the types in a local array
  2411. $temp = array();
  2412. foreach ($this->_fields as $field) {
  2413. $temp[] = $field['type'];
  2414. if ('repeater' == $field['type'] || 'cond' == $field['type']){
  2415. foreach((array)$field["fields"] as $repeater_field) {
  2416. $temp[] = $repeater_field["type"];
  2417. }
  2418. }
  2419. }
  2420.  
  2421. //remove duplicates
  2422. $this->field_types = array_unique($temp);
  2423. //call this function one more time now that we have an array of field types
  2424. return $this->has_field($type);
  2425. }
  2426.  
  2427. /**
  2428. * Check if any of the fields types exists
  2429. *
  2430. * @since 1.1.3
  2431. * @access public
  2432. * @param array $types array of field types
  2433. * @return boolean
  2434. */
  2435. public function has_field_any($types){
  2436. foreach ((array)$types as $t) {
  2437. if ($this->has_field($t))
  2438. return true;
  2439. }
  2440. return false;
  2441. }
  2442.  
  2443. /**
  2444. * Check if current page is edit page.
  2445. *
  2446. * @since 0.1
  2447. * @access public
  2448. */
  2449. public function is_edit_page() {
  2450. //global $pagenow;
  2451. return true;
  2452. //return in_array( $pagenow, array( 'post.php', 'post-new.php' ) );
  2453. }
  2454.  
  2455. /**
  2456. * Fixes the odd indexing of multiple file uploads.
  2457. *
  2458. * Goes from the format:
  2459. * $_FILES['field']['key']['index']
  2460. * to
  2461. * The More standard and appropriate:
  2462. * $_FILES['field']['index']['key']
  2463. *
  2464. * @param string $files
  2465. * @since 0.1
  2466. * @access public
  2467. */
  2468. public function fix_file_array( &$files ) {
  2469.  
  2470. $output = array();
  2471.  
  2472. foreach ( $files as $key => $list ) {
  2473. foreach ( $list as $index => $value ) {
  2474. $output[$index][$key] = $value;
  2475. }
  2476. }
  2477.  
  2478. return $files = $output;
  2479.  
  2480. }
  2481.  
  2482. /**
  2483. * Get proper JQuery UI version.
  2484. *
  2485. * Used in order to not conflict with WP Admin Scripts.
  2486. *
  2487. * @since 0.1
  2488. * @access public
  2489. */
  2490. public function get_jqueryui_ver() {
  2491.  
  2492. global $wp_version;
  2493.  
  2494. if ( version_compare( $wp_version, '3.1', '>=') ) {
  2495. return '1.8.10';
  2496. }
  2497.  
  2498. return '1.7.3';
  2499.  
  2500. }
  2501.  
  2502. /**
  2503. * Add Field to page (generic function)
  2504. * @author Ohad Raz
  2505. * @since 0.1
  2506. * @access public
  2507. * @param $id string field id, i.e. the meta key
  2508. * @param $args mixed|array
  2509. */
  2510. public function addField($id,$args){
  2511. $new_field = array('id'=> $id,'std' => '','desc' => '','style' =>'');
  2512. $new_field = array_merge($new_field, $args);
  2513. $this->_fields[] = $new_field;
  2514. }
  2515.  
  2516. /**
  2517. * Add typography Field
  2518. *
  2519. * @author Ohad Raz
  2520. * @since 0.3
  2521. *
  2522. * @access public
  2523. *
  2524. * @param $id string id of the field
  2525. * @param $args mixed|array
  2526. * @param boolean $repeater=false
  2527. */
  2528. public function addTypo($id,$args,$repeater=false){
  2529. $new_field = array(
  2530. 'type' => 'typo',
  2531. 'id'=> $id,
  2532. 'std' => array(
  2533. 'size' => '12px',
  2534. 'color' => '#000000',
  2535. 'face' => 'arial',
  2536. 'style' => 'normal',
  2537. 'weight' => 'normal'
  2538. ),
  2539. 'desc' => '',
  2540. 'style' =>'',
  2541. 'name'=> 'Typography field'
  2542. );
  2543. $new_field = array_merge($new_field, $args);
  2544. $this->_fields[] = $new_field;
  2545. }
  2546.  
  2547. /**
  2548. * Add Text Field to Page
  2549. * @author Ohad Raz
  2550. * @since 0.1
  2551. * @access public
  2552. * @param $id string field id, i.e. the meta key
  2553. * @param $args mixed|array
  2554. * 'name' => // field name/label string optional
  2555. * 'desc' => // field description, string optional
  2556. * 'std' => // default value, string optional
  2557. * 'style' => // custom style for field, string optional
  2558. * 'validate_func' => // validate function, string optional
  2559. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2560. */
  2561. public function addText($id,$args,$repeater=false){
  2562. $new_field = array('type' => 'text','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Text Field');
  2563. $new_field = array_merge($new_field, $args);
  2564. if(false === $repeater){
  2565. $this->_fields[] = $new_field;
  2566. }else{
  2567. return $new_field;
  2568. }
  2569. }
  2570.  
  2571. /**
  2572. * Add Pluploader Field to Page
  2573. * @author Ohad Raz
  2574. * @since 0.9.7
  2575. * @access public
  2576. * @param $id string field id, i.e. the meta key
  2577. * @param $args mixed|array
  2578. * 'name' => // field name/label string optional
  2579. * 'desc' => // field description, string optional
  2580. * 'std' => // default value, string optional
  2581. * 'style' => // custom style for field, string optional
  2582. * 'validate_func' => // validate function, string optional
  2583. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2584. */
  2585. public function addPlupload($id,$args,$repeater=false){
  2586. $new_field = array('type' => 'plupload','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'PlUpload Field','width' => null, 'height' => null,'multiple' => false);
  2587. $new_field = array_merge($new_field, $args);
  2588. if(false === $repeater){
  2589. $this->_fields[] = $new_field;
  2590. }else{
  2591. return $new_field;
  2592. }
  2593. }
  2594.  
  2595. /**
  2596. * Add Hidden Field to Page
  2597. * @author Ohad Raz
  2598. * @since 0.1
  2599. * @access public
  2600. * @param $id string field id, i.e. the meta key
  2601. * @param $args mixed|array
  2602. * 'name' => // field name/label string optional
  2603. * 'desc' => // field description, string optional
  2604. * 'std' => // default value, string optional
  2605. * 'style' => // custom style for field, string optional
  2606. * 'validate_func' => // validate function, string optional
  2607. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2608. */
  2609. public function addHidden($id,$args,$repeater=false){
  2610. $new_field = array('type' => 'hidden','id'=> $id,'std' => '','desc' => '','style' =>'','name' => '');
  2611. $new_field = array_merge($new_field, $args);
  2612. if(false === $repeater){
  2613. $this->_fields[] = $new_field;
  2614. }else{
  2615. return $new_field;
  2616. }
  2617. }
  2618.  
  2619. /**
  2620. * Add code Editor to page
  2621. * @author Ohad Raz
  2622. * @since 0.1
  2623. * @access public
  2624. * @param $id string field id, i.e. the meta key
  2625. * @param $args mixed|array
  2626. * 'name' => // field name/label string optional
  2627. * 'desc' => // field description, string optional
  2628. * 'std' => // default value, string optional
  2629. * 'style' => // custom style for field, string optional
  2630. * 'syntax' => // syntax language to use in editor (php,javascript,css,html)
  2631. * 'validate_func' => // validate function, string optional
  2632. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2633. */
  2634. public function addCode($id,$args,$repeater=false){
  2635. $new_field = array('type' => 'code','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Code Editor Field','syntax' => 'php', 'theme' => 'default');
  2636. $new_field = array_merge($new_field, (array)$args);
  2637. if(false === $repeater){
  2638. $this->_fields[] = $new_field;
  2639. }else{
  2640. return $new_field;
  2641. }
  2642. }
  2643.  
  2644. /**
  2645. * Add Paragraph to Page
  2646. * @author Ohad Raz
  2647. * @since 0.1
  2648. * @access public
  2649. *
  2650. * @param $p paragraph html
  2651. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2652. */
  2653. public function addParagraph($p,$repeater=false){
  2654. $new_field = array('type' => 'paragraph','id'=> '','value' => $p);
  2655. if(false === $repeater){
  2656. $this->_fields[] = $new_field;
  2657. }else{
  2658. return $new_field;
  2659. }
  2660. }
  2661.  
  2662. /**
  2663. * Add Checkbox Field to Page
  2664. * @author Ohad Raz
  2665. * @since 0.1
  2666. * @access public
  2667. * @param $id string field id, i.e. the meta key
  2668. * @param $args mixed|array
  2669. * 'name' => // field name/label string optional
  2670. * 'desc' => // field description, string optional
  2671. * 'std' => // default value, string optional
  2672. * 'validate_func' => // validate function, string optional
  2673. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2674. */
  2675. public function addCheckbox($id,$args,$repeater=false){
  2676. $new_field = array('type' => 'checkbox','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Checkbox Field');
  2677. $new_field = array_merge($new_field, $args);
  2678. if(false === $repeater){
  2679. $this->_fields[] = $new_field;
  2680. }else{
  2681. return $new_field;
  2682. }
  2683. }
  2684.  
  2685. /**
  2686. * Add Checkbox conditional Field to Page
  2687. * @author Ohad Raz
  2688. * @since 0.5
  2689. * @access public
  2690. * @param $id string field id, i.e. the key
  2691. * @param $args mixed|array
  2692. * 'name' => // field name/label string optional
  2693. * 'desc' => // field description, string optional
  2694. * 'std' => // default value, string optional
  2695. * 'validate_func' => // validate function, string optional
  2696. * 'fields' => list of fields to show conditionally.
  2697. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2698. */
  2699. public function addCondition($id,$args,$repeater=false){
  2700. $new_field = array('type' => 'cond','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Conditional Field','fields' => array());
  2701. $new_field = array_merge($new_field, $args);
  2702. if(false === $repeater){
  2703. $this->_fields[] = $new_field;
  2704. }else{
  2705. return $new_field;
  2706. }
  2707. }
  2708.  
  2709. /**
  2710. * Add CheckboxList Field to Page
  2711. * @author Ohad Raz
  2712. * @since 0.1
  2713. * @access public
  2714. * @param $id string field id, i.e. the meta key
  2715. * @param $options (array) array of key => value pairs for select options
  2716. * @param $args mixed|array
  2717. * 'name' => // field name/label string optional
  2718. * 'desc' => // field description, string optional
  2719. * 'std' => // default value, string optional
  2720. * 'validate_func' => // validate function, string optional
  2721. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2722. *
  2723. * @return : remember to call: $checkbox_list = get_post_meta(get_the_ID(), 'meta_name', false);
  2724. * which means the last param as false to get the values in an array
  2725. */
  2726. public function addCheckboxList($id,$options=array(),$args,$repeater=false){
  2727. $new_field = array('type' => 'checkbox_list','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Checkbox List Field','options' => $options, 'class' => '');
  2728. $new_field = array_merge($new_field, $args);
  2729. if(false === $repeater){
  2730. $this->_fields[] = $new_field;
  2731. }else{
  2732. return $new_field;
  2733. }
  2734. }
  2735.  
  2736. /**
  2737. * Add Textarea Field to Page
  2738. * @author Ohad Raz
  2739. * @since 0.1
  2740. * @access public
  2741. * @param $id string field id, i.e. the meta key
  2742. * @param $args mixed|array
  2743. * 'name' => // field name/label string optional
  2744. * 'desc' => // field description, string optional
  2745. * 'std' => // default value, string optional
  2746. * 'style' => // custom style for field, string optional
  2747. * 'validate_func' => // validate function, string optional
  2748. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2749. */
  2750. public function addTextarea($id,$args,$repeater=false){
  2751. $new_field = array('type' => 'textarea','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Textarea Field');
  2752. $new_field = array_merge($new_field, $args);
  2753. if(false === $repeater){
  2754. $this->_fields[] = $new_field;
  2755. }else{
  2756. return $new_field;
  2757. }
  2758. }
  2759.  
  2760. /**
  2761. * Add Select Field to Page
  2762. * @author Ohad Raz
  2763. * @since 0.1
  2764. * @access public
  2765. * @param $id string field id, i.e. the meta key
  2766. * @param $options (array) array of key => value pairs for select options
  2767. * @param $args mixed|array
  2768. * 'name' => // field name/label string optional
  2769. * 'desc' => // field description, string optional
  2770. * 'std' => // default value, (array) optional
  2771. * 'multiple' => // select multiple values, optional. Default is false.
  2772. * 'validate_func' => // validate function, string optional
  2773. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2774. */
  2775. public function addSelect($id,$options,$args,$repeater=false){
  2776. $new_field = array('type' => 'select','id'=> $id,'std' => array(),'desc' => '','style' =>'','name' => 'Select Field','multiple' => false,'options' => $options);
  2777. $new_field = array_merge($new_field, $args);
  2778. if(false === $repeater){
  2779. $this->_fields[] = $new_field;
  2780. }else{
  2781. return $new_field;
  2782. }
  2783. }
  2784.  
  2785. /**
  2786. * Add Sortable Field to Page
  2787. * @author Ohad Raz
  2788. * @since 0.4
  2789. * @access public
  2790. * @param $id string field id, i.e. the meta key
  2791. * @param $options (array) array of key => value pairs for sortable options as value => label
  2792. * @param $args mixed|array
  2793. * 'name' => // field name/label string optional
  2794. * 'desc' => // field description, string optional
  2795. * 'std' => // default value, (array) optional
  2796. * 'validate_func' => // validate function, string optional
  2797. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2798. */
  2799. public function addSortable($id,$options,$args,$repeater=false){
  2800. $new_field = array('type' => 'sortable','id'=> $id,'std' => array(),'desc' => '','style' =>'','name' => 'Select Field','multiple' => false,'options' => $options);
  2801. $new_field = array_merge($new_field, $args);
  2802. if(false === $repeater){
  2803. $this->_fields[] = $new_field;
  2804. }else{
  2805. return $new_field;
  2806. }
  2807. }
  2808.  
  2809.  
  2810. /**
  2811. * Add Radio Field to Page
  2812. * @author Ohad Raz
  2813. * @since 0.1
  2814. * @access public
  2815. * @param $id string field id, i.e. the meta key
  2816. * @param $options (array) array of key => value pairs for radio options
  2817. * @param $args mixed|array
  2818. * 'name' => // field name/label string optional
  2819. * 'desc' => // field description, string optional
  2820. * 'std' => // default value, string optional
  2821. * 'validate_func' => // validate function, string optional
  2822. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2823. */
  2824. public function addRadio($id,$options,$args,$repeater=false){
  2825. $new_field = array('type' => 'radio','id'=> $id,'std' => array(),'desc' => '','style' =>'','name' => 'Radio Field','options' => $options,'multiple' => false);
  2826. $new_field = array_merge($new_field, $args);
  2827. if(false === $repeater){
  2828. $this->_fields[] = $new_field;
  2829. }else{
  2830. return $new_field;
  2831. }
  2832. }
  2833.  
  2834. /**
  2835. * Add Date Field to Page
  2836. * @author Ohad Raz
  2837. * @since 0.1
  2838. * @access public
  2839. * @param $id string field id, i.e. the meta key
  2840. * @param $args mixed|array
  2841. * 'name' => // field name/label string optional
  2842. * 'desc' => // field description, string optional
  2843. * 'std' => // default value, string optional
  2844. * 'validate_func' => // validate function, string optional
  2845. * 'format' => // date format, default yy-mm-dd. Optional. Default "'d MM, yy'" See more formats here: http://goo.gl/Wcwxn
  2846. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2847. */
  2848. public function addDate($id,$args,$repeater=false){
  2849. $new_field = array('type' => 'date','id'=> $id,'std' => '','desc' => '','format'=>'d MM, yy','name' => 'Date Field');
  2850. $new_field = array_merge($new_field, $args);
  2851. if(false === $repeater){
  2852. $this->_fields[] = $new_field;
  2853. }else{
  2854. return $new_field;
  2855. }
  2856. }
  2857.  
  2858. /**
  2859. * Add Time Field to Page
  2860. * @author Ohad Raz
  2861. * @since 0.1
  2862. * @access public
  2863. * @param $id string- field id, i.e. the meta key
  2864. * @param $args mixed|array
  2865. * 'name' => // field name/label string optional
  2866. * 'desc' => // field description, string optional
  2867. * 'std' => // default value, string optional
  2868. * 'validate_func' => // validate function, string optional
  2869. * 'format' => // time format, default hh:mm. Optional. See more formats here: http://goo.gl/83woX
  2870. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2871. */
  2872. public function addTime($id,$args,$repeater=false){
  2873. $new_field = array('type' => 'time','id'=> $id,'std' => '','desc' => '','format'=>'hh:mm','name' => 'Time Field');
  2874. $new_field = array_merge($new_field, $args);
  2875. if(false === $repeater){
  2876. $this->_fields[] = $new_field;
  2877. }else{
  2878. return $new_field;
  2879. }
  2880. }
  2881.  
  2882. /**
  2883. * Add Color Field to Page
  2884. * @author Ohad Raz
  2885. * @since 0.1
  2886. * @access public
  2887. * @param $id string field id, i.e. the meta key
  2888. * @param $args mixed|array
  2889. * 'name' => // field name/label string optional
  2890. * 'desc' => // field description, string optional
  2891. * 'std' => // default value, string optional
  2892. * 'validate_func' => // validate function, string optional
  2893. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2894. */
  2895. public function addColor($id,$args,$repeater=false){
  2896. $new_field = array('type' => 'color','id'=> $id,'std' => '','desc' => '','name' => 'ColorPicker Field');
  2897. $new_field = array_merge($new_field, $args);
  2898. if(false === $repeater){
  2899. $this->_fields[] = $new_field;
  2900. }else{
  2901. return $new_field;
  2902. }
  2903. }
  2904.  
  2905. /**
  2906. * Add Image Field to Page
  2907. * @author Ohad Raz
  2908. * @since 0.1
  2909. * @access public
  2910. * @param $id string field id, i.e. the meta key
  2911. * @param $args mixed|array
  2912. * 'name' => // field name/label string optional
  2913. * 'desc' => // field description, string optional
  2914. * 'validate_func' => // validate function, string optional
  2915. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2916. */
  2917. public function addImage($id,$args,$repeater=false){
  2918. $new_field = array('type' => 'image','id'=> $id,'desc' => '','name' => 'Image Field');
  2919. $new_field = array_merge($new_field, $args);
  2920. if(false === $repeater){
  2921. $this->_fields[] = $new_field;
  2922. }else{
  2923. return $new_field;
  2924. }
  2925. }
  2926.  
  2927.  
  2928. /**
  2929. * Add WYSIWYG Field to Page
  2930. * @author Ohad Raz
  2931. * @since 0.1
  2932. * @access public
  2933. * @param $id string field id, i.e. the meta key
  2934. * @param $args mixed|array
  2935. * 'name' => // field name/label string optional
  2936. * 'desc' => // field description, string optional
  2937. * 'std' => // default value, string optional
  2938. * 'style' => // custom style for field, string optional Default 'width: 300px; height: 400px'
  2939. * 'validate_func' => // validate function, string optional
  2940. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2941. */
  2942. public function addWysiwyg($id,$args,$repeater=false){
  2943. $new_field = array('type' => 'wysiwyg','id'=> $id,'std' => '','desc' => '','style' =>'width: 300px; height: 400px','name' => 'WYSIWYG Editor Field');
  2944. $new_field = array_merge($new_field, $args);
  2945. if(false === $repeater){
  2946. $this->_fields[] = $new_field;
  2947. }else{
  2948. return $new_field;
  2949. }
  2950. }
  2951.  
  2952. /**
  2953. * Add Taxonomy Field to Page
  2954. * @author Ohad Raz
  2955. * @since 0.1
  2956. * @access public
  2957. * @param $id string field id, i.e. the meta key
  2958. * @param $options mixed|array options of taxonomy field
  2959. * 'taxonomy' => // taxonomy name can be category,post_tag or any custom taxonomy default is category
  2960. * 'type' => // how to show taxonomy? 'select' (default) or 'checkbox_list'
  2961. * 'args' => // arguments to query taxonomy, see http://goo.gl/uAANN default ('hide_empty' => false)
  2962. * @param $args mixed|array
  2963. * 'name' => // field name/label string optional
  2964. * 'desc' => // field description, string optional
  2965. * 'std' => // default value, string optional
  2966. * 'validate_func' => // validate function, string optional
  2967. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2968. */
  2969. public function addTaxonomy($id,$options,$args,$repeater=false){
  2970. $temp = array('taxonomy'=> 'category','type' => 'select','args'=> array('hide_empty' => 0));
  2971. $options = array_merge($temp,$options);
  2972. $new_field = array('type' => 'taxonomy','id'=> $id,'desc' => '','name' => 'Taxonomy Field','options'=> $options, 'multiple' => false);
  2973. $new_field = array_merge($new_field, $args);
  2974. if(false === $repeater){
  2975. $this->_fields[] = $new_field;
  2976. }else{
  2977. return $new_field;
  2978. }
  2979. }
  2980.  
  2981. /**
  2982. * Add WP_Roles Field to Page
  2983. * @author Ohad Raz
  2984. * @since 0.1
  2985. * @access public
  2986. * @param $id string field id, i.e. the meta key
  2987. * @param $options mixed|array options of taxonomy field
  2988. * 'type' => // how to show taxonomy? 'select' (default) or 'checkbox_list'
  2989. * @param $args mixed|array
  2990. * 'name' => // field name/label string optional
  2991. * 'desc' => // field description, string optional
  2992. * 'std' => // default value, string optional
  2993. * 'validate_func' => // validate function, string optional
  2994. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  2995. */
  2996. public function addRoles($id,$options,$args,$repeater=false){
  2997. $options = array_merge(array('type'=>'select'),$options);
  2998. $new_field = array('type' => 'WProle','id'=> $id,'desc' => '','name' => 'WP Roles Field','options'=> $options, 'multiple' => false);
  2999. $new_field = array_merge($new_field, $args);
  3000. if(false === $repeater){
  3001. $this->_fields[] = $new_field;
  3002. }else{
  3003. return $new_field;
  3004. }
  3005. }
  3006.  
  3007. /**
  3008. * Add posts Field to Page
  3009. * @author Ohad Raz
  3010. * @since 0.1
  3011. * @access public
  3012. * @param $id string field id, i.e. the meta key
  3013. * @param $options mixed|array options of taxonomy field
  3014. * 'post_type' => // post type name, 'post' (default) 'page' or any custom post type
  3015. * type' => // how to show posts? 'select' (default) or 'checkbox_list'
  3016. * args' => // arguments to query posts, see http://goo.gl/is0yK default ('posts_per_page' => -1)
  3017. * @param $args mixed|array
  3018. * 'name' => // field name/label string optional
  3019. * 'desc' => // field description, string optional
  3020. * 'std' => // default value, string optional
  3021. * 'validate_func' => // validate function, string optional
  3022. * @param $repeater bool is this a field inside a repeatr? true|false(default)
  3023. */
  3024. public function addPosts($id,$options,$args,$repeater=false){
  3025. $temp = array('type'=>'select','args'=>array('posts_per_page' => -1,'post_type' =>'post'));
  3026. $options = array_replace_recursive($temp,$options);
  3027. $new_field = array('type' => 'posts','id'=> $id,'desc' => '','name' => 'Posts Field','options'=> $options, 'multiple' => false);
  3028. $new_field = array_merge($new_field, $args);
  3029. if(false === $repeater){
  3030. $this->_fields[] = $new_field;
  3031. }else{
  3032. return $new_field;
  3033. }
  3034. }
  3035.  
  3036. /**
  3037. * Add repeater Field Block to Page
  3038. * @author Ohad Raz
  3039. * @since 0.1
  3040. * @access public
  3041. * @param $id string field id, i.e. the meta key
  3042. * @param $args mixed|array
  3043. * 'name' => // field name/label string optional
  3044. * 'desc' => // field description, string optional
  3045. * 'std' => // default value, string optional
  3046. * 'style' => // custom style for field, string optional
  3047. * 'validate_func' => // validate function, string optional
  3048. * 'fields' => //fields to repeater
  3049. * @modified 0.4 added sortable option
  3050. */
  3051. public function addRepeaterBlock($id,$args){
  3052. $new_field = array('type' => 'repeater','id'=> $id,'name' => 'Reapeater Field','fields' => array(),'inline'=> false, 'sortable' => false);
  3053. $new_field = array_merge($new_field, $args);
  3054. $this->_fields[] = $new_field;
  3055. }
  3056.  
  3057.  
  3058. /**
  3059. * Finish Declaration of Page
  3060. * @author Ohad Raz
  3061. * @since 0.1
  3062. * @access public
  3063. * @deprecated 1.1.8
  3064. */
  3065. public function Finish() {
  3066. /*$this->add_missed_values();
  3067. $this->check_field_upload();
  3068. $this->check_field_plupload();
  3069. $this->check_field_color();
  3070. $this->check_field_date();
  3071. $this->check_field_time();
  3072. $this->check_field_code();*/
  3073. }
  3074.  
  3075. /**
  3076. * Helper function to check for empty arrays
  3077. * @author Ohad Raz
  3078. * @since 0.1
  3079. * @access public
  3080. * @param $args mixed|array
  3081. */
  3082. public function is_array_empty($array){
  3083. if (!is_array($array))
  3084. return true;
  3085.  
  3086. foreach ($array as $a){
  3087. if (is_array($a)){
  3088. foreach ($a as $sub_a){
  3089. if (!empty($sub_a) && $sub_a != '')
  3090. return false;
  3091. }
  3092. }else{
  3093. if (!empty($a) && $a != '')
  3094. return false;
  3095. }
  3096. }
  3097. return true;
  3098. }
  3099.  
  3100. /**
  3101. * Get the list of avialable Fonts
  3102. *
  3103. * @author Ohad Raz
  3104. * @since 0.3
  3105. * @access public
  3106. *
  3107. * @return mixed|array
  3108. */
  3109. public function get_fonts_family($font = null) {
  3110. $fonts = get_option('WP_EX_FONTS_LIST', $default = false);
  3111. if ($fonts === false){
  3112. $fonts = array(
  3113. 'arial' => array(
  3114. 'name' => 'Arial',
  3115. 'css' => "font-family: Arial, sans-serif;",
  3116. ),
  3117. 'verdana' => array(
  3118. 'name' => "Verdana, Geneva",
  3119. 'css' => "font-family: Verdana, Geneva;",
  3120. ),
  3121. 'trebuchet' => array(
  3122. 'name' => "Trebuchet",
  3123. 'css' => "font-family: Trebuchet;",
  3124. ),
  3125. 'georgia' => array(
  3126. 'name' => "Georgia",
  3127. 'css' => "font-family: Georgia;",
  3128. ),
  3129. 'times' => array(
  3130. 'name' => "Times New Roman",
  3131. 'css' => "font-family: Times New Roman;",
  3132. ),
  3133. 'tahoma' => array(
  3134. 'name' => "Tahoma, Geneva",
  3135. 'css' => "font-family: Tahoma, Geneva;",
  3136. ),
  3137. 'palatino' => array(
  3138. 'name' => "Palatino",
  3139. 'css' => "font-family: Palatino;",
  3140. ),
  3141. 'helvetica' => array(
  3142. 'name' => "Verdana, Geneva",
  3143. 'css' => "font-family: Helvetica*;",
  3144. ),
  3145. );
  3146. if ($this->google_fonts){
  3147. $api_keys = array(
  3148. 'AIzaSyDXgT0NYjLhDmUzdcxC5RITeEDimRmpq3s',
  3149. 'AIzaSyD6j7CsUTblh29PAXN3NqxBjnN-5nuuFGU',
  3150. 'AIzaSyB8Ua6XIfe-gqbkE8P3XL4spd0x8Ft7eWo',
  3151. 'AIzaSyDJYYVPLT9JaoMPF8G5cFm1YjTZMjknizE',
  3152. 'AIzaSyDXt6e2t_gCfhlSfY8ShpR9WpqjMsjEimU'
  3153. );
  3154. $k = rand(0,count($api_keys) -1 );
  3155. $gs = wp_remote_get( 'https://www.googleapis.com/webfonts/v1/webfonts?sort=popularity&key='.$api_keys[$k] ,array('sslverify' => false));
  3156. if(! is_wp_error( $gs ) ) {
  3157. $fontsSeraliazed = $gs['body'];
  3158. $fontArray = json_decode($gs['body']);
  3159. $fontArray = $fontArray->items;
  3160. foreach ( $fontArray as $f ){
  3161. $key = strtolower(str_replace(" ", "_", $f->family));
  3162. $fonts[$key] = array(
  3163. 'name' => $f->family,
  3164. 'import' => str_replace(" ","+",$f->family),
  3165. 'css' => 'font-family: '.$f->family .';', //@import url(http://fonts.googleapis.com/css?family=
  3166. );
  3167. }
  3168. }
  3169. }
  3170. update_option('WP_EX_FONTS_LIST',$fonts);
  3171. }
  3172. $fonts = apply_filters( 'WP_EX_available_fonts_family', $fonts );
  3173. if ($font === null){
  3174. return $fonts;
  3175. }else{
  3176. foreach ($fonts as $f => $value) {
  3177. if ($f == $font)
  3178. return $value;
  3179. }
  3180. }
  3181. }
  3182.  
  3183. /**
  3184. * Get list of font faces
  3185. *
  3186. * @author Ohad Raz
  3187. * @since 0.3
  3188. * @access public
  3189. *
  3190. * @return array
  3191. */
  3192. public function get_font_style(){
  3193. $default = array(
  3194. 'normal' => 'Normal',
  3195. 'italic' => 'Italic',
  3196. 'oblique ' => 'Oblique'
  3197. );
  3198. return apply_filters( 'BF_available_fonts_style', $default );
  3199. }
  3200.  
  3201. /**
  3202. * Get list of font wieght
  3203. *
  3204. * @author Ohad Raz
  3205. * @since 0.9.9
  3206. * @access public
  3207. *
  3208. * @return array
  3209. */
  3210. public function get_font_weight(){
  3211. $default = array(
  3212. 'normal' => 'Normal',
  3213. 'bold' => 'Bold',
  3214. 'bolder' => 'Bolder',
  3215. 'lighter' => 'Lighter',
  3216. '100' => '100',
  3217. '200' => '200',
  3218. '300' => '300',
  3219. '400' => '400',
  3220. '500' => '500',
  3221. '600' => '600',
  3222. '700' => '700',
  3223. '800' => '800',
  3224. '900' => '900',
  3225. 'inherit' => 'Inherit'
  3226. );
  3227. return apply_filters( 'BF_available_fonts_weights', $default );
  3228. }
  3229.  
  3230. /**
  3231. * Export Import Functions
  3232. */
  3233.  
  3234. /**
  3235. * Add import export to Page
  3236. * @author Ohad Raz
  3237. * @since 0.8
  3238. * @access public
  3239. *
  3240. * @return void
  3241. */
  3242. public function addImportExport(){
  3243. $new_field = array('type' => 'import_export','id'=> '','value' => '');
  3244. $this->_fields[] = $new_field;
  3245. }
  3246.  
  3247.  
  3248. public function show_import_export(){
  3249. $this->show_field_begin(array('name' => ''),null);
  3250. $ret ='
  3251. <div class="apc_ie_panel field">
  3252. <div style="padding 10px;" class="apc_export"><h3>'.__('Export','apc').'</h3>
  3253. <p>'. __('To export saved settings click the Export button bellow and you will get the export Code in the box bellow, which you can later use to import.','apc').'</p>
  3254. <div class="export_code">
  3255. <label for="export_code">'. __('Export Code','apc').'</label><br/>
  3256. <textarea id="export_code"></textarea>
  3257. <input class="button" type="button" value="'. __('Get Export','apc').'" id="apc_export_b" />'.$this->create_export_download_link().'
  3258. <div class="export_status" style="display: none;"><img src="http://i.imgur.com/l4pWs.gif" alt="loading..."/></div>
  3259. <div class="export_results alert" style="display: none;"></div>
  3260. </div>
  3261. </div>
  3262. <div style="padding 10px;" class="apc_import"><h3>'.__('Import','apc').'</h3>
  3263. <p>'. __('To Import saved settings paste the Export output in to the Import Code box bellow and click Import.','apc').'</p>
  3264. <div class="import_code">
  3265. <label for="import_code">'. __('Import Code','apc').'</label><br/>
  3266. <textarea id="import_code"></textarea>
  3267. <input class="button" type="button" value="'. __('Import','apc').'" id="apc_import_b" />
  3268. <div class="import_status" style="display: none;"><img src="http://i.imgur.com/l4pWs.gif" alt="loading..."/></div>
  3269. <div class="import_results alert" style="display: none;"></div>
  3270. </div>
  3271. </div>
  3272. <input type="hidden" id="option_group_name" value="'.$this->option_group.'" />
  3273. <input type="hidden" id="apc_import_nonce" name="apc_Import" value="'.wp_create_nonce("apc_import").'" />
  3274. <input type="hidden" id="apc_export_nonce" name="apc_export" value="'.wp_create_nonce("apc_export").'" />
  3275. ';
  3276. echo apply_filters('apc_import_export_panel',$ret);
  3277. $this->show_field_end(array('name' => '','desc' => ''),null);
  3278. }
  3279.  
  3280. /**
  3281. * Ajax export
  3282. *
  3283. * @author Ohad Raz
  3284. * @since 0.8
  3285. * @access public
  3286. *
  3287. * @return json object
  3288. */
  3289. public function export(){
  3290. check_ajax_referer( 'apc_export', 'seq' );
  3291. if (!isset($_GET['group'])){
  3292. $re['err'] = __('error in ajax request! (1)','apc');
  3293. $re['nonce'] = wp_create_nonce("apc_export");
  3294. echo json_encode($re);
  3295. die();
  3296. }
  3297.  
  3298. $options = get_option($this->option_group,false);
  3299. if ($options !== false)
  3300. $re['code']= "<!*!* START export Code !*!*>\n".base64_encode(serialize($options))."\n<!*!* END export Code !*!*>";
  3301. else
  3302. $re['err'] = __('error in ajax request! (2)','apc');
  3303.  
  3304. //update_nonce
  3305. $re['nonce'] = wp_create_nonce("apc_export");
  3306. echo json_encode($re);
  3307. die();
  3308.  
  3309. }
  3310.  
  3311. /**
  3312. * Ajax import
  3313. *
  3314. * @author Ohad Raz
  3315. * @since 0.8
  3316. * @access public
  3317. *
  3318. * @return json object
  3319. */
  3320. public function import(){
  3321. check_ajax_referer( 'apc_import', 'seq' );
  3322. if (!isset($_POST['imp'])){
  3323. $re['err'] = __('error in ajax request! (3)','apc');
  3324. $re['nonce'] = wp_create_nonce("apc_import");
  3325. echo json_encode($re);
  3326. die();
  3327. }
  3328. $import_code = $_POST['imp'];
  3329. $import_code = str_replace("<!*!* START export Code !*!*>\n","",$import_code);
  3330. $import_code = str_replace("\n<!*!* END export Code !*!*>","",$import_code);
  3331. $import_code = base64_decode($import_code);
  3332. $import_code = unserialize($import_code);
  3333. if (is_array($import_code)){
  3334. update_option($this->option_group,$import_code);
  3335. $re['success']= __('Setting imported, make sure you ','apc'). '<input class="button-primary" type="button" value="'. __('Refresh this page','apc').'" id="apc_refresh_page_b" />';
  3336. }else{
  3337. $re['err'] = __('Could not import settings! (4)','apc');
  3338. }
  3339. //update_nonce
  3340. $re['nonce'] = wp_create_nonce("apc_import");
  3341. echo json_encode($re);
  3342. die();
  3343. }
  3344.  
  3345.  
  3346. //then define the function that will take care of the actual download
  3347. public function download_file($content = null, $file_name = null){
  3348. if (! wp_verify_nonce($_REQUEST['nonce'], 'theme_export_options') )
  3349. wp_die('Security check');
  3350.  
  3351. //here you get the options to export and set it as content, ex:
  3352. $options= get_option($_REQUEST['option_group']);
  3353. $content = "<!*!* START export Code !*!*>\n".base64_encode(serialize($options))."\n<!*!* END export Code !*!*>";
  3354. $file_name = apply_filters('apc_theme_export_filename', 'options.txt');
  3355. header('HTTP/1.1 200 OK');
  3356.  
  3357. if ( !current_user_can('edit_themes') )
  3358. wp_die('<p>'.__('You do not have sufficient permissions to edit templates for this site.','apc').'</p>');
  3359.  
  3360. if ($content === null || $file_name === null){
  3361. wp_die('<p>'.__('Error Downloading file.','apc').'</p>');
  3362. }
  3363. $fsize = strlen($content);
  3364. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  3365. header('Content-Description: File Transfer');
  3366. header("Content-Disposition: attachment; filename=" . $file_name);
  3367. header("Content-Length: ".$fsize);
  3368. header("Expires: 0");
  3369. header("Pragma: public");
  3370. echo $content;
  3371. exit;
  3372. }
  3373.  
  3374. public function create_export_download_link($echo = false){
  3375. $site_url = get_bloginfo('url');
  3376. $args = array(
  3377. 'theme_export_options' => 'safe_download',
  3378. 'nonce' => wp_create_nonce('theme_export_options'),
  3379. 'option_group' => $this->option_group
  3380. );
  3381. $export_url = add_query_arg($args, $site_url);
  3382. if ($echo === true)
  3383. echo '<a href="'.$export_url.'" target="_blank">'.__('Download Export','apc').'</a>';
  3384. elseif ($echo == 'url')
  3385. return $export_url;
  3386. return '<a class="button" href="'.$export_url.'" target="_blank">'.__('Download Export','apc').'</a>';
  3387. }
  3388.  
  3389. //first add a new query var
  3390. public function add_query_var_vars() {
  3391. global $wp;
  3392. $wp->add_query_var('theme_export_options');
  3393. }
  3394.  
  3395. //then add a template redirect which looks for that query var and if found calls the download function
  3396. public function admin_redirect_download_files(){
  3397. global $wp;
  3398. global $wp_query;
  3399. //download theme export
  3400. if (array_key_exists('theme_export_options', $wp->query_vars) && $wp->query_vars['theme_export_options'] == 'safe_download' && $this->option_group == $_REQUEST['option_group'] ){
  3401. $this->download_file();
  3402. die();
  3403. }
  3404. }
  3405.  
  3406. public function Handle_plupload_action(){
  3407. // check ajax noonce
  3408. $imgid = $_POST["imgid"];
  3409. check_ajax_referer($imgid . 'pluploadan');
  3410.  
  3411. // handle file upload
  3412. $status = wp_handle_upload($_FILES[$imgid . 'async-upload'], array('test_form' => true, 'action' => 'plupload_action'));
  3413.  
  3414. // send the uploaded file url in response
  3415. echo $status['url'];
  3416. exit;
  3417. }
  3418.  
  3419. /**
  3420. * load_textdomain
  3421. * @author Ohad Raz
  3422. * @since 1.0.9
  3423. * @return void
  3424. */
  3425. public function load_textdomain(){
  3426. //In themes/plugins/mu-plugins directory
  3427. load_textdomain( 'apc', dirname(__FILE__) . '/lang/' . get_locale() .'.mo' );
  3428. }
  3429.  
  3430. /**
  3431. * Validation functions
  3432. */
  3433.  
  3434. /**
  3435. * validate field
  3436. * @access public
  3437. * @author Ohad Raz <admin@bainternet.info>
  3438. * @since 1.1.9
  3439. * @param array $field field data
  3440. * @param mixed $meta value to validate
  3441. * @return boolean
  3442. */
  3443. public function validate_field($field,$meta){
  3444. if (!isset($field['validate']) || !is_array($field['validate'] ))
  3445. return true;
  3446.  
  3447. $ret = true;
  3448. foreach ($field['validate'] as $type => $args) {
  3449. if (method_exists($this,'is_' . $type)){
  3450. if (call_user_func ( array( $this, 'is_' . $type ), $meta ,$args['param']) === false){
  3451. $this->errors_flag = true;
  3452. $this->errors[$field['id']]['name'] = $field['name'];
  3453. $this->errors[$field['id']]['m'][] = (isset($args['message'])? $args['message'] : __('Not Valid ','apc') . $type);
  3454. $ret = false;
  3455. }
  3456. }
  3457. }
  3458. return $ret;
  3459. }
  3460.  
  3461. /**
  3462. * displayErrors function to print out validation errors.
  3463. * @access public
  3464. * @author Ohad Raz <admin@bainternet.info>
  3465. * @since 1.1.9
  3466. * @return void
  3467. */
  3468. public function displayErrors(){
  3469. if ($this->errors_flag){
  3470. echo '<div class="alert alert-error"><button data-dismiss="alert" class="close" type="button">×</button>';
  3471. echo '<h4>'.__('Errors in saving changes', 'apc').'</h4>';
  3472. foreach ($this->errors as $id => $arr) {
  3473. echo "<strong>{$arr['name']}</strong>: ";
  3474. foreach ($arr['m'] as $m) {
  3475. echo "<br />&nbsp;&nbsp;&nbsp;&nbsp;{$m}";
  3476. }
  3477. echo '<br />';
  3478. }
  3479. echo '</div>';
  3480. }
  3481. }
  3482.  
  3483. /**
  3484. * getFieldErrors return field errors
  3485. * @access public
  3486. * @author Ohad Raz <admin@bainternet.info>
  3487. * @since 1.1.9
  3488. * @param string $field_id
  3489. * @return array
  3490. */
  3491. public function getFieldErrors($field_id){
  3492. if ($this->errors_flag){
  3493. if (isset($this->errors[$field_id]))
  3494. return $this->errors[$field_id];
  3495. }
  3496. return __('Unkown Error','apc');
  3497. }
  3498.  
  3499. /**
  3500. * has_error check if a field has errors
  3501. * @access public
  3502. * @author Ohad Raz <admin@bainternet.info>
  3503. * @since 1.1.9
  3504. * @param string $field_id field ID
  3505. * @return boolean
  3506. */
  3507. public function has_error($field_id){
  3508. //exit if not saved or no validation errors
  3509. if (!$this->saved_flag || !$this->errors_flag)
  3510. return false;
  3511. //check if this field has validation errors
  3512. if (isset($this->errors[$field_id]))
  3513. return true;
  3514. return false;
  3515. }
  3516.  
  3517. /**
  3518. * valid email
  3519. * @access public
  3520. * @author Ohad Raz <admin@bainternet.info>
  3521. * @since 1.1.9
  3522. * @param string
  3523. * @return boolean
  3524. */
  3525. public function is_email($val){
  3526. return (bool)(preg_match("/^([a-z0-9+_-]+)(.[a-z0-9+_-]+)*@([a-z0-9-]+.)+[a-z]{2,6}$/ix",$val));
  3527. }
  3528.  
  3529. /**
  3530. * check a number optional -,+,. values
  3531. * @access public
  3532. * @author Ohad Raz <admin@bainternet.info>
  3533. * @since 1.1.9
  3534. * @param string
  3535. * @return boolean
  3536. */
  3537. public function is_numeric($val){
  3538. return (bool)preg_match('/^[-+]?[0-9]*.?[0-9]+$/', (int)$val);
  3539. }
  3540.  
  3541. /**
  3542. * check given number below value
  3543. * @access public
  3544. * @author Ohad Raz <admin@bainternet.info>
  3545. * @since 1.1.9
  3546. * @param string
  3547. * @return boolean
  3548. */
  3549. public function is_minvalue($number,$max){
  3550. return (bool)((int)$number > (int)$max);
  3551. }
  3552.  
  3553. /**
  3554. * check given number exceeds max values
  3555. * @access public
  3556. * @author Ohad Raz <admin@bainternet.info>
  3557. * @since 1.1.9
  3558. * @param string
  3559. * @return boolean
  3560. */
  3561. public function is_maxvalue($number,$max){
  3562. return ((int)$number < (int)$max);
  3563. }
  3564.  
  3565. /**
  3566. * Check the string length has minimum length
  3567. * @access public
  3568. * @author Ohad Raz <admin@bainternet.info>
  3569. * @since 1.1.9
  3570. * @param string
  3571. * @return boolean
  3572. */
  3573. public function is_minlength($val, $min){
  3574. return (strlen($val) >= (int)$min);
  3575. }
  3576.  
  3577. /**
  3578. * check string length exceeds maximum length
  3579. * @access public
  3580. * @author Ohad Raz <admin@bainternet.info>
  3581. * @since 1.1.9
  3582. * @param string
  3583. * @return boolean
  3584. */
  3585. public function is_maxlength($val, $max){
  3586. return (strlen($val) <= (int)$max);
  3587. }
  3588.  
  3589. /**
  3590. * check for exactly length of string
  3591. * @access public
  3592. * @author Ohad Raz <admin@bainternet.info>
  3593. * @since 1.1.9
  3594. * @param string
  3595. * @return boolean
  3596. */
  3597. public function is_length($val, $length){
  3598. return (strlen($val) == (int)$length);
  3599. }
  3600.  
  3601. /**
  3602. * Valid URL or web address
  3603. * @access public
  3604. * @author Ohad Raz <admin@bainternet.info>
  3605. * @since 1.1.9
  3606. * @param string
  3607. * @return boolean
  3608. */
  3609. public function is_url($val){
  3610. return (bool)preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $val);
  3611. }
  3612.  
  3613. /**
  3614. * Matches alpha and numbers only
  3615. * @access public
  3616. * @author Ohad Raz <admin@bainternet.info>
  3617. * @since 1.1.9
  3618. * @param string
  3619. * @return boolean
  3620. */
  3621. public function is_alphanumeric($val){
  3622. return (bool)preg_match("/^([a-zA-Z0-9])+$/i", $val);
  3623. }
  3624.  
  3625.  
  3626. } // End Class
  3627.  
  3628. endif; // End Check Class Exists
Add Comment
Please, Sign In to add comment