self['DIR'] = $dir.'/'; $dex = count($splode)-1; $this->self['FOLDER'] = $splode[$dex]; if(strstr($this->self['DIR'],'wp-content/plugins/') or strstr($this->self['DIR'],'wp-content\\plugins\\')){ $this->self['PATH'] = plugins_url($this->self['FOLDER']).'/'; }else{ $this->self['PATH'] = $this->get_site_template_url().'/'; } if($prefix==''){$prefix = $this->last_page_in_url($this->self['DIR']);} $this->self['prefix'] = $prefix; $this->self['BAD_CHARS'] = array('•','
','
','<','>','&','\\','"',"'",';'); $this->self['NEW_CHARS'] = array('(_BL_)','(_BR_)','(_HR_)','(_LT_)','(_GT_)','(_AM_)','(_BS_)','(_DQ_)','(_SQ_)','(_SC_)'); $this->self['BAD_CHARS_64'] = array('•','
','
','<','>','&','\\','"',"'",';','/','+'); $this->self['NEW_CHARS_64'] = array('(_BL_)','(_BR_)','(_HR_)','(_LT_)','(_GT_)','(_AM_)','(_BS_)','(_DQ_)','(_SQ_)','(_SC_)','(_FS_)','(_PL_)'); $this->self['TURNOFFS'] = array(); } // Bridge for communication between JS and this PHP class. Only runs methods named/designated specifically for receiving these communications. function ajax_communication(){ $command = $this->get_value($_POST,'command'); if(substr($command,0,5)=='ajax_'){ if(method_exists($this,$command)){ $this->runit($command,$_POST); } } } // Get the page URL across a variety of server types. function current_page_url($comm='') { $pageURL = 'http'; if( isset($_SERVER["HTTPS"]) ) { if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";} } $pageURL .= "://"; if ($_SERVER["SERVER_PORT"] != "80") { $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"]; } else { $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]; } if($comm=='base'){ $exp = explode('?',$pageURL); return $exp[0]; } return $pageURL; } // Add a string to a string with a delimiter if it is not blank. function delimitit($str,$delim=',',$val=''){ if($str!=''){$str .= $delim;} $str .= $val; return $str; } // Simplify the process of adding filters by running local methods named for them. function filter_handler($pass,$prio=10,$accs=1){add_filter($pass,array(&$this,'wp_'.$pass),$prio,$accs);} // Call a function/method by name by first checking if it exists within the class, then if it exists in the base file... return the function's return value. function function_call($fct,$pass=''){ if(method_exists($this,$fct)){ if($pass!=''){ return call_user_func(array($this, $fct), $pass); }else{ return call_user_func(array($this, $fct)); } }else if(function_exists($fct)){ if($pass!=''){ return call_user_func($fct,$pass); }else{ return call_user_func($fct); } } return $fct; } // First check if Yoast WPSEO is sintalled and is handling breadcrumbs, if not then we generate them using in-line markups that can be turned off per registered setting. function generate_breadcrumbs(){ if(is_home() or is_front_page()){return '';} if(function_exists('yoast_breadcrumb')){ $crumbs = yoast_breadcrumb('','',false); if($crumbs!=''){ $crumbs = preg_replace('!xmlns:v="(.*?)"!s','',$crumbs); $crumbs = preg_replace('!typeof="(.*?)"!s','',$crumbs); $crumbs = preg_replace('!property="(.*?)"!s','',$crumbs); $crumbs = preg_replace('!rel="(.*?)"!s','',$crumbs); return ''; } } $RAT = ''; $blist = $this->get_markup('BreadcrumbList','type'); $llist = $this->get_markup('ListItem','type'); $aline = $this->get_markup('url','rel'); $iline = $this->get_markup('item','prop'); $nline = $this->get_markup('name','prop'); $markup = false;if($this->inline_markup('yes')=='yes'){$markup = true;} $RAT .= ''; return $RAT; } // Simplified form field function, what more to say? function generate_field($data,$wrap=true){ $RAT = ''; $type = $this->get_value($data,'type'); $name = $this->get_value($data,'name'); $fid = $this->get_value($data,'id'); $val = $this->get_value($data,'value'); $filter = $this->get_value($data,'filter'); $include = $this->get_value($data,'include'); if(get_option($fid)!=''){$val = stripslashes(get_option($fid));} // if($filter!=''){$filter = ' onkeypress="return inputfilter_'.$filter.'(event);"';} $filter = '';// TASK - input filter not working $filter .= $include; if($type=='hidden'){ $RAT .= ''; }else if($type=='button'){ $RAT .= ''; }else if($type=='text'){ $RAT .= ''; }else if($type=='number'){ $RAT .= ''; }else if($type=='textarea'){ $RAT .= ' '; }else if($type=='select'){ $opts = $this->get_value($data,'options',array()); if(count($opts)>0){ $RAT .= ''; } }else if($type=='checkbox'){ if($val!=''){ $checked = ' checked="checked"'; }else{ $checked = ""; } $RAT .= ''; }else if($type=='pass'){ $RAT .= $this->get_value($data,'pass'); } return $RAT; } // Get attachment id from image source and return image metadata. function get_attachment_data_by_src($src,$stat=''){ $attachment_id = attachment_url_to_postid($src); return wp_get_attachment_metadata($attachment_id,true); } // Get the registered setting for the separator, then if it is a Fontawesome icon code generate it as such. function get_breadcrumb_separator(){ $sep = $this->htmlout($this->get_customizer_setting('seo_breadcrumbsep')); if(substr($sep,0,3)=='fa-'){return '';} return ''.$sep.''; } // Retrieve the excerpt for a post and concatenate it by word count. function get_excerpt_by_id($post_id,$excerpt_length=20){ $the_post = get_post($post_id); //Gets post ID $the_excerpt = $the_post->post_content; //Gets post_content to be used as a basis for the excerpt $the_excerpt = strip_tags(strip_shortcodes($the_excerpt)); //Strips tags and images $the_excerpt = $this->string_limit_words($the_excerpt,$excerpt_length); return $the_excerpt; } // Retrieve the featured thumbnail and return either the source URL or an array with width, height and url. function get_featured_image($post_id,$how=''){ if(has_post_thumbnail($post_id)){ $imgid = get_post_thumbnail_id($post_id); $img = wp_get_attachment_url($imgid); $imgdata = wp_get_attachment_metadata($imgid,true); $iwid = $this->get_value($imgdata,'width'); $ihit = $this->get_value($imgdata,'height'); if($iwid!=''){$imgwid = $iwid;} if($ihit!=''){$imgwid = $ihit;} if($how=='info'){return array('url'=>$img,'width'=>$iwid,'height'=>$ihit);} return $img; } return ''; } // Return a array of icons available to the current version of fontawesome. function get_fontawesome_icons(){ if(isset($this->self['FONT_AWESOME_ICONS'])){return $this->self['FONT_AWESOME_ICONS'];} // icon base from version 4.7.0 $raw = '500px,address-book,address-book-o,address-card,address-card-o,adjust,adn,align-center,align-justify,align-left,align-right,amazon,ambulance,american-sign-language-interpreting,anchor,android,angellist,angle-double-down,angle-double-left,angle-double-right,angle-double-up,angle-down,angle-left,angle-right,angle-up,apple,archive,area-chart,arrow-circle-down,arrow-circle-left,arrow-circle-o-down,arrow-circle-o-left,arrow-circle-o-right,arrow-circle-o-up,arrow-circle-right,arrow-circle-up,arrow-down,arrow-left,arrow-right,arrow-up,arrows,arrows-alt,arrows-h,arrows-v,asl-interpreting,assistive-listening-systems,asterisk,at,audio-description,automobile,backward,balance-scale,ban,bandcamp,bank,bar-chart,bar-chart-o,barcode,bars,bath,bathtub,battery,battery-0,battery-1,battery-2,battery-3,battery-4,battery-empty,battery-full,battery-half,battery-quarter,battery-three-quarters,bed,beer,behance,behance-square,bell,bell-o,bell-slash,bell-slash-o,bicycle,binoculars,birthday-cake,bitbucket,bitbucket-square,bitcoin,black-tie,blind,bluetooth,bluetooth-b,bold,bolt,bomb,book,bookmark,bookmark-o,braille,briefcase,btc,bug,building,building-o,bullhorn,bullseye,bus,buysellads,cab,calculator,calendar,calendar-check-o,calendar-minus-o,calendar-o,calendar-plus-o,calendar-times-o,camera,camera-retro,car,caret-down,caret-left,caret-right,caret-square-o-down,caret-square-o-left,caret-square-o-right,caret-square-o-up,caret-up,cart-arrow-down,cart-plus,cc,cc-amex,cc-diners-club,cc-discover,cc-jcb,cc-mastercard,cc-paypal,cc-stripe,cc-visa,certificate,chain,chain-broken,check,check-circle,check-circle-o,check-square,check-square-o,chevron-circle-down,chevron-circle-left,chevron-circle-right,chevron-circle-up,chevron-down,chevron-left,chevron-right,chevron-up,child,chrome,circle,circle-o,circle-o-notch,circle-thin,clipboard,clock-o,clone,close,cloud,cloud-download,cloud-upload,cny,code,code-fork,codepen,codiepie,coffee,cog,cogs,columns,comment,comment-o,commenting,commenting-o,comments,comments-o,compass,compress,connectdevelop,contao,copy,copyright,creative-commons,credit-card,credit-card-alt,crop,crosshairs,css3,cube,cubes,cut,cutlery,dashboard,dashcube,database,deaf,deafness,dedent,delicious,desktop,deviantart,diamond,digg,dollar,dot-circle-o,download,dribbble,drivers-license,drivers-license-o,dropbox,drupal,edge,edit,eercast,eject,ellipsis-h,ellipsis-v,empire,envelope,envelope-o,envelope-open,envelope-open-o,envelope-square,envira,eraser,etsy,eur,euro,exchange,exclamation,exclamation-circle,exclamation-triangle,expand,expeditedssl,external-link,external-link-square,eye,eye-slash,eyedropper,fa,facebook,facebook-f,facebook-official,facebook-square,fast-backward,fast-forward,fax,feed,female,fighter-jet,file,file-archive-o,file-audio-o,file-code-o,file-excel-o,file-image-o,file-movie-o,file-o,file-pdf-o,file-photo-o,file-picture-o,file-powerpoint-o,file-sound-o,file-text,file-text-o,file-video-o,file-word-o,file-zip-o,files-o,film,filter,fire,fire-extinguisher,firefox,first-order,flag,flag-checkered,flag-o,flash,flask,flickr,floppy-o,folder,folder-o,folder-open,folder-open-o,font,font-awesome,fonticons,fort-awesome,forumbee,forward,foursquare,free-code-camp,frown-o,futbol-o,gamepad,gavel,gbp,ge,gear,gears,genderless,get-pocket,gg,gg-circle,gift,git,git-square,github,github-alt,github-square,gitlab,gittip,glass,glide,glide-g,globe,google,google-plus,google-plus-circle,google-plus-official,google-plus-square,google-wallet,graduation-cap,gratipay,grav,group,h-square,hacker-news,hand-grab-o,hand-lizard-o,hand-o-down,hand-o-left,hand-o-right,hand-o-up,hand-paper-o,hand-peace-o,hand-pointer-o,hand-rock-o,hand-scissors-o,hand-spock-o,hand-stop-o,handshake-o,hard-of-hearing,hashtag,hdd-o,header,headphones,heart,heart-o,heartbeat,history,home,hospital-o,hotel,hourglass,hourglass-1,hourglass-2,hourglass-3,hourglass-end,hourglass-half,hourglass-o,hourglass-start,houzz,html5,i-cursor,id-badge,id-card,id-card-o,ils,image,imdb,inbox,indent,industry,info,info-circle,inr,instagram,institution,internet-explorer,intersex,ioxhost,italic,joomla,jpy,jsfiddle,key,keyboard-o,krw,language,laptop,lastfm,lastfm-square,leaf,leanpub,legal,lemon-o,level-down,level-up,life-bouy,life-buoy,life-ring,life-saver,lightbulb-o,line-chart,link,linkedin,linkedin-square,linode,linux,list,list-alt,list-ol,list-ul,location-arrow,lock,long-arrow-down,long-arrow-left,long-arrow-right,long-arrow-up,low-vision,magic,magnet,mail-forward,mail-reply,mail-reply-all,male,map,map-marker,map-o,map-pin,map-signs,mars,mars-double,mars-stroke,mars-stroke-h,mars-stroke-v,maxcdn,meanpath,medium,medkit,meetup,meh-o,mercury,microchip,microphone,microphone-slash,minus,minus-circle,minus-square,minus-square-o,mixcloud,mobile,mobile-phone,modx,money,moon-o,mortar-board,motorcycle,mouse-pointer,music,navicon,neuter,newspaper-o,object-group,object-ungroup,odnoklassniki,odnoklassniki-square,opencart,openid,opera,optin-monster,outdent,pagelines,paint-brush,paper-plane,paper-plane-o,paperclip,paragraph,paste,pause,pause-circle,pause-circle-o,paw,paypal,pencil,pencil-square,pencil-square-o,percent,phone,phone-square,photo,picture-o,pie-chart,pied-piper,pied-piper-alt,pied-piper-pp,pinterest,pinterest-p,pinterest-square,plane,play,play-circle,play-circle-o,plug,plus,plus-circle,plus-square,plus-square-o,podcast,power-off,print,product-hunt,puzzle-piece,qq,qrcode,question,question-circle,question-circle-o,quora,quote-left,quote-right,ra,random,ravelry,rebel,recycle,reddit,reddit-alien,reddit-square,refresh,registered,remove,renren,reorder,repeat,reply,reply-all,resistance,retweet,rmb,road,rocket,rotate-left,rotate-right,rouble,rss,rss-square,rub,ruble,rupee,s15,safari,save,scissors,scribd,search,search-minus,search-plus,sellsy,send,send-o,server,share,share-alt,share-alt-square,share-square,share-square-o,shekel,sheqel,shield,ship,shirtsinbulk,shopping-bag,shopping-basket,shopping-cart,shower,sign-in,sign-language,sign-out,signal,signing,simplybuilt,sitemap,skyatlas,skype,slack,sliders,slideshare,smile-o,snapchat,snapchat-ghost,snapchat-square,snowflake-o,soccer-ball-o,sort,sort-alpha-asc,sort-alpha-desc,sort-amount-asc,sort-amount-desc,sort-asc,sort-desc,sort-down,sort-numeric-asc,sort-numeric-desc,sort-up,soundcloud,space-shuttle,spinner,spoon,spotify,square,square-o,stack-exchange,stack-overflow,star,star-half,star-half-empty,star-half-full,star-half-o,star-o,steam,steam-square,step-backward,step-forward,stethoscope,sticky-note,sticky-note-o,stop,stop-circle,stop-circle-o,street-view,strikethrough,stumbleupon,stumbleupon-circle,subscript,subway,suitcase,sun-o,superpowers,superscript,support,table,tablet,tachometer,tag,tags,tasks,taxi,telegram,television,tencent-weibo,terminal,text-height,text-width,th,th-large,th-list,themeisle,thermometer,thermometer-0,thermometer-1,thermometer-2,thermometer-3,thermometer-4,thermometer-empty,thermometer-full,thermometer-half,thermometer-quarter,thermometer-three-quarters,thumb-tack,thumbs-down,thumbs-o-down,thumbs-o-up,thumbs-up,ticket,times,times-circle,times-circle-o,times-rectangle,times-rectangle-o,tint,toggle-down,toggle-left,toggle-off,toggle-on,toggle-right,toggle-up,trademark,train,transgender,transgender-alt,trash,trash-o,tree,trello,tripadvisor,trophy,truck,try,tty,tumblr,tumblr-square,turkish-lira,tv,twitch,twitter,twitter-square,umbrella,underline,undo,universal-access,university,unlink,unlock,unlock-alt,unsorted,upload,usb,usd,user,user-circle,user-circle-o,user-md,user-o,user-plus,user-secret,user-times,users,vcard,vcard-o,venus,venus-double,venus-mars,viacoin,viadeo,viadeo-square,video-camera,vimeo,vimeo-square,vine,vk,volume-control-phone,volume-down,volume-off,volume-up,warning,wechat,weibo,weixin,whatsapp,wheelchair,wheelchair-alt,wifi,wikipedia-w,window-close,window-close-o,window-maximize,window-minimize,window-restore,windows,won,wordpress,wpbeginner,wpexplorer,wpforms,wrench,xing,xing-square,y-combinator,y-combinator-square,yahoo,yc,yc-square,yelp,yen,yoast,youtube,youtube-play,youtube-square'; $icons = array(); $raws = explode(',',$raw); foreach($raws as $icn){$icons[] = 'fa-'.$icn;} return $icons; } // Return the current URL for loading the fontawesome library from the bootstrap CDN. function get_fontawesome_url(){$ver = $this->get_fontawesome_version();return 'https://maxcdn.bootstrapcdn.com/font-awesome/'.$ver.'/css/font-awesome.min.css';} // Return the curent version of fontawesome and initializes the data as an option that can be updated with new versions. function get_fontawesome_version(){ if(isset($this->self['FONT_AWESOME_VERSION'])){return $this->self['FONT_AWESOME_VERSION'];} return '4.7.0'; } // Retrieve width, height and mime type from an image by source URL. function get_image_info($image,$field){ if($image==''){return '';} $imgdata = $this->get_attachment_data_by_src($image); if($field=='width'){return $this->get_value($imgdata,'width');} if($field=='height'){return $this->get_value($imgdata,'height');} } // Used to add markups to objects in the DOM after checking if they are turned off by setting. function get_markup($mark,$how,$what=''){ if($this->inline_markup('yes')==''){return '';} if($how=='type'){ return ' itemscope itemtype="http://schema.org/'.$mark.'"'; }else if($how=='prop'){ return ' itemprop="'.$mark.'"'; }else if($how=='rel'){ return ' rel="v:'.$mark.'"'; } return ''; } // Return the page title across different page/post types. This simplifies development with one centralized function call. function get_page_title($id=NULL){ if(is_category() or is_tax()){return $this->taxes(array('com'=>'title'));} if(is_tag()){$tag = get_tag($id);if(isset($tag->name)){return $tag->name;}else{return '';}} return get_the_title($id); } // Return category data for a post in a number of ways, from full array to a particular variable/value. function get_post_category_data($post_id=NULL,$how='',$what=''){ if($post_id==NULL){$post_id = get_the_ID();} $cats = array(); $cat = ''; $cid = ''; $dep = 0; $ctgy = get_the_category($post_id); if($how=='all'){ $cats = $ctgy; }else if($how=='base'){ $dep = 1000; }else{ $dep = -1; } foreach($ctgy as $rex=>$vex){ $catid = $vex->cat_ID; $ndep = $this->taxes(array('com'=>'depth','id'=>$catid)); if($dep!=$ndep){ if($how=='all'){ if($cat!=''){$cat .= ',';} $cat .= $vex->cat_name; if($cid!=''){$cid .= ',';} $cid .= $catid; }else{ $isdep = false; if($how=='base'){ if($ndep<$dep){ $isdep = true; } }else{ if($ndep>$dep){ $isdep = true; } } if($isdep==true){ $dep = $ndep; $cat = $vex->cat_name; $cid = $catid; $cats = $vex; } } } } if($what=='array'){ return $cats; }else if($what=='id'){ return $cid; }else{ return $cat; } } // These two functions consolodate two WP steps into one. function get_site_base_url(){return esc_url(home_url());} function get_site_template_url(){return esc_url(get_template_directory_uri());} // Get a value from an array or object across nested levels of depth. function get_value($incoming,$var,$def=''){ if(is_object($incoming) and is_array($var)){$incoming = $this->object_to_array($incoming);} if (is_object($incoming)) { if(isset($incoming->$var)){ return $incoming->$var; } }else{ if(is_array($var)){ if(count($var)>0){ $tar = $incoming; foreach($var as $far){ if(isset($tar[$far])){ $tar = $tar[$far]; }else{ return $def; } } return $tar; } }else{ if(isset($incoming[$var])){ return $incoming[$var]; } } } return $def; } // Simple mysql encoding of a string without using slashes. This is more reliable and works across PHP and JS. function htmlin($nstr) { if(is_array($nstr)){ if(count($nstr)>0){ foreach($nstr as $dex=>$data){ $nstr[$dex] = $this->htmlin($data); } } }else{ for($cc=0;$ccself['BAD_CHARS']);$cc++){ $narr = explode($this->self['BAD_CHARS'][$cc],$nstr); $nstr = implode($this->self['NEW_CHARS'][$cc],$narr); } } return $nstr; } // Decoding of a string that was encoded with htmlin(). function htmlout($nstr) { if(is_array($nstr)){ if(count($nstr)>0){ foreach($nstr as $dex=>$data){ $nstr[$dex] = $this->htmlout($data); } } }else{ for($cc=0;$ccself['NEW_CHARS']);$cc++){ $narr = explode($this->self['NEW_CHARS'][$cc],$nstr); $nstr = implode($this->self['BAD_CHARS'][$cc],$narr); } $nstr = stripslashes($nstr); } return $nstr; } // The main init() function, added as an action in the base level of the functions file. function init(){ if(method_exists($this,'registration')){$this->registration();} if($this->has_customizer_settings()){ add_action('customize_register',array(&$this,'init_customizer_settings')); } if($this->has_cron()){ add_filter( 'cron_schedules', array(&$this,'custom_cron_schedules')); foreach($this->self['cron_list'] as $fct=>$interval){ $action = $fct.'_cron'; add_action($action, $fct); if(!wp_next_scheduled($action)){ wp_schedule_event( time(), $interval, $action); } } } if($this->using_meta() and $this->is_editor('post')) { add_action('edit_form_advanced',array(&$this,'add_post_editor')); add_action('edit_page_form',array(&$this,'add_post_editor')); add_action('edit_post',array(&$this,'update_post'),10,2); } $this->runit('extends_init'); } // Verify that the current page is a specific WP-Admin page, currently used to check for post editor. function is_editor($page){ global $pagenow; if($pagenow==$page.'.php'){return true;} return false; } // Check if linline markups are turned off, hooked by functions that utilize markups. function inline_markup($is,$isnt=''){ $in = false; $isinline = $this->get_customizer_setting('seo_inlinemarkup'); if($isinline!=''){$in = true;} if($in==true){return $is;} return $isnt; } // Check if the user is logged in and has Administraotor level access. function is_user_admin(){ $user = wp_get_current_user(); if($user->exists() and current_user_can('manage_options')){return true;} return false; } // Break down the URL and return the page slug found after the last / slash. function last_page_in_url($url=NULL){ if($url==NULL){$url = $this->current_page_url();} $drop = explode('?',$url); $splt = explode('/',$drop[0]); $cnt = count($splt)-1; $last = $splt[$cnt]; if($last==''){ $last = $splt[($cnt-1)]; } return $last; } // Convert a PHP object to an array. function object_to_array($d){if(is_object($d)){$d = get_object_vars($d);}if(is_array($d)){return array_map(array($this,'object_to_array'),$d);}else{return $d;}} // Run a function/method by name by first checking if it exists within the class, then if it exists in the base file. function runit($fct,$pass=''){ if(method_exists($this,$fct)){ if($pass!=''){ call_user_func(array($this, $fct), $pass); }else{ call_user_func(array($this, $fct)); } }else if(function_exists($fct)){ if($pass!=''){ call_user_func($fct,$pass); }else{ call_user_func($fct); } } } // Find and return a portion of a string that falls between a starting string and an ending string. Used in various places for removing HTML tags and attributes that invalidate Google AMP compliance. function scrape_between($txt,$start,$end){ $splode = explode($start,$txt); $part = $this->get_value($splode,1); $parts = explode($end,$part); return $parts[0]; } // Check if a value exists in an array and if that value is true. No nested or object checking here, not currently in use. function set_and_true($arr,$var){if(isset($arr[$var])){if($arr[$var]==true){return true;}}return false;} // Concatenate a string by word count. function string_limit_words($string, $word_limit){ $words = explode(' ', $string, ($word_limit + 1)); if(count($words) > $word_limit) array_pop($words); return implode(' ', $words); } // Return various pieces of category/taxonomy data. This centralized function makes development easier. function taxes($params){ $id = $this->get_value($params,'id'); $com = $this->get_value($params,'com'); $cat = $this->get_value($params,'category'); if($id=='' or $id==NULL){ if($cat==''){$cat = single_term_title("", false);} $id = get_cat_ID($cat); } if($com=='id'){ return $id; }else if($com=='title'){ return get_cat_name($id); }else if($com=='description'){ return category_description($id); }else if($com=='depth'){ $dep = 0; $category = get_category($id); for($i=1;$i<=9;$i++){ if($category->category_parent){ $category = get_category($category->category_parent); $dep = $i; } } return $dep+1; }else if($com=='data'){ $category_data = get_term_by('term_id',$id,'category'); $var = $this->get_value($params,'var'); if($var==''){return $category_data;} if(is_object($category_data)){ return $category_data->$var; }else{ return $this->get_value($category_data,$var); } }else if($com=='link'){ $catslug = $this->taxes(array('com'=>'path','id'=>$id)); return $this->get_site_base_url().'/category/'.$catslug; }else if($com=='path'){ $data = $this->taxes(array('com'=>'data','id'=>$id)); $pslug = $this->get_value($data,'slug'); $parent = $this->get_value($data,'parent',0); $slug = $this->get_value($params,'slug'); if($pslug!=''){ $slug = $pslug.'/'.$slug; if($parent!=0){$slug = $this->taxes(array('com'=>'path','id'=>$parent,'slug'=>$slug));} } return $slug; }else if($com=='crumbs'){ $link = $this->taxes(array('com'=>'link','id'=>$id)); $data = $this->taxes(array('com'=>'data','id'=>$id)); $slug = $this->get_value($data,'slug'); $parent = $this->get_value($data,'parent'); $name = $this->get_value($data,'name'); $count = $this->get_value($data,'count'); $strg = $this->get_value($params,'text'); $how = $this->get_value($params,'how'); $markup = $this->get_value($params,'markup',true); if($markup==false){ $href = ''.$name.''; $blank = ''.$name.''; }else{ $href = ''.$name.''; $href = ''.$name.''; $blank = ''.$name.''; } if($slug!=''){ if($strg=='' and $how==''){ $strg = $blank; }else{ $strg = $href.' '.$this->get_breadcrumb_separator().' '.$strg; } if($parent!=0){$strg = $this->taxes(array('com'=>'crumbs','id'=>$parent,'text'=>$strg,'how'=>$how,'markup'=>$markup));} } return $strg; } return ''; } // Basic testing function, used to display a nested data object. function test_array($arr=array(),$how='echo',$px=0){ if($how!='override' and $this->debugging()==false){return '';} if(is_string($arr)){ if($how=='echo'){ echo $arr; } return $arr; } if(is_object($arr)){$arr = $this->object_to_array($arr);} $RAT = ''; if(is_array($arr)){ if(count($arr)>0){ foreach($arr as $k=>$v){ if(is_array($v) or is_object($v)){ if($how=='echo' or $how=='override'){ if($how=='js'){ echo $k.' = '; }else{ echo '
['.$k.'] '; } $this->test_array($v,$how,$px+20); if($how!='js'){echo '
';} }else{ if($how=='js'){ echo $k.' = '; }else{ $RAT .= '
['.$k.'] '; } $RAT .= $this->test_array($v,$how,$px+20); if($how!='js'){$RAT .= '
';} } }else{ if($how=='js'){ $div = $k.' = '.$v.'\n'; }else if($how=='raw'){ $div = '['.$k.']'.$v; }else{ $div = '
['.$k.'] '.$v.'
'; } if($how=='echo' or $how=='override'){ echo $div; }else{ $RAT .= $div; } } } } } return $RAT; } // Echo the page title across different page/post types. This simplifies development with one centralized function call. function theme_page_title($post_id=NULL){ if(is_category()){single_cat_title();} elseif(is_tag()){single_tag_title();} elseif(is_author()){global $post;$author_id = $post->post_author;the_author_meta('display_name', $author_id);} elseif(is_day()){the_time('l, F j, Y');} elseif(is_month()){the_time('F Y');} elseif(is_year()){the_time('Y');} elseif(is_single() or is_page()){the_title();} } // Remove dashes from a string and return the string with each word capitalized. function ucwords_undash($input){return ucwords(str_replace('-',' ',$input));} // Validate a URL by checking it's headers. function url_exists($url){ $headers=get_headers($url); return stripos($headers[0],"200 OK")?true:false; } // Retrieve text/HTML from a URL. This function consolodates the two steps necessary to gather the data and return only the text. This is used to check our API for updates to the Fontawesome version/list. function url_get_contents($url){ $response = wp_remote_get($url); return $this->get_value($response,'body'); } // Check if a nav menu is available, assigned, and/or empty. These checks are useful in various situations. function use_nav_menu($location,$com=''){ $isok = false; if(has_nav_menu($location)){ if($com=='assigned'){return true;} if(wp_nav_menu(array('theme_location'=>$location,'echo'=>false))!==false){ $isok = true; }else{ if($com=='empty'){return true;} } } return $isok; } // Check if a string fits the valid URL structure. function validate_url($string){ if(filter_var($string, FILTER_VALIDATE_URL)){return true;} return false; } //*************************************** // CUSTOMIZER REGISTRATION AND HANDLING //*************************************** // These functions simplify the registration of WP Customizer settings and make the data readily available to our framework. // Create a section in the customizer, each setting will be assigned to it's section in the order they are registered. function register_customizer_section($sect,$params=array()){$this->self['customizer_sections'][$sect] = $params;} // Add a setting to the Customizer and store the data for use by the framework. Centralizing and storing the data in the class speeds up processing time. function register_customizer_setting($setting,$params=array()){$this->self['customizer_settings'][$setting] = $params;} // Check if any settings have been registered, used to check if handling is necessary. function has_customizer_settings(){if(isset($this->self['customizer_settings'])){if(count($this->self['customizer_settings'])>0){return true;}}return false;} // Pull the Customizer setting, then if blank run through default values provided by the funtion call then by registration. Registering default values makes development easier. function get_customizer_setting($setting,$default=NULL){ $mod = get_theme_mod($setting); if($mod==''){ if($default!=NULL){ $mod = $default; }else{ if(isset($this->self['customizer_settings'][$setting])){ $mod = $this->get_value($this->self['customizer_settings'][$setting],'default'); } } } $mod = $this->htmlout($mod); return $mod; } // Return an array with registration data for a particular setting. function get_customizer_settings($mod){return $this->get_value($this->self['customizer_settings'],$mod,array());} // Handle the WP Customizer setup of sections and settings using the registered data. This is added as a WordPress action by the theme's init() function. function init_customizer_settings($wp_customize){ // section priority can be set, but is built in registration order if not set $secprio = 1; foreach($this->self['customizer_sections'] as $section=>$data){ $title = $this->get_value($data,'title'); $prio = $this->get_value($data,'priority'); if($prio==''){$prio = $secprio;$secprio += 1;} $wp_customize->add_section($section,array('title'=>$title,'priority'=>$prio)); } // these default sections are not needed, the colors adn images are organized into the registered sections $wp_customize->remove_section('colors'); $wp_customize->remove_section('header_image'); $wp_customize->remove_section('background_image'); // reorganize settings by section, it ignores setting that did not register a section $bysect = array(); foreach($this->self['customizer_settings'] as $setting=>$data){ $sect = $this->get_value($data,'section'); if($sect!=''){ if(!isset($bysect[$sect])){$bysect[$sect] = array();} $bysect[$sect][$setting] = $data; } } // create settings while setting priority to display in order that settings were registered if(count($bysect)>0){ foreach($bysect as $sect=>$sets){ $dex = 1; foreach($sets as $setting=>$data){ $data['priority'] = $dex; $dex += 1; $this->create_customizer_setting($setting,$data); } } } } // Add settings and controls to the Customizer from registered data. function create_customizer_setting($id,$params){ global $wp_customize; $type = $this->get_value($params,'type'); $sec = $this->get_value($params,'section'); $title = $this->get_value($params,'title'); $def = $this->get_value($params,'default'); $prio = $this->get_value($params,'priority'); $choices = $this->get_value($params,'choices'); $desc = $this->get_value($params,'description'); $live = $this->get_value($params,'live',false); $theme = $this->self['prefix']; if($id!='' and $type!='' and $sec!=''){ $transport = 'refresh'; if($live==true){$transport = 'postMessage';} if($type=='color'){ $wp_customize->add_setting($id,array('default' => $def , 'transport' => $transport , 'sanitize_callback' => 'sanitize_hex_color')); }else{ $wp_customize->add_setting($id,array('default' => $def , 'transport' => $transport , 'sanitize_callback' => 'sanitize_text_field')); } $pass = array('label'=>$title,$theme,'section'=>$sec,'settings'=>$id); if($prio!=''){$pass['priority'] = $prio;} if($choices!=''){$pass['choices'] = $choices;} if($desc!=''){$pass['description'] = $desc;} if($type=='color'){ $wp_customize->add_control(new WP_Customize_Color_Control($wp_customize,$id,$pass)); }else if($type=='image'){ $wp_customize->add_control(new WP_Customize_Image_Control($wp_customize,$id,$pass)); }else{ $pass['type'] = $type; $wp_customize->add_control($id,$pass); } } } // AMP REQUIRED - We have to add all CSS into the header in an AMP specific style tag that is limited to 50KB and must not use certain characters. All registered settings that ustilize CSS are inserted into the AMP style tag using this function. This is called from amp_publisher('start'). function init_customizer_head($raw=''){ if($this->has_customizer_settings()){ $css = ''; $js = ''; foreach($this->self['customizer_settings'] as $setting=>$data){ $acss = $this->get_value($data,'css'); if($acss!=''){ if(strstr($acss,'[[VALUE]]')){ $val = $this->get_customizer_setting($setting); $css .= str_replace('[[VALUE]]',$val,$acss); }else{ $css .= $this->function_call($acss); } } $ajs = $this->get_value($data,'js'); if($ajs!=''){ if(strstr($ajs,'[[VALUE]]')){ $val = $this->get_customizer_setting($setting); $js .= str_replace('[[VALUE]]',$val,$ajs); }else{ $js .= $this->function_call($ajs); } } } if($raw=='css'){ echo $css; }else if($raw=='js'){ echo $js; }else{ if($css!=''){echo '';} if($js!=''){echo '';} } } } //************************* // COLOR CODE PROCESSING //************************* // Check if a string is a hex color code. function isHex($input){ if(substr($input,0,1)=='#'){return true;} return false; } // Check if a string is a rgb color code. function isRGB($input){ if(substr($input,0,3)=='rgb'){return true;} return false; } // Convert hex to rgb color code. function hexToRGB($hex) { $hex = str_replace("#", "", $hex); if(strlen($hex) == 3) { $r = hexdec($hex[0].$hex[0]); $g = hexdec($hex[1].$hex[1]); $b = hexdec($hex[2].$hex[2]); } else { $r = hexdec($hex[0].$hex[1]); $g = hexdec($hex[2].$hex[3]); $b = hexdec($hex[4].$hex[5]); } return array('r'=>$r, 'g'=>$g, 'b'=>$b); } // Convert rgb to hex color code. function rgbToHex($rgb){ $rgb = $this->rgbToArray($rgb); return '#' . sprintf('%02x', $rgb['r']) . sprintf('%02x', $rgb['g']) . sprintf('%02x', $rgb['b']); } // Retrieve rbg values as an array. function rgbToArray($rgb){ if(is_string($rgb)){ $str = str_replace(array('rgb(',')',' '),array('','',''),$rgb); $exp = explode(',',$str); $rgb = array('r'=>$exp[0],'g'=>$exp[1],'b'=>$exp[2]); } return $rgb; } //************************************ // CRONJOB REGISTRATION AND HANDLING //************************************ // These functions simplify the process of setting up a conjob and utilizing a selection of alternate interval periods. // Register a cronjob and choose an interval: minute, hour, halfday, day, week, month, 3hours, 6hours, 5minutes function register_cron($fct,$interval){ $intervals = array('minute'=>'minutely','hour'=>'hourly','halfday'=>'twicedaily','day'=>'daily','week'=>'weekly','month'=>'monthly','3hours'=>'3hours','6hours'=>'6hours','5minutes'=>'5minutes'); $itype = ''; if(isset($intervals[$interval])){ $itype = $intervals[$interval]; }else{ foreach($intervals as $k=>$v){ if($interval==$v){ $itype = $v; } } } if($itype!=''){ $this->self['cron_list'][$fct] = $itype; } } // Check if the class has any cronjobs registered. Used before initiating WP setup script. function has_cron(){if(isset($this->self['cron_list'])){if(count($this->self['cron_list'])>0){return true;}}return false;} // Adds several interval options that only get filtered into WP if they are registered. function custom_cron_schedules( $schedules ) { $arr = array(); if($this->has_cron()){ foreach($this->self['cron_list'] as $fct=>$type){ $arr[$type] = true; } } if(isset($arr['minutely'])){$schedules['minutely'] = array('interval' => 60,'display' => 'Every Minute');} if(isset($arr['weekly'])){$schedules['weekly'] = array('interval' => 60480,'display' => 'Every Week');} if(isset($arr['monthly'])){$schedules['monthly'] = array('interval' => 259200,'display' => 'Every 30 Days');} if(isset($arr['3hours'])){$schedules['3hours'] = array('interval' => 1080,'display' => 'Every 3 Hours');} if(isset($arr['6hours'])){$schedules['6hours'] = array('interval' => 2160,'display' => 'Every 6 Hours');} if(isset($arr['5minutes'])){$schedules['5minutes'] = array('interval' => 300,'display' => 'Every 5 Minutes');} return $schedules; } // Retrieve next scheduled date/data for a registered cronjob. function get_cron($fct){return wp_next_scheduled($fct.'_cron');} // Clear the next scheduled date/data for a registered cronjob. This is useful when testing cronjobs. function clear_cron($fct){wp_clear_scheduled_hook($fct.'_cron');} // Remove a cronjob from the WP registry. This is useful when testing cronjobs. function cancel_cron($fct){ $action = $fct.'_cron'; $next = wp_next_scheduled($action); wp_unschedule_event( $next, $action); } // ************************************* // POST META REGISTRATION AND HANDLING // ************************************* // These functions consolodate the extensive number of steps required to include a meta field and the ability to edit it through the post editor. Now I can just register a meta value in the functions file, and the rest is done. // Register a meta value by sending this function a variable name and an array of parameters, including acceptable post types. // EXAMPLE: $OBJ->register_meta('VARNAME',array('type'=>'checkbox','name'=>'VAR TITLE','desc'=>'DESCRIPTION - NOT REQUIRED','post_type'=>array('post','page'))); function register_meta($name,$data=array()){ $field = $this->get_fieldname($name,true); $this->self['meta_list'][$field] = $data; $this->self['meta_list'][$field]['id'] = $this->get_fieldname($name); } // Take registered meta fields and add a Meta Box to the WP post editor for this object and it's fields. function add_post_editor(){ $how = ''; $screen = get_current_screen(); $type = $screen->post_type; if($type=='post' or $type=='page'){$how = $type;} $mtitle = $this->get_value($this->self,'Title'); if($how!=''){add_meta_box($this->self['prefix'].'_layout_box',$mtitle,array(&$this,'echo_post_editor'),$how,'advanced','core');} } // Second step in adding a Meta Box to the WP post editor, this step fills that box. function echo_post_editor(){ wp_nonce_field( $this->self['prefix'].'_post_nonce', $this->self['prefix'].'_nonce_field' ); $atts = array('media_buttons'=>false); $arr = $this->self['meta_list']; if(count($arr)>0){ $functs = array(); foreach($arr as $name=>$data){ $type = $this->get_value($data,'type'); $title = $this->get_value($data,'name'); $desc = $this->get_value($data,'desc'); if($type=='function'){ $fct = $this->get_value($data,'function'); if($fct!=''){if(!in_array($fct,$functs)){$functs[] = $fct;}} }else{ echo '
'; $val = $this->get_meta(get_the_ID(),$name); if($type=='html'){ echo ''.$title.''; wp_editor($val,$name,$atts); }else{ $data['value'] = $val; echo $this->generate_field($data); echo $title; } if($desc!=''){echo '
'.$desc.'
';} echo '
'; } } if(count($functs)>0){ foreach($functs as $dex=>$fct){ $this->runit($fct); } } } } // Meta fields are registered as a variable name with an object prefix to keep it distinct from fields registerd by other WP products. function get_fieldname($field,$over=false){ $pref = $this->self['prefix']; if($over==false){if(!strstr($field,$pref)){return '_'.$pref.'_'.$field;}} return $field; } // Simplified meta value function that adds the object prefix and weeds out un-registered meta fields. function get_meta($post_id,$var=''){ if($var==''){return '';} if(!isset($this->self['meta_list'][$var])){return '';} $field = $this->get_fieldname($var); return get_post_meta($post_id,$field,true); } // Return registered data as an array or return a value for a particular registered data point. function get_meta_data($field,$var=''){ if(isset($this->self['meta_list'][$field])){ if($var!=''){return $this->get_value($this->self['meta_list'][$field],$var);} return $this->self['meta_list'][$field]; } return array(); } // Hook into the post editor update functionality to include our registered meta fields. function update_post($post_id,$post){ $runit = false; if(is_single($post_id)){ if ( !empty($_POST) && check_admin_referer($this->self['prefix'].'_post_nonce',$this->self['prefix'].'_nonce_field') ){ $runit = true; } }else{ $runit = true; } if($runit==true){ $arr = $this->self['meta_list']; if(count($arr)>0){ foreach($arr as $name=>$data){ $type = $this->get_value($data,'type'); $field = $this->get_fieldname($name); $oldval = $this->get_meta($post_id,$field); if($type=='checkbox'){ $newval = '';if(isset($_POST[$field])){$newval = 1;} }else{ $newval = $this->get_value($_POST,$field); } if($newval!=$oldval or $newval==''){$this->update_meta($post_id,$field,$newval);} } } } } // Update post meta by adding/editing where appropriate, and deleting when empty. Updating the meta field this way minimizes database weight by not storing empty values and simplifies using meta values in this object. function update_meta($post_id,$var,$newval,$pref=false){ $field = $this->get_fieldname($var,$pref); $ftype = $this->get_meta_data($var,'type'); if($ftype=='checkbox'){ if($newval=='1' or $newval=='true'){ $newval = '1'; }else{ $newval = ''; } } if($newval===''){ delete_post_meta($post_id,$field); }else{ add_post_meta($post_id, $field, $newval, true) or update_post_meta($post_id, $field, $newval); } } // Verify that this object has meta field(s) reistered, used to check if a process is needed before running it. function using_meta(){ if(isset($this->self['meta_list']) and count($this->self['meta_list'])>0){ foreach($this->self['meta_list'] as $var=>$arr){ if($this->get_value($arr,'type')!=''){return true;} } } return false; } // Handle the amp_header() function from base file available to theme users/developers. function amp_header(){$this->amp_publisher('start');} // Handle the amp_footer() function from base file available to theme users/developers. function amp_footer(){$this->amp_publisher('end');} // Handle the amp_publisher() function from base file available to theme users/developers. // Googel AMP compliance is so rigid that we must control many aspects of generating page/theme content. We tried to open up as much as possible to the theme's template files, as well as making it easy to include these parts through a centralized function. function amp_publisher($part='',$pass=''){ global $post; if(isset($post)){$page_id = $post->ID;}else{$page_id = 0;} $layout = $this->get_customizer_setting('site_layout'); $url = $this->current_page_url(); $title = $this->get_page_title(); $data = $this->get_document_data(); $pagetype = $this->get_value($data,'pagetype'); $pageid = $this->get_value($data,'pageid'); $dtype = $this->get_value($data,'jsontype'); $doctype = $this->get_markup($dtype,'type'); $hline = $this->get_markup('headline','prop'); $nline = $this->get_markup('name','prop'); $meline = $this->get_markup('mainEntityOfPage','prop'); $homeurl = home_url(); $img = $this->get_customizer_setting('header_logoimage'); $blogname = get_bloginfo('name'); $slogan = get_bloginfo('description'); $data = $this->get_document_data(); $desc = $this->get_value($data,'desc'); $published = $this->get_value($data,'published'); $modified = $this->get_value($data,'modified'); $publisher = $this->get_value($data,'publisher'); $image = $this->get_value($data,'img'); $imagew = $this->get_value($data,'imgw'); $imageh = $this->get_value($data,'imgh'); $ampd = $this->is_amp(); $comm = $this->is_amp_not(); $isin = $this->is_user_admin(); $preview = $this->is_amp_preview(); $edit = false;if($isin and !$preview){$edit = true;} if($part=='before locations'){ if($this->is_advanced()){$this->prepare_locations('before',$pageid,$pagetype);} }else if($part=='after locations'){ if($this->is_advanced()){$this->prepare_locations('after',$pageid,$pagetype);} }else if($part=='sidebar locations'){ if($this->is_advanced()){$this->prepare_locations('sidebar',$pageid,$pagetype);} }else if($part=='start'){ if($edit or $comm){wp_enqueue_script('jquery');} if($edit){wp_enqueue_script('jquery-ui-sortable');} if($ampd){ echo ''; echo ''; echo ''; wp_head(); $metadesc = ''; if(defined('WPSEO_FILE')){ $metadesc = WPSEO_Frontend::get_instance()->metadesc(false); }else{ echo ''; } if($metadesc==''){ if($this->is_advanced()){$metadesc = $this->get_page_setting($pageid,$pagetype,'metadesc');} if($metadesc==''){if(is_home() or is_front_page()){$metadesc = get_bloginfo('description');}} if($metadesc!=''){echo '';} } $keywords = ''; //if(is_singular()){ $list = get_the_tag_list(); $tags = get_tags(); if($tags!='' and count($tags)>0){ foreach($tags as $tag){ $tname = $tag->name; $keywords = $this->delimitit($keywords,', ',$tname); } } //} if($keywords!=''){echo '';} // this is only needed in non-amp version of the page when implemented linked to amp version... the amp canonical should have link to non-amp version if available, all pages generated by this theme are either amp or non-amp //echo ''; echo ''; echo ''; echo $this->generate_amp_markups(); echo ''; echo ''; $this->include_amp_modules(); echo ''; echo ''; if($this->is_advanced()){$this->adv_pageview($pageid,$pagetype,$ampd);} }else{ echo ''; echo ''; echo ''; echo ''; wp_head(); echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; if($edit){ echo ''; echo ''; echo ''; if($this->is_advanced()){ global $tacgadv; echo ''; echo ''; echo ''; } } echo ''; echo ''; echo ''; } }else if($part=='end'){ if($ampd){ if($this->is_advanced()){echo $this->adv_analytics();} }else if($edit){ echo $this->generate_live_editor(); echo '
X
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; } if($ampd and $this->is_advanced()){echo $this->generate_sticky_ad();} echo ''; echo ''; }else if($part=='body tag'){ echo $this->inline_markup(' itemscope itemtype="http://schema.org/WebPage"'); }else if($part=='body start'){ if($this->use_nav_menu('main-nav')){ if($ampd){ echo ''; }else{ echo '
'; echo '
'; } echo '
'; echo '
'; if($ampd){ echo ''; }else{ echo ''; } echo '
'; echo '
'; echo '
'; wp_nav_menu(array('container'=>false,'theme_location'=>'main-nav')); echo '
'; echo '
'; echo $this->generate_mobile_menu_block(); echo '
'; echo '
'; if($ampd){ echo ''; }else{ echo '
'; } } echo '
'; $gline = $this->inline_markup(' role="banner" itemscope itemtype="http://schema.org/WPHeader"'); $isinline = $this->inline_markup('yes'); $iline = $this->inline_markup(' itemprop="logo" itemscope itemtype="http://schema.org/ImageObject"'); $hsl = '';if($img!=''){$hsl = ' haslogo';} echo ''; echo '
'; echo '
'; if(is_home() or is_front_page()){ if($blogname!=='' or $slogan!=''){ if($blogname!=''){echo '

'.$blogname.'

';} if($slogan!=''){echo '

'.$slogan.'

';} } }else if(is_search()){ $srch = $this->get_value($_GET,'s'); echo '

'; if($srch==''){ echo __('No search text entered, try again','amp-publisher'); }else{ echo __('Search results for','amp-publisher').' "'.$srch.'"'; } echo '

'; }else{ $ttl = ''; if(is_category()){$ttl = 'Category';} elseif(is_tag()){$ttl = 'Tag';} elseif(is_author()){$ttl = 'Author';} echo '
'.$ttl.'
'; echo '
'; echo '

'; echo $this->theme_page_title(); echo '

'; echo '
'; } echo '
'; echo '
'; }else if($part=='main tag'){ $markup = $this->inline_markup(' itemscope itemprop="mainContentOfPage" itemtype="http://schema.org/WebPageElement"'); if(is_single()){$markup = '';} echo $markup; }else if($part=='body end'){ echo '
'; $social = $this->generate_social_bar(); if($social!=''){ $socclass = ''; $socstyle = $this->get_customizer_setting('social_footerstyle'); $socsize = $this->get_customizer_setting('social_footersize'); if($socstyle!=''){$socclass .= ' '.$socstyle;} if($socsize!=''){$socclass .= ' '.$socsize;} $sochide = $this->get_customizer_setting('footer_hidesocial'); if($sochide!='' and $ampd){$social = '';} echo ''; } $fline = $this->inline_markup(' role="contentinfo" itemscope itemtype="http://schema.org/WPFooter"'); echo '
'; echo ''; echo '
'; echo '
'; echo '
'; echo '
';// END #container if($edit){ echo '
'; echo '
'; echo '
'; echo ''; if($this->is_advanced()){ echo ''; echo ''; } echo ''; echo ''; echo '
'; echo '
'; $css = ''; $css .= $this->self['PATH'].'style.css'; $css .= ','.$this->self['PATH'].'script/live_editor.css'; $css .= ','.$this->get_fontawesome_url(); wp_editor('','tacgwpeditor',array('tinymce'=>array('content_css'=>$css))); echo '
'; echo '
'; echo '
'; } }else if($part=='page title'){ $this->theme_page_title(); }else if($part=='page title markup'){ echo $hline; }else if($part=='breadcrumbs'){ echo $this->generate_breadcrumbs(); }else if($part=='archive description'){ $desc = category_description(); $desc = $this->content_filter($desc,$ampd); echo $desc; }else if($part=='posts class'){ $barred = ''; $bar = $this->is_sidebar($pageid,$pagetype); if($bar!='' and $bar!='na'){$barred = ' sidebarred';} $display = $this->get_customizer_setting('site_postsdisplaymode','article'); if(substr($display,0,5)=='image'){$display .= ' posts-image';} if(substr($display,0,7)=='article'){$display .= ' posts-article';} echo ' sbtgt'.$barred.' posts-mod posts-'.$display; if($this->get_customizer_setting('site_postsdisplayborder')!=''){echo ' bordered';} }else if($part=='post'){ if($pass!=''){echo $this->generate_post($pass,'',$ampd);} }else if($part=='posts navigation'){ $this->page_navigation(); }else if($part=='page id'){ echo ' id="post-'.$page_id.'"'; }else if($part=='page class'){ $barred = ''; $bar = $this->is_sidebar($pageid,$pagetype); if($bar!='' and $bar!='na'){$barred = ' sidebarred';} echo ' sbtgt'.$barred; }else if($part=='author box'){ if(post_password_required() and $pass!='author'){return '';}else{$this->user_profile_display($pass);} }else if($part=='page content'){ // this is obsolete right now, using the_content() instead if($ampd){ $content = get_the_content(); $content = $this->content_filter($content,$ampd); if($content==''){$content = __('This page contains no content.','amp-publisher');} echo $content; }else{ the_content(); } }else if($part=='post byline'){ echo ''; }else if($part=='sidebar'){ $bar = $this->is_sidebar($pageid,$pagetype); $barred = ''; $runbar = true; if($ampd or $comm){ if($bar=='' or $bar=='na'){$runbar = false;} }else{ if($bar==''){$barred = ' dimmed';} if($bar=='na'){$barred = ' empty';} } if($runbar){ echo ''; } }else if($part=='comment form'){ if($this->is_comments()){ echo '
'; comment_form(array( 'title_reply_before' => '

', 'title_reply_after' => '

', )); echo '
'; }else if($this->is_comments_wp()){ if($pass!=''){ echo '
'; echo '

'.$pass.'

'; echo '
'; } } }else if($part=='password protected content'){ if($ampd or $comm){ echo __('This content is password protected, and the page is generated by Google AMP (disallows forms).','amp-publisher'); echo ' '; echo __('Click here to enable forms and enter the password.','amp-publisher'); echo ''; }else{ the_content(); } }else if($part=='hide comments'){ if($pagetype=='page' or $pagetype=='post'){return get_option('tacg_nocomson'.$pagetype.'s');} return true; } return ''; } function extends_init(){ $this->self['apibaseurl'] = 'https://ampwptools.com/'; $this->self['Title'] = 'AMP Publisher'; if(class_exists('wfConfig')){ $wfwall = wfConfig::get('ajaxWatcherDisabled_front'); if(!$wfwall){ $wferr = 'Wordfence Firewall is active on the "Front" end, the javascript file it loads will cause Google AMP Validation to fail.
You can turn this setting off in: wp-admin ~ Wordfence ~ Firewall ~ uncheck "Front" under "Monitor Background Requests for False Positives:"
AMP does not need to validate while logged in, so you may leave "Admin Panel" checked.'; $this->register_notice($wferr,'warning'); } } $this->filter_handler('body_class');// Add class name for the site's layout to the body tag $this->filter_handler('comment_post_redirect');// Add variables and anchor to the comment redirect url to trigger the non-AMP version of posts for commenting. $this->filter_handler('comment_reply_link',30,4);// Add variables and anchor to the comment reply url to trigger the non-AMP version of posts for commenting. $this->filter_handler('get_avatar',10,5);// Filter the avatar to make the image AMP compliant. $this->filter_handler('language_attributes',9999);// Filter out language attributes that invalidate Google AMP compliance. $this->filter_handler('mce_buttons_2');// Remove options from the WP HTML Editor that would invalidate AMP compliance. $this->filter_handler('post_thumbnail_html');// Filter the post thuumbnail to make it AMP compliant. $this->filter_handler('pre_get_document_title');// Filter the document meta-title if Yoast WPSEO is not already handling it. // We turn off the Admin bar only during AMP previews for validation purposes... otherwise it is completely unaffected. if($this->is_user_admin() and $this->get_value($_GET,'amp')=='1'){$this->filter_handler('show_admin_bar');} $this->filter_handler('the_content',1,1);// Filter the content for AMP compliance. $this->filter_handler('tiny_mce_before_init',9);// Turn off options and filters used by the WP HTML Editor that could invalidate AMP compliance. } function is_amp_search(){return true;} function is_advanced(){if(is_callable(array($this,'verifyaddadv'))){return $this->verifyaddadv();}return false;} // Create a device preview window running the current page through AMP. Initiated from generate_live_editor(). function ajax_amp_preview($params){ $wid = $this->get_value($params,'width','100%'); $hit = $this->get_value($params,'height','600px'); $how = $this->get_value($params,'how'); $url = $this->get_value($params,'url'); $adds = $this->get_value($params,'adds'); $urls = explode('?',$url); $url = $urls[0]; echo '
'; $ashow = ''; if(how!=''){$ashow = 'as'.$how;} echo '
'; echo '
'; echo '';// iframe for device preview only echo '
'; echo '
'; } // Create a window for choosing a Fontawesome icon. function ajax_choose_fontawesome($params){ $where = $this->get_value($params,'where'); $jst = 'html_editor'; if($where=='buttonbar'){$jst = 'buttonbar';} $icons = $this->get_fontawesome_icons(); echo '
'; echo '

'.__('Select an Icon','amp-publisher').'

'; echo ''; echo ''; echo '
'; echo '
'; echo '
'; if(count($icons)>0){ foreach($icons as $icon){ echo '
'; echo ''; echo '
'; } }else{ echo __('Unable to access the Font Awesome Library at this moment.','amp-publisher'); } echo '
'; echo '
'; } // Create window content for instructions, notices and advanced interfaces available to the Live Editor. function ajax_content_editor($params){ $btnid = $this->get_value($params,'id'); if($btnid=='page'){ $apiret = $this->url_get_contents($this->self['apibaseurl'].'support'); if($apiret==''){$apiret = 'ERROR #100 : Unable to access API';} echo $apiret; return; }else{ if($this->is_advanced()){$this->adv_content_editor($params);} } } // Process commands and changes sent from the Live Editor. function ajax_live_editor($params){ $text = $this->get_value($params,'txt'); $nodes = $this->get_value($params,'nodes'); if($nodes==''){ $id = $this->get_value($params,'id'); $type = $this->get_value($params,'typ'); $mod = $this->get_value($params,'mod'); $text = $this->get_value($params,'txt'); $txt = $this->htmlout($text); $txt = stripslashes($txt); $slug = $this->get_value($params,'slug'); $post_id = $this->get_value($params,'postid'); if($id=='pageorpost-content'){ $my_post = array('ID'=>$post_id,'post_content'=>$txt); wp_update_post( $my_post ); echo $this->content_filter($txt); }elseif($id=='pageorpost-title'){ $my_post = array('ID'=>$post_id,'post_title'=>$txt); wp_update_post($my_post); }elseif($id=='archive-content'){ $term_id = $this->get_value($params,'termid'); wp_update_term($term_id, 'category', array('description'=>$txt)); echo $this->content_filter($txt); }elseif($id=='archive-title'){ echo $txt; $term_id = $this->get_value($params,'termid'); wp_update_term($term_id, 'category', array('name'=>$txt)); }elseif($id=='featuredimage'){ if($txt==''){ delete_post_thumbnail($post_id); }else{ $attach_id = attachment_url_to_postid($txt); set_post_thumbnail($post_id,$attach_id); } }elseif($id=='HideFeaturedImage' or $id=='NonAMP' or $id=='HideSidebar'){ $this->update_meta($post_id,$id,$txt); }elseif($id=='testtext'){ $txt = $this->htmlin($txt); $this->save_dat('testtext',$txt); echo $this->content_filter($txt); }elseif($type=='text'){ set_theme_mod($mod,$txt); echo $this->content_filter($txt); }elseif(type=='dat'){ $this->save_dat($id,$txt); }elseif($type=='color'){ set_theme_mod($mod,$txt); }elseif($type=='setting'){ if($this->is_advanced()){ $pageid = $post_id; $pagetype = $this->get_value($params,'pagetype'); if($pagetype=='category'){$pageid = $this->get_value($params,'termid');} $this->set_page_setting($pageid,$pagetype,$id,$txt); } } }else{ $arr = explode(',',$nodes); if(count($arr)>0){ foreach($arr as $node){ $val = $this->get_value($params,$node); if(substr($node,0,11)!='editoption_'){ if($node=='page_title'){ $post_id = $this->get_value($params,'postid'); $my_post = array('ID'=>$post_id,'post_title'=>$val); wp_update_post($my_post); continue; } $data = $this->get_customizer_settings($node); $type = $this->get_value($data,'type'); if($type=='image'){ $add = $this->get_value($params,'editoption_addmedia'); if($val==''){ $url = ''; }else{ if($this->url_exists($val)){$url = $val;} } set_theme_mod($node,$url); }else{ $val = stripslashes($val); $val = $this->htmlin($val); set_theme_mod($node,$val); } } } } } } // Create the Live Editor interface sections and settings. function ajax_load_editor($params){ $id = $this->get_value($params,'id'); $type = $this->get_value($params,'typ'); $local = $this->get_value($params,'local'); global $tacgfct; $theme = $this->get_customizer_setting('site_layout'); $textnotice = '
'.__('Some settings will require a browser refresh to view all potential changes.','amp-publisher').'
'; if($type=='editor'){ if($id=='sitewide_editor'){ echo '
'; echo '
'.__('General Layout','amp-publisher').'
'; echo $this->editor_node('site_layout'); //echo $this->editor_node('site_rounded'); echo $this->editor_node('site_wrapconstrain'); echo '
'.__('Posts / Archives Display','amp-publisher').'
'; echo $this->editor_node('site_postsdisplaymode'); echo $this->editor_node('site_postsdisplayborder'); echo $this->editor_node('site_postsdisplayheight'); echo $this->editor_node('site_hidebyline'); if($this->is_advanced()){echo $this->editor_node('site_postads');} echo '
'.__('The Flags you see (category/tag) in Posts "Article" Display Mode use the site link colors by default, but you may choose custom styling for them here. Clear the color assignment to again use the link colors. You must refresh the browser to view changes to the flags.','amp-publisher').'
'; echo '
'; echo $this->editor_node('site_postagfcolor','refresh'); echo $this->editor_node('site_postagcolor','refresh'); echo $this->editor_node('site_postaghcolor','refresh'); echo '
'; echo '
'.__('Sidebar Visibility','amp-publisher').'
'; echo '
'; echo $this->editor_node('site_hidehomesidebar','refresh'); echo $this->editor_node('site_hidepagesidebar','refresh'); echo $this->editor_node('site_hidepostsidebar','refresh'); echo $this->editor_node('site_hidecategorysidebar','refresh'); echo $textnotice; echo '
'; if(!$this->is_advanced()){ echo $this->generate_icon_button(array('label'=>__('Restore Sitewide Defaults','amp-publisher'),'title'=>__('Restore all sitewide styles and settings to the default.','amp-publisher'),'icon'=>'recycle','click'=>'tacg_restore_defaults();','style'=>'width:100%;margin-top:5px;')); } echo '
'; }else if($id=='sitewide_style'){ echo '
'; echo '
'.__('Font Styling','amp-publisher').'
'; echo $this->editor_node('site_fontsize'); echo $this->editor_node('site_h1fontsize'); echo $this->editor_node('site_h2fontsize'); echo $this->editor_node('site_h3fontsize'); echo '
'; echo $textnotice; echo $this->editor_node('site_fontcolor','refresh'); //echo $this->editor_node('site_accentcolor','refresh');//ACCENT echo $this->editor_node('site_linkcolor','refresh'); echo $this->editor_node('site_linkhovercolor','refresh'); echo '
'; echo '
'.__('Background Color / Image','amp-publisher').'
'; echo $this->editor_node('site_bgcolor'); echo $this->editor_node('site_bgimage'); echo $this->editor_node('site_bgimagerepeat'); echo '
Default Image
'; echo '
'.__('When an image is needed but none is assigned, the theme uses a default image labeled "no available photo". You may assign your own default image instead.','amp-publisher').'
'; echo '
'; echo $this->editor_node('site_defaultimage','refresh'); echo '
'; if($this->is_advanced()){ echo '
'.__('Title Block Modules','amp-publisher').'
'; echo '
'.__('You insert Title Block Modules with the Composer wherever you wish. You decide here which style and colors they use.','amp-publisher').'
'; echo $this->editor_node('site_tbkdisplay'); echo $this->editor_node('site_tbkcolor'); echo '
'; echo $this->editor_node('site_tbkbgcolor','refresh'); echo '
'; } echo '
'; }else if($id=='banner'){ echo '
'; echo $this->editor_node('header_hidebanner'); echo $this->editor_node('header_vpad'); //echo $this->editor_node('header_lhpad'); echo $this->editor_node('header_bgcolor'); echo $this->editor_node('header_logoimage'); echo $this->editor_node('header_bgimage'); echo $this->editor_node('header_bgimagerepeat'); echo '
'.__('Cassic Layout','amp-publisher').'
'; echo '
'.__('Options used only in the Classic Layout.','amp-publisher').'
'; echo $this->editor_node('header_txtcolor'); echo $this->editor_node('header_blogvpad'); echo $this->editor_node('header_hide_blogname'); echo $this->editor_node('header_hide_blogdesc'); echo '
'; }else if($id=='titlebar'){ echo '
'; echo '
'.__('Title & Tagline sizes are determined by your sitewide H1 & H2 settings (respectively).
The Classic Layout hides the Title Bar, the page title is inserted near the page content.','amp-publisher').'
'; echo $this->editor_node('header_hidetitlebar'); echo $this->editor_node('header_tbartxtcolor'); echo $this->editor_node('header_tbarbgcolor'); echo $this->editor_node('header_tbarvpad'); echo '
'; }else if($id=='sub-header'){ echo '
'; //echo $this->editor_node('subheader_mobiletransform'); echo $this->editor_node('navmenu_menufontsize'); echo $this->editor_node('navmenu_menucase'); echo $this->editor_node('subheader_bgcolor'); echo $this->editor_node('subheader_txtcolor'); echo '
'; echo $this->editor_node('subheader_menuhovertext'); echo $this->editor_node('subheader_hidesearch'); echo '
'; echo $textnotice; echo '
'.__('Hover-Drop Menu','amp-publisher').'
'; echo '
'; echo $this->editor_node('navmenu_submenutext'); echo $this->editor_node('navmenu_submenubg'); echo $this->editor_node('navmenu_submenuhovertext'); echo $this->editor_node('navmenu_submenuhoverbg'); echo $this->editor_node('navmenu_submenuborder'); echo '
'; echo $this->editor_node('navmenu_submenuborderhide'); echo '
'.__('Slideout Mobile Menu','amp-publisher').'
'; echo '
'.__('The Mobile Menu is opened using the "Hamburger" button that appears in devices and small browser windows. The button is always visible in the Side Navigation Layout.','amp-publisher').'
'; echo '
'; echo $this->editor_node('mobilemenu_block'); echo '
'; echo '
'; }else if($id=='social_editor'){ echo '
'; echo '
'.__('Button Manager','amp-publisher').'
'; echo $this->editor_node('social_buttonlist'); echo $this->generate_social_button_manager(); echo '
'.__('Some icons will look odd if your choose the Circle or Square styles. Look for icons that are close in width and height.','amp-publisher').'
'; echo '
'.__('Header Button Styling','amp-publisher').'
'; echo $this->editor_node('header_hidesocial'); echo $this->editor_node('social_rssfeed'); echo $this->editor_node('social_headerstyle'); echo $this->editor_node('social_iconcolor'); echo $this->editor_node('social_iconhovercolor'); echo $this->editor_node('social_bordercolor'); echo '
'.__('Footer Button Styling','amp-publisher').'
'; echo $this->editor_node('footer_hidesocial'); echo $this->editor_node('social_footerbarcolor'); echo $this->editor_node('social_footerstyle'); echo $this->editor_node('social_footersize'); echo $this->editor_node('social_footericoncolor'); echo $this->editor_node('social_footericonhovercolor'); echo $this->editor_node('social_footerbordercolor'); echo '
'; }else if($id=='footer'){ echo '
'; echo $this->editor_node('footer_copyrighttext'); echo $this->editor_node('footer_textcolor'); echo $this->editor_node('footer_bgcolor'); echo '
'.__('Menu Text Color','amp-publisher').'
'; echo '
'.__('This menu location only displays top level links, children (nested links) are not included.','amp-publisher').'
'; echo $this->editor_node('footer_menutext'); echo '
'; echo $this->editor_node('footer_menuhovertext'); echo '
'; echo $textnotice; echo '
'; }else if($id=='seo'){ echo '
'; echo $this->editor_node('seo_inlinemarkup'); echo '
'.__('Breadcrumbs','amp-publisher').'
'; echo '
'.__('When you have Yoast SEO activated and "Enable Breadcrumbs" enabled, the breadcrumbs are instead generated by that plugin.','amp-publisher').'
'; echo $this->editor_node('seo_breadcrumbhide'); echo $this->editor_node('seo_boldlast'); echo $this->editor_node('seo_breadcrumbsep'); echo '
'; }else{ if($this->is_advanced()){$this->adv_load_editor($params);} } } } // Create new content for mobile menu block when it is changed in Live Editor. function ajax_mobile_menu_block($params){echo $this->generate_mobile_menu_block($params);} // Clear all registered settings, resetting the site back to it's default design. function ajax_restore_defaults($params){ if(isset($this->self['customizer_settings'])){ foreach($this->self['customizer_settings'] as $setting=>$data){remove_theme_mod($setting);} } } // To meet Google AMP compliance we must filter out unwanted tags and attributes, replace img tags with amp-img tags, and convert as many inline styles to stock classes as possible. function amp_filter($content,$pass=''){ $content = $this->amp_styles_to_classes($content);// converts inline styles to classes where possible $content = $this->strip_tag_attribute($content,'style');// remove inline styling for AMP validation $content = $this->strip_tag($content,'iframe');// remove injected iframes from content $content = $this->amp_filter_image($content,$pass);// comvert img tags into amp-img tags return $content; } function amp_filter_image($content,$pass=''){ $content = preg_replace("@()@i", "$1",$content);// close open image tags - step 1 $content = str_replace('/>','>',$content);// close image tags - step 2 $exp = explode('scrape_between('[ST]'.$part,'[ST]',''); $imgw = $this->scrape_between($tag,'width="','"'); $imgh = $this->scrape_between($tag,'height="','"'); if($imgw=='' and $imgh==''){ $imgw = $this->scrape_between($tag,'data-wid="','"'); $imgh = $this->scrape_between($tag,'data-hit="','"'); } $find = ''; $sizes = ''; if(strstr($tag,'alignleft') or strstr($tag,'alignright')){$sizes = ' sizes="(max-width: '.$imgw.'px) calc(100vw - 60px), '.$imgw.'px"';} $tag = $this->process_url_ssl($tag); $layout = 'responsive'; if($pass=='fixed'){$layout = 'fixed';$sizes = '';} $rep = ''; $content = str_replace($find,$rep,$content); } return $content; } // We process the video shortcode prior to running do_shortcode() to ensure that the amp-video tag conversion will work correctly. function amp_filter_video($txt,$ampd=false){ $exp = explode('[video ',$txt); foreach($exp as $part){ $video = $this->scrape_between('[SS]'.$part,'[SS]','][/video]'); $find = '[video '.$video.'][/video]'; $rep = ''; $vex = 'video='; $vid = str_replace(array('mp4=', 'm4v=', 'webm=', 'ogv=', 'wmv=', 'flv='),array($vex,$vex,$vex,$vex,$vex,$vex),$video); if($this->is_advanced()){$rep = '[video provider="video" '.$vid.']';} $txt = str_replace($find,$rep,$txt); } $embeds = $this->extract_wp_embeds($txt); if(count($embeds)>0){ foreach($embeds as $prov=>$vids){ foreach($vids as $vid=>$dats){ $url = $this->get_value($dats,'url'); $key = $this->get_value($dats,'key'); $video = $this->get_value($dats,'val'); $find = '[embed]'.$url.'[/embed]'; $rep = $this->generate_video_module(array('provider'=>$prov,$key=>$video),$ampd); $txt = str_replace($find,$rep,$txt); } } } return $txt; } // Retrieve an array of replacements for converting inline styles to classes. function amp_style_replacements(){ $replacements = array(); $replacements['text-align'] = 'align'; $replacements['text-decoration'] = 'deco-'; $replacements['font-size'] = 'fsize-'; $replacements['font-weight'] = 'fwgt-'; $replacements['font-family'] = 'ffam-'; $replacements['color'] = 'clr-'; $replacements['background-color'] = 'bgclr-'; $replacements['margin'] = 'marg-'; $replacements['margin-top'] = 'margt-'; $replacements['margin-right'] = 'margr-'; $replacements['margin-bottom'] = 'margb-'; $replacements['margin-left'] = 'margl-'; $replacements['padding'] = 'padd-'; $replacements['padding-top'] = 'padt-'; $replacements['padding-right'] = 'padr-'; $replacements['padding-bottom'] = 'padb-'; $replacements['padding-left'] = 'padl-'; $replacements['float'] = 'float-'; return $replacements; } // Convert raw style data gathered from conversions, modules and filters into CSS for inclusion in the header. function amp_styles_css($k,$v){ $v = trim($v); $v = str_replace('#','',$v); $vc = $v; $va = $v; if($k=='font-family'){ $vc = str_replace(',','-',$vc); $va = str_replace('-',',',$va); } $vc = str_replace(' ','_',$vc); $va = str_replace('_',' ',$va); $val = ''; $replacements = $this->amp_style_replacements(); $rv = $this->get_value($replacements,$k); if($rv!=''){ $ck = ''; if($k=='color' or $k=='background-color'){$ck = '#';} $val = '.'.$rv.$vc.'{'.$k.':'.$ck.$va.';}'; } return $val; } // Convert inline styles to classes. Some are covered by stock styles, the rest are included in the header inside the AMP specific style tag. function amp_styles_to_classes($in,$ask=''){ $replacements = $this->amp_style_replacements(); $handler = array(); $out = $in; $RAT = ''; $arr = explode('<',$in); foreach($arr as $arp){ $brr = explode('>',$arp); $tag = $brr[0]; if(strstr($tag,'style="')){ $styles = array(); $style = $this->scrape_between($tag,'style="','"'); $classes = ''; $parts = explode(';',$style); if(count($parts)>0){ foreach($parts as $part){ $prt = trim($part); $keys = explode(':',$prt); $key = $keys[0]; $val = trim($this->get_value($keys,1)); if(isset($replacements[$key])){ $styles[$key] = $val; $handler[] = $styles; } } foreach($styles as $k=>$v){ $vcon = $replacements[$k]; $vc = trim($v); if($k=='font-family'){$vc = str_replace(',','-',$vc);} $vc = str_replace(' ','_',$vc); $vc = str_replace('#','',$vc); $vcon .= $vc; $classes = $this->delimitit($classes,' ',$vcon); } } if(strstr($tag,'class="')){ $scrap = $this->scrape_between($tag,'class="','"'); if($scrap!=''){$classes = $this->delimitit($classes,' ',$scrap);} } $newtag = preg_replace('!style="(.*?)"!s','',$tag); $newtag = preg_replace('!class="(.*?)"!s','',$newtag); if(substr($newtag,-1,1)=='/'){ $bstr = substr($newtag,0,-1); $newtag = $bstr.' class="'.$classes.'" /'; }else{ $newtag .= ' class="'.$classes.'"'; } $newtag = '<'.trim($newtag).'>'; $oldtag = '<'.$tag.'>'; $out = str_replace($oldtag,$newtag,$out); } } if($ask=='styles'){return $handler;} return $out; } // Probe the server to see if SSL is in use. function check_for_ssl(){ $ssl = false; if(isset($_SERVER['HTTPS'])){ // SERVER-HTTPS-ON if(strtolower($_SERVER['HTTPS'])=='on'){$ssl = true;} // SERVER-HTTPS-1 if($_SERVER['HTTPS']=='1'){$ssl = true;} } // SERVERPORT443 if(isset($_SERVER['SERVER_PORT']) && ($_SERVER['SERVER_PORT']=='443')){$ssl = true;} // ENVHTTPS if(isset($_ENV['HTTPS']) && ($_ENV['HTTPS']=='on')){$ssl = true;} // CLOUDFRONT if(!empty($_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO']) && ($_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO']=='https')){$ssl = true;} // CLOUDFLARE if(!empty($_SERVER['HTTP_CF_VISITOR']) && ($_SERVER['HTTP_CF_VISITOR']=='https')){$ssl = true;} // LOADBALANCER if(!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO']=='https')){$ssl = true;} // CDN if (!empty($_SERVER['HTTP_X_FORWARDED_SSL']) && ($_SERVER['HTTP_X_FORWARDED_SSL']=='on')){$ssl = true;} return $ssl; } // Retrieve the stylesheet data from the child theme. function child_stylesheet(){ $folder = get_stylesheet_directory_uri(); $sheet = $this->url_get_contents($folder.'/style.css'); $sheet = $this->scrape_between($sheet.'[ENDD]','START_STYLEHEET***********************/','[ENDD]'); return $sheet; } // Main content filter, handles AMP vs non-AMP and sub-filters. function content_filter($content,$ampd=false){ $content = preg_replace("/\r\n|\r|\n/",'
',$content); if($ampd==true){ $content = $this->amp_filter_video($content,true); $content = $this->amp_filter($content); } if($this->is_advanced()){$content = $this->adv_content_filter($content);} $content = do_shortcode($content); return $content; } // Generate input fields used in Live Editor. function editor_node($id,$type=NULL,$label=NULL,$class='datanode',$desc=NULL){ $RAT = ''; $val = $def = $oe = $oc = ''; if(is_array($type)){ $data = $type; $type = NULL; $def = $this->get_value($data,'default'); $val = $this->get_value($data,'value'); $val = $this->htmlout($val); }else{ $data = $this->get_customizer_settings($id); $def = $this->get_value($data,'default'); $val = $this->get_customizer_setting($id); $val = $this->htmlout($val); } $filter = $this->get_value($data,'filter'); $flag = $this->get_value($data,'flag'); $oe = $this->get_value($data,'onedit'); $oc = $this->get_value($data,'onclear'); $refresh = false; if($type=='refresh'){$refresh = true;$type = NULL;} $onsave = ''; if($refresh==true){$onsave = 'refresh';} if($type==NULL){$type = $this->get_value($data,'type');} if($label==NULL){$label = $this->get_value($data,'title');} if($desc==NULL){$desc = $this->get_value($data,'description');} if($val==''){$val = $def;} $tval = $val;if($type=='textarea'){$tval = $this->htmlin($val);} $RAT .= ''; $RAT .= ''; $disp = 'block';if($id=='editoption_addmedia' or $type=='hidden'){$disp = 'none';} $RAT .= '
'; if($type!='hidden'){ if($type=='color'){$RAT .= $this->generate_live_color_picker($id,$val,$label);} $RAT .= ''; if($type=='image'){$RAT .= $this->generate_browser_zone($id,$val,$label);} if($type=='checkbox'){$RAT .= $this->generate_live_checkbox($id,$val,$flag);} if($type=='text'){$RAT .= $this->generate_live_textfield($id,$val,$filter,$flag);} //if($type=='hidden'){$RAT .= $this->generate_live_textfield($id,$val,$filter,$flag,true);} if($type=='textarea'){$RAT .= $this->generate_live_textarea($id,$val,$flag);} if($type=='select'){ $opts = $this->get_value($data,'choices'); $RAT .= $this->generate_live_select($id,$val,$opts,$flag); } if($type=='html'){$RAT .= 'Open HTML Editor';} $RAT .= ''; if($type!='image'){ $RAT .= ''; if($desc!=''){ $RAT .= '
'.$desc.'
'; } } } $RAT .= '
'; return $RAT; } // Parse through page/post content loking for WP Embed codes for videos that need to be converted to AMP modules. function extract_wp_embeds($txt){ $RET = array(); $exp = explode('[embed]',$txt); if(count($exp)>1){ foreach($exp as $part){ $video = $this->scrape_between('[SS]'.$part,'[SS]','[/embed]'); if($video!=''){ $url = $video; $find = '[embed]'.$video.'[/embed]'; $rep = ''; $prov = ''; if(strstr($video,'youtube.com')){$prov = 'youtube';} if(strstr($video,'vimeo.com')){$prov = 'vimeo';} if(strstr($video,'dailymotion.com')){$prov = 'dailymotion';} if(strstr($video,'facebook.com')){$prov = 'facebook';} if($prov!=''){ $srckey = 'videoid'; if(substr($video,-1,1)=='/'){$video = substr($video,0,-1);} $vids = explode('/',$video); $vidc = count($vids)-1; $vidcode = $vids[$vidc]; if($vidcode==''){$vidcode = $vids[($vidc-1)];} $vid = $vidcode; if($prov=='dailymotion'){$exp = explode('_',$vidcode);$vid = $exp[0];} if($prov=='youtube'){$vid = str_replace('watch?v=','',$vidcode);} $videoid = $vid; if($prov=='facebook'){$srckey = 'href';$vid = $video;} if(!isset($RET[$prov])){$RET[$prov] = array();} $RET[$prov][$videoid] = array('provider'=>$prov,'id'=>$videoid,'url'=>$url,'key'=>$srckey,'val'=>$vid); } } } } return $RET; } // Extract image data from HTML content to handle amximum image sizing for AMP responsive images. function gather_image_styles($stack,$content){ $exp = explode('scrape_between('[ST]'.$part,'[ST]','>'); $imgid = $this->scrape_between($tag,'wp-image-','"'); $ixp = explode(' ',$imgid); $imgid = $ixp[0]; $imgw = $this->scrape_between($tag,'width="','"'); $imgh = $this->scrape_between($tag,'height="','"'); if($imgw=='' and $imgh==''){ $imgw = $this->scrape_between($tag,'data-wid="','"'); $imgh = $this->scrape_between($tag,'data-hit="','"'); } if($imgid!='' and $imgw!='' and $imgh!=''){ $stack[] = '.wp-image-'.$imgid.'{max-width:'.$imgw.'px;max-height:'.$imgh.'px;}'; } } return $stack; } // Check if Yoast WPSEO is installed and handling opengraph and twitter JSON+LD markups. We fill in the gaps and add futher markups where we can. Markups through JSON+LD are best practice and recommended by Google, though not required for AMP compliance. function generate_amp_markups(){ $data = $this->get_document_data(); $pageid = $this->get_value($data,'pageid'); $pagetype = $this->get_value($data,'pagetype'); $jsontype = $this->get_value($data,'jsontype'); $url = $this->get_value($data,'url'); $headline = $this->get_value($data,'headline'); $desc = $this->get_value($data,'desc'); $contype = $this->get_value($data,'contype'); $title = $this->get_value($data,'title'); $sitename = $this->get_value($data,'sitename'); $published = $this->get_value($data,'published'); $modified = $this->get_value($data,'modified'); $author = $this->get_value($data,'author'); $authorid = $this->get_value($data,'authorid'); $publisher = $this->get_value($data,'publisher'); $publishertype = $this->get_value($data,'publishertype'); $logo = $this->get_value($data,'logo'); $logow = $this->get_value($data,'logow'); $logoh = $this->get_value($data,'logoh'); $img = $this->get_value($data,'img'); $imgw = $this->get_value($data,'imgw'); $imgh = $this->get_value($data,'imgh'); $images = $this->get_value($data,'',array()); $category = $this->get_value($data,'category'); $RAT = ''; // Yoast SEO integration, use yoast if installed and option is turned on $useog = true; $usetwit = true; $yoast = false; $yoasted = false; if(defined('WPSEO_FILE')){ $yoast = true; $options = WPSEO_Options::get_option('wpseo_social'); if($options['opengraph']===true){$useog = false;} if($options['twitter']===true){$usetwit = false;} } if(is_home() or is_front_page()){if($yoast==true){$yoasted = true;}} if($useog==true){ $RAT .= ''; $RAT .= ''; $RAT .= ''; $RAT .= ''; $RAT .= ''; if($img!=''){$RAT .= '';} if(count($images)>0){ foreach($images as $image){ $RAT .= ''; } } } if($usetwit==true){ $RAT .= ''; $RAT .= ''; if($img!=''){$RAT .= '';} } if(is_single()){ if($category!=''){$RAT .= '';} if($published!=''){$RAT .= '';} if($modified!=''){ $RAT .= ''; $RAT .= ''; } } if($logo==''){ $logo = $this->get_default_image(); $logow = $this->get_image_info($logo,'width'); $logoh = $this->get_image_info($logo,'height'); } if($img==''){$img = $logo;$imgw = $logow;$imgh = $logoh;} $RAT .= ''; return $RAT; } // Create the Google AMP friendly version of a search form. function generate_amp_search_form($how='',$hwid=''){ $sval = $this->get_value($_GET,'s'); $RAT = ''; $RAT .= '
'; $RAT .= '
'; $RAT .= ''; $RAT .= ''; $RAT .= ''.__('Search','amp-publisher').''; $RAT .= ''; $RAT .= '
'; $RAT .= '
'; return $RAT; } // Create the image chooser box used in Live Editor. function generate_browser_zone($id,$val='',$label=NULL){ if($label==NULL){$label = __('Image Preview','amp-publisher');} $RAT = ''; $RAT .= '
'; $RAT .= '
'.$label.'
'; if($val==''){$val = $this->self['PATH'].'images/chooseimage.png';} $RAT .= ''; $RAT .= ''; $RAT .= '
'.__('Click to Browse Media Library','amp-publisher').'
'; $RAT .= '
'; $RAT .= '
'; $RAT .= '
'; return $RAT; } // Create the CSS included in the header for chosen layouts and post display modes. function generate_compiled_css($ampd,$pageid,$pagetype){ $RAT = ''; if($ampd){ $layout = $this->get_customizer_setting('site_layout'); if($layout==''){$layout = 'base';} $RAT .= $this->function_call('generate_css_layout_'.$layout); $cssfiles = array(); $display = $this->get_customizer_setting('site_postsdisplaymode'); $cssfiles = $this->process_css_for_display($cssfiles,$display); if($this->is_advanced()){$cssfiles = $this->adv_compiled_css($cssfiles,$ampd,$pageid,$pagetype);} if(count($cssfiles)>0){foreach($cssfiles as $file){$RAT .= $this->function_call('generate_css_'.$file);}} }else{ $arr = $this->get_customizer_settings('site_layout'); $layouts = $this->get_value($arr,'choices'); if($layouts!=''){foreach($layouts as $layout=>$layttl){$RAT .= $this->function_call('generate_css_layout_'.$layout);}} $displays = array('article','image','onethree','thumbnail'); foreach($displays as $display){$RAT .= $this->function_call('generate_css_display_'.$display);} $modules = array('social_share','accordion','carousel'); foreach($modules as $mod){$RAT .= $this->function_call('generate_css_module_'.$mod);} } return $RAT; } // Create the CSS included in the header for AMP filters, conversions and settings. function generate_custom_css(){ $RAT = ''; // start a stack of styles to be managed - preventing redundancy $stack = array(); if($this->is_advanced()){$RAT .= $this->generate_composer_css();} // gather styles onto the stack for Page/Post/Category Content conversions $content = $this->get_document_content(); $styles = $this->amp_styles_to_classes($content,'styles'); if(count($styles)>0){ foreach($styles as $style){ foreach($style as $k=>$v){ $val = $this->amp_styles_css($k,$v); if($val!=''){if(!isset($stack[$val])){$stack[$val] = $val;}} } } } // handle maximum widths for responsive amp-img in document content $stack = $this->gather_image_styles($stack,$content); // check for banner logo, get width, then setup css media override to responsive when the image is wider than the viewport... only way to bypass the AMP manipulations that I've found so far $logo = $this->get_customizer_setting('header_logoimage'); if($logo!=''){ $imgdata = $this->get_attachment_data_by_src($logo); $wid = $this->get_value($imgdata,'width'); $hit = $this->get_value($imgdata,'height'); $stack[] = '.headerlogo{max-width:'.$wid.'px;}'; $stack[] = '.bloginfo.haslogo{padding-left:'.($wid+40).'px;}'; } // add social network colors for use in buttons and links $socs = $this->get_social_network_data('social'); foreach($socs as $soc=>$data){ $color = $this->get_value($data,'color'); $stack[] = '.clr-'.$soc.',a.clr-'.$soc.'{color:'.$color.';}'; $stack[] = '.bgclr-'.$soc.'{background-color:'.$color.';}'; } // process stack into CSS if(count($stack)>0){foreach($stack as $css){$RAT .= $css;}} return $RAT; } // Create the big blue button used in the Live Editor. function generate_icon_button($params){ $label = $this->get_value($params,'label'); $title = $this->get_value($params,'title'); $icon = $this->get_value($params,'icon'); $size = $this->get_value($params,'size'); $class = $this->get_value($params,'class'); $style = $this->get_value($params,'style'); $click = $this->get_value($params,'click'); $stize = '';if($size!=''){$stize = ' style="font-size:'.$size.'px;"';} $cls = 'icnbtn';if($class!=''){$cls .= ' '.$class;} $ttl = '';if($title!=''){$ttl = 'title="'.$title.'"';} $RAT = ''; $RAT .= ''; if($icon!=''){$RAT .= '';} if($label!=''){$RAT .= ''.$label.'';} $RAT .= ''; return $RAT; } // Create the checkbox input used by the Live Editor. function generate_live_checkbox($id,$val,$flag=''){ $chk = ''; if($val=='1' or $val=='true' or $val===true){$chk = ' checked';} return ''; } // Create the color picker used by the Live Editor. function generate_live_color_picker($id,$val,$ttl=''){ $RAT = ''; $rgb = ''; $hex = ''; if($this->isRGB($val)){$hex = $this->rgbToHex($val);$rgb = $this->rgbToArray($val);} if($this->isHex($val)){$rgb = $this->hexToRGB($val);$hex = $val;} $RAT .= '
'; $RAT .= '
'; $RAT .= ''; $RAT .= '
'; $RAT .= ''; return $RAT; } // Create the Live Editor interface. function generate_live_editor(){ $editors = array(); $editors['sitewide_editor'] = __('Site Layout / Options','amp-publisher'); $editors['sitewide_style'] = __('Sitewide Styling','amp-publisher'); $editors['banner'] = __('Header - Banner / Logo','amp-publisher'); $editors['titlebar'] = __('Header - Title Bar','amp-publisher'); $editors['sub-header'] = __('Navigation Bar','amp-publisher'); $editors['social_editor'] = __('Social Sharing Buttons','amp-publisher'); $editors['footer'] = __('Footer Styling','amp-publisher'); $editors['seo'] = __('SEO Enhancements','amp-publisher'); if($this->is_advanced()){ $editors['script_editor'] = __('Script / CSS Includes','amp-publisher'); $editors['analytics'] = __('Analytics','amp-publisher'); $editors['sitewide_settings'] = __('Backup / Restore','amp-publisher'); if($this->is_api()){$editors['amptools'] = __('WP AMP Tools API','amp-publisher');} } $docdata = $this->get_document_data(); $pageid = $docdata['pageid']; echo '
'; echo '
'; echo '
'; echo '
'.__('AMP Publisher','amp-publisher').'
'; if($this->is_advanced()){echo '';} echo '
'; echo ''.__('Preview','amp-publisher').''; echo ''; echo '
'; echo ''; $validateurl = $docdata['url']; $validateurl = str_replace('://','%3A%2F%2F',$validateurl); echo ''.__('Validate','amp-publisher').''; echo ''; echo ''.__('Instructions','amp-publisher').''; echo ''; echo '
'; echo '
'; echo ''; echo ''.__('Non-AMP','amp-publisher').''; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; echo ''.__('Site Settings','amp-publisher').''; echo '
'; if($this->is_advanced()){ if(is_single() or is_page() or is_category() or $pageid==0){ echo '
'; echo ''.__('Live Composer','amp-publisher').''; echo '
'; } }else{ echo '
'; echo ''.__('Support & News','amp-publisher').''; echo '
'; } echo '
'; $lestat = $this->report_notices(); $leclass = '';if($lestat!=''){$leclass = 'notices';} echo '
'; echo '
'.$lestat.'
'; echo '
'; echo '
'.__('Save Changes','amp-publisher').'
'; echo '
'; echo '
'; echo '
'; echo '
'; $comclass = '';if($this->is_advanced()){$comclass = ' class="advison"';} echo '
'; echo '
'; foreach($editors as $editor=>$ttl){ echo '
'; $icn = 'paint-brush'; if($editor=='sitewide_editor'){$icn = 'gears';} if($editor=='sitewide_settings'){$icn = 'hdd-o';} if($editor=='analytics'){$icn = 'bar-chart';} if($editor=='script_editor'){$icn = 'code';} if($editor=='seo'){$icn = 'globe';} if($editor=='amptools'){$icn = 'download';} echo '
'.$ttl.'
'; echo '
'; $this->ajax_load_editor(array('id'=>$editor,'typ'=>'editor')); echo '
'; echo '
'; } echo '
'; if(is_single() or is_page() or is_category() or $pageid==0){ // echo '
'; echo '
'; } echo '
'; echo '
'; } // Create the select input used by the Live Editor. function generate_live_select($id,$val,$opts,$flag=''){ $RAT = ''; $RAT .= ''; return $RAT; } // Create the textarea input used by the Live Editor. function generate_live_textarea($id,$val,$flag=''){ return ''; } // Create the text input used by the Live Editor. function generate_live_textfield($id,$val,$filter='safe',$flag=''){ if($filter==''){$filter = 'safe';} // $keydown = ' onkeydown="return inputfilter_'.$filter.'(event);"'; // if($filter=='none'){$keydown = '';} $keydown = '';// TASK - turning off character filter, it does not work return ''; } // Create content for the display block in the slide-out mobile menu. function generate_mobile_menu_block($params=array()){ $RAT = ''; $block = $this->get_customizer_setting('mobilemenu_block','post'); $type = $this->get_value($params,'type',$block); if($type=='post' or $type=='page'){ $atts = shortcode_atts(array('number'=>3,'excerpt_words'=>50,'post_type'=>$type),array()); $RAT .= $this->generate_mobile_menu_latest($atts); }else{ if($type=='custom'){ $content = $this->get_customizer_setting('mobilemenu_custom'); $content = $this->htmlout($content); $content = $this->content_filter($content,true); $RAT .= $content; } } return $RAT; } // Create latest post content for the mobile menu block. function generate_mobile_menu_latest($atts){ $RAT = ''; $type = $this->get_value($atts,'post_type','post'); $limit = $this->get_value($atts,'number',2); $exc = $this->get_value($atts,'excerpt_words',20); global $wpdb; $homeid = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE post_name = 'home'"); $args = array( 'numberposts' => $limit, 'offset' => 0, 'category' => 0, 'orderby' => 'post_date', 'order' => 'DESC', 'include' => '', 'exclude' => $homeid, 'meta_key' => '', 'meta_value' =>'', 'post_type' => $type, 'post_status' => 'publish', 'suppress_filters' => true ); $recent_posts = wp_get_recent_posts( $args, $output = ARRAY_A ); $list = array(); foreach($recent_posts as $dex=>$data){ $post_id = $this->get_value($data,'ID'); if($post_id!=''){ $ttl = $this->get_value($data,'post_title'); $url = esc_url(get_permalink($post_id)); $txt = $this->get_excerpt_by_id($post_id,20); $RAT .= ''; } } return $RAT; } // Create a placeholder box instead of an AMP module when required data is missing. This alerts the admin to the missing content without invalidating AMP compliance. function generate_placeholder($mod,$pass='',$over=''){ $RAT = ''; if($mod=='ad'){$mod = 'AD';} $RAT .= '
'; $RAT .= '
AMP '.$this->ucwords_undash($mod).' Module
'; if($pass!=''){$RAT .= '
'.$pass.'
';} $RAT .= '
'; return $RAT; } // Create the post block DOM used to display posts in archives and post modules. The DOM is modified by CSS for the various display modes. function generate_post($data,$how='',$ampd=false){ $post_id = $this->get_value($data,'ID'); $ttl = $this->get_value($data,'post_title'); $date = $this->get_value($data,'post_date'); $height = $this->get_value($data,'height',300); $twid = $this->get_value($data,'thumbwidth',150); $thit = $this->get_value($data,'thumbheight','auto'); $display = $this->get_value($data,'display'); $url = esc_url(get_permalink($post_id)); $useexcerpt = true; if(is_home() or is_front_page()){ $full = get_option('tacg_fulltextonhome'); }else{ $full = get_option('tacg_fulltextonsite'); } if($full=='1'){$useexcerpt = false;} $sitedisplay = $this->get_customizer_setting('site_postsdisplaymode'); if($display==''){$display = $sitedisplay;} $isarticle = true; if(substr($display,0,7)!='article' or substr($sitedisplay,0,7)!='article'){$isarticle = true;$useexcerpt = true;} if($how=='author'){$useexcerpt = true;} if($useexcerpt){ $txt = $this->get_excerpt_by_id($post_id,24); }else{ $txt = get_the_content($post_id); } $txt = $this->content_filter($txt,$ampd); if($useexcerpt){$txt .= '... '.__('Read More','amp-publisher').'';} $img = $this->get_default_image(); $imgwid = 260; $imghit = 160; if(has_post_thumbnail($post_id)){ $imgid = get_post_thumbnail_id($post_id); $img = wp_get_attachment_url($imgid); $imgdata = wp_get_attachment_metadata($imgid,true); $iwid = $this->get_value($imgdata,'width'); $ihit = $this->get_value($imgdata,'height'); }else{ $iwid = $this->get_image_info($img,'width'); $ihit = $this->get_image_info($img,'height'); } if($iwid!=''){$imgwid = $iwid;} if($ihit!=''){$imghit = $ihit;} $timetxt = ''; if($date!=''){$timetxt = date("M j, Y",strtotime($date));} $author = ''; $authorid = $this->get_value($data,'post_author'); if($authorid!=''){ $user = get_userdata($authorid); $author = $this->get_value($user,array('data','display_name')); } $cats = $this->get_post_category_data($post_id,'all','array'); $notags = false; $tags = array(); if(count($cats)>0){ foreach($cats as $cat){ $catid = $this->get_value($cat,'term_id'); if($catid>1 or $notags){ $catname = $this->get_value($cat,'name'); $catlink = $this->taxes(array('com'=>'link','id'=>$catid)); $tags[$catname] = $catlink; } } } if(count($tags)==0){ $thetags = wp_get_post_tags($post_id); if(count($thetags)>0){ foreach($thetags as $term){ $catid = $this->get_value($term,'term_id'); $catname = $this->get_value($term,'name'); $catlink = get_tag_link($catid); if($catlink!='' and $catname!=''){$tags[$catname] = $catlink;} } } } if($how=='array'){return array('title'=>$ttl,'snippet'=>$txt,'image'=>$img,'wid'=>$imgwid,'hit'=>$imghit,'link'=>$url,'tags'=>$tags,'date'=>$timetxt,'author'=>$author);} $addhit = ''; if(substr($display,0,5)=='image'){$addhit .= ' hit-'.$height;} if($display=='thumbnail'){$addhit .= ' wid-'.$twid;} $RAT = ''; $RAT .= '
'; $RAT .= '
'; if(count($tags)>0){ $RAT .= '
'; foreach($tags as $tag=>$tagurl){ $RAT .= ''.$tag.''; } $RAT .= '
'; } $RAT .= '
'; $RAT .= ''; $imgadd = ''; $imgd = ''; if($display=='thumbnail'){ if($thit=='auto'){ if($ampd){ $imgadd .= ' width="'.$imgwid.'" height="'.$imghit.'" layout="responsive" class="ampimage"'; }else{ $sthit = floor($imghit/$imgwid*$twid); $imgadd .= ' width="'.$twid.'" height="'.$sthit.'" layout="responsive" class="ampimage"'; } }else{ $imgadd .= ' width="'.$twid.'" height="'.$thit.'" layout="fixed" class="ampimage"'; } }else{ if($ampd){ if($display=='articlefw'){ $imgd = 'amp-';$imgadd .= ' width="'.$imgwid.'" height="'.$imghit.'" sizes="(max-width: '.$imgwid.'px) 100vw, '.$imgwid.'px" layout="responsive" class="ampimage"'; }else{ $imgd = 'amp-';$imgadd .= ' width="'.$imgwid.'" height="'.$imghit.'" layout="responsive" class="ampimage"'; } }else{ if($display=='articlefw'){$imgadd .= ' width="'.$imgwid.'" height="'.$imghit.'"';} } } if($ampd){$imgd = 'amp-';} if($display=='thumbnail'){$RAT .= '';} $RAT .= '<'.$imgd.'img src="'.$img.'"'.$imgadd.'>'; // placeholder and fallback if any $RAT .= ''; if($display=='thumbnail'){$RAT .= '';} $RAT .= ''; $RAT .= '
'; $RAT .= '
'; $RAT .= '

'.$ttl.'

'; $RAT .= ''; $RAT .= ''; $RAT .= $txt; $RAT .= ''; if($this->is_advanced()){$RAT .= $this->adv_post_ads($post_id,$ampd);} $RAT .= '
'; $RAT .= '
'; $RAT .= '
'; $RAT .= '
'; $RAT .= '
'; $RAT .= '
'; return $RAT; } // Create the social/custom button bar displayed in the header and footer. function generate_social_bar(){ $RAT = ''; $list = $this->get_customizer_setting('social_buttonlist'); if($list!=''){ $exp = explode('[JJ]',$list); foreach($exp as $part){ $parts = explode('[DD]',$part); $icon = $this->get_value($parts,0); $url = $this->get_value($parts,1); $ttl = $this->get_value($parts,2); $RAT .= '
  •  
  • '; } } $usefeed = $this->get_customizer_setting('social_rssfeed'); if($usefeed==''){ $feedurl = $this->get_site_base_url().'/feed'; $RAT .= '
  •  
  • '; } return $RAT; } // Create the button used by the Social Sharing Button Manager. function generate_social_button_item($data){ $icon = $this->get_value($data,'icon'); $url = $this->get_value($data,'url'); $ttl = $this->get_value($data,'title'); $RAT = ''; $RAT .= '
    '; $RAT .= '
    '; $RAT .= '
    '; $RAT .= '
    '; $RAT .= '
    '; $RAT .= '
    EMPTY URL
    '; $RAT .= '
    INVALID URL
    '; $RAT .= '
    '; $RAT .= __('Link URL','amp-publisher'); $RAT .= ''; $RAT .= __('Title (for mouse/SEO)','amp-publisher'); $RAT .= ''; $RAT .= '
    '; $RAT .= '
    '; return $RAT; } // Create the Social Sharing Button Manager in the Live Editor. This is the only feature available to the Live Editor that is not available to WP Customizer. function generate_social_button_manager(){ $RAT = ''; $RAT .= ''.__('Choose an Icon to Create a Button','amp-publisher').''; $list = $this->get_customizer_setting('social_buttonlist'); $RAT .= '
    '; if($list!=''){ $exp = explode('[JJ]',$list); foreach($exp as $part){ $parts = explode('[DD]',$part); $icon = $this->get_value($parts,0); $url = $this->get_value($parts,1); $ttl = $this->get_value($parts,2); $RAT .= $this->generate_social_button_item(array('icon'=>$icon,'url'=>$url,'title'=>$ttl)); } } $RAT .= '
    '; return $RAT; } // Create an AMP video module. function generate_video_module($attrs,$ampd=false){ $RAT = ''; $provider = $this->get_value($attrs,'provider'); $source = $this->get_value($attrs,'sourcecode'); $aspect = $this->get_value($attrs,'aspectratio'); $width = 16; $height = 9; $layout = 'responsive'; if($layout=='responsive' and $aspect!=''){ $vals = explode('x',$aspect); $xwid = $this->get_value($vals,0,$width); $xhit = $this->get_value($vals,1,$height); $width = $xwid; $height = $xhit; } $atts = ''; $warn = ''; $vidttl = ''; if($provider==''){ $warn = 'You must choose a Provider'; }else{ $providers = $GLOBALS['VIDEO_PROVIDERS']; $vars = array('reach-player'=>'embed-id','brid-player'=>'video','dailymotion'=>'videoid','facebook'=>'href','vimeo'=>'videoid','youtube'=>'videoid'); $ttls = array('reach-player'=>'Embed ID','brid-player'=>'Video ID','dailymotion'=>'Video ID','facebook'=>'Video URL','vimeo'=>'Video ID','youtube'=>'Video ID'); $pass = ''.$this->get_value($providers,$provider).''; $ttl = $this->get_value($ttls,$provider); $video = $this->get_value($attrs,'video'); if($provider=='brid-player'){ $partner = $this->get_value($attrs,'partner'); $player = $this->get_value($attrs,'player'); $playlist = $this->get_value($attrs,'playlist'); if($partner=='' or $player==''){ $warn = 'You must enter your Brid.tv "Partner ID" and "Player ID"'; }else if($video=='' and $playlist==''){ $warn = 'You must enter either a Brid.tv "Video ID" or "Playlist ID"'; }else{ $atts .= ' data-partner="'.$partner.'"'; $atts .= ' data-player="'.$player.'"'; if($play!=''){ $atts .= ' data-playlist="'.$play.'"'; $vidttl = 'Playlist ID: '.$video; }else{ $atts .= ' data-video="'.$video.'"'; $vidttl = 'Video ID: '.$video; } } }else{ $vidvar = ''; if($provider=='vimeo' or $provider=='dailymotion' or $provider=='youtube'){ $vidvar = 'videoid'; }else if($provider=='reach-player'){ $vidvar = 'embed-id'; }else if($provider=='facebook'){ $vidvar = 'href'; $atts .= ' data-embed-as="video"'; }else if($provider=='video'){ if(strstr($video,'wp-content/uploads')){ $exp = explode('wp-content/uploads',$video); $path = $this->get_value($exp,1); if($path!=''){ $vidvar = 'video'; $atts .= ' controls'; $atts .= ' src="../wp-content/uploads'.$path.'"'; $atts .= ' poster="'.$this->self['PATH'].'images/vidposter.jpg"'; } } } if($vidvar!=''){ if($source=='shortcode'){ $video = $this->get_value($attrs,'video'); }else{ $video = $this->get_value($attrs,$vidvar); } $prov = $providers[$provider]; if($video==''){ $warn = 'You must enter your '.$prov.' "'.$ttl.'"'; }else{ $atts .= ' data-'.$vidvar.'="'.$video.'"'; if($provider=='facebook' or $provider=='video'){ $vidttl = $video; }else{ $vidttl = $this->get_value($ttls,$provider).': '.$video; } } } } } if($ampd and $warn==''){ $RAT .= ''; }else{ if($provider==''){ $pass = $this->generate_warning($warn); }else{ $pass = ''.$providers[$provider].''; if($warn==''){ $pass .= '
    '.$vidttl.''; }else{ $pass .= $this->generate_warning($warn); } } $over = ''; if($ampd){$over = 'amp';} $RAT .= $this->generate_placeholder('video',$pass,$over); } return $RAT; } // Create a warning box, used to alert about missing data where AMP modules would be displayed. function generate_warning($pass){ $RAT = ''; $RAT .= ''.$pass.''; return $RAT; } // Return the image source URL for default image setting, if none is set it returns the theme's default image. This prevents invalidating AMP compliance if no image is available and nudges the user to assign one where they should. function get_default_image(){ $def = $this->get_customizer_setting('site_defaultimage'); if($def!=''){return $def;} return $this->self['PATH'].'images/no-image-found.jpg'; } // Retrieve filtered page content across types. This simplifies development and ensures properly formatted content. function get_document_content(){ $data = $this->get_document_data(); $pageid = $this->get_value($data,'pageid'); $pagetype = $this->get_value($data,'pagetype'); if($pagetype=='category'){ $term = get_term($pageid,'category'); $desc = $this->get_value($term,'description'); $content = $this->content_filter($desc); }else{ $content_post = get_post($pageid); $content = $this->get_value($content_post,'post_content'); $content = str_replace(']]>', ']]>', $content); $content = $this->htmlout($content); } return $content; } // Return an array with information about the document, it's content, and it's markup data. function get_document_data(){ $jsontype = 'WebPage'; $url = $this->current_page_url(); $headline = $this->get_page_title(); $desc = ''; $contype = 'website'; $title = $headline; $sitename = get_bloginfo('title'); if(is_home() or is_front_page()){ $headline = $sitename; $jsontype = 'WebSite'; $desc = get_bloginfo('description'); }else{ if(is_category()){ $jsontype = 'WebSite'; }else{ if(is_single()){$jsontype = 'NewsArticle';} $contype = 'article'; } } $published = ''; $modified = ''; $author = ''; $authorid = ''; if(is_category()){ $term_id = $this->taxes(array('com'=>'id')); $data = $this->taxes(array('com'=>'data','id'=>$term_id)); $pageid = $term_id; $pagetype = 'category'; }else if(is_front_page() or is_home()){ $data = get_post(); $post_id = $this->get_value($data,'ID'); $post_type = $this->get_value($data,'post_type'); if($post_type=='page'){ $pageid = $post_id; $pagetype = 'page'; }else{ $pageid = 0; $pagetype = 'post'; } }else{ $data = get_post(); $post_id = $this->get_value($data,'ID'); $authorid = $this->get_value($data,'post_author'); $published = $this->get_value($data,'post_date'); $modified = $this->get_value($data,'post_modified'); $published = str_replace(' ','T',$published); $modified = str_replace(' ','T',$modified); $pageid = $post_id; $pagetype = $this->get_value($data,'post_type'); } if($authorid!=''){$author = get_the_author_meta('nicename',$authorid);} if($published==''){$published = date('Y-m-dTh:i:sZ',time());} $logow = ''; $logoh = ''; $imgw = ''; $imgh = ''; $images = array(); $logo = $this->get_customizer_setting('header_logoimage'); if($logo!=''){ $logow = $this->get_image_info($logo,'width'); $logoh = $this->get_image_info($logo,'height'); } $img = $this->get_featured_image($pageid); if($img!=''){ $imgw = $this->get_image_info($img,'width'); $imgh = $this->get_image_info($img,'height'); } $publisher = get_bloginfo('name'); $publishertype = 'Organization'; $category = ''; $categories = ''; if(is_single()){ $category = $this->get_post_category_data(); $categories = $this->get_post_category_data($pageid,'all','array'); } $DAT = array(); $DAT['pagetype'] = $pagetype; $DAT['pageid'] = $pageid; $DAT['jsontype'] = $jsontype; $DAT['url'] = $url; $DAT['slug'] = $this->last_page_in_url($url); $DAT['headline'] = $headline; $DAT['desc'] = $desc; $DAT['contype'] = $contype; $DAT['title'] = $title; $DAT['sitename'] = $sitename; $DAT['published'] = $published; $DAT['modified'] = $modified; $DAT['author'] = $author; $DAT['authorid'] = $authorid; $DAT['publisher'] = $publisher; $DAT['publishertype'] = $publishertype; $DAT['logo'] = $logo; $DAT['logow'] = $logow; $DAT['logoh'] = $logoh; $DAT['img'] = $img; $DAT['imgw'] = $imgw; $DAT['imgh'] = $imgh; $DAT['images'] = $images; $DAT['category'] = $category; $DAT['categories'] = $categories; return $DAT; } // Return an array with standard size choices available to the Live Editor. function get_size_choices($how=''){ $RET = array(); $pre = substr($how,0,5); if($how=='auto' or $how=='thumbheight'){$RET ['auto'] = 'Auto';} $RET['100'] = '100px'; if($pre=='thumb'){ $RET['110'] = '110px'; $RET['120'] = '120px'; $RET['130'] = '130px'; $RET['140'] = '140px'; } $RET['150'] = '150px'; if($pre=='thumb'){ $RET['160'] = '160px'; $RET['170'] = '170px'; $RET['180'] = '180px'; $RET['190'] = '190px'; } $RET['200'] = '200px'; if($pre=='thumb'){ $RET['220'] = '220px'; $RET['240'] = '240px'; $RET['260'] = '260px'; $RET['280'] = '280px'; } $RET['300'] = '300px'; if($pre!='thumb'){ $RET['400'] = '400px'; $RET['500'] = '500px'; $RET['600'] = '600px'; $RET['700'] = '700px'; $RET['800'] = '800px'; $RET['900'] = '900px'; $RET['1000'] = '1000px'; } return $RET; } // Return an array with icon, color and display data for social networks. function get_social_network_data($network=NULL){ $RET['facebook'] = array('icon'=>'facebook','square'=>'facebook-square','color'=>'#3b5998','title'=>'Facebook'); $RET['flickr'] = array('icon'=>'flickr','color'=>'#dc4e41','title'=>'Flickr'); $RET['gplus'] = array('icon'=>'google-plus','square'=>'google-plus-square','color'=>'#D51F1E','title'=>'Google+'); $RET['instagram'] = array('icon'=>'instagram','color'=>'#F00','title'=>'Instagram'); $RET['linkedin'] = array('icon'=>'linkedin','square'=>'linkedin-square','color'=>'#0077b5','title'=>'LinkedIn'); $RET['pinterest'] = array('icon'=>'pinterest-p','square'=>'pinterest-square','color'=>'#bd081c','title'=>'Pinterest'); $RET['tumblr'] = array('icon'=>'tumblr','square'=>'tumblr-square','color'=>'#33465D','title'=>'Tumblr'); $RET['twitter'] = array('icon'=>'twitter','square'=>'twitter-square','color'=>'#55acee','title'=>'Twitter'); $RET['vimeo'] = array('icon'=>'vimeo','square'=>'vimeo-square','color'=>'#1AB7EA','title'=>'Vimeo'); $RET['youtube'] = array('icon'=>'youtube-play','square'=>'youtube-square','color'=>'#DD2623','title'=>'YouTube'); if($network!='social'){ $RET['email'] = array('icon'=>'envelope-o','square'=>'envelope-square','color'=>'#000','title'=>'Email'); $RET['rss'] = array('icon'=>'rss','square'=>'rss-square','color'=>'#F90','title'=>'RSS Feed'); } if($network!=NULL and $network!='social'){return $this->get_value($RET,$network,array());} return $RET; } // Create script tag for a Google AMP module. Each type of module requires it's script file to be included in the header. function include_amp_module($mod){ $vers = '0.1'; if($mod=='sticky-ad'){$vers = '1.0';} echo ''; } // Process and include all Google AMP module script files that are required. function include_amp_modules(){ $used = array(); $this->include_amp_module('form');$used['form'] = true; $this->include_amp_module('sidebar');$used['sidebar'] = true; $txt = $this->get_document_content(); $embeds = $this->extract_wp_embeds($txt); if(count($embeds)>0){foreach($embeds as $prov=>$embs){$this->register_amp_module($prov);}} $reg = $this->registered_amp_modules(); if(count($reg)>0){foreach($reg as $module){$this->include_amp_module($module);$used[$module] = true;}} if($this->is_advanced()){$used = $this->adv_amp_modules($used);} } // The default state of the entire site while not logged in is AMP compliant, then non-AMP versions of pages/posts are opened to allow form handling and submission (this is opposite of how everyone else is doing it). // AMP is turned off when logged in for the Live Editor to work, but you can still view the document through AMP using the preview options. // Check if the document is supposed to be displayed through AMP or not. function is_amp(){ $doc = $this->get_document_data(); $dt = $doc['pagetype']; if($dt!='post' and $dt!='page' and $dt!='category'){ return false; }else{ if($dt=='post' or $dt=='page'){ $pageid = $doc['pageid']; $mamp = $this->get_meta($pageid,'NonAMP'); if($mamp=='1'){return false;} } } if($this->get_value($_GET,'useforms')=='1'){return false;} if($this->is_amp_preview()){return true;} if($this->is_user_admin()){return false;} return true; } // Check if the document should be generated as a "non-AMP" version for form handling. function is_amp_not(){ $doc = $this->get_document_data(); $dt = $doc['pagetype']; if($dt!='post' and $dt!='page' and $dt!='category'){ return true; }else{ if($dt=='post' or $dt=='page'){ $pageid = $doc['pageid']; $mamp = $this->get_meta($pageid,'NonAMP'); if($mamp=='1' or $mamp=='true'){return true;} } } if($this->get_value($_GET,'useforms')=='1'){return true;} return false; } // Check if the document should be generated as an AMP preview. function is_amp_preview(){ if($this->get_value($_GET,'amp')=='1'){return true;} if($this->get_value($_GET,'preview')=='1'){return true;} return false; } // Check if the current theme is a child theme. function is_child(){ if(function_exists('tacg_amp_child_theme')){return true;} return false; } // Check if the document can use comments and if it should be generated as a "non-AMP" version for form handling. function is_comments(){ //if($this->is_comments_wp() && ($this->is_amp_not() or $this->is_user_admin())){return true;} if($this->is_comments_wp() && ($this->is_amp_not() or ($this->is_user_admin() and !$this->is_amp_preview()))){return true;} return false; } // Check several points to find out if comments are on, available and should be displayed. function is_comments_wp(){ if((!is_admin()) && is_singular() && comments_open() && get_option('thread_comments')){return true;} return false; } // Check several points to find out if the sidebar is on, available and should be displayed. function is_sidebar($pageid=NULL,$pagetype=NULL){ if($pagetype=='post' and $this->get_meta($pageid,'HideSidebar')!=''){return '';} $data = $this->get_document_data(); $pagetype = $this->get_value($data,'pagetype'); $pageid = $this->get_value($data,'pageid'); $pageurl = $this->get_value($data,'url'); $blogurl = $this->get_site_base_url(); $fhome = false; if($pageurl!=''){ $purls = explode('?',$pageurl); $purl = $purls[0]; $furl = str_replace($blogurl,'',$purl); if(substr($furl,0,1)=='/'){$furl = substr($furl,1);} if($furl==''){$fhome = true;} } $sid = ''; if(is_category()){ $sid = 'category'; }else if(is_home() and is_front_page()){ $sid = 'home';// default }else if(is_front_page()){ $sid = 'home';// front }else if(is_home()){ $sid = 'home'; if($pagetype=='post' and $pageid=='0'){ if($fhome==true){ $sid = 'home';// default }else{ $sid = 'category';// blog } } }else if(is_page()){ $sid = 'page'; }else if(is_single()){ $sid = 'post'; }else if(is_archive()){ $sid = 'archive'; } $side = $sid.'sidebar'; if($this->get_customizer_setting('site_hide'.$side)!=''){return '';} if(is_active_sidebar($side)){return $side;} if($this->is_advanced()){if($this->adv_is_sidebar($pageid,$pagetype)!='na'){return $side;}} if(is_active_sidebar('sitesidebar')){return $side;} return 'na'; } // Create the pagination bar for posts/archives. function page_navigation() { global $wp_query; $bignum = 999999999; if ( $wp_query->max_num_pages <= 1 ){return;} echo '