"Fossies" - the Fresh Open Source Software Archive

Member "Open-Web-Analytics-1.7.0/wp_plugin.php" (16 Sep 2020, 62395 Bytes) of package /linux/www/Open-Web-Analytics-1.7.0.tar.gz:


The requested HTML page contains a <FORM> tag that is unusable on "Fossies" in "automatic" (rendered) mode so that page is shown as HTML source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "wp_plugin.php" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.6.9_vs_1.7.0.

    1 <?php 
    2 
    3 /*
    4 Plugin Name: Open Web Analytics
    5 Plugin URI: http://www.openwebanalytics.com
    6 Description: This plugin enables Wordpress blog owners to use the Open Web Analytics Framework.
    7 Author: Peter Adams
    8 Version: master
    9 Author URI: http://www.openwebanalytics.com
   10 */
   11 
   12 //
   13 // Open Web Analytics - An Open Source Web Analytics Framework
   14 //
   15 // Copyright 2008 Peter Adams. All rights reserved.
   16 //
   17 // Licensed under GPL v2.0 http://www.gnu.org/copyleft/gpl.html
   18 //
   19 // Unless required by applicable law or agreed to in writing, software
   20 // distributed under the License is distributed on an "AS IS" BASIS,
   21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   22 // See the License for the specific language governing permissions and
   23 // limitations under the License.
   24 //
   25 // $Id$
   26 //
   27 
   28 // if this file is called directly, abort.
   29 if ( ! defined( 'WPINC' ) ) {
   30     die;
   31 }
   32 
   33 // Define the plugin path constant 
   34 define('OWA_WP_PATH', plugin_dir_path( __FILE__ ) );
   35 
   36 // Hook package creation
   37 add_action('plugins_loaded', array( 'owa_wp_plugin', 'getInstance'), 10 );
   38 
   39 // Installation hook
   40 //register_activation_hook(__FILE__, array('owa_wp_plugin', 'install') );
   41 
   42 
   43 /////////////////////////////////////////////////////////////////////////////////
   44 
   45 
   46 /**
   47  * OWA WordPress Plugin Class
   48  *
   49  */
   50 class owa_wp_plugin extends owa_wp_module {
   51     
   52     // cmd array
   53     var $cmds = array();
   54     // plugin options
   55     var $options = array(
   56         
   57         'track_feed_links'          => true,
   58         'feed_tracking_medium'      => 'feed',
   59         'feed_subscription_param'   => 'owa_sid'
   60     );
   61     
   62     /**
   63      * Constructor
   64      *
   65      */ 
   66     function __construct() {
   67         
   68         // needed???
   69         ob_start();
   70         
   71         // bail if this isn't a request type that OWA needs ot be loaded on.
   72         if ( ! $this->isProperWordPressRequest() ) {
   73             
   74             return;
   75         }
   76                 
   77         // load parent constructor
   78         $params = array();
   79         $params['module_name'] = 'owa-wordpress';
   80         parent::__construct( $params ); 
   81     }
   82     
   83     /**
   84      * Singelton
   85      */
   86     static function getInstance() {
   87         
   88         static $o;
   89     
   90         if ( ! isset( $o ) ) {
   91             
   92             $o = new owa_wp_plugin();
   93         }
   94         
   95         return $o;
   96     }
   97     
   98     
   99     function _init() {
  100                 
  101         // setup plugin options
  102         $this->initOptions();
  103 
  104         // register WordPress hooks and filters
  105         
  106         if ( $this->getOption('enable') ) {
  107             
  108             // insert javascript tracking tag   
  109             add_action('wp_head', array( $this,'insertTrackingTag' ), 100 );
  110             
  111             if (  $this->getOption('trackAdminPages') ) {
  112                 
  113                 add_action('admin_head', array( $this,'insertTrackingTag' ), 100 ); 
  114                             
  115             }
  116 
  117             
  118             // track feeds
  119             if ( $this->getOption('trackFeeds') ) {
  120                 // add tracking to feed entry permalinks
  121                 add_filter('the_permalink_rss', array( $this, 'decorateFeedEntryPermalink' ) );
  122             
  123                 // add tracking to feed subscription links
  124                 add_filter('bloginfo_url', array($this, 'decorateFeedSubscriptionLink' ) );
  125             }
  126             
  127             // Track admin actions if OWA is available as a library
  128             if( $this->isOwaAvailable() ) {
  129                 
  130                 
  131                 // @todo find a way for these methods to POST these to the OWA instance instead of via OWA's PHP Tracker
  132                 $this->defineActionHooks();
  133                 
  134                 // Create a new tracked site in OWA.
  135                 // @todo move this to REST API call when it's ready.
  136                 add_action('wpmu_new_blog', array($this, 'createTrackedSiteForNewBlog'), 10, 6);
  137                 
  138                 $owa = self::getOwaInstance();
  139             
  140                 if ( owa_coreAPI::isUpdateRequired() ) {
  141                     
  142                     add_action('admin_notices', array($this, 'updateNag') );
  143                 }   
  144             }
  145         }
  146 
  147     }
  148         
  149     function updateNag() {
  150         
  151         echo '<BR><div class="update-nag "><p>'. '<B>Open Web Analytics</b> updates are required before tracking can continue. <a href="/wp-admin/admin.php?page=owa-analytics">Please update now!</a></p></div>';
  152     }
  153     
  154     private function isProperWordPressRequest() {
  155         
  156         // cron requests
  157         if ( array_key_exists('doing_wp_cron', $_GET ) ) {
  158             
  159             return;
  160         }
  161         
  162         if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
  163             
  164             return;
  165         }
  166         
  167         if ( defined( 'JSON_REQUEST' ) && JSON_REQUEST ) {
  168             
  169             return;
  170         }
  171         
  172         
  173         return true;
  174     }
  175     
  176     private function initOptions() {
  177         
  178         
  179         // needs to be first as default Options are set here and used down stream in
  180         // all other hooks and classes.
  181         $this->processAdminConfig();
  182         
  183         
  184         // get user defaults from option page
  185         $user_defaults = array_combine( array_keys( $this->registerOptions() ), array_column( $this->registerOptions() , 'default_value') );
  186         
  187         if ( $user_defaults ) {
  188             
  189             $this->options = array_merge($this->options, $user_defaults);
  190         }
  191         
  192         // fetch plugin options from DB and combine them with defaults.
  193         $options = get_option( 'owa_wp' );
  194         //echo 'options from DB: '. print_r( $options, true );
  195         if ( $options ) {
  196             
  197             $this->options = array_merge($this->options, $options);
  198         }
  199         
  200         // needed for backwards compatability of old style embedded installs.
  201         // must go after user default merge
  202         $this->setEmbeddedOptions(); 
  203     }
  204     
  205     /**
  206      * Get an option value
  207      */
  208     function getOption( $key ) {
  209         
  210         $options = array();
  211         $options = $this->options;
  212         if ( array_key_exists( $key, $options ) ) {
  213             
  214             return $this->options[ $key ];
  215         }
  216     }
  217     
  218     /**
  219      * Set an option value
  220      */
  221     function setOption( $key, $value ) {
  222         
  223         $this->options[ $key ] = $value;
  224     }
  225         
  226     /**
  227      * Hooks for tracking WordPress Admin actions
  228      */
  229     function defineActionHooks() {
  230         
  231         
  232         // These hooks rely on accessing OWA server-side 
  233         // as a PHP object.     
  234         
  235         if ( $this->getOption( 'trackAdminActions' ) ) {
  236             
  237             // New Comment
  238             add_action( 'comment_post', array( $this, 'trackCommentAction' ), 10, 2);
  239             // Comment Edit
  240             add_action( 'transition_comment_status', array( $this, 'trackCommentEditAction' ), 10, 3);
  241             // User Registration
  242             add_action( 'user_register', array( $this, 'trackUserRegistrationAction' ) );
  243             // user login
  244             add_action( 'wp_login', array( $this, 'trackUserLoginAction' ) );
  245             // User Profile Update
  246             add_action( 'profile_update', array( $this, 'trackUserProfileUpdateAction' ), 10, 2);
  247             // Password Reset
  248             add_action( 'password_reset', array( $this, 'trackPasswordResetAction' ) );
  249             // Trackback
  250             add_action( 'trackback_post', array( $this, 'trackTrackbackAction' ) );
  251             // New Attachment
  252             add_action( 'add_attachment', array( $this, 'trackAttachmentCreatedAction' ) );
  253             // Attachment Edit
  254             add_action( 'edit_attachment', array( $this, 'trackAttachmentEditAction' ) );
  255             // Post Edit
  256             add_action( 'transition_post_status', array( $this, 'trackPostAction') , 10, 3);
  257             // New Blog (WPMU)
  258             add_action( 'wpmu_new_blog', array( $this, 'trackNewBlogAction') , 10, 5);
  259         }
  260         
  261         // track feeds
  262         
  263         if ( $this->getOption( 'trackFeeds' ) ) {
  264         
  265             add_action('wp_loaded', array( $this, 'addFeedTrackingQueryParams'));
  266             add_action( 'template_redirect', array( $this, 'trackFeedRequest'), 1 );
  267         }
  268     }   
  269     
  270     // Add query vars to WordPress
  271     function addFeedTrackingQueryParams() {
  272         
  273         global $wp; 
  274         
  275         // feed tracking param
  276         $wp->add_query_var('owa_sid'); 
  277         
  278     }
  279     
  280     /**
  281      * Determines the title of the page being requested
  282      *
  283      * @param string $page_type
  284      * @return string $title
  285      */
  286     function getPageTitle() {
  287     
  288         $page_type = $this->getPageType();
  289         
  290         if ( $page_type == "Home" ) {
  291         
  292             $title = get_bloginfo( "name" );
  293         
  294         } elseif ( $page_type == "Search Results" ) {
  295             
  296             $title = "Search Results for \"" . get_search_query() . "\"";   
  297         
  298         } else {
  299             
  300             $title = wp_title($sep = '', $display = 0);
  301         }   
  302         
  303         return $title;
  304     }
  305     
  306     function setPageTitleCmd() {
  307         
  308         $this->cmds[] = sprintf("owa_cmds.push([ 'setPageTitle', '%s' ]);", $this->getPageTitle() );
  309     }
  310     
  311     function setUserNameCmd() {
  312         
  313         $current_user = wp_get_current_user();
  314         $this->cmds[] = sprintf("owa_cmds.push([ 'setUserName', '%s' ]);", $current_user->user_login );
  315     }
  316     
  317     /**
  318      * Determines the type of WordPress page
  319      *
  320      * @return string $type
  321      */
  322     function getPageType() {    
  323         
  324         if ( is_home() ) {
  325             $type = "Home";
  326         } elseif ( is_attachment() ){
  327             $type = "Attachment";
  328         } elseif ( is_page() ) {
  329             $type = "Page";
  330         // general page catch, should be after more specific post types 
  331         } elseif ( is_single() ) {
  332             $type = "Post";
  333         } elseif ( is_feed() ) {
  334             $type = "Feed";
  335         } elseif ( is_author() ) {
  336             $type = "Author";
  337         } elseif ( is_category() ) {
  338             $type = "Category";
  339         } elseif ( is_search() ) {
  340             $type = "Search Results";
  341         } elseif ( is_month() ) {
  342             $type = "Month";
  343         } elseif ( is_day() ) {
  344             $type = "Day";
  345         } elseif ( is_year() ) {
  346             $type = "Year";
  347         } elseif ( is_time() ) {
  348             $type = "Time";
  349         } elseif ( is_tag() ) {
  350             $type = "Tag";
  351         } elseif ( is_tax() ) {
  352             $type = "Taxonomy";
  353         // general archive catch, should be after specific archive types    
  354         } elseif ( is_archive() ) {
  355             $type = "Archive";
  356         } elseif ( is_admin() ) {
  357             $type = "Admin";
  358         } else {
  359             $type = '(not set)';
  360         }
  361         
  362         return $type;
  363     }
  364     
  365     function setDebugCmd() {
  366         
  367         $this->cmds[] = "owa_cmds.push( ['setDebug', true ] );";
  368     }
  369     
  370     function setSiteIdCmd() {
  371         
  372         $this->cmds[] = sprintf("owa_cmds.push( ['setSiteId', '%s' ] );", $this->getOption('siteId') );
  373     }
  374     
  375     function setPageTypeCmd() {
  376         
  377         $this->cmds[] = sprintf("owa_cmds.push( ['setPageType', '%s' ] );", $this->getPageType() );
  378     }
  379     
  380     function setTrackPageViewCmd() {
  381         
  382         $this->cmds[] = "owa_cmds.push( ['trackPageView'] );";
  383     }
  384     
  385     function setTrackClicksCmd() {
  386         
  387         $this->cmds[] = "owa_cmds.push( ['trackClicks'] );";
  388     }
  389     
  390     function setTrackDomstreamsCmd() {
  391         
  392         $this->cmds[] = "owa_cmds.push( ['trackDomStream'] );";
  393     }
  394     
  395     function cmdsToString() {
  396         
  397         $out = '';
  398         
  399         foreach ( $this->cmds as $cmd ) {
  400             
  401             $out .= $cmd . " \n";   
  402         }
  403         
  404         return $out;
  405     }
  406         
  407     // check to see if OWA is available as a php library on the same server
  408     function isOwaAvailable() {
  409         
  410         if ( $this->getOption( 'owaPath' ) ) {
  411             
  412             $owa = owa_wp_plugin::getOwaInstance();
  413             
  414             return $owa->isOwaInstalled();      
  415         }
  416 
  417     }
  418     
  419             
  420     /**
  421      * Insert Tracking Tag
  422      *
  423      * Adds javascript tracking tag int <head> of all pages.
  424      * 
  425      */
  426     function insertTrackingTag() {
  427             
  428         if (is_admin()) {
  429             
  430             $screen = get_current_screen();
  431             ///print_r($screen);    
  432             if ( in_array( $screen->id, [ 'owa_page_owa-analytics', 'owa_page_owa-wordpress' ] ) ) {
  433                 
  434                 return;
  435             }
  436         }
  437                 
  438         // Don't log if the page request is a preview - Wordpress 2.x or greater
  439         if ( function_exists( 'is_preview' ) ) {
  440             
  441             if ( is_preview() ) {
  442                 
  443                 return;
  444             }
  445         }
  446         
  447         // dont log customizer previews either.
  448         if ( function_exists( 'is_customize_preview' ) ) {
  449             
  450             if ( is_customize_preview() ) {
  451                 
  452                 return;
  453             }
  454         }
  455         
  456         // dont log requests for admin interface pages
  457         if ( ! $this->getOption( 'trackAdminPages') && function_exists( ' is_admin' ) && is_admin() ) {
  458             
  459             return;
  460         }
  461         
  462         // set user name in tracking for names users with wp-admin accounts
  463         if ( $this->getOption( 'trackNamedUsers') ) {
  464             
  465             $this->setUserNameCmd();
  466         }
  467     
  468         
  469         // get instance of OWA
  470         $owa = self::getOwaInstance();
  471         
  472         // set any cmds
  473         
  474         if ( $this->getOption('debug') ) {
  475             
  476             $this->setDebugCmd();
  477         }
  478         
  479         $this->setSiteIdCmd();
  480         $this->setPageTypeCmd();
  481         $this->setPageTitleCmd();
  482         
  483         // set track clicks command
  484         if ( $this->getOption('trackClicks') ) {
  485             
  486             $this->setTrackClicksCmd();
  487         }
  488         
  489         // set track domstream command
  490         if ( $this->getOption('trackDomstreams') ) {
  491             
  492             $this->setTrackDomstreamsCmd();
  493         }
  494         
  495         // set track page view command
  496         $this->setTrackPageViewCmd();
  497         
  498         // convert cmds to string and pass to tracking tag template 
  499         $options = $this->cmdsToString();
  500         
  501         echo sprintf( $this->getTrackerSnippetTemplate(), $options );
  502         
  503     }   
  504     
  505     function getTrackerSnippetTemplate() {
  506         
  507         $tag =  "<!-- Open Web Analytics --> \n";
  508         $tag .= '<script type="text/javascript">' . "\n";
  509         $tag .= "var owa_cmds = owa_cmds || []; \n";
  510         
  511         $base_url = $this->getOption('owaEndpoint');
  512         $tag .= "var owa_baseUrl = '$base_url'; \n";
  513         
  514         $tag .= "%s";
  515         
  516         $tag .= "
  517         (function() {var _owa = document.createElement('script'); _owa.type = 'text/javascript'; _owa.async = true;
  518         owa_baseUrl = ('https:' == document.location.protocol ? window.owa_baseSecUrl || owa_baseUrl.replace(/http:/, 'https:') : owa_baseUrl );
  519         _owa.src = owa_baseUrl + 'modules/base/js/owa.tracker-combined-min.js';
  520         var _owa_s = document.getElementsByTagName('script')[0]; _owa_s.parentNode.insertBefore(_owa, _owa_s);}()); 
  521         
  522         \n ";
  523         
  524         $tag .= "</script> \n
  525         <!-- End Open Web Analytics --> \n
  526         ";
  527         
  528         return $tag;
  529     }
  530     
  531         
  532     /**
  533      * Adds tracking source param to links in feeds
  534      *
  535      * @param string $link
  536      * @return string
  537      */
  538     function decorateFeedEntryPermalink($link) {
  539         
  540         // check for presence of '?' which is not present under URL rewrite conditions
  541     
  542         if ( $this->getOption( 'track_feed_links' ) ) {
  543         
  544             if ( strpos($link, "?") === false ) {
  545                 // add the '?' if not found
  546                 $link .= '?';
  547             }
  548             
  549             // setup link template
  550             $link_template = "%s&amp;%s=%s&amp;%s=%s";
  551                 
  552             return sprintf($link_template,
  553                            $link,
  554                            'owa_medium',
  555                            $this->getOption( 'feed_tracking_medium' ),
  556                            $this->getOption( 'feed_subscription_param' ),
  557                            $_GET[ $this->getOption( 'feed_subscription_param' ) ] 
  558             );
  559         }
  560     }
  561     
  562     /**
  563      * Wordpress filter function adds a GUID to the feed URL.
  564      *
  565      * @param array $binfo
  566      * @return string $newbinfo
  567      */
  568     function decorateFeedSubscriptionLink( $binfo ) {
  569         
  570         $is_feed = strpos($binfo, "feed=");
  571         
  572         if ( $is_feed && $this->getOption( 'track_feed_links' ) ) {
  573             
  574             $guid = crc32(getmypid().microtime());
  575         
  576             $newbinfo = $binfo . "&amp;" . $this->getOption('feed_subscription_param') . "=" . $guid;
  577         
  578         } else { 
  579             
  580             $newbinfo = $binfo;
  581         }
  582         
  583         return $newbinfo;
  584     }
  585     
  586     // create a new tracked site.
  587     function createTrackedSiteForNewBlog($blog_id, $user_id, $domain, $path, $site_id, $meta) {
  588     
  589         $owa = self::getOwaInstance();
  590         $sm = owa_coreAPI::supportClassFactory( 'base', 'siteManager' );
  591         $sm->createNewSite( $domain, $domain, '', ''); 
  592     }
  593     
  594     
  595     /**
  596      * New Blog Action Tracker
  597      */
  598     function trackNewBlogAction( $blog_id, $user_id, $domain, $path, $site_id ) {
  599     
  600         $owa = self::getOwaInstance();
  601         $owa->trackAction('WordPress', 'Blog Created', $domain);
  602     }
  603     
  604     /**
  605      * Edit Post Action Tracker
  606      */
  607     function trackedPostEditAction( $post_id, $post ) {
  608         
  609         // we don't want to track autosaves...
  610         if( wp_is_post_autosave( $post ) ) {
  611             
  612             return;
  613         }
  614         
  615         $owa = self::getOwaInstance();
  616         $label = $post->post_title;
  617         $owa->trackAction( 'WordPress', $post->post_type.' edited', $label );
  618     }
  619     
  620     /**
  621      * Post Action Tracker
  622      *
  623      * Trackes new and edited post actions. Including custom post types.
  624      */
  625     function trackPostAction( $new_status, $old_status, $post ) {
  626         
  627         $action_name = '';
  628         
  629         // we don't want to track autosaves...
  630         if(wp_is_post_autosave( $post ) ) {
  631             
  632             return;
  633         }
  634         
  635         // or drafts
  636         if ( $new_status === 'draft' && $old_status === 'draft' ) {
  637             
  638             return;
  639         
  640         } 
  641         
  642         // set action label
  643         if ( $new_status === 'publish' && $old_status != 'publish' ) {
  644             
  645             $action_name = $post->post_type.' publish';
  646         
  647         } elseif ( $new_status === $old_status ) {
  648         
  649             $action_name = $post->post_type.' edit';
  650         }
  651         
  652         // track action
  653         if ( $action_name ) {   
  654         
  655 
  656             $owa = self::getOwaInstance();
  657             owa_coreAPI::debug(sprintf("new: %s, old: %s, post: %s", $new_status, $old_status, print_r($post, true)));
  658             $label = $post->post_title;
  659             
  660             $owa->trackAction('WordPress', $action_name, $label);
  661         }
  662     }
  663     
  664     /**
  665      * Edit Attachment Action Tracker
  666      */
  667     function trackAttachmentEditAction( $post_id ) {
  668     
  669         $owa = self::getOwaInstance();
  670         $post = get_post( $post_id );
  671         $label = $post->post_title;
  672         $owa->trackAction('WordPress', 'Attachment Edit', $label);
  673     }
  674     
  675     /**
  676      * New Attachment Action Tracker
  677      */
  678     function trackAttachmentCreatedAction( $post_id ) {
  679     
  680         $owa = self::getOwaInstance();
  681         $post = get_post($post_id);
  682         $label = $post->post_title;
  683         $owa->trackAction('WordPress', 'Attachment Created', $label);
  684     }
  685     
  686     /**
  687      * User Registration Action Tracker
  688      */
  689     function trackUserRegistrationAction( $user_id ) {
  690         
  691         $owa = self::getOwaInstance();
  692         $user = get_userdata($user_id);
  693         if (!empty($user->first_name) && !empty($user->last_name)) {
  694             $label = $user->first_name.' '.$user->last_name;    
  695         } else {
  696             $label = $user->display_name;
  697         }
  698         
  699         $owa->trackAction('WordPress', 'User Registration', $label);
  700     }
  701     
  702     /**
  703      * User Login Action Tracker
  704      */
  705     function trackUserLoginAction( $user_id ) {
  706     
  707         $owa = self::getOwaInstance();
  708         $label = $user_id;
  709         $owa->trackAction('WordPress', 'User Login', $label);
  710     }
  711     
  712     /**
  713      * Profile Update Action Tracker
  714      */
  715     function trackUserProfileUpdateAction( $user_id, $old_user_data = '' ) {
  716     
  717         $owa = self::getOwaInstance();
  718         $user = get_userdata($user_id);
  719         if (!empty($user->first_name) && !empty($user->last_name)) {
  720             $label = $user->first_name.' '.$user->last_name;    
  721         } else {
  722             $label = $user->display_name;
  723         }
  724         
  725         $owa->trackAction('WordPress', 'User Profile Update', $label);
  726     }
  727     
  728     /**
  729      * Password Reset Action Tracker
  730      */
  731     function trackPasswordResetAction( $user ) {
  732         
  733         $owa = self::getOwaInstance();
  734         $label = $user->display_name;
  735         $owa->trackAction('WordPress', 'User Password Reset', $label);
  736     }
  737     
  738     /**
  739      * Trackback Action Tracker
  740      */
  741     function trackTrackbackAction( $comment_id ) {
  742         
  743         $owa = self::getOwaInstance();
  744         $label = $comment_id;
  745         $owa->trackAction('WordPress', 'Trackback', $label);
  746     }
  747     
  748     function trackCommentAction( $id, $comment_data = '' ) {
  749 
  750         if ( $comment_data === 'approved' || $comment_data === 1 ) {
  751     
  752             $owa = self::getOwaInstance();
  753             $label = '';
  754             $owa->trackAction('WordPress', 'comment', $label);
  755         }
  756     }
  757     
  758     function trackCommentEditAction( $new_status, $old_status, $comment ) {
  759         
  760         if ($new_status === 'approved') {
  761             
  762             if (isset($comment->comment_author)) {
  763                 
  764                 $label = $comment->comment_author; 
  765             
  766             } else {
  767             
  768                 $label = '';
  769             }
  770             
  771             $owa = self::getOwaInstance();
  772             $owa->trackAction('WordPress', 'comment', $label);
  773         }
  774     }
  775     
  776     // Tracks feed requests
  777     function trackFeedRequest() {
  778         
  779         if ( is_feed() ) {
  780         
  781             $owa = self::getOwaInstance();
  782     
  783             if( $owa->getSetting( 'base', 'log_feedreaders') ) {
  784                 
  785                 owa_coreAPI::debug('Tracking WordPress feed request');          
  786                 
  787                 $event = $owa->makeEvent();
  788                 // set event type
  789                 $event->setEventType( 'base.feed_request' );
  790                 // determine and set the type of feed
  791                 $event->set( 'feed_format', get_query_var( 'feed' ) );
  792                 $event->set( 'feed_subscription_id', get_query_var( 'owa_sid' ) );
  793                 //$event->set( 'feed_subscription_id', $_GET['owa_sid'] );
  794                 // track
  795                 $owa->trackEvent( $event );
  796             }
  797         }
  798     }
  799     
  800     // backward compatability for old style embedded installs.
  801     private function setEmbeddedOptions() {
  802         
  803         // check for presence of OWA in same directory.
  804         // used by isOwaAvailable method.
  805         $path =  plugin_dir_path(__FILE__) ;
  806         
  807         if ( file_exists( $path.'owa_env.php' ) ) {
  808             
  809             $this->setOption('owaPath', $path );
  810         }
  811         
  812         
  813         if ( $this->isOwaAvailable() ) {
  814             
  815             $this->setOption('trackAdminActions', true);
  816             
  817             $owa = self::getOwaInstance();
  818             
  819             if ( ! $this->getOption('apiKey') ) {
  820                 
  821                 $cu = owa_coreAPI::getCurrentUser();
  822                 $this->setOption('apiKey', $cu->getUserData('api_key') );
  823             }
  824             
  825             $this->setOption('owaEndpoint', $owa->getSetting('base', 'public_url') );
  826             
  827             // set site iD, if not already set from the DB  
  828             if ( ! $this->getOption('siteId') ) {
  829                 
  830                 $this->setOption('siteId', self::generateSiteId() );
  831             }
  832         
  833         
  834         }
  835         
  836         owa_wp_util::addFilter('owa_wp_settings_field_siteId', array( $this, 'getSitesFromOwa'), 10, 1);
  837         
  838     }
  839     
  840     public function registerOptions() {     
  841         
  842         $settings = array(
  843         
  844             'enable'                => array(
  845             
  846                 'default_value'                         => true,
  847                 'field'                                 => array(
  848                     'type'                                  => 'boolean',
  849                     'title'                                 => 'Enable OWA ',
  850                     'page_name'                             => 'owa-wordpress',
  851                     'section'                               => 'general',
  852                     'description'                           => 'Enable OWA.',
  853                     'label_for'                             => 'Enable OWA.',
  854                     'error_message'                         => 'You must select On or Off.'     
  855                 )               
  856             ),
  857             
  858             'apiKey'                => array(
  859             
  860                 'default_value'                         => '',
  861                 'field'                                 => array(
  862                     'type'                                  => 'text',
  863                     'title'                                 => 'API Key',
  864                     'page_name'                             => 'owa-wordpress',
  865                     'section'                               => 'general',
  866                     'description'                           => 'API key for accessing your OWA instance.',
  867                     'label_for'                             => 'OWA API Key',
  868                     'length'                                => 70,
  869                     'error_message'                         => ''       
  870                 )               
  871             ),
  872             
  873             'owaEndpoint'           => array(
  874             
  875                 'default_value'                         => '',
  876                 'field'                                 => array(
  877                     'type'                                  => 'url',
  878                     'title'                                 => 'OWA Endpoint',
  879                     'page_name'                             => 'owa-wordpress',
  880                     'section'                               => 'general',
  881                     'description'                           => 'The URL of your OWA instance. (i.e. http://www.mydomain.com/path/to/owa/)',
  882                     'label_for'                             => 'OWA Endpoint',
  883                     'length'                                => 70,
  884                     'error_message'                         => ''       
  885                 )               
  886             ),
  887             
  888             'siteId'                => array(
  889             
  890                 'default_value'                         => '',
  891                 'field'                                 => array(
  892                     'type'                                  => 'select',
  893                     'title'                                 => 'Website ID',
  894                     'page_name'                             => 'owa-wordpress',
  895                     'section'                               => 'general',
  896                     'description'                           => 'Select the ID of the website you want to track. (must have a valid API key and endpoint)',
  897                     'label_for'                             => 'Tracked website ID',
  898                     'length'                                => 90,
  899                     'error_message'                         => '',
  900                     'options'                               => []       
  901                 )               
  902             ),
  903 
  904             
  905             'trackClicks'               => array(
  906             
  907                 'default_value'                         => true,
  908                 'field'                                 => array(
  909                     'type'                                  => 'boolean',
  910                     'title'                                 => 'Track Clicks',
  911                     'page_name'                             => 'owa-wordpress',
  912                     'section'                               => 'tracking',
  913                     'description'                           => 'Track the clicks visitors make on your web pages.',
  914                     'label_for'                             => 'Track clicks within a web page',
  915                     'error_message'                         => 'You must select On or Off.'     
  916                 )               
  917             ),
  918             
  919             'trackDomstreams'               => array(
  920             
  921                 'default_value'                         => false,
  922                 'field'                                 => array(
  923                     'type'                                  => 'boolean',
  924                     'title'                                 => 'Track Domstreams',
  925                     'page_name'                             => 'owa-wordpress',
  926                     'section'                               => 'tracking',
  927                     'description'                           => 'Record visitor mouse movements on each web page.',
  928                     'label_for'                             => 'Record mouse movements',
  929                     'error_message'                         => 'You must select On or Off.'     
  930                 )               
  931             ),
  932             
  933             'trackFeeds'                => array(
  934             
  935                 'default_value'                         => true,
  936                 'field'                                 => array(
  937                     'type'                                  => 'boolean',
  938                     'title'                                 => 'Track Feed Requests',
  939                     'page_name'                             => 'owa-wordpress',
  940                     'section'                               => 'tracking',
  941                     'description'                           => 'Track requests for RSS/ATOM syndication feeds.',
  942                     'label_for'                             => 'Track RSSS/ATOM Feeds',
  943                     'error_message'                         => 'You must select On or Off.'     
  944                 )               
  945             ),
  946             
  947             'trackNamedUsers'               => array(
  948             
  949                 'default_value'                         => true,
  950                 'field'                                 => array(
  951                     'type'                                  => 'boolean',
  952                     'title'                                 => 'Track Named Users',
  953                     'page_name'                             => 'owa-wordpress',
  954                     'section'                               => 'tracking',
  955                     'description'                           => 'Track user names and email addresses of WordPress admin users.',
  956                     'label_for'                             => 'Track named users',
  957                     'error_message'                         => 'You must select On or Off.'     
  958                 )               
  959             ),
  960             
  961             'trackAdminPages'               => array(
  962             
  963                 'default_value'                         => false,
  964                 'field'                                 => array(
  965                     'type'                                  => 'boolean',
  966                     'title'                                 => 'Track WP Admin Pages',
  967                     'page_name'                             => 'owa-wordpress',
  968                     'section'                               => 'tracking',
  969                     'description'                           => 'Track WordPress admin interface pages (/wp-admin...)',
  970                     'label_for'                             => 'Track WP admin pages',
  971                     'error_message'                         => 'You must select On or Off.'     
  972                 )               
  973             ),
  974             
  975             'trackAdminActions'             => array(
  976             
  977                 'default_value'                         => false,
  978                 'field'                                 => array(
  979                     'type'                                  => 'boolean',
  980                     'title'                                 => 'Track WP Admin Actions',
  981                     'page_name'                             => 'owa-wordpress',
  982                     'section'                               => 'tracking',
  983                     'description'                           => 'Track WordPress admin actions such as login, new posts, edits, etc.',
  984                     'label_for'                             => 'Track WP admin actions',
  985                     'error_message'                         => 'You must select On or Off.'     
  986                 )               
  987             ),
  988             
  989             'owaPath'                       => array(
  990             
  991                 'default_value'                         => '',
  992                 'field'                                 => array(
  993                     'type'                                  => 'text',
  994                     'title'                                 => 'OWA Path',
  995                     'page_name'                             => 'owa-wordpress',
  996                     'section'                               => 'advanced',
  997                     'description'                           => 'The path to OWA on your server. Used for certain WordPress admin action tracking if OWA is on the same server as your wordPress install.',
  998                     'label_for'                             => 'OWA Path',
  999                     'length'                                    => 70,
 1000                     'error_message'                         => ''       
 1001                 )               
 1002             ),
 1003             
 1004             'debug'             => array(
 1005             
 1006                 'default_value'                         => false,
 1007                 'field'                                 => array(
 1008                     'type'                                  => 'boolean',
 1009                     'title'                                 => 'Debug Mode',
 1010                     'page_name'                             => 'owa-wordpress',
 1011                     'section'                               => 'advanced',
 1012                     'description'                           => 'Outputs debug notices to log file and browser console.',
 1013                     'label_for'                             => 'Debug Mode',
 1014                     'error_message'                         => 'You must select On or Off.'     
 1015                 )               
 1016             ),
 1017 
 1018         );
 1019     
 1020         return $settings;
 1021     }
 1022 
 1023     public function registerSettingsPages() {
 1024         
 1025         $pages = array(
 1026         
 1027             'owa-wordpress'         => array(
 1028                 
 1029                 'parent_slug'                   => 'owa-wordpress',
 1030                 'is_top_level'                  => true,
 1031                 'top_level_menu_title'          => 'OWA',
 1032                 'title'                         => 'Open Web Analytics',
 1033                 'menu_title'                    => 'Tracking Settings',
 1034                 'required_capability'           => 'manage_options',
 1035                 'menu_slug'                     => 'owa-wordpress-settings',
 1036                 'menu-icon'                     => 'dashicons-chart-pie',
 1037                 'description'                   => 'Settings for Open Web Analytics.',
 1038                 'sections'                      => array(
 1039                     'general'                       => array(
 1040                         'id'                            => 'general',
 1041                         'title'                         => 'General',
 1042                         'description'                   => 'These settings control the integration between Open Web Analytics and WordPress.'
 1043                     ),
 1044                     'tracking'                      => array(
 1045                         'id'                            => 'tracking',
 1046                         'title'                         => 'Tracking',
 1047                         'description'                   => 'These settings control how Open Web Analytics will track your WordPress website.'
 1048                     ),
 1049                     'advanced'                      => array(
 1050                         'id'                            => 'advanced',
 1051                         'title'                         => 'Advanced',
 1052                         'description'                   => 'These are advanced integration settings that are seldom used. Do not change these unless you know what you are doing. ;)'
 1053                     )
 1054                 )
 1055             )
 1056         );
 1057         
 1058         if ( $this->isOwaAvailable() ) {
 1059             
 1060             $pages['owa-analytics'] = array(
 1061                 
 1062                 'parent_slug'                   => 'owa-wordpress',
 1063                 'title'                         => 'OWA Analytics',
 1064                 'menu_title'                    => 'Analytics',
 1065                 'required_capability'           => 'manage_options',
 1066                 'menu_slug'                     => 'owa-analytics',
 1067                 'description'                   => 'OWA Analytics dashboard.',
 1068                 'render_callback'               => array( $this, 'pageController')
 1069             );
 1070         }
 1071         
 1072         return $pages;
 1073     }
 1074     
 1075     public static function debug( $msg, $exit = false ) {
 1076         
 1077         if ( defined( 'WP_DEBUG' ) && defined( 'WP_DEBUG_LOG') && WP_DEBUG == true && WP_DEBUG_LOG == true) {
 1078             
 1079             if (is_array( $msg) || is_object( $msg ) ) {
 1080                 
 1081                 $msg = print_r( $msg , true);
 1082             }
 1083 
 1084             error_log( $msg );
 1085             
 1086             if ( $exit ) {
 1087                 
 1088                 exit;
 1089             }
 1090         }
 1091     }
 1092     
 1093     function owaRemoteGet( $params ) {
 1094         
 1095         if ( $this->getOption('apiKey') && $this->getOption('owaEndpoint') ) {
 1096             
 1097             $params['owa_apiKey'] = $this->getOption('apiKey');
 1098             $ret =  wp_remote_get( $this->getOption('owaEndpoint').'api/?' . build_query( $params ) );  
 1099             self::debug('Got response from OWA endpoint' );
 1100             if ( ! is_wp_error( $ret ) ) {
 1101                 
 1102                 $body = wp_remote_retrieve_body( $ret );
 1103                 $body = json_decode($body);
 1104                 return $body;
 1105                 
 1106             } else {
 1107                 
 1108                 self::debug('REST call from WordPress Failed with params: '. print_r($params, true) );
 1109             }
 1110             
 1111             
 1112         }
 1113     }
 1114     
 1115     function getSitesFromOwa( $sites ) {
 1116         
 1117         $params = ['owa_module' => 'base', 'owa_version' => 'v1', 'owa_do' => 'sites' ];
 1118         
 1119         $sites = $this->owaRemoteGet( $params );
 1120             
 1121         $list = [];
 1122         
 1123         foreach ( $sites->data as $site) {
 1124             
 1125             $list[ $site->properties->site_id->value ] = ['label' => sprintf('%s (%s)', $site->properties->site_id->value, $site->properties->domain->value), 'siteId' => $site->properties->site_id->value ];
 1126         }
 1127         
 1128         return $list;
 1129         
 1130     }
 1131     
 1132     function isSiteIdValid( $site_id ) {
 1133         
 1134         $sites = $this->getSitesFromOwa();
 1135         self::debug( $sites );
 1136     }
 1137     
 1138     /////////////////////// Methods that require OWA on server ////////////////////////////
 1139     
 1140     // gets an instance of your OWA as a php object
 1141     public static function getOwaInstance() {
 1142         
 1143         static $owa;
 1144         
 1145         if( empty( $owa ) ) {
 1146                 
 1147             require_once('owa_env.php');
 1148             require_once(OWA_BASE_CLASSES_DIR.'owa_php.php');
 1149             
 1150             // create owa instance w/ config
 1151             $owa = new owa_php();
 1152             
 1153             if ( $owa->isOwaInstalled() ) {
 1154             
 1155                 $owa->setSiteId( self::generateSiteId() );
 1156 
 1157                 $owa->setSetting( 'base', 'is_embedded', true );
 1158             
 1159                 $current_user = wp_get_current_user();
 1160                 owa_coreAPI::debug( 'WordPress login: '.$current_user->user_login );
 1161                 if ( $current_user->user_login ) {
 1162                     
 1163                     // check to see if user exists in OWA.
 1164                     $user = owa_coreApi::entityFactory('base.user');
 1165                     $user->load($current_user->user_login, 'user_id');
 1166                     
 1167                     if (! $user->get('id') ) {
 1168                         
 1169                         // if not create it
 1170                         $user->createNewUser(
 1171                             $current_user->user_login, 
 1172                             owa_wp_plugin::translateAuthRole( $current_user->roles ), 
 1173                             $password = '', 
 1174                             $current_user->user_email, 
 1175                             $current_user->first_name.' '.$current_user->last_name
 1176                         );
 1177                         
 1178                     } else {
 1179                         
 1180                         // or load from db
 1181                         owa_coreAPI::debug('loading OWA current user');
 1182                         $cu = owa_coreAPI::getCurrentUser();
 1183                         $cu->load( $current_user->user_login ); 
 1184                     }
 1185                     
 1186                 }
 1187             }
 1188         }
 1189         
 1190         return $owa;
 1191     }
 1192     
 1193     
 1194     
 1195     public static function generateSiteId() {
 1196         
 1197         return md5( get_option( 'siteurl' ) );
 1198     }
 1199     
 1200     /**
 1201      * Callback for reporting dashboard/pages 
 1202      */
 1203     function pageController( $params = array() ) {
 1204         
 1205         $url = $this->getOption('owaEndpoint');
 1206         
 1207         if ( $this->isOwaAvailable() ) {
 1208             
 1209             // load OWA
 1210             $owa = $this->getOwaInstance();
 1211             // get current user ID to see if it's the admin user
 1212             $cu = owa_coreAPI::getCurrentUser();
 1213             $user_id = $cu->getUserData('user_id');
 1214             
 1215             if ( $user_id ) {
 1216                 
 1217                 $email = $cu->getUserData('email_address');
 1218                 $password = $cu->getUserData('password');
 1219                 $temp_passkey = $cu->getUserData('temp_passkey');
 1220                 $reset_url = $url . sprintf('?%sdo=base.usersPasswordEntry&%sk=%s&owa_is_embedded=1', $owa->getSetting('base', 'ns'), $owa->getSetting('base', 'ns'), $temp_passkey);
 1221                 // display a bug that lets the user know what their OWA user name and email address are so they can login.
 1222                 echo sprintf('<div class="notice notice-info is-dismissible"><p>Your OWA user id is: <B><em>%s</em></b>. Password reset email is <b><em>%s</em></b>. You may need to <a href="%s">reset your OWA password here</a> to login.</p></div><BR>', $user_id, $email, $reset_url);
 1223                 
 1224             }
 1225         }
 1226         
 1227         // insert iframe of OWA endpoint                        
 1228         echo sprintf('<iframe id="owa_wp_analytics" src="%s" style="display: block; width: 100%%; height:100vh;border: none; overflow-y: hidden; overflow-x: hidden;" height="100%%" >', $url);
 1229     }
 1230         
 1231     /**
 1232      * Translate WordPress to OWA Authentication Roles
 1233      *
 1234      * @param $roles    array   array of WP roles
 1235      * @return  string
 1236      */ 
 1237     static function translateAuthRole( $roles ) {
 1238         
 1239         if (!empty($roles)) {
 1240         
 1241             if (in_array('administrator', $roles)) {
 1242                 $owa_role = 'admin';
 1243             } elseif (in_array('editor', $roles)) {
 1244                 $owa_role = 'viewer';
 1245             } elseif (in_array('author', $roles)) {
 1246                 $owa_role = 'viewer';
 1247             } elseif (in_array('contributor', $roles)) {
 1248                 $owa_role = 'viewer';
 1249             } elseif (in_array('subscriber', $roles)) {
 1250                 $owa_role = 'everyone';
 1251             } else {
 1252                 $owa_role = 'everyone';
 1253             }
 1254             
 1255         } else {
 1256             $owa_role = 'everyone';
 1257         }
 1258         
 1259         return $owa_role;
 1260     }
 1261 
 1262 }
 1263 
 1264 class owa_wp_module {
 1265     
 1266     public $module_name;
 1267     public $controllers;
 1268     public $entities;
 1269     public $views;
 1270     public $ns;
 1271     public $package_name;
 1272     public $options;
 1273     public $settings;
 1274     public $settings_pages;
 1275     
 1276     public function __construct( $params = array() ) {
 1277     
 1278         $this->controllers = array();
 1279         $this->entities = array();
 1280         $this->views = array();
 1281         $this->settings_pages = array();
 1282         
 1283         
 1284         // set module name
 1285         if ( array_key_exists( 'module_name', $params ) ) {
 1286             
 1287             $this->module_name = $params['module_name'];
 1288         }
 1289         
 1290         // set package name
 1291         if ( array_key_exists( 'package_name', $params ) ) {
 1292             
 1293             $this->package_name = $params['package_name'];
 1294         }
 1295         
 1296         // set namespace
 1297         if ( array_key_exists( 'ns', $params ) ) {
 1298             
 1299             $this->ns = $params['ns'];
 1300         }
 1301         
 1302         
 1303         
 1304         // kick off the init sequence for each module during Wordpress 'init' hook.
 1305         add_action('init', array( $this, 'init'), 15, 0 );
 1306     }
 1307     
 1308     public function init() {
 1309     
 1310         $this->_init();
 1311         // load public hooks
 1312         $this->definePublicHooks();
 1313         // load admin hooks during WordPress 'admin_init' hook
 1314     
 1315         owa_wp_util::addAction( 'admin_init', array( $this, 'defineAdminHooks') );
 1316     }
 1317     
 1318         /**
 1319      * Inititalizes Settings Page Objects
 1320      *
 1321      */
 1322     public function initSettingsPage() {
 1323         
 1324         // check for prior initialization as I'm not sure if the WP hook admin_init or admin_menu 
 1325         // gets called first.
 1326         if ( ! $this->settings_pages ) {            
 1327             
 1328             $sp_params = array(
 1329             
 1330                 'ns'                => $this->ns,
 1331                 'package'           => $this->package_name,
 1332                 'module'            => $this->module_name
 1333             );
 1334             
 1335             $pages = $this->registerSettingsPages();
 1336             
 1337             if ( $pages ) {
 1338                 
 1339                 foreach ( $pages as $k => $params ) {
 1340                     
 1341                     $new_params = array_merge($params, $sp_params);
 1342                     $new_params['name'] = $k;
 1343                     
 1344                     $this->settings_pages[ $k ] = new owa_wp_settingsPage( $new_params, $this->options );
 1345                 }
 1346             }
 1347         }
 1348     }
 1349     
 1350     /**
 1351      * Callback function for WordPress admin_menu hook
 1352      *
 1353      * Hooks create Menu Pages.
 1354      */
 1355     public function addSettingsPages() {
 1356     
 1357         $this->initSettingsPage();
 1358         
 1359         $pages = $this->settings_pages;
 1360         
 1361         if ( $pages ) {
 1362             
 1363             foreach ( $pages as $k => $page ) {
 1364                 
 1365                 $menu_slug = '';
 1366                 
 1367                 $menu_slug = $page->get('menu_slug');
 1368                 
 1369                 // check for custom callback function.
 1370                 if ( $page->get( 'render_callback' ) ) {
 1371                     
 1372                     $callback = $page->get( 'render_callback' );
 1373                     
 1374                 } else {
 1375                     
 1376                     $callback = array( $page, 'renderPage' );
 1377                 }
 1378                 
 1379                 if ( $page->get('is_top_level') ) {
 1380                     
 1381                     add_menu_page( 
 1382                         $page->get('title'), 
 1383                         $page->get('top_level_menu_title'), 
 1384                         $page->get('required_capability'), 
 1385                         $page->get('parent_slug'), 
 1386                         $callback, 
 1387                         $page->get('menu-icon'), 
 1388                         2 
 1389                     );
 1390                     
 1391                     $menu_slug = $page->get('parent_slug');
 1392                 }
 1393                 
 1394                 // register the page with WordPress admin navigation.
 1395                 add_submenu_page( 
 1396                     $page->get('parent_slug'), 
 1397                     $page->get('title'), 
 1398                     $page->get('menu_title'), 
 1399                     $page->get('required_capability'),
 1400                     $menu_slug,
 1401                     $callback 
 1402                 );          
 1403             }
 1404         }
 1405     }
 1406     
 1407     public function processAdminConfig() {
 1408         
 1409         $config = $this->registerOptions();
 1410         
 1411         if ( $config ) {
 1412         
 1413             foreach ( $config as $k => $v ) {
 1414                 
 1415                 // register setting field with module
 1416                 if ( array_key_exists( 'field', $v ) ) {
 1417                     // check for page_name, if not set it as 'default'
 1418                     if ( ! array_key_exists( 'page_name', $v['field'] ) ) {
 1419                         
 1420                         $v['field']['page_name'] = 'default';
 1421                     }
 1422                     
 1423                     // add field to settings array
 1424                     $this->settings[ $v['field']['page_name'] ][ $k ] = $v[ 'field' ];
 1425                 }
 1426                 
 1427                 // register default option value with module
 1428                 if (array_key_exists( 'default_value', $v ) ) {
 1429                 
 1430                     $this->options[ $k ] = $v[ 'default_value' ];
 1431                 }
 1432             }
 1433             
 1434             // hook settings fields into WordPress      
 1435             if ( $this->settings ) {
 1436                 
 1437                 // we need ot init the settings page objects here 
 1438                 // as they are needed by two the callbacks to seperate WordPress Hooks admin_init and admin_menu.
 1439                 //$this->initSettingsPage();
 1440                 
 1441                 add_action( 'admin_init', array($this, 'registerSettings'),10,0);
 1442                 // regsiter the settings pages with WordPress
 1443                 add_action( 'admin_menu', array($this, 'addSettingsPages'), 11,0);
 1444         
 1445             }               
 1446         }
 1447     }
 1448     
 1449     public function registerAdminConfig() {
 1450         
 1451         return false;
 1452     }
 1453     
 1454     public function registerSettings() {
 1455                     
 1456         // process options
 1457         
 1458         $this->initSettingsPage();
 1459         
 1460         //add_action( 'admin_menu', array($this, 'addSettingsPages'), 10, 0 );
 1461         
 1462         // iterate throught group of settings fields.
 1463         
 1464         foreach ( $this->settings as $group_name => $group ) {
 1465         
 1466             // iterate throug thhe fields in the group
 1467             foreach ( $group as $k => $v ) {
 1468                 
 1469                 // register each field with WordPress
 1470                 $this->settings_pages[ $group_name ]->registerField( $k, $v );
 1471             }
 1472             
 1473             // register the group
 1474             $this->settings_pages[ $group_name ]->registerSettings( $group_name );
 1475             
 1476             // register the sections
 1477             
 1478             $sections = $this->settings_pages[ $group_name ]->get('sections');
 1479             
 1480             if ( $sections ) {
 1481                 
 1482                 foreach ( $sections as $section_name => $section ) {
 1483                 
 1484                     $this->settings_pages[ $group_name ]->registerSection( $section );      
 1485                 }
 1486             }
 1487         }
 1488     }
 1489     
 1490     /**
 1491      * Get Options Key 
 1492      *
 1493      * Gets the key under which options for the module should be persisted.
 1494      *
 1495      * @return string
 1496      */
 1497     public function getOptionsKey() {
 1498         
 1499         //return owa_wp_util::getModuleOptionKey( $this->package_name, $this->module_name );
 1500     }
 1501     
 1502     public function registerController( $action_name, $class, $path ) {
 1503         
 1504         $this->controllers[ $action_name ] = array(
 1505             'class'         => $class,
 1506             'path'          => $path
 1507         );
 1508     }
 1509     
 1510     public function registerControllers( $controllers = array() ) {
 1511         
 1512         return $controllers;
 1513     }
 1514     
 1515     public function loadDependancies() {
 1516             
 1517         return false;
 1518     }
 1519     
 1520     public function registerOptions() {
 1521         
 1522         return false;
 1523     }
 1524     
 1525     public function setDefaultOptions( $options ) {
 1526         
 1527         //$options[ $this->getOptionsKey() ] = $this->options;
 1528         return $this->options;
 1529         //return $options;
 1530     } 
 1531     
 1532     /**
 1533      * Register all of the hooks related to the module
 1534      * of the plugin.
 1535      *
 1536      * @since    1.0.0
 1537      * @access   private
 1538      */
 1539     public function defineAdminHooks() {
 1540         
 1541         return false;
 1542     }
 1543     
 1544     /**
 1545      * Register all of the hooks related to the public-facing functionality
 1546      * of the plugin.
 1547      *
 1548      * @since    1.0.0
 1549      * @access   private
 1550      */
 1551     public function definePublicHooks() {
 1552         
 1553         return false;
 1554     }
 1555 }
 1556 
 1557 class owa_wp_util {
 1558 
 1559     public static function getTaxonomies( $args ) {
 1560     
 1561         return get_taxonomies( $args );
 1562     }
 1563     
 1564     public static function getPostTypes( $args, $type = 'names', $operator = 'and') {
 1565         
 1566         return get_post_types( $args, $type, $operator );
 1567     }
 1568     
 1569     public static function getRemoteUrl( $url ) {
 1570         
 1571         return wp_remote_get ( urlencode ( $url ) );
 1572     }
 1573     
 1574     public static function getModuleOptionKey( $package_name, $module_name ) {
 1575         
 1576         return sprintf( '%s_%s_%s', 'owa_wp', $package_name, $module_name );
 1577     }
 1578     
 1579     public static function setDefaultParams( $defaults, $params, $class_name = '' ) {
 1580         
 1581         $newparams = $defaults;
 1582         
 1583         foreach ( $params as $k => $v ) {
 1584             
 1585             $newparams[$k] = $v;
 1586         }
 1587         
 1588         return $newparams;
 1589     }
 1590     
 1591     public static function addFilter( $hook, $callback, $priority = '', $accepted_args = '' ) {
 1592         
 1593         return add_filter( $hook, $callback, $priority, $accepted_args );
 1594     }
 1595     
 1596     public static function addAction( $hook, $callback, $priority = '', $accepted_args = '' ) {
 1597         
 1598         return add_action( $hook, $callback, $priority, $accepted_args );
 1599     }
 1600     
 1601     public static function escapeOutput( $string ) {
 1602         
 1603         return esc_html( $string );
 1604     }
 1605     
 1606     //
 1607      // Outputs Localized String
 1608      //
 1609      //
 1610     public static function out( $string ) {
 1611         
 1612         echo ( owa_wp_util::escapeOutput ( $string ) );
 1613     }
 1614     
 1615     //
 1616      // Localize String
 1617      //
 1618      //
 1619     public static function localize( $string ) {
 1620         
 1621         return $string;
 1622     }
 1623     
 1624     //
 1625      // Flushes WordPress rewrite rules.
 1626      //
 1627      //
 1628     public static function flushRewriteRules() {
 1629         
 1630         global $wp_rewrite;
 1631         $wp_rewrite->flush_rules();
 1632     }
 1633     
 1634     //
 1635      // Get a direct link to install or update a plugin
 1636      //
 1637      //
 1638     public static function getWpPluginInstallUrl( $slug, $action = 'install-plugin' ) {
 1639         
 1640         return wp_nonce_url(
 1641             add_query_arg(
 1642                 array(
 1643                     'action' => $action,
 1644                     'plugin' => $slug
 1645                 ),
 1646                 admin_url( 'update.php' )
 1647             ),
 1648             $action . '_' . $slug
 1649         );
 1650     }
 1651 }
 1652 
 1653 /////// settings class ///////////
 1654 
 1655 class owa_wp_settingsPage {
 1656     
 1657     public $page_slug;
 1658     
 1659     public $package;
 1660     
 1661     public $module;
 1662     
 1663     public $ns;
 1664     
 1665     public $name;
 1666     
 1667     public $option_group_name; // owa-package-module-groupname
 1668     
 1669     public $fields;
 1670     
 1671     public $properties;
 1672     
 1673     public $options;
 1674     
 1675     public function __construct( $params, $options ) {
 1676         
 1677 
 1678         $defaults = array(
 1679             
 1680             'ns'                    => 'owa_wp',
 1681             'package'               => '',
 1682             'module'                => '',
 1683             'page_slug'             => '',
 1684             'name'                  => '',
 1685             'title'                 => 'Placeholder Title',
 1686             'description'           => 'Placeholder description.',
 1687             'sections'              => array(),
 1688             'required_capability'   => 'manage_options' 
 1689         
 1690         );
 1691         
 1692         $params = owa_wp_util::setDefaultParams( $defaults, $params );
 1693         $this->options = $options;
 1694         $this->ns               = $params['ns'];
 1695         $this->package          = $params['package'];
 1696         $this->module           = $params['module'];
 1697         $this->name             = $params['name'];
 1698     
 1699         if ( ! $params['page_slug'] ) {
 1700                         
 1701             $params['page_slug'] = $this->generatePageSlug();       
 1702         }
 1703         
 1704         $this->page_slug = $params['page_slug'];
 1705         
 1706         $this->default_options = array();
 1707         
 1708         $this->properties = $params;
 1709                 
 1710         owa_wp_util::addFilter('owa_wp_settings_field_types', array( $this, 'registerFieldTypes'), 10, 1);
 1711         
 1712         // add error display callback.
 1713         add_action( 'admin_notices', array( $this, 'displayErrorNotices' ) );
 1714     }
 1715     
 1716     public function registerFieldTypes( $types = array() ) {
 1717         
 1718         
 1719         $types['text'] = 'owa_wp_settings_field_text';
 1720         
 1721         $types['boolean'] = 'owa_wp_settings_field_boolean';
 1722             
 1723         $types['integer'] = 'owa_wp_settings_field_integer';
 1724         
 1725         $types['boolean_array'] = 'owa_wp_settings_field_booleanarray';
 1726         
 1727         $types['on_off_array'] = 'owa_wp_settings_field_onoffarray';
 1728         
 1729         $types['comma_separated_list'] = 'owa_wp_settings_field_commaseparatedlist';
 1730         
 1731         $types['select'] = 'owa_wp_settings_field_select';
 1732         
 1733         $types['textarea'] = 'owa_wp_settings_field_textarea';
 1734         
 1735         $types['url'] = 'owa_wp_settings_field_url';
 1736 
 1737         
 1738         return $types;
 1739     }
 1740     
 1741     public function get( $key ) {
 1742         
 1743         if (array_key_exists( $key, $this->properties ) ) {
 1744             
 1745             return $this->properties[ $key ];
 1746         } 
 1747     }
 1748     
 1749     public function generatePageSlug() {
 1750         
 1751         return sprintf( '%s-%s', $this->ns, $this->name );
 1752     }
 1753     
 1754     public function registerSettings() {
 1755 
 1756             register_setting( $this->getOptionGroupName(), 'owa_wp', array( $this, 'validateAndSanitize' ) );
 1757     }
 1758     
 1759     public function validateAndSanitize( $options ) {
 1760     
 1761         $sanitized = '';
 1762         
 1763         if ( is_array( $options ) ) {   
 1764             
 1765             $sanitized = array();
 1766             
 1767             foreach ( $this->fields as $k => $f ) {
 1768                 
 1769                 // if the option is present
 1770                 if ( array_key_exists( $k, $options ) ) {   
 1771                     
 1772                     $value = $options[ $k ] ;
 1773                     
 1774                     // check if value is required.
 1775                     if ( ! $value && $f->isRequired() ) {
 1776                         
 1777                         $f->addError( $k, $f->get('label_for'). ' field is required' );
 1778                         continue;
 1779                     }
 1780                     
 1781                     // sanitize value
 1782                     $value = $f->sanitize( $options[ $k ] );
 1783                     
 1784                     // validate value. Could be empty at this point.
 1785                     if ( $f->isValid( $value ) ) {
 1786                         //sanitize
 1787                         $sanitized[ $k ] =  $value;
 1788                     }
 1789                     
 1790                 } else {
 1791                 
 1792                     // set a false value in case it's a boollean type
 1793                     $sanitized[ $k ] = $f->setFalseValue();
 1794                 }
 1795             }           
 1796         }
 1797         
 1798         return $sanitized;
 1799     }
 1800     
 1801     public function getOptionGroupName() {
 1802         
 1803         return sprintf( '%s_group', $this->get('page_slug') );
 1804     }
 1805     
 1806     //
 1807      //Register a Settings Section with WordPress.
 1808      //
 1809      //
 1810     public function registerSection( $params ) {
 1811         
 1812         // todo: add in a class type lookup here to use a custom section object
 1813         // so that we can do custom rendering of section HTML if we 
 1814         // ever need to.
 1815         // $section = somemaplookup( $params['type']);
 1816         
 1817         $section = new owa_wp_settings_section($params);
 1818         
 1819         // Store the section object in case we need it later or want to inspect
 1820         $this->sections[ $section->get( 'id' ) ] = $section;
 1821         
 1822         // register the section with WordPress
 1823         add_settings_section( $section->get('id'), $section->get('title'), $section->get('callback'), $this->page_slug );
 1824     }
 1825     
 1826     public function echoHtml( $html ) {
 1827         
 1828         echo $html;
 1829     }
 1830     
 1831     public function registerField( $key, $params ) {
 1832         
 1833         // Add to params array
 1834         // We need to pack params because ultimately add_settings_field 
 1835         // can only pass an array to the callback function that renders
 1836         // the field. Sux. wish it would accept an object...
 1837             
 1838         $params['id'] = $key;
 1839         $params['package'] = $this->package;
 1840         $params['module'] = $this->module;
 1841         
 1842         // make field object based on type
 1843         
 1844         $types = apply_filters( 'owa_wp_settings_field_types', array() );
 1845         
 1846         $field = new $types[ $params['type'] ]($params, $this->options);
 1847         
 1848         if ( $field ) {
 1849             // park this field object for use later by validation and sanitization          
 1850             $this->fields[ $key ] = $field;
 1851                 
 1852             // register label formatter callback
 1853             $callback = $field->get( 'value_label_callback' );
 1854             if ( $callback ) {
 1855                 owa_wp_util::addFilter( $field->get( 'id' ) . '_field_value_label', $callback, 10, 1 );
 1856             }
 1857             // add setting to wordpress settings api
 1858             add_settings_field( 
 1859                 $key, 
 1860                 $field->get( 'title' ), 
 1861                 array( $field, 'render'), 
 1862                 $this->page_slug, 
 1863                 $field->get( 'section' ), 
 1864                 $field->getProperties() 
 1865             ); 
 1866         } else {
 1867             
 1868             error_log("No field of type {$params['type']} registered.");
 1869         }
 1870     }
 1871         
 1872     public function renderPage() {
 1873         
 1874         wp_enqueue_script('jquery','','','',true);
 1875         wp_enqueue_script('jquery-ui-core','','','',true);
 1876         wp_enqueue_script('jquery-ui-tabs','','','',true);
 1877         //add_settings_field( $id, $title, $callback, $page, $section = 'default', $args = array() )
 1878         
 1879         if ( ! current_user_can( $this->get('required_capability') ) ) {
 1880     
 1881             wp_die(__( 'You do not have sufficient permissions to access this page!' ) );
 1882         }
 1883     
 1884         echo '<div class="wrap">';
 1885         echo    '<div class="icon32" id="icon-options-general"><br></div>';
 1886         echo    sprintf('<h2>%s</h2>', $this->get( 'title') );
 1887         echo    $this->get('description');
 1888         
 1889         if ( $this->fields ) {
 1890             settings_errors();
 1891             echo    sprintf('<form id=%s" action="options.php" method="post">', $this->page_slug);
 1892             settings_fields( $this->getOptionGroupName() );
 1893             //do_settings_sections( $this->get('page_slug') );
 1894             $this->doTabbedSettingsSections( $this->get('page_slug') );
 1895             echo    '<p class="submit">';
 1896             echo    sprintf('<input name="Submit" type="submit" class="button-primary" value="%s" />', 'Save Changes' );
 1897             echo    '</p>';
 1898             echo    '</form>';
 1899         }
 1900 
 1901         echo    '</div>';
 1902     }
 1903     
 1904     ///
 1905      // Outputs Settings Sections and Fields
 1906      //
 1907      // Sadly this is a replacement for WP's do_settings_sections template function
 1908      // because it doesn't allows for filtered output which we need for adding tabs.
 1909      //
 1910      // var $page   string  name of the settings page.
 1911      //
 1912     public function doTabbedSettingsSections( $page ) {
 1913         
 1914         global $wp_settings_sections, $wp_settings_fields;
 1915  
 1916         if ( ! isset( $wp_settings_sections[$page] ) ) {
 1917         
 1918             return;
 1919         }
 1920         
 1921         echo '<div class="owa_wp_admin_tabs">';
 1922         echo '<h2 class="nav-tab-wrapper">';
 1923         echo '<ul style="padding:0px;margin:0px;">';
 1924         foreach ( (array) $wp_settings_sections[$page] as $section ) {
 1925             
 1926             echo  sprintf('<li class="nav-tab" style=""><a href="#%s" class="%s">%s</a></li>', $section['id'], '', $section['title']);
 1927             
 1928         }
 1929         echo '</ul>';
 1930         echo '</h2>';
 1931         
 1932         foreach ( (array) $wp_settings_sections[$page] as $section ) {
 1933             
 1934             echo sprintf( '<div id="%s">', $section['id'] );
 1935             if ( $section['title'] )
 1936                 echo "<h3>{$section['title']}</h3>\n";
 1937      
 1938             if ( $section['callback'] )
 1939                 call_user_func( $section['callback'], $section );
 1940      
 1941             if ( ! isset( $wp_settings_fields ) || !isset( $wp_settings_fields[$page] ) || !isset( $wp_settings_fields[$page][$section['id']] ) )
 1942                 continue;
 1943             echo '<table class="form-table">';
 1944             do_settings_fields( $page, $section['id'] );
 1945             echo '</table>';
 1946             echo '</div>';
 1947         }
 1948         echo '</div>';
 1949         
 1950         echo'   <script>
 1951                     jQuery(function() { 
 1952                     
 1953                         jQuery( ".owa_wp_admin_tabs" ).tabs({
 1954                              
 1955                             create: function(event, ui) {
 1956                                 
 1957                                 // CSS hackery to match up with WP built in tab styles.
 1958                                 jQuery(this).find("li a").css({"text-decoration": "none", color: "grey"});
 1959                                 ui.tab.find("a").css({color: "black"});
 1960                                 ui.tab.addClass("nav-tab-active");
 1961                                 // properly set the form action to correspond to active tab
 1962                                 // in case it is resubmitted
 1963                                 target = jQuery(".owa_wp_admin_tabs").parent().attr("action");
 1964                                 new_target = target + "" + window.location.hash;
 1965                                 jQuery(".owa_wp_admin_tabs").parent().attr("action", new_target);
 1966                             },
 1967                             
 1968                             activate: function(event, ui) {
 1969                                 
 1970                                 // CSS hackery to match up with WP built in tab styles.
 1971                                 ui.oldTab.removeClass("nav-tab-active");
 1972                                 ui.oldTab.find("a").css({color: "grey"});
 1973                                 ui.newTab.addClass("nav-tab-active");
 1974                                 ui.newTab.find("a").css({color: "black"});
 1975                                 
 1976                                 // get target tab nav link.
 1977                                 new_tab_anchor = ui.newTab.find("a").attr("href");
 1978                                 // set the url anchor
 1979                                 window.location.hash = new_tab_anchor;
 1980                                 // get current action attr of the form
 1981                                 target = jQuery(".owa_wp_admin_tabs").parent().attr("action");
 1982                                 // clear any existing hash from form target
 1983                                 if ( target.indexOf("#") > -1 ) {
 1984                                 
 1985                                     pieces = target.split("#");
 1986                                     new_target = pieces[0] + "" + new_tab_anchor;
 1987                                     
 1988                                 } else {
 1989                                 
 1990                                     new_target = target + "" + new_tab_anchor;
 1991                                 }
 1992                                 // add the anchor hash to the form action so that
 1993                                 // the user returns to the correct tab after submit
 1994                                 jQuery(".owa_wp_admin_tabs").parent().attr("action", new_target);
 1995                                 
 1996                             }
 1997                         });
 1998                     });
 1999                     
 2000             
 2001                 </script>';
 2002     }
 2003     
 2004     public function displayErrorNotices() {
 2005     
 2006         settings_errors( $this->page_slug );
 2007     }
 2008 }
 2009 
 2010 class owa_wp_settings_field {
 2011     
 2012     public $id;
 2013     
 2014     public $package;
 2015     
 2016     public $module;
 2017     
 2018     public $properties;
 2019     
 2020     public $options;
 2021     
 2022     //
 2023      // name of the validator callback to be used
 2024      //
 2025     public $validator_callback;
 2026     
 2027     //
 2028      // name of the santizer callback to be used
 2029      //
 2030     public $santizer_callback;
 2031     
 2032     public function __construct( $params = '', $options ) {
 2033         
 2034         $defaults = array(
 2035             
 2036             'title'         => 'Sample Title',
 2037             'type'          => 'text',
 2038             'section'       => '',
 2039             'default_value' => '',
 2040             'dom_id'        => '',
 2041             'name'          => '',
 2042             'id'            => '',
 2043             'package'       => '',
 2044             'module'        => '',
 2045             'required'      => false,
 2046             'label_for'     => ''
 2047             
 2048         );
 2049         
 2050         $params = owa_wp_util::setDefaultParams( $defaults, $params );
 2051         
 2052         $this->options = $options;
 2053         
 2054         $this->package      = $params['package'];
 2055         $this->module       = $params['module'];
 2056         $this->id           = $params['id'];
 2057         $this->properties   = $params;
 2058         
 2059         $this->properties['name'] = $this->setName();
 2060         $this->properties['dom_id'] = $this->setDomId();
 2061     }
 2062     
 2063     public function get( $key ) {
 2064         
 2065         if (array_key_exists( $key, $this->properties) ) {
 2066             
 2067             return $this->properties[ $key ];
 2068         }
 2069     }
 2070     
 2071     public function getProperties() {
 2072         
 2073         return $this->properties;
 2074     }
 2075     
 2076     public function setName( ) {
 2077         
 2078         return sprintf( 
 2079             '%s[%s]', 
 2080             'owa_wp', 
 2081             $this->id
 2082         );
 2083     }
 2084     
 2085     public function render( $field ) {
 2086         
 2087         return false;
 2088     }   
 2089     
 2090     public function setDomId( ) {
 2091         
 2092         return sprintf( 
 2093             '%s_%s', 
 2094             'owa_wp', 
 2095             $this->id
 2096         );
 2097     }   
 2098     
 2099     public function sanitize( $value ) {
 2100         
 2101         return $value;
 2102     }
 2103     
 2104     public function isValid( $value ) {
 2105         
 2106         return true;
 2107     }
 2108         
 2109     public function addError( $key, $message ) {
 2110         
 2111         add_settings_error(
 2112             $this->get( 'id' ),
 2113             $key,
 2114             $message,
 2115             'error'
 2116         );
 2117         
 2118     }
 2119     
 2120     public function setFalseValue() {
 2121         
 2122         return 0;
 2123     }
 2124     
 2125     public function isRequired() {
 2126         
 2127         return $this->get('required');
 2128     }
 2129     
 2130     public function getErrorMessage() {
 2131         
 2132         return $this->get('error_message');
 2133     }
 2134 }
 2135 
 2136 class owa_wp_settings_field_text extends owa_wp_settings_field {
 2137 
 2138     public function render( $attrs ) {
 2139     //print_r();
 2140         $value = $this->options[ $attrs['id'] ];
 2141         
 2142         if ( ! $value ) {
 2143             //print_r($this->properties);
 2144             //$value = $this->options[] ;
 2145         }
 2146         
 2147         if ( array_key_exists( 'length', $attrs ) ) {
 2148             
 2149             $size = $attrs['length'];   
 2150             
 2151         } else {
 2152             
 2153             $size = 30;
 2154         }
 2155         
 2156         
 2157             
 2158         
 2159         echo sprintf(
 2160             '<input name="%s" id="%s" value="%s" type="text" size="%s" /> ', 
 2161             esc_attr( $attrs['name'] ), 
 2162             esc_attr( $attrs['dom_id'] ),
 2163             esc_attr( $value ),
 2164             $size 
 2165         );
 2166         
 2167         echo sprintf('<p class="description">%s</p>', $attrs['description']);
 2168     }   
 2169     
 2170     public function sanitize( $value ) {
 2171         
 2172         return trim($value);
 2173     }
 2174 }
 2175 
 2176 class owa_wp_settings_field_url extends owa_wp_settings_field {
 2177 
 2178     public function render( $attrs ) {
 2179     
 2180         $value = $this->options[ $attrs['id'] ];
 2181                 
 2182         $size = $attrs['length'];
 2183         
 2184         if ( ! $size ) {
 2185             
 2186             $size = 60;
 2187         }
 2188         
 2189         echo sprintf(
 2190             '<input name="%s" id="%s" value="%s" type="text" size="%s" /> ', 
 2191             esc_attr( $attrs['name'] ), 
 2192             esc_attr( $attrs['dom_id'] ),
 2193             esc_attr( $value ),
 2194             $size 
 2195         );
 2196         
 2197         echo sprintf('<p class="description">%s</p>', $attrs['description']);
 2198     }   
 2199     
 2200     public function sanitize( $value ) {
 2201         
 2202         $value = trim( $value );
 2203         
 2204         $value = $url = filter_var( $value, FILTER_SANITIZE_URL );
 2205 
 2206 /*
 2207         if ( ! strpos( $value, '/', -1 ) ) {
 2208             
 2209             $value .= '/'; 
 2210         }
 2211 */
 2212             
 2213         return $value;
 2214     }
 2215     
 2216     public function isValid( $value ) {
 2217         
 2218     
 2219         if ( substr( $value, -4 ) === '.php' ) {
 2220             
 2221             $this->addError( 
 2222                 $this->get('dom_id'), 
 2223                 sprintf(
 2224                     '%s %s',
 2225                     $this->get( 'label_for' ),
 2226                     owa_wp_util::localize( 'URL should be the base directory of your OWA instance, not a file endpoint.' ) ) );
 2227                     
 2228             return false;
 2229         }
 2230         
 2231         if ( ! substr( $value, 0, 4 ) === "http" ) {
 2232             
 2233             $this->addError( 
 2234             $this->get('dom_id'), 
 2235             sprintf(
 2236                 '%s %s',
 2237                 $this->get( 'label_for' ),
 2238                 owa_wp_util::localize( 'URL scheme required. (i.e. http:// or https://)' ) ) );
 2239             
 2240             return false;
 2241         }
 2242             
 2243         if ( filter_var( $value, FILTER_VALIDATE_URL ) ) {
 2244             
 2245             return true;    
 2246             
 2247         } else {
 2248             
 2249             // not a valid url
 2250             $this->addError( 
 2251                     $this->get('dom_id'), 
 2252                     sprintf(
 2253                         '%s %s',
 2254                         $this->get( 'label_for' ),
 2255                         owa_wp_util::localize( 'Not a valid URL' ) ) );
 2256         }       
 2257     }
 2258     
 2259 }
 2260 
 2261 class owa_wp_settings_field_textarea extends owa_wp_settings_field {
 2262 
 2263     public function render( $attrs ) {
 2264     //print_r();
 2265         $value = $this->options[ $attrs['id'] ];
 2266         
 2267         echo sprintf(
 2268             '<textarea name="%s" rows="%s" cols="%s" />%s</textarea> ', 
 2269             esc_attr( $attrs['name'] ), 
 2270             esc_attr( $attrs['rows'] ),
 2271             esc_attr( $attrs['cols'] ),
 2272             esc_attr( $value ) 
 2273         );
 2274         
 2275         echo sprintf('<p class="description">%s</p>', $attrs['description']);
 2276     }   
 2277     
 2278     public function sanitize( $value ) {
 2279         
 2280         return trim($value);
 2281     }
 2282 }
 2283 
 2284 
 2285 
 2286 class owa_wp_settings_field_commaseparatedlist extends owa_wp_settings_field_text {
 2287     
 2288     public function sanitize( $value ) {
 2289         
 2290         $value = trim( $value );
 2291         $value = str_replace(' ', '', $value ); 
 2292         $value = trim( $value, ',');
 2293         
 2294         return $value;
 2295     }
 2296     
 2297     public function isValid( $value ) {
 2298         
 2299         $re = '/^\d+(?:,\d+)*$/';
 2300     
 2301         if ( preg_match( $re, $value ) ) {
 2302             
 2303             return true;
 2304         
 2305         } else {
 2306         
 2307             $this->addError( 
 2308                 $this->get('dom_id'), 
 2309                 sprintf(
 2310                     '%s %s',
 2311                     $this->get( 'label_for' ),
 2312                     owa_wp_util::localize( 'can only contain a list of numbers separated by commas.' ) 
 2313                 )
 2314             );
 2315         }
 2316     }
 2317 }
 2318 
 2319 class owa_wp_settings_field_onoffarray extends owa_wp_settings_field {
 2320 
 2321     public function render ( $attrs ) {
 2322         
 2323         // get persisted options
 2324         $values = $this->options[ $attrs['id'] ];
 2325         
 2326         // get the default options
 2327         //$defaults = pp_api::getDefaultOption( $this->package, $this->module, $attrs['id'] );
 2328         
 2329         $options = $attrs['options'];
 2330         
 2331         if ( ! $values ) {
 2332         
 2333             $values = $defaults;
 2334         }
 2335     
 2336         echo sprintf('<p class="description">%s</p>', $attrs['description']);
 2337         
 2338         foreach ( $options as $k => $label ) {
 2339             
 2340             $checked = '';
 2341             $check = false;
 2342             
 2343             if ( in_array( trim( $k ), array_keys( $values ), true ) && $values[ trim( $k ) ] == true ) {
 2344                 
 2345                 $check = true;
 2346             } 
 2347                 
 2348             $on_checked = '';
 2349             $off_checked = '';
 2350             
 2351             if ( $check ) {
 2352                 
 2353                 $on_checked = 'checked=checked';
 2354                 
 2355             } else {
 2356                 
 2357                 $off_checked = 'checked';
 2358             }
 2359             
 2360             //$callback = $this->get('value_label_callback');
 2361                 
 2362             //$dvalue_label = apply_filters( $this->get('id').'_field_value_label', $ovalue );
 2363             
 2364             echo sprintf(
 2365                 '<p>%s: <label for="%s_on"><input class="" name="%s[%s]" id="%s_on" value="1" type="radio" %s> On</label>&nbsp; &nbsp; ', 
 2366                 $label,
 2367                 esc_attr( $attrs['dom_id'] ),
 2368                 esc_attr( $attrs['name'] ), 
 2369                 esc_attr( $k ),
 2370                 esc_attr( $attrs['dom_id'] ),
 2371                 $on_checked
 2372             );
 2373             
 2374             echo sprintf(
 2375                 '<label for="%s_off"><input class="" name="%s[%s]" id="%s" value="0" type="radio" %s> Off</label></p>', 
 2376                 
 2377                 esc_attr( $attrs['dom_id'] ),
 2378                 esc_attr( $attrs['name'] ), 
 2379                 esc_attr( $k ),
 2380                 esc_attr( $attrs['dom_id'] ),
 2381                 $off_checked
 2382             );
 2383         }
 2384     }
 2385     
 2386     public function setFalseValue() {
 2387         
 2388         return array();
 2389     }
 2390 }
 2391 
 2392 class owa_wp_settings_field_booleanarray extends owa_wp_settings_field {
 2393 
 2394     public function render ( $attrs ) {
 2395         
 2396         // get persisted options
 2397         $values = $this->options[ $attrs['id'] ];
 2398         
 2399         // get the default options
 2400         //$defaults = pp_api::getDefaultOption( $this->package, $this->module, $attrs['id'] );
 2401         
 2402         if ( ! $values ) {
 2403         
 2404             $values = array();
 2405         }
 2406     
 2407         echo sprintf('<p class="description">%s</p>', $attrs['description']);
 2408         
 2409         foreach ( $defaults as $dvalue ) {
 2410             
 2411             $checked = '';
 2412             $check = in_array( trim($dvalue), $values, true ); 
 2413                 
 2414             if ( $check ) {
 2415                 
 2416                 $checked = 'checked="checked"';
 2417             }
 2418             
 2419             $callback = $this->get('value_label_callback');
 2420                 
 2421             $dvalue_label = apply_filters( $this->get('id').'_field_value_label', $dvalue );
 2422             
 2423             echo sprintf(
 2424                 '<p><input name="%s[]" id="%s" value="%s" type="checkbox" %s> %s</p>', 
 2425                 esc_attr( $attrs['name'] ), 
 2426                 esc_attr( $attrs['dom_id'] ),
 2427                 esc_attr( $dvalue ),
 2428                 $checked,
 2429                 esc_html( $dvalue_label )
 2430             );
 2431         }
 2432     }
 2433     
 2434     public function setFalseValue() {
 2435         
 2436         return array();
 2437     }
 2438 }
 2439 
 2440 class owa_wp_settings_field_integer extends owa_wp_settings_field_text {
 2441     
 2442     
 2443     public function sanitize( $value ) {
 2444         
 2445         return intval( trim( $value ) );
 2446     }
 2447     
 2448     public function isValid( $value ) {
 2449         
 2450         if ( is_numeric( $value ) && $value > $this->get('min_value') ) {
 2451             
 2452             return true;
 2453             
 2454         } else {
 2455         
 2456             $this->addError( 
 2457                 $this->get('dom_id'), 
 2458                 sprintf(
 2459                     '%s %s %s %s %s.',
 2460                     $this->get('label_for'),
 2461                     owa_wp_util::localize('must be a number between'),
 2462                     $this->get('min_value'),
 2463                     owa_wp_util::localize('and'),
 2464                     $this->get('max_value')
 2465                 )
 2466             );
 2467         }
 2468     }
 2469 }
 2470 
 2471 class owa_wp_settings_field_select extends owa_wp_settings_field {
 2472     
 2473     public function sanitize ( $value ) {
 2474         
 2475         return $value;
 2476     }
 2477     
 2478     public function render( $attrs ) {
 2479         
 2480         $selected = $this->options[ $attrs['id'] ];
 2481         
 2482         $options = $attrs['options'];
 2483         $options = apply_filters( 'owa_wp_settings_field_'.$attrs['id'] , $options );
 2484         
 2485         if ( $options) {
 2486             $opts = '<option value="">Select...</option>';
 2487             
 2488             foreach ($options as $option) {
 2489                 
 2490                 $selected_attr = '';
 2491                 
 2492                 if ($option['siteId'] === $selected) {
 2493                     
 2494                     $selected_attr = 'selected';
 2495                 }
 2496                 
 2497                 $opts .= sprintf(
 2498                     '<option value="%s" %s>%s</option> \n',
 2499                     $option['siteId'],
 2500                     $selected_attr,
 2501                     $option['label']
 2502                 );
 2503         
 2504             }
 2505         } else {
 2506             
 2507             $opts = '<option value="">No options are available.</option>';
 2508         }
 2509         
 2510         echo sprintf(
 2511             '<select id="%s" name="%s">%s</select>', 
 2512             
 2513             esc_attr( $attrs['dom_id'] ),
 2514             esc_attr( $attrs['name'] ), 
 2515             $opts
 2516         );
 2517         
 2518         echo sprintf('<p class="description">%s</p>', $attrs['description']);
 2519     
 2520     }
 2521 }
 2522 
 2523 class owa_wp_settings_field_boolean extends owa_wp_settings_field {
 2524     
 2525     public function isValid( $value ) {
 2526     
 2527         $value = intval($value);
 2528         
 2529         if ( $value === 1 || $value === 0 ) {
 2530             
 2531             return true;
 2532         } else {
 2533         
 2534             $this->addError( $this->get('dom_id'), $this->get('label_for') . ' ' . owa_wp_util::localize( 'field must be On or Off.' ) );
 2535         }
 2536 
 2537     }
 2538     
 2539     public function sanitize ( $value ) {
 2540         
 2541         return intval( $value );
 2542     }
 2543     
 2544     public function render( $attrs ) {
 2545         //print_r($attrs);
 2546         //print_r($this->options);
 2547         $value = $this->options[ $attrs['id'] ];
 2548         
 2549         if ( ! $value && ! is_numeric( $value )  ) {
 2550             
 2551             //$value = pp_api::getDefaultOption( $this->package, $this->module, $attrs['id'] );
 2552         }
 2553         
 2554         $on_checked = '';
 2555         $off_checked = '';
 2556         
 2557         if ( $value ) {
 2558             
 2559             $on_checked = 'checked=checked';
 2560             
 2561         } else {
 2562             
 2563             $off_checked = 'checked';
 2564         }
 2565         
 2566         echo sprintf(
 2567             '<label for="%s_on"><input class="" name="%s" id="%s_on" value="1" type="radio" %s> On</label>&nbsp; &nbsp; ', 
 2568             
 2569             esc_attr( $attrs['dom_id'] ),
 2570             esc_attr( $attrs['name'] ), 
 2571             esc_attr( $attrs['dom_id'] ),
 2572             $on_checked
 2573         );
 2574         
 2575         echo sprintf(
 2576             '<label for="%s_off"><input class="" name="%s" id="%s" value="0" type="radio" %s> Off</label>', 
 2577             esc_attr( $attrs['dom_id'] ),
 2578             esc_attr( $attrs['name'] ), 
 2579             esc_attr( $attrs['dom_id'] ),
 2580             $off_checked
 2581         );
 2582         
 2583         echo sprintf('<p class="description">%s</p>', $attrs['description']);
 2584     }
 2585 }
 2586 
 2587 class owa_wp_settings_section {
 2588     
 2589     public $properties;
 2590     
 2591     public function __construct( $params ) {
 2592     
 2593         $this->properties = array();
 2594         
 2595         $defaults = array(
 2596             
 2597             'id'            => '',
 2598             'title'         => '',
 2599             'callback'      => array( $this, 'renderSection'),
 2600             'description'   => ''
 2601         );
 2602         
 2603         $this->properties = owa_wp_util::setDefaultParams( $defaults, $params );
 2604     }
 2605     
 2606     public function get( $key ) {
 2607         
 2608         if ( array_key_exists( $key, $this->properties ) ) {
 2609             
 2610             return $this->properties[ $key ];
 2611         }
 2612     }
 2613     
 2614     //
 2615      // Renders the html of the section header
 2616      //
 2617      // Callback function for 
 2618      //
 2619      // wordpress passes a single array here that contains ID, etc..
 2620      //
 2621     public function renderSection( $arg ) {
 2622     
 2623         echo $this->get('description');
 2624     }
 2625 }
 2626 
 2627 ?>