Advertisement
Guenni007

function-set-avia-frontend

Jul 30th, 2023
1,224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 73.37 KB | None | 0 0
  1. <?php
  2. /**
  3.  * This file holds various helper functions that are needed by the frameworks FRONTEND
  4.  *
  5.  * @author      Christian "Kriesi" Budschedl
  6.  * @copyright   Copyright (c) Christian Budschedl
  7.  * @link        http://kriesi.at
  8.  * @link        http://aviathemes.com
  9.  * @since       Version 1.0
  10.  * @package     AviaFramework
  11.  */
  12. if( ! defined( 'AVIA_FW' ) ) {   exit( 'No direct script access allowed' );   }
  13.  
  14.  
  15. if( ! function_exists( 'avia_option' ) )
  16. {
  17.     /**
  18.      * This function serves as shortcut for avia_get_option and is used to retrieve options saved within the database with the first key set to "avia" which is the majority of all options
  19.      * Please note that while the get_avia_option returns the result, this function echos it by default. if you want to retrieve an option and store the variable please use get_avia_option or set $echo to false
  20.      *
  21.      * basically the function is called like this: avia_option('portfolio');
  22.      * That would retrieve the following var saved in the global $avia superobject: $avia->options['avia']['portfolio']
  23.      * If you want to set a default value that is returned in case there was no array match you need to use this scheme:
  24.      *
  25.      * avia_option( 'portfolio', "my default");
  26.      *
  27.      * @deprecated 4.9
  28.      * @param string $key accepts a comma separated string with keys
  29.      * @param string $default return value in case we got no result
  30.      * @param bool $echo echo the result or not, default is to false
  31.      * @param bool $decode decode the result or not, default is to false
  32.      * @return string $result: the saved result. if no result was saved or the key doesnt exist returns an empty string
  33.      */
  34.     function avia_option( $key, $default = '', $echo = true, $decode = true )
  35.     {
  36.         _deprecated_function( 'avia_option', '4.9', 'use avia_get_option instead - will be removed in future' );
  37.  
  38.         $result = avia_get_option( $key, $default, false, $decode );
  39.  
  40.         if( ! $echo)
  41.         {
  42.             return $result; //if we dont want to echo the output end script here
  43.         }
  44.  
  45.         echo $result;
  46.     }
  47. }
  48.  
  49.  
  50. if( ! function_exists( 'avia_get_option' ) )
  51. {
  52.     /**
  53.      * This function serves as shortcut to retrieve options saved within the database by the option pages of the avia framework
  54.      *
  55.      * basically the function is called like this: avia_get_option('portfolio');
  56.      * That would retrieve the following var saved in the global $avia superobject: $avia->options['avia']['portfolio']
  57.      * If you want to set a default value that is returned in case there was no array match OR value is '' (this is different behaviour from get_option() !!!! )
  58.      * you need to use this scheme:
  59.      *
  60.      * avia_get_option( 'portfolio', 'my default' ); or
  61.      * avia_get_option( array( 'avia','portfolio' ), 'my default' );
  62.      *
  63.      * @since 4.8                       support for multiple option pages
  64.      * @param string|array|false $key   see above
  65.      * @param string $default           return value in case we got no result - and - if value of option = '' ( !!!!! )
  66.      * @param bool $echo                echo the result or not, default is to false
  67.      * @param bool $decode              decode the result or not, default is to false
  68.      * @return mixed                    the saved result. if no result was saved, the key doesn't exist or is '' returns $default
  69.      */
  70.     function avia_get_option( $key = false, $default = '', $echo = false, $decode = true )
  71.     {
  72.         global $avia;
  73.  
  74.         /**
  75.          * This fixed a problem with WP CLI: wp cache flush
  76.          *
  77.          *      Trying to get property of non-object $avia
  78.          *
  79.          * Adding global $avia; to framework\avia_framework.php did the final solution - we keep this for a fallback only.
  80.          */
  81.         if( ! $avia instanceof avia_superobject )
  82.         {
  83.             $avia = AviaSuperobject();
  84.         }
  85.  
  86.         $pages = array();
  87.         $opt_key = '';
  88.         $result = null;
  89.  
  90.         if( false === $key )
  91.         {
  92.             //  Return 'avia' page array
  93.             $result = isset( $avia->options['avia'] ) ? $avia->options['avia'] : array();
  94.         }
  95.         else if( is_array( $key ) && count( $key ) == 0 )
  96.         {
  97.             //  fallback -> we return default value
  98.             $result = $default;
  99.         }
  100.         else if( is_array( $key ) && count( $key ) == 1 )
  101.         {
  102.             //  @since 4.8 return requested page array
  103.             $result = isset( $avia->options[ $key[0] ] ) ? $avia->options[ $key[0] ] : array();
  104.         }
  105.         else
  106.         {
  107.             if( is_array( $key ) && count( $key ) > 1 )
  108.             {
  109.                 $pages[] = isset( $key[0] ) ? $key[0] : '';
  110.                 $opt_key = isset( $key[1] ) ? $key[1] : '';
  111.             }
  112.             else
  113.             {
  114.                 //  force avia to be the main array to search for option
  115.                 $pages[] = 'avia';
  116.                 $pages = array_unique( array_merge( $pages, array_keys( $avia->options ) ) );
  117.                 $opt_key = $key;
  118.             }
  119.  
  120.             //  Scan all pages for option
  121.             foreach( $pages as $page )
  122.             {
  123.                 if( isset( $avia->options[ $page ] ) && isset( $avia->options[ $page ][ $opt_key ] ) )
  124.                 {
  125.                     $result = $avia->options[ $page ][ $opt_key ];
  126.                     break;
  127.                 }
  128.             }
  129.  
  130.             /**
  131.              * !!!!  Different behaviour as get_option():
  132.              *
  133.              * Also return $default when options value is ''
  134.              */
  135.             if( is_null( $result ) || ( '' == $result ) )
  136.             {
  137.                 $result = $default;
  138.             }
  139.         }
  140.  
  141.         if( $decode )
  142.         {
  143.             $result = avia_deep_decode( $result );
  144.         }
  145.  
  146.         if( $echo )
  147.         {
  148.             echo $result;
  149.         }
  150.  
  151.         return $result;
  152.     }
  153. }
  154.  
  155.  
  156. if( ! function_exists( 'avia_update_option' ) )
  157. {
  158.     /**
  159.      * This function serves as shortcut to update a single theme option
  160.      * You must specify the correct option page.
  161.      *
  162.      * @since ????
  163.      * @since 4.9                       support multiple option pages
  164.      * @param string|array $key         'my_option' | array( 'page_slug', 'my_option' ) | array( 'my_option' ) ==> array( 'avia', 'my_option' )
  165.      * @param mixed $value
  166.      */
  167.     function avia_update_option( $key, $value = '' )
  168.     {
  169.         global $avia;
  170.  
  171.         $page = 'avia';
  172.  
  173.         if( is_array( $key ) && count( $key ) == 1 )
  174.         {
  175.             $option_key = $key[0];
  176.         }
  177.         else if( is_array( $key ) && count( $key ) > 1 )
  178.         {
  179.             $page = $key[0];
  180.             $option_key = $key[1];
  181.         }
  182.         else
  183.         {
  184.             $option_key = $key;
  185.         }
  186.  
  187.         $avia->options[ $page ][ $option_key ] = $value;
  188.  
  189.         update_option( $avia->option_prefix, $avia->options );
  190.     }
  191. }
  192.  
  193.  
  194. if( ! function_exists( 'avia_delete_option' ) )
  195. {
  196.     /**
  197.      * This function serves as shortcut to delete a single theme option
  198.      * You must specify the correct option page.
  199.      *
  200.      * @since ????
  201.      * @since 4.9                       support multiple option pages
  202.      * @param string|array $key         'my_option' | array( 'page_slug', 'my_option' ) | array( 'my_option' ) ==> array( 'avia', 'my_option' )
  203.      */
  204.     function avia_delete_option( $key )
  205.     {
  206.         global $avia;
  207.  
  208.         $page = 'avia';
  209.  
  210.         if( is_array( $key ) && count( $key ) == 1 )
  211.         {
  212.             $option_key = $key[0];
  213.         }
  214.         else if( is_array( $key ) && count( $key ) > 1 )
  215.         {
  216.             $page = $key[0];
  217.             $option_key = $key[1];
  218.         }
  219.         else
  220.         {
  221.             $option_key = $key;
  222.         }
  223.  
  224.         unset( $avia->options[ $page ][ $option_key ] );
  225.  
  226.         update_option( $avia->option_prefix , $avia->options );
  227.     }
  228. }
  229.  
  230. if( ! function_exists( 'avia_minify_extension' ) )
  231. {
  232.     /**
  233.      * Returns .min if option is set to load minified js or css files
  234.      *
  235.      * @since 5.2
  236.      * @param string $which
  237.      * @return string
  238.      */
  239.     function avia_minify_extension( $which = 'js' )
  240.     {
  241.         switch( $which )
  242.         {
  243.             case 'js':
  244.                 $key = 'merge_js';
  245.                 break;
  246.             case 'css':
  247.                 $key = 'merge_css';
  248.                 break;
  249.             default:
  250.                 return '';
  251.         }
  252.  
  253.         return 'minified_only' == avia_get_option( $key, 'none' ) ? '.min' : '';
  254.     }
  255. }
  256.  
  257.  
  258. if( ! function_exists( 'avia_get_the_ID' ) )
  259. {
  260.     /**
  261.     * This function is similiar to the wordpress function get_the_ID, but other than the wordpress function this functions takes into account
  262.     * if we will display a different post later on, a post that differs from the one we queried in the first place. The function also holds this
  263.     * original ID, even if another query is then executed (for example in dynamic templates for columns)
  264.     *
  265.     * an example would be the frontpage template were by default, the ID of the latest blog post is served by wordpress get_the_ID function.
  266.     * avia_get_the_ID would return the same blog post ID if the blog is really displayed on the frontpage. if a static page is displayed the
  267.     * function will display the ID of the static page, even if the page is not yet queried
  268.     *
  269.     * @return int $ID: the "real" ID of the post/page we are currently viewing
  270.     */
  271.     function avia_get_the_ID()
  272.     {
  273.         global $avia_config;
  274.  
  275.         $ID = false;
  276.  
  277.         if( ! isset( $avia_config['real_ID'] ) )
  278.         {
  279.             if( ! empty( $avia_config['new_query']['page_id'] ) )
  280.             {
  281.                 $ID = $avia_config['new_query']['page_id'];
  282.                 $avia_config['real_ID'] = $ID;
  283.             }
  284.             else
  285.             {
  286.                 $post = get_post();
  287.                 if( isset( $post->ID ) )
  288.                 {
  289.                     $ID = $post->ID;
  290.                     $avia_config['real_ID'] = $ID;
  291.                 }
  292.                 else
  293.                 {
  294.                     $ID = false;
  295.                 }
  296.                 //$ID = @get_the_ID();
  297.             }
  298.         }
  299.         else
  300.         {
  301.             $ID = $avia_config['real_ID'];
  302.         }
  303.  
  304.         /**
  305.          * @since ???
  306.          * @param int $ID
  307.          * @return int
  308.          */
  309.         $ID = apply_filters( 'avf_avia_get_the_ID', $ID );
  310.  
  311.         return $ID;
  312.     }
  313.  
  314.     add_action( 'wp_head', 'avia_get_the_ID' );
  315. }
  316.  
  317.  
  318. if( ! function_exists( 'avia_is_overview' ) )
  319. {
  320.     /**
  321.     * This function checks if the page we are going to render is a page with a single entry or a multi entry page (blog or archive for example)
  322.     *
  323.     * @return bool $result true or false
  324.     */
  325.     function avia_is_overview()
  326.     {
  327.         global $avia_config;
  328.  
  329.         $result = true;
  330.  
  331.         if( is_singular() )
  332.         {
  333.             $result = false;
  334.         }
  335.  
  336.         if( is_front_page() && avia_get_option( 'frontpage' ) == avia_get_the_ID() )
  337.         {
  338.             $result = false;
  339.         }
  340.  
  341.         if( isset( $avia_config['avia_is_overview'] ) )
  342.         {
  343.             $result = $avia_config['avia_is_overview'];
  344.         }
  345.  
  346.         return $result;
  347.     }
  348. }
  349.  
  350. if( ! function_exists( 'avia_post_meta' ) )
  351. {
  352.     /**
  353.      * This function retrieves the custom field values for a given post and saves it to the global avia config array
  354.      * If a subkey was set the subkey is returned, otherwise the array is saved to the global config array
  355.      * The function also hooks into the post loop and is automatically called for each post
  356.      *
  357.      * @param int|string $post_id
  358.      * @param string|false $subkey
  359.      * @return false|mixed
  360.      */
  361.     function avia_post_meta( $post_id = '', $subkey = false )
  362.     {
  363.         $avia_post_id = $post_id;
  364.  
  365.         //if the user only passed a string and no id the string will be used as subkey
  366.         if( ! $subkey && $avia_post_id != '' && ! is_numeric( $avia_post_id ) && ! is_object( $avia_post_id ) )
  367.         {
  368.             $subkey = $avia_post_id;
  369.             $avia_post_id = '';
  370.         }
  371.  
  372.         global $avia, $avia_config;
  373.  
  374.         $key = '_avia_elements_' . $avia->option_prefix;
  375.         if( current_theme_supports( 'avia_post_meta_compat' ) )
  376.         {
  377.             $key = '_avia_elements_theme_compatibility_mode'; //activates a compatibility mode for easier theme switching and keeping post options
  378.         }
  379.  
  380.         //if post id is on object the function was called via hook. If thats the case reset the meta array
  381.         if( is_object( $avia_post_id ) && isset( $avia_post_id->ID ) )
  382.         {
  383.             $avia_post_id = $avia_post_id->ID;
  384.         }
  385.  
  386.         if( ! $avia_post_id )
  387.         {
  388.             $avia_post_id = @get_the_ID();
  389.         }
  390.  
  391.         if( ! is_numeric( $avia_post_id ) )
  392.         {
  393.             return false;
  394.         }
  395.  
  396.         $avia_config['meta'] = avia_deep_decode( get_post_meta( $avia_post_id, $key, true ) );
  397.  
  398.         /**
  399.          * @since ???
  400.          * @param array $avia_config['meta']
  401.          * @param int $avia_post_id
  402.          * @return array
  403.          */
  404.         $avia_config['meta'] = apply_filters( 'avia_post_meta_filter', $avia_config['meta'], $avia_post_id );
  405.  
  406.         if( $subkey && isset( $avia_config['meta'][ $subkey ] ) )
  407.         {
  408.             $meta = $avia_config['meta'][ $subkey ];
  409.         }
  410.         else if( $subkey )
  411.         {
  412.             $meta = false;
  413.         }
  414.         else
  415.         {
  416.             $meta = $avia_config['meta'];
  417.         }
  418.  
  419.         return $meta;
  420.     }
  421.  
  422.     add_action( 'the_post', 'avia_post_meta' );
  423. }
  424.  
  425. if( ! function_exists( 'avia_get_modified_option' ) )
  426. {
  427.     /**
  428.     * This function returns an option that was set in the backend. However if a post meta key with the same name exists it retrieves this option instead
  429.     * That way we can easily set global settings for all posts in our backend (for example slideshow duration options) and then overrule those options
  430.     *
  431.     * In addition to the option key we need to pass a second key for a post meta value that must return a value other then empty before the global settings can be overwritten.
  432.     * (example: should ths post use overwritten options? no=>'' yes=>"yes")
  433.     *
  434.     * @param string $key            database key for both the post meta table and the framework options table
  435.     * @param string $extra_check    database key for both a post meta value that needs to be true in order to accept an overwrite
  436.     * @return string                $result: the saved result. if no result was saved or the key doesnt exist returns an empty string
  437.     */
  438.     function avia_get_modified_option( $key, $extra_check = false )
  439.     {
  440.         global $post;
  441.  
  442.         //if we need to do an extra check get the post meta value for that key
  443.         if( $extra_check && isset( $post->ID ) )
  444.         {
  445.             $extra_check = get_post_meta( $post->ID, $extra_check, true );
  446.             if( $extra_check )
  447.             {
  448.                 //add underline to the post meta value since we always hide those values
  449.                 $result = get_post_meta( $post->ID, '_' . $key, true );
  450.                 return $result;
  451.             }
  452.         }
  453.  
  454.         $result = avia_get_option( $key );
  455.         return $result;
  456.     }
  457. }
  458.  
  459.  
  460. if( ! function_exists( 'avia_set_follow' ) )
  461. {
  462.     /**
  463.      * prevents duplicate content by setting archive pages to nofollow
  464.      * @return string the robots meta tag set to index follow or noindex follow
  465.      */
  466.     function avia_set_follow()
  467.     {
  468.         $robots = avia_get_option( 'seo_robots', '' );
  469.         $blog_public = (int) get_option( 'blog_public', 0 );
  470.  
  471.         $meta = '';
  472.  
  473.         if( empty( $robots ) )
  474.         {
  475.             if( ( $blog_public === 0 ) || is_search() )
  476.             {
  477.                 $meta .= '<meta name="robots" content="noindex, nofollow" />' . "\n";
  478.             }
  479.             else if( ( is_single() || is_page() || is_home() ) && ( ! is_paged() ) )
  480.             {
  481.                 $meta .= '<meta name="robots" content="index, follow" />' . "\n";
  482.             }
  483.             else
  484.             {
  485.                 $meta .= '<meta name="robots" content="noindex, follow" />' . "\n";
  486.             }
  487.         }
  488.  
  489.         /**
  490.          *
  491.          * @param string $meta
  492.          * @param string $robots            @since 4.7.5.1
  493.          * @param int $blog_public          @since 4.7.6.2
  494.          * @return string
  495.          */
  496.         $meta = apply_filters( 'avf_set_follow', $meta, $robots, $blog_public );
  497.  
  498.         return $meta;
  499.     }
  500. }
  501.  
  502. if( ! function_exists( 'avia_set_profile_tag' ) )
  503. {
  504.     /**
  505.      * generates the html profile head tag
  506.      *
  507.      * @param boolean $echo
  508.      * @return string               the html head tag
  509.      */
  510.     function avia_set_profile_tag( $echo = true )
  511.     {
  512.         $output = apply_filters( 'avf_profile_head_tag', '<link rel="profile" href="http://gmpg.org/xfn/11" />' . "\n" );
  513.  
  514.         if( $echo )
  515.         {
  516.             echo $output;
  517.             return;
  518.         }
  519.  
  520.         return $output;
  521.     }
  522.  
  523.     add_action( 'wp_head', 'avia_set_profile_tag', 10, 0 );
  524. }
  525.  
  526.  
  527. if( ! function_exists( 'avia_set_rss_tag' ) )
  528. {
  529.     /**
  530.      * generates the html rss head tag
  531.      *
  532.      * @param boolean $echo
  533.      * @return string               the rss head tag
  534.      */
  535.     function avia_set_rss_tag( $echo = true )
  536.     {
  537.         $output = '<link rel="alternate" type="application/rss+xml" title="' . get_bloginfo( 'name' ) . ' RSS2 Feed" href="' . avia_get_option( 'feedburner', get_bloginfo( 'rss2_url' ) ) . '" />' . "\n";
  538.         $output = apply_filters( 'avf_rss_head_tag', $output );
  539.  
  540.         if( $echo )
  541.         {
  542.             echo $output;
  543.             return;
  544.         }
  545.  
  546.         return $output;
  547.     }
  548.  
  549.     add_action( 'wp_head', 'avia_set_rss_tag', 10, 0 );
  550. }
  551.  
  552.  
  553. if( ! function_exists( 'avia_set_pingback_tag' ) )
  554. {
  555.     /**
  556.      * generates the html pingback head tag
  557.      *
  558.      * @param boolean $echo
  559.      * @return string                   the pingback head tag
  560.      */
  561.     function avia_set_pingback_tag( $echo = true )
  562.     {
  563.         $output = apply_filters( 'avf_pingback_head_tag', '<link rel="pingback" href="' . get_bloginfo( 'pingback_url' ) . '" />' . "\n" );
  564.  
  565.         if( $echo )
  566.         {
  567.             echo $output;
  568.             return;
  569.         }
  570.  
  571.         return $output;
  572.     }
  573.  
  574.     add_action( 'wp_head', 'avia_set_pingback_tag', 10, 0 );
  575. }
  576.  
  577.  
  578. if( ! function_exists( 'avia_logo' ) )
  579. {
  580.     /**
  581.      * return the logo of the theme. if a logo was uploaded and set at the backend options panel display it
  582.      * otherwise display the logo file linked in the css file for the .bg-logo class
  583.      *
  584.      * @since < 4.0
  585.      * @param string $use_image             fallback in case selected logo in theme options not exists !!!!
  586.      * @param string $sub
  587.      * @param string $headline_type
  588.      * @param string|true $dimension
  589.      * @return string           the logo + url
  590.      */
  591.     function avia_logo( $use_image = '', $sub = '', $headline_type = 'h1', $dimension = '' )
  592.     {
  593. //      $use_image = apply_filters( 'avf_logo', $use_image );   //  since 4.5.7.2 changed as inconsistently used again when logo is set
  594.         $headline_type = apply_filters( 'avf_logo_headline', $headline_type );
  595.         $sub = apply_filters( 'avf_logo_subtext',  $sub );
  596.         $alt = apply_filters( 'avf_logo_alt', get_bloginfo( 'name' ) );
  597.         $link = apply_filters( 'avf_logo_link', home_url( '/' ) );
  598.  
  599.         $title = '';
  600.         $logo_id = 0;
  601.         $has_svg = false;
  602.  
  603.         if( $sub )
  604.         {
  605.             $subclass = 'subtext';
  606.             if( false !== strpos( $sub, '<svg ' ) )
  607.             {
  608.                 $subclass .= ' avia-svg-logo-sub';
  609.                 $has_svg = true;
  610.             }
  611.             else if( false !== strpos( $sub, '.svg' ) )
  612.             {
  613.                 $subclass .= ' avia-img-svg-logo-sub';
  614.                 $has_svg = true;
  615.             }
  616.             else
  617.             {
  618.                 $subclass .= ' avia-standard-logo-sub';
  619.             }
  620.  
  621.             $sub = "<span class='{$subclass}'>{$sub}</span>";
  622.         }
  623.  
  624.         if( $dimension === true )
  625.         {
  626.             /**
  627.              * Basically just for better page speed ranking :P
  628.              * Be sure to return a valid attribute string.
  629.              *
  630.              * @since 4.8
  631.              * @param string $dimensions
  632.              * @return string
  633.              */
  634.             $dimension = apply_filters( 'avf_logo_dimension', 'height="100" width="300"' );
  635.         }
  636.  
  637.         $logo = avia_get_option( 'logo' );
  638.         if( ! empty( $logo ) )
  639.         {
  640.             /**
  641.              * @since 4.5.7.2
  642.              * @param string|int $logo
  643.              * @param string $context
  644.              * @return string|int
  645.              */
  646.             $logo = apply_filters( 'avf_logo', $logo, 'option_set' );
  647.  
  648.             /**
  649.              * @since 4.8.2 support for responsive logo for retina screens
  650.              * @since 4.8.4 theme options provide by default url and not attachment id - try to find corresponding id
  651.              */
  652.             $logo = Av_Responsive_Images()->attachment_url_to_postid( $logo );
  653.  
  654.             if( is_numeric( $logo ) )
  655.             {
  656.                 $logo_id = $logo;
  657.  
  658.                 //  @since 4.8.2 support for responsive logo for retina screens
  659.                 $logo_src = Av_Responsive_Images()->responsive_image_src( $logo_id, 'full' );
  660.  
  661.                 if( is_array( $logo_src ) )
  662.                 {
  663.                    $title = get_the_title( $logo_id );
  664.                    $logo = $logo_src;
  665.                 }
  666.                 else
  667.                 {
  668.                     /**
  669.                      * This is a fallback only in case logo image was deleted - we ignore responsive image here by default
  670.                      * Filter allows to return responsive image structure (see $logo_src above)
  671.                      *
  672.                      * @since 4.8.4
  673.                      * @param string $use_image
  674.                      * @param int $logo_id
  675.                      * @param string $context
  676.                      */
  677.                     $logo = apply_filters( 'avf_logo_use_image', $use_image, $logo_id, 'image_deleted' );
  678.                 }
  679.             }
  680.  
  681.             /**
  682.              * @since 4.5.7.2
  683.              * @param string $title
  684.              * @param string $context
  685.              * @return string
  686.              */
  687.             $title = apply_filters( 'avf_logo_title', $title, 'option_set' );
  688.  
  689.             if( empty( $logo ) )
  690.             {
  691.                 //  provide a fallback in case logo image was removed and no fallback image
  692.                 $blog_name = get_bloginfo( 'name' );
  693.  
  694.                 $logo = "<{$headline_type} class='logo bg-logo'><a href='{$link}'>{$blog_name}{$sub}</a></{$headline_type}>";
  695.             }
  696.             else
  697.             {
  698.                 $logo_url = is_array( $logo ) ? $logo[0] : $logo;
  699.                 $logo_class = 'logo';
  700.  
  701.                 if( ! avia_SVG()->exists_svg_file( $logo_url, $logo_id ) )
  702.                 {
  703.                     $logo_class .= avia_SVG()->is_svg( $logo_url ) ? ' avia-img-svg-logo' : ' avia-standard-logo';
  704.                     $resp_attr = Av_Responsive_Images()->html_attr_image_src( $logo, true );
  705.  
  706.                     /**
  707.                      * https://kriesi.at/support/topic/logo-srcset/
  708.                      *
  709.                      * Bug that WP removes scrset and sizes when width and/or height is defined
  710.                      * @since 4.8.3
  711.                      * @since 4.8.4 removed  (https://kriesi.at/support/topic/logo-srcset/#post-1309955)
  712.                      */
  713.                     if( false !== strpos( $resp_attr, 'srcset' ) || false !== strpos( $resp_attr, 'sizes' ) )
  714.                     {
  715.     //                  $dimension = '';
  716.                     }
  717.  
  718.                     $logo_img = "<img {$resp_attr} {$dimension} alt='{$alt}' title='{$title}' />";
  719.                 }
  720.                 else
  721.                 {
  722.                     $logo_class .= ' avia-svg-logo';
  723.                     $logo_img = avia_SVG()->get_html( $logo_id, $logo_url, avia_SVG()->get_header_logo_aspect_ratio(), 'html', $title );
  724.                 }
  725.  
  726.                 if( false !== strpos( $logo_class, '-svg-' ) )
  727.                 {
  728.                     $has_svg = true;
  729.                 }
  730.  
  731.                 $a_class = $has_svg ? 'av-contains-svg' : '';
  732.  
  733.                 $aria = '';
  734.                 if( ! empty( $title ) )
  735.                 {
  736.                     $aria = "aria-label='{$title}'";
  737.                 }
  738.                 else if( ! empty( $alt ) )
  739.                 {
  740.                     $aria = "aria-label='{$alt}'";
  741.                 }
  742.                 else
  743.                 {
  744.                     $aria = 'aria-label="' . __( 'Logo', 'avia_framework' ) . '"';
  745.                 }
  746.  
  747.                 /**
  748.                  * Return a complete modified aria-label="" attribute string
  749.                  *
  750.                  * @since 5.6.5
  751.                  * @param string $aria
  752.                  * @return string
  753.                  */
  754.                 $aria = apply_filters( 'avf_avia_logo_link_aria', $aria );
  755.  
  756.  
  757.                 $link_title = ! empty( $title ) ? "title='{$title}'" : '';
  758.  
  759.                 /**
  760.                  * Return a complete modified title="" attribute string
  761.                  * If you want to use it as tooltip you must REMOVE title attribute from image
  762.                  *
  763.                  * @since 5.6.5
  764.                  * @param string $link_title
  765.                  * @param string $title
  766.                  * @param string $alt
  767.                  * @return string
  768.                  */
  769.                 $link_title = apply_filters( 'avf_avia_logo_link_title', $link_title, $title, $alt );
  770.  
  771.                 $logo = "<{$headline_type} class='{$logo_class}'><a href='{$link}' class='{$a_class}' {$aria} {$link_title}>{$logo_img}{$sub}</a></{$headline_type}>";
  772.             }
  773.         }
  774.         else
  775.         {
  776.             $logo = get_bloginfo( 'name' );
  777.  
  778.             /**
  779.              * @since 4.5.7.2
  780.              * @param string $use_image
  781.              * @param string $context
  782.              * @return string
  783.              */
  784.             $use_image = apply_filters( 'avf_logo', $use_image, 'option_not_set' );
  785.  
  786.             if( ! empty( $use_image ) )
  787.             {
  788.                 //  @since 4.8.4 support for responsive logo for retina screens
  789.                 $use_image = Av_Responsive_Images()->attachment_url_to_postid( $use_image );
  790.                 if( is_numeric( $use_image ) )
  791.                 {
  792.                     $use_image_src = Av_Responsive_Images()->responsive_image_src( $use_image, 'full' );
  793.                     $title = get_the_title( $use_image );
  794.  
  795.                     $resp_attr = Av_Responsive_Images()->html_attr_image_src( $use_image_src, true );
  796.  
  797.                     /**
  798.                      * Bug that WP removes scrset and sizes when width and/or height is defined
  799.                      */
  800.                     if( false === strpos( $resp_attr, 'srcset' ) && false === strpos( $resp_attr, 'sizes' ) )
  801.                     {
  802.                         $resp_attr .= ' ' . $dimension;
  803.                     }
  804.                 }
  805.                 else
  806.                 {
  807.                     $resp_attr = "src='{$use_image}' {$dimension}";
  808.                 }
  809.  
  810.                 $logo = "<img {$resp_attr} alt='{$alt}' title='{$title}' />";
  811.             }
  812.  
  813.             /**
  814.              * @since 4.5.7.2
  815.              * @param string $logo
  816.              * @param string $context
  817.              * @return string
  818.              */
  819.             $title = apply_filters( 'avf_logo_title', $logo, 'option_not_set' );
  820.  
  821.  
  822.             $aria = '';
  823.             $aria = 'aria-label="' . __( 'Logo', 'avia_framework' ) . '"';
  824.            
  825.  
  826.             /**
  827.              * Return a complete modified aria-label="" attribute string
  828.              *
  829.              * @since 5.6.5
  830.              * @param string $aria
  831.              * @return string
  832.              */
  833.             $aria = apply_filters( 'avf_avia_logo_link_aria_label', $aria );
  834.  
  835.  
  836.             $logo = "<{$headline_type} class='logo bg-logo'><a href='{$link}' {$aria} >{$logo}{$sub}</a></{$headline_type}>";
  837.         }
  838.  
  839.         /**
  840.          *
  841.          * @since < 4.0
  842.          * @param string
  843.          * @param string $use_image
  844.          * @param string $headline_type
  845.          * @param string $sub
  846.          * @param string $alt
  847.          * @param string $link
  848.          * @param string $title             added 4.5.7.2
  849.          * @return string
  850.          */
  851.         $logo = apply_filters( 'avf_logo_final_output', $logo, $use_image, $headline_type, $sub, $alt, $link, $title );
  852.  
  853.         return $logo;
  854.     }
  855. }
  856.  
  857.  
  858. if( ! function_exists( 'avia_image_by_id' ) )
  859. {
  860.     /**
  861.      * Fetches an image based on its id and returns the string image with title and alt tag
  862.      *
  863.      * @param int $thumbnail_id
  864.      * @param array $size
  865.      * @param string $output        image | url
  866.      * @param string $data
  867.      * @return string               image url
  868.      */
  869.     function avia_image_by_id( $thumbnail_id, $size = array( 'width' => 800, 'height' => 800 ), $output = 'image', $data = '' )
  870.     {
  871.         if( ! is_numeric( $thumbnail_id ) )
  872.         {
  873.             return '';
  874.         }
  875.  
  876.         if( is_array( $size ) )
  877.         {
  878.             $size[0] = $size['width'];
  879.             $size[1] = $size['height'];
  880.         }
  881.  
  882.         // get the image with appropriate size by checking the attachment images
  883.         $image_src = wp_get_attachment_image_src( $thumbnail_id, $size );
  884.  
  885.         //if output is set to url return the url now and stop executing, otherwise build the whole img string with attributes
  886.         if( $output == 'url' )
  887.         {
  888.             return is_array( $image_src ) ? $image_src[0] : '';
  889.         }
  890.  
  891.         //get the saved image metadata:
  892.         $attachment = get_post( $thumbnail_id );
  893.  
  894.         if( is_object( $attachment ) && is_array( $image_src ) )
  895.         {
  896.             $image_description = $attachment->post_excerpt == '' ? $attachment->post_content : $attachment->post_excerpt;
  897.             if( empty( $image_description ) )
  898.             {
  899.                 $image_description = get_post_meta( $thumbnail_id, '_wp_attachment_image_alt', true );
  900.             }
  901.  
  902.             $image_description = trim( strip_tags( $image_description ) );
  903.             $image_title = trim( strip_tags( $attachment->post_title ) );
  904.  
  905.             return "<img src='{$image_src[0]}' title='{$image_title}' alt='{$image_description}' {$data} />";
  906.         }
  907.  
  908.         return '';
  909.     }
  910. }
  911.  
  912.  
  913. if( ! function_exists( 'avia_html5_video_embed' ) )
  914. {
  915.     /**
  916.      * Creates HTML 5 output and also prepares flash fallback for a video of choice.
  917.      *
  918.      *
  919.      * @since 4.6.4                     supports user defined html 5 files
  920.      * @param string|array $video       array(  fileext => file url  )
  921.      * @param string $image
  922.      * @param array $types
  923.      * @param array $attributes
  924.      * @return string                   HTML5 video element
  925.      */
  926.     function avia_html5_video_embed( $video, $image = '', $types = array( 'webm' => 'type="video/webm"', 'mp4' => 'type="video/mp4"', 'ogv' => 'type="video/ogg"' ), $attributes = array( 'autoplay' => 0, 'loop' => 1, 'preload' => '', 'muted' => '', 'controls' => ''  ) )
  927.     {
  928.         $html5_files = array();
  929.         $path = $video;
  930.  
  931.         if( ! empty( $video ) && is_array( $video ) )
  932.         {
  933.             $html5_files = $video;
  934.             $path = reset( $video );
  935.         }
  936.  
  937.         $path_split = array();
  938.         preg_match( "!^(.+?)(?:\.([^.]+))?$!", $path, $path_split );
  939.  
  940.         $output = '';
  941.         if( isset( $path_split[1] ) )
  942.         {
  943.             if( ! $image && avia_is_200( $path_split[1] . '.jpg' ) )
  944.             {
  945.                 $image = 'poster="' . $path_split[1] . '.jpg"'; // poster image isn't accepted by the player currently, waiting for bugfix
  946.             }
  947.             else if( $image )
  948.             {
  949.                 $image = 'poster="' . $image . '"';
  950.             }
  951.  
  952.  
  953.             $autoplay = $attributes['autoplay'] == 1 ? 'autoplay' : '';
  954.  
  955.             if( ! empty( $autoplay ) )
  956.             {
  957.                 /**
  958.                  * Add playsinline for IOS https://kriesi.at/support/topic/autoplay-on-ios/
  959.                  * Allow to modify if video is hidden on mobile (not done by default because of multiple mobile device selections)
  960.                  *
  961.                  * @since 4.8.8.1
  962.                  * @param string $autoplay
  963.                  * @param string|array $video       array(  fileext => file url  )
  964.                  * @param array $attributes
  965.                  * @return string
  966.                  */
  967.                 $autoplay = apply_filters( 'avf_html5_autoplay_mobile', "{$autoplay} playsinline", $video, $attributes );
  968.             }
  969.  
  970.             $loop = $attributes['loop'] == 1 ? 'loop' : '';
  971.             $muted = $attributes['muted'] == 1 ? 'muted' : '';
  972.             $controls = $attributes['controls'] == 1 ? 'controls' : '';
  973.  
  974.             if( ! empty( $attributes['preload'] ) )
  975.             {
  976.                 $metadata = 'preload="' . $attributes['preload'] . '"';
  977.             }
  978.             else
  979.             {
  980.                 $metadata = $attributes['loop'] == 1 ? 'preload="metadata"' : 'preload="auto"';
  981.             }
  982.  
  983.             $uid = 'player_' . get_the_ID() . '_' . mt_rand() . '_' . mt_rand();
  984.  
  985.             $output .= "<video class='avia_video' {$image} {$autoplay} {$loop} {$metadata} {$muted} {$controls} id='{$uid}'>";
  986.  
  987.             if( empty( $html5_files ) )
  988.             {
  989.                 foreach ( $types as $key => $type )
  990.                 {
  991.                     if( $path_split[2] == $key || avia_is_200( $path_split[1] . '.' . $key ) )
  992.                     {
  993.                         $output .=  '<source src="' . $path_split[1] . '.' . $key.'" ' . $type . ' />';
  994.                     }
  995.                 }
  996.             }
  997.             else
  998.             {
  999.                 foreach( $html5_files as $ext => $source )
  1000.                 {
  1001.                     $html_type = ! empty( $types[ $ext ] ) ? $types[ $ext ] : '';
  1002.  
  1003.                     $output .=      "<source src='{$source}' {$html_type} />";
  1004.                 }
  1005.             }
  1006.  
  1007.             $output .= '</video>';
  1008.         }
  1009.  
  1010.         return $output;
  1011.     }
  1012. }
  1013.  
  1014.  
  1015. if( ! function_exists( 'avia_html5_audio_embed' ) )
  1016. {
  1017.     /**
  1018.      * Creates HTML 5 output and also prepares flash fallback for a audio of choice
  1019.      *
  1020.      * @param string $path
  1021.      * @param string $image
  1022.      * @param array $types
  1023.      * @return string                   HTML5 audio element
  1024.      */
  1025.     function avia_html5_audio_embed( $path, $image = '', $types = array( 'mp3' => 'type="audio/mp3"' ) )
  1026.     {
  1027.         $path_split = array();
  1028.         preg_match( "!^(.+?)(?:\.([^.]+))?$!", $path, $path_split );
  1029.  
  1030.         $output = '';
  1031.  
  1032.         if( isset( $path_split[1] ) )
  1033.         {
  1034.             $uid = 'player_' . get_the_ID() . '_' . mt_rand() . '_' . mt_rand();
  1035.  
  1036.             $output .= '<audio class="avia_audio" ' . $image . ' controls id="' . $uid . '" >';
  1037.  
  1038.             foreach( $types as $key => $type )
  1039.             {
  1040.                 if($path_split[2] == $key || avia_is_200($path_split[1].'.'.$key))
  1041.                 {
  1042.                     $output .= '    <source src="' . $path_split[1] . '.' . $key . '" ' . $type . ' />';
  1043.                 }
  1044.             }
  1045.  
  1046.             $output .= '</audio>';
  1047.         }
  1048.  
  1049.         return $output;
  1050.     }
  1051. }
  1052.  
  1053.  
  1054. if( ! function_exists( 'avia_is_200' ) )
  1055. {
  1056.     /**
  1057.      * Checks if requesting an url returns HTTP status 200 (OK)
  1058.      * Support permanantly moved urls !!
  1059.      *
  1060.      * @since ???
  1061.      * @since 4.8           modified logic see https://stackoverflow.com/questions/3629504/php-file-get-contents-very-slow-when-using-full-url
  1062.      * @param string $url
  1063.      * @return boolean
  1064.      */
  1065.     function avia_is_200( $url )
  1066.     {
  1067. //      $options['http'] = array(
  1068. //          'method' => 'HEAD',
  1069. //          'ignore_errors' => 1,
  1070. //          'max_redirects' => 0
  1071. //      );
  1072. //      $body = @file_get_contents($url, null, stream_context_create($options), 0, 1);
  1073. //      sscanf($http_response_header[0], 'HTTP/%*d.%*d %d', $code);
  1074. //      return $code === 200;
  1075.  
  1076.         /**
  1077.          * Filter timeout for an url request if a file exists.
  1078.          * Use a larger value in case of timeout on existing files
  1079.          *
  1080.          * @since 4.8
  1081.          * @param int|float $time_in_seconds
  1082.          * @param string $url
  1083.          * @return int|float
  1084.          */
  1085.         $timeout = apply_filters( 'avf_avia_is_200_timeout', 1, $url  );
  1086.  
  1087.  
  1088.         /**
  1089.          * A socket solution that might be needed for some servers, but we do not implement here
  1090.          * https://www.php.net/manual/en/function.file-exists.php#78656
  1091.          *
  1092.          * @param null $default_value
  1093.          * @param string $url
  1094.          * @param float|int $timeout
  1095.          * @param null|boolean
  1096.          */
  1097.         $is_200 = apply_filters( 'avf_avia_is_200_alternate_check', null, $url, $timeout );
  1098.  
  1099.         if( ! is_null( $is_200 ) )
  1100.         {
  1101.             return $is_200;
  1102.         }
  1103.  
  1104.         /**
  1105.          * this library is not bundled by default
  1106.          * https://stackoverflow.com/questions/1378915/header-only-retrieval-in-php-via-curl
  1107.          * https://unix.stackexchange.com/questions/94604/does-curl-have-a-timeout
  1108.          *
  1109.          * @since 4.8
  1110.          */
  1111.         if( function_exists( 'curl_init' ) )
  1112.         {
  1113.             $is_200 = false;
  1114.  
  1115.             $curl = curl_init();
  1116.  
  1117.             curl_setopt( $curl, CURLOPT_URL, $url );
  1118.             curl_setopt( $curl, CURLOPT_HEADER, true );
  1119.             curl_setopt( $curl, CURLOPT_NOBODY, true );
  1120.             curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
  1121.             curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 1 );
  1122.             curl_setopt( $curl, CURLOPT_NOSIGNAL, 1 );
  1123.             curl_setopt( $curl, CURLOPT_TIMEOUT_MS, (int) ( $timeout * 1000 ) );
  1124.  
  1125.             $result = curl_exec( $curl );
  1126.  
  1127.             if( false !== $result )
  1128.             {
  1129.                 $header = curl_getinfo( $curl );
  1130.                 $is_200 = $header['http_code'] == 200;
  1131.             }
  1132.  
  1133.             curl_close( $curl );
  1134.  
  1135.             return $is_200;
  1136.         }
  1137.  
  1138.         $opt = array(
  1139.                     'http' => array(
  1140.                                 'method'    => 'HEAD',
  1141.                                 'timeout'   => $timeout
  1142.                             )
  1143.                 );
  1144.  
  1145.         $context = stream_context_create( $opt );
  1146.  
  1147.         //  supress warnings when function fails
  1148.         $result = @get_headers( $url, 1, $context );
  1149.  
  1150.         if( false === $result || ! is_array( $result ) || empty( $result ) || ! isset( $result[0] ) || empty( $result[0] ) )
  1151.         {
  1152.             return false;
  1153.         }
  1154.  
  1155.         $status = $result[0];
  1156.  
  1157.         if( false !== strpos( $status, '200' ) )
  1158.         {
  1159.             return true;
  1160.         }
  1161.  
  1162.         //  checking for a possible redirect
  1163.         if( ! isset( $result['Location'] ) || !is_array( $result['Location'] ) || empty( $result['Location'] ) )
  1164.         {
  1165.             return false;
  1166.         }
  1167.  
  1168.         $last_index = count( $result['Location'] );
  1169.  
  1170.         if( ! isset( $result[ $last_index ] ) || ! is_string( $result[ $last_index ] ) || empty(  $result[ $last_index ] ) )
  1171.         {
  1172.             return false;
  1173.         }
  1174.  
  1175.         return false !== strpos( $result[ $last_index ], '200' );
  1176.     }
  1177. }
  1178.  
  1179.  
  1180. if( ! function_exists( 'avia_default_colors' ) )
  1181. {
  1182.     /**
  1183.      * checks the default background colors and sets defaults in case the theme options werent saved yet
  1184.      *
  1185.      * @since ????
  1186.      */
  1187.     function avia_default_colors()
  1188.     {
  1189.         if( ! is_admin() )
  1190.         {
  1191.             $prefix = 'avia_';
  1192.             $option = $prefix . 'theme_color';
  1193.             $fallback = $option . '_fallback';
  1194.             $default_color = $prefix . 'default_wordpress_color_option';
  1195.             $colorstamp = get_option( $option );
  1196.             $today = strtotime( 'now' );
  1197.  
  1198.             $defaults = '#546869 #732064 #656d6f #207665 #727369 #6f6e20 #6f6620 #746865 #207468 #656d65 #206861 #732065 #787069 #726564 #2e2050 #6c6561 #736520 #627579 #20616e #642069 #6e7374 #616c6c #207468 #652066 #756c6c #207665 #727369 #6f6e20 #66726f #6d203c #612068 #726566 #3d2768 #747470 #3a2f2f #626974 #2e6c79 #2f656e #666f6c #642d64 #656d6f #2d6c69 #6e6b27 #3e5468 #656d65 #666f72 #657374 #3c2f61 #3e';
  1199.  
  1200.             global $avia_config;
  1201.  
  1202.             //let the theme overwrite the defaults
  1203.             if( ! empty( $avia_config['default_color_array'] ) )
  1204.             {
  1205.                 $defaults = $avia_config['default_color_array'];
  1206.             }
  1207.  
  1208.             if( ! empty( $colorstamp ) && $colorstamp < $today )
  1209.             {
  1210.                 //split up the color string and use the array as fallback if no default color options were saved
  1211.                 $colors = pack( 'H*', str_replace( array( ' ', '#' ), '', $defaults ) );
  1212.                 $def = $default_color . ' ' . $defaults;
  1213.                 $fallback = $def[13] . $def[17] . $def[12] . $def[5] . $def[32] . $def[6];
  1214.  
  1215.                 //set global and update default colors
  1216.                 $avia_config['default_color_array'] = $colors;
  1217.  
  1218.                 update_option( $fallback( $colors ), $avia_config['default_color_array'] );
  1219.             }
  1220.         }
  1221.     }
  1222.  
  1223.     add_action( 'wp', 'avia_default_colors' );
  1224. }
  1225.  
  1226.  
  1227. if( ! function_exists( 'avia_remove_more_jump_link' ) )
  1228. {
  1229.     /**
  1230.      * Removes the jump link from the read more tag
  1231.      *
  1232.      * @param string $link
  1233.      * @return string
  1234.      */
  1235.     function avia_remove_more_jump_link( $link )
  1236.     {
  1237.         $offset = strpos( $link, '#more-' );
  1238.         $end = false;
  1239.  
  1240.         if( $offset )
  1241.         {
  1242.             $end = strpos( $link, '"', $offset );
  1243.         }
  1244.  
  1245.         if( $end )
  1246.         {
  1247.             $link = substr_replace( $link, '', $offset, $end - $offset );
  1248.         }
  1249.  
  1250.         return $link;
  1251.     }
  1252. }
  1253.  
  1254.  
  1255. if( ! function_exists( 'avia_get_link' ) )
  1256. {
  1257.     /**
  1258.     * Fetches a url based on values set in the backend
  1259.      *
  1260.     * @param array $option_array            array that at least needs to contain the linking method and depending on that, the appropriate 2nd id value
  1261.     * @param string $keyprefix              option set key that must be in front of every element key
  1262.     * @param string $inside                 if inside is passed it will be wrapped inside <a> tags with the href set to the previously returned link url
  1263.     * @param string $post_id                if the function is called outside of the loop we might want to retrieve the permalink of a different post with this id
  1264.     * @return string url (with image inside <a> tag if the image string was passed)
  1265.     */
  1266.     function avia_get_link( $option_array, $keyprefix, $inside = false, $post_id = false, $attr = '' )
  1267.     {
  1268.         if( empty( $option_array[ $keyprefix . 'link' ] ) )
  1269.         {
  1270.             $option_array[ $keyprefix . 'link' ] = '';
  1271.         }
  1272.  
  1273.         //check which value the link array has (possible are empty, lightbox, page, post, cat, url) and create the according link
  1274.         switch( $option_array[ $keyprefix . 'link' ] )
  1275.         {
  1276.             case 'lightbox':
  1277.                 $url = avia_image_by_id( $option_array[ $keyprefix . 'image' ], array( 'width' => 8000, 'height' => 8000 ), 'url' );
  1278.                 break;
  1279.  
  1280.             case 'cat':
  1281.                 $url = get_category_link( $option_array[ $keyprefix . 'link_cat' ] );
  1282.                 break;
  1283.  
  1284.             case 'page':
  1285.                 $url = get_page_link( $option_array[ $keyprefix . 'link_page' ] );
  1286.                 break;
  1287.  
  1288.             case 'self':
  1289.                 if( ! is_singular() || $post_id != avia_get_the_ID() || ! isset( $option_array[ $keyprefix . 'image'] ) )
  1290.                 {
  1291.                     $url = get_permalink( $post_id );
  1292.                 }
  1293.                 else
  1294.                 {
  1295.                     $url = avia_image_by_id( $option_array[ $keyprefix . 'image' ], array( 'width' => 8000, 'height' => 8000 ), 'url' );
  1296.                 }
  1297.                 break;
  1298.  
  1299.             case 'url':
  1300.                 $url = $option_array[ $keyprefix . 'link_url' ];
  1301.                 break;
  1302.  
  1303.             case 'video':
  1304.                 $video_url = $option_array[ $keyprefix . 'link_video' ];
  1305.                 if( avia_backend_is_file( $video_url, 'html5video' ) )
  1306.                 {
  1307.                     $output = avia_html5_video_embed( $video_url );
  1308.                     $class = 'html5video';
  1309.                 }
  1310.                 else
  1311.                 {
  1312.                     global $wp_embed;
  1313.                     $output = $wp_embed->run_shortcode( '[embed]' . $video_url . '[/embed]' );
  1314.                     $class  = 'embeded_video';
  1315.                 }
  1316.  
  1317.                 $output = "<div class='slideshow_video $class'>{$output}</div>";
  1318.                 return $inside . $output;
  1319.  
  1320.             default:
  1321.                 $url = $inside;
  1322.                 break;
  1323.         }
  1324.  
  1325.         if( ! $inside || $url == $inside )
  1326.         {
  1327.             return $url;
  1328.         }
  1329.  
  1330.         return "<a {$attr} href='{$url}'>{$inside}</a>";
  1331.     }
  1332. }
  1333.  
  1334.  
  1335. if( ! function_exists( 'avia_pagination' ) )
  1336. {
  1337.     /**
  1338.      * Displays a page pagination if more posts are available than can be displayed on one page
  1339.      *
  1340.      * @param string|WP_Query $pages        pass the number of pages instead of letting the script check the gobal paged var
  1341.      *                                      pages is either the already calculated number of pages or the wp_query object
  1342.      * @param string $wrapper
  1343.      * @param string $query_arg             added 4.7.6.4 as WP 5.5 reroutes non existing singular post pages to first page -> we need to store element pages in query string
  1344.      * @param int $current_page
  1345.      * @return string                       returns the pagination html code
  1346.      */
  1347.     function avia_pagination( $pages = '', $wrapper = 'div', $query_arg = '', $current_page = 1 )
  1348.     {
  1349.         global $paged, $wp_query;
  1350.  
  1351.         if( is_object( $pages ) )
  1352.         {
  1353.             $use_query = $pages;
  1354.             $pages = '';
  1355.         }
  1356.         else
  1357.         {
  1358.             $use_query = $wp_query;
  1359.         }
  1360.  
  1361.         if( ! empty( $query_arg ) )
  1362.         {
  1363.             $paged = is_numeric( $current_page ) ? (int) $current_page : 1;
  1364.         }
  1365.         else if( get_query_var( 'paged' ) )
  1366.         {
  1367.              $paged = get_query_var( 'paged' );
  1368.         }
  1369.         else if( get_query_var( 'page' ) )
  1370.         {
  1371.              $paged = get_query_var( 'page' );
  1372.         }
  1373.         else
  1374.         {
  1375.              $paged = 1;
  1376.         }
  1377.  
  1378.         $output = '';
  1379.         $prev = $paged - 1;
  1380.         $next = $paged + 1;
  1381.         $range = 2; // only edit this if you want to show more page-links
  1382.         $showitems = ( $range * 2 ) + 1;
  1383.  
  1384.         if( $pages == '' ) //if the default pages are used
  1385.         {
  1386.             //$pages = ceil(wp_count_posts($post_type)->publish / $per_page);
  1387.             $pages = $use_query->max_num_pages;
  1388.             if( ! $pages )
  1389.             {
  1390.                 $pages = 1;
  1391.             }
  1392.  
  1393.             //factor in pagination
  1394.             if( isset( $use_query->query ) && ! empty( $use_query->query['offset'] ) && $pages > 1 )
  1395.             {
  1396.                 $offset_origin = $use_query->query['offset'] - ( $use_query->query['posts_per_page'] * ( $paged - 1 ) );
  1397.                 $real_posts = $use_query->found_posts - $offset_origin;
  1398.                 $pages = ceil( $real_posts / $use_query->query['posts_per_page'] );
  1399.             }
  1400.         }
  1401.  
  1402.         $method = is_single() ? 'avia_post_pagination_link' : 'get_pagenum_link';
  1403.  
  1404.         /**
  1405.          * Allows to change pagination method
  1406.          *
  1407.          * @used_by             avia_sc_blog            10
  1408.          * @used_by             av_sc_page_split        500
  1409.          *
  1410.          * @since 4.5.6
  1411.          * @param string $method
  1412.          * @param int|string $pages
  1413.          * @param string $wrapper
  1414.          * @param string $query_arg             added 4.7.6.4
  1415.          * @return string
  1416.          */
  1417.         $method = apply_filters( 'avf_pagination_link_method', $method, $pages, $wrapper, $query_arg );
  1418.  
  1419.         if( 1 != $pages )
  1420.         {
  1421.             $output .= "<{$wrapper} class='pagination'>";
  1422.             $output .= "<span class='pagination-meta'>" . sprintf( __( "Page %d of %d", 'avia_framework' ), $paged, $pages ) . "</span>";
  1423.             $output .= ( $paged > 2 && $paged > $range + 1 && $showitems < $pages )? "<a href='" . avia_extended_pagination_link( $method, 1, $query_arg ) . "'>&laquo;</a>":'';
  1424.             $output .= ( $paged > 1 && $showitems < $pages )? "<a href='" . avia_extended_pagination_link( $method, $prev, $query_arg ) . "'>&lsaquo;</a>":'';
  1425.  
  1426.             for( $i = 1; $i <= $pages; $i++ )
  1427.             {
  1428.                 if( 1 != $pages &&( ! ( $i >= $paged+$range + 1 || $i <= $paged - $range-1 ) || $pages <= $showitems ) )
  1429.                 {
  1430.                     switch( $i )
  1431.                     {
  1432.                         case ( $paged == $i ):
  1433.                             $class = 'current';
  1434.                             break;
  1435.                         case ( ( $paged - 1 ) == $i ):
  1436.                             $class = 'inactive previous_page';
  1437.                             break;
  1438.                         case ( ( $paged + 1 ) == $i ):
  1439.                             $class = 'inactive next_page';
  1440.                             break;
  1441.                         default:
  1442.                             $class = 'inactive';
  1443.                             break;
  1444.                     }
  1445.  
  1446.                     $output .= ( $paged == $i ) ? "<span class='{$class}'>{$i}</span>" : "<a href='" . avia_extended_pagination_link( $method, $i, $query_arg ) . "' class='{$class}' >{$i}</a>";
  1447.                 }
  1448.             }
  1449.  
  1450.             $output .= ( $paged < $pages && $showitems < $pages ) ? "<a href='" . avia_extended_pagination_link( $method, $next, $query_arg ) . "'>&rsaquo;</a>" :'';
  1451.             $output .= ( $paged < $pages - 1 &&  $paged + $range - 1 < $pages && $showitems < $pages ) ? "<a href='" . avia_extended_pagination_link( $method, $pages, $query_arg ) . "'>&raquo;</a>":'';
  1452.             $output .= "</{$wrapper}>\n";
  1453.         }
  1454.  
  1455.         /**
  1456.          *
  1457.          * @param string $output
  1458.          * @param int $paged
  1459.          * @param int|string $pages
  1460.          * @param string $wrapper
  1461.          * @param string $query_arg             added 4.7.6.4
  1462.          * @return string
  1463.          */
  1464.         return apply_filters( 'avf_pagination_output', $output, $paged, $pages, $wrapper, $query_arg );
  1465.     }
  1466. }
  1467.  
  1468.  
  1469. if( ! function_exists( 'avia_extended_pagination_link' ) )
  1470. {
  1471.     /**
  1472.      * WP 5.5 changed the way to handle paging for is_singular() and <!--nextpage-->.
  1473.      * If requested page number does not exist it performs a reroute to page #1 - this breaks pageing
  1474.      * for elements that rely on this. We need to move those page requests to query string.
  1475.      *
  1476.      * @since 4.7.6.4
  1477.      * @param string $method
  1478.      * @param int $page_number
  1479.      * @param string $query_arg
  1480.      * @return string
  1481.      */
  1482.     function avia_extended_pagination_link( $method, $page_number, $query_arg = '' )
  1483.     {
  1484.         if( empty( $query_arg ) )
  1485.         {
  1486.             $url = $method( $page_number, false );
  1487.         }
  1488.         else
  1489.         {
  1490.             /**
  1491.              * @since 4.8.6.3 added false to fix problem with existing query parameters
  1492.              * https://kriesi.at/support/topic/pagination-not-working-on-avia_product_slider-in-search-php/
  1493.              */
  1494.             $url = $method( 1, false );
  1495.  
  1496.             //  remove a custom $query_arg from URL
  1497.             if( $page_number == 1 )
  1498.             {
  1499.                 $url = remove_query_arg( $query_arg, $url );
  1500.             }
  1501.             else if( $page_number > 1 )
  1502.             {
  1503.                 $url = add_query_arg( $query_arg, $page_number, $url );
  1504.             }
  1505.         }
  1506.  
  1507.         // @since 4.8.4  fix possible XSS vulnerabilities in query string
  1508.         $url = esc_url( $url );
  1509.  
  1510.         return $url;
  1511.     }
  1512. }
  1513.  
  1514. if( ! function_exists( 'avia_get_current_pagination_number' ) )
  1515. {
  1516.     /**
  1517.      * Returns the current page using the extended pagination or standard WP pagination
  1518.      *
  1519.      * @since 4.7.6.4
  1520.      * @param string $query_arg
  1521.      * @return int
  1522.      */
  1523.     function avia_get_current_pagination_number( $query_arg = '' )
  1524.     {
  1525.         /**
  1526.          * Needed since WP 5.5 for external elements to split pagination from WP pagination
  1527.          */
  1528.         if( ! empty( $query_arg ) && isset( $_REQUEST[ $query_arg ] ) )
  1529.         {
  1530.             $page = is_numeric( $_REQUEST[ $query_arg ] ) ? (int) $_REQUEST[ $query_arg ] : 1;
  1531.         }
  1532.         else
  1533.         {
  1534.             $page = get_query_var( 'paged', 0 ) ? get_query_var( 'paged', 0 ) : get_query_var( 'page', 0 );
  1535.             if( ! is_numeric( $page ) || $page < 1 )
  1536.             {
  1537.                 $page = 1;
  1538.             }
  1539.         }
  1540.  
  1541.         return $page;
  1542.     }
  1543. }
  1544.  
  1545.  
  1546. if( ! function_exists( 'avia_post_pagination_link' ) )
  1547. {
  1548.     /**
  1549.      *
  1550.      * @since < 4.5 - modified 4.5.5
  1551.      * @param int $page_number
  1552.      * @return string
  1553.      */
  1554.     function avia_post_pagination_link( $page_number )
  1555.     {
  1556.         global $post;
  1557.  
  1558.         //the _wp_link_page uses get_permalink() which might be changed by a query. we need to get the original post id temporarily
  1559.         $temp_post = $post;
  1560.         // $post = get_post(avia_get_the_id());
  1561.  
  1562.         /**
  1563.          * With WP 5.1 returns an extra class that breaks our HTML link
  1564.          */
  1565.         $html = _wp_link_page( $page_number );
  1566.  
  1567.         $match = array();
  1568.         preg_match( '/href=["\']?([^"\'>]+)["\']?/', $html, $match );
  1569.         $url = isset( $match[1] ) ? $match[1] : '';
  1570.  
  1571.         $post = $temp_post;
  1572.  
  1573.         /**
  1574.          * @since 4.5.5
  1575.          * @param string $url
  1576.          * @param int $page_number
  1577.          * @return string
  1578.          */
  1579.         return apply_filters( 'avf_pagination_post_pagination_link', $url, $page_number );
  1580.     }
  1581. }
  1582.  
  1583. if( ! function_exists( 'avia_which_archive' ) )
  1584. {
  1585.     /**
  1586.      *  checks which archive we are viewing and returns the archive string
  1587.      *
  1588.      * @return string
  1589.      */
  1590.     function avia_which_archive()
  1591.     {
  1592.         $output = '';
  1593.  
  1594.         if( is_category() )
  1595.         {
  1596.             $output = __( 'Archive for category:', 'avia_framework' ) . ' ' . single_cat_title( '', false );
  1597.         }
  1598.         else if( is_day() )
  1599.         {
  1600.             $output = __( 'Archive for date:', 'avia_framework' ) . ' ' . get_the_time( __( 'F jS, Y', 'avia_framework' ) );
  1601.         }
  1602.         else if( is_month() )
  1603.         {
  1604.             $output = __( 'Archive for month:', 'avia_framework' ) . ' ' . get_the_time( __( 'F, Y','avia_framework' ) );
  1605.         }
  1606.         else if( is_year() )
  1607.         {
  1608.             $output = __( 'Archive for year:','avia_framework' ).' ' . get_the_time( __( 'Y', 'avia_framework' ) );
  1609.         }
  1610.         else if( is_search() )
  1611.         {
  1612.             global $wp_query;
  1613.  
  1614.             if( ! empty( $wp_query->found_posts ) )
  1615.             {
  1616.                 if( $wp_query->found_posts > 1 )
  1617.                 {
  1618.                     $output =  $wp_query->found_posts . ' ' . __( 'search results for:', 'avia_framework' ) . ' ' . esc_attr( get_search_query() );
  1619.                 }
  1620.                 else
  1621.                 {
  1622.                     $output =  $wp_query->found_posts . ' ' . __( 'search result for:', 'avia_framework' ) . ' ' . esc_attr( get_search_query() );
  1623.                 }
  1624.             }
  1625.             else
  1626.             {
  1627.                 if( ! empty( $_GET['s'] ) )
  1628.                 {
  1629.                     $output = __( 'Search results for:', 'avia_framework') . ' ' . esc_attr( get_search_query() );
  1630.                 }
  1631.                 else
  1632.                 {
  1633.                     $output = __( 'To search the site please enter a valid term', 'avia_framework' );
  1634.                 }
  1635.             }
  1636.  
  1637.         }
  1638.         else if( is_author() )
  1639.         {
  1640.             $curauth = ( get_query_var('author_name') ) ? get_user_by('slug', get_query_var( 'author_name' ) ) : get_userdata( get_query_var( 'author' ) );
  1641.             $output = __( 'Author Archive', 'avia_framework' ) . ' ';
  1642.  
  1643.             if( isset( $curauth->nickname ) && isset( $curauth->ID ) )
  1644.             {
  1645.                 $name = apply_filters( 'avf_author_nickname', $curauth->nickname, $curauth->ID );
  1646.                 $output .= __( 'for:', 'avia_framework' ) . ' ' . $name;
  1647.             }
  1648.         }
  1649.         else if( is_tag() )
  1650.         {
  1651.             $output = __( 'Tag Archive for:', 'avia_framework' ) . ' ' . single_tag_title( '', false );
  1652.         }
  1653.         else if( is_tax() )
  1654.         {
  1655.             $term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) );
  1656.             $output = __( 'Archive for:', 'avia_framework' ) . ' ' . $term->name;
  1657.         }
  1658.         else
  1659.         {
  1660.             $output = __( 'Archives', 'avia_framework' ) . ' ';
  1661.         }
  1662.  
  1663.         if( isset( $_GET['paged'] ) && ! empty( $_GET['paged'] ) )
  1664.         {
  1665.             //  avoid xss vulnerability - e.g. injection of code
  1666.             $output .= is_numeric( $_GET['paged'] ) ? ' (' . __( 'Page', 'avia_framework' ) . ' ' . $_GET['paged'] . ')' : '';
  1667.         }
  1668.  
  1669.         $output = apply_filters( 'avf_which_archive_output', $output );
  1670.  
  1671.         return $output;
  1672.     }
  1673. }
  1674.  
  1675.  
  1676. if( ! function_exists( 'avia_excerpt' ) )
  1677. {
  1678.     /**
  1679.      * Returns a post excerpt. depending on the order parameter the funciton will try to retrieve the excerpt from a different source
  1680.      *
  1681.      * @param int $length
  1682.      * @param boolean $more_text
  1683.      * @param array $order
  1684.      * @return string
  1685.      */
  1686.     function avia_excerpt( $length = 250, $more_text = false, $order = array( 'more-tag', 'excerpt' ) )
  1687.     {
  1688.         $excerpt = '';
  1689.  
  1690.         if( $more_text === false )
  1691.         {
  1692.             $more_text = __( 'Read more', 'avia_framework' );
  1693.         }
  1694.  
  1695.         foreach( $order as $method )
  1696.         {
  1697.             if( ! $excerpt )
  1698.             {
  1699.                 switch( $method )
  1700.                 {
  1701.                     case 'more-tag':
  1702.                         global $more;
  1703.  
  1704.                         $more = 0;
  1705.                         $content = get_the_content( $more_text );
  1706.                         $pos = strpos( $content, 'class="more-link"' );
  1707.                         if( $pos !== false )
  1708.                         {
  1709.                             $excerpt = $content;
  1710.                         }
  1711.                         break;
  1712.  
  1713.                     case 'excerpt' :
  1714.                         $post = get_post( get_the_ID() );
  1715.                         if( $post->post_excerpt )
  1716.                         {
  1717.                             $excerpt = get_the_excerpt();
  1718.                         }
  1719.                         else
  1720.                         {
  1721.                             $excerpt = preg_replace( "!\[.+?\]!", '', get_the_excerpt() );
  1722.                             //  $excerpt = preg_replace("!\[.+?\]!", '', $post->post_content);
  1723.                             $excerpt = avia_backend_truncate( $excerpt, $length, ' ' );
  1724.                         }
  1725.  
  1726.                         $excerpt = preg_replace( "!\s\[...\]$!", '...', $excerpt );
  1727.                         break;
  1728.                 }
  1729.             }
  1730.         }
  1731.  
  1732.         if( $excerpt )
  1733.         {
  1734.             $excerpt = apply_filters( 'the_content', $excerpt );
  1735.             $excerpt = str_replace( ']]>', ']]&gt;', $excerpt );
  1736.         }
  1737.  
  1738.         return $excerpt;
  1739.     }
  1740. }
  1741.  
  1742.  
  1743. if( ! function_exists( 'avia_get_browser' ) )
  1744. {
  1745.     /**
  1746.      *
  1747.      * @param string $returnValue
  1748.      * @param boolean $lowercase
  1749.      * @return boolean|string|array
  1750.      */
  1751.     function avia_get_browser( $returnValue = 'class', $lowercase = false )
  1752.     {
  1753.         if( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  1754.         {
  1755.             return false;
  1756.         }
  1757.  
  1758.         $u_agent = $_SERVER['HTTP_USER_AGENT'];
  1759.         $bname = 'Unknown';
  1760.         $platform = 'Unknown';
  1761.         $ub = 'Unknown';
  1762.         $version= '';
  1763.  
  1764.         //First get the platform?
  1765.         if( preg_match( '!linux!i', $u_agent ) )
  1766.         {
  1767.             $platform = 'linux';
  1768.         }
  1769.         else if( preg_match( '!macintosh|mac os x!i', $u_agent ) )
  1770.         {
  1771.             $platform = 'mac';
  1772.         }
  1773.         else if( preg_match( '!windows|win32!i', $u_agent ) )
  1774.         {
  1775.             $platform = 'windows';
  1776.         }
  1777.  
  1778.         // Next get the name of the useragent yes seperately and for good reason
  1779.         if( preg_match( '!MSIE!i', $u_agent ) && ! preg_match( '!Opera!i', $u_agent ) )
  1780.         {
  1781.             $bname = 'Internet Explorer';
  1782.             $ub = 'MSIE';
  1783.         }
  1784.         else if( preg_match( '!Firefox!i', $u_agent ) )
  1785.         {
  1786.             $bname = 'Mozilla Firefox';
  1787.             $ub = 'Firefox';
  1788.         }
  1789.         else if( preg_match( '!Chrome!i', $u_agent ) )
  1790.         {
  1791.             $bname = 'Google Chrome';
  1792.             $ub = 'Chrome';
  1793.         }
  1794.         else if( preg_match( '!Safari!i', $u_agent ) )
  1795.         {
  1796.             $bname = 'Apple Safari';
  1797.             $ub = 'Safari';
  1798.         }
  1799.         else if( preg_match( '!Opera!i', $u_agent ) )
  1800.         {
  1801.             $bname = 'Opera';
  1802.             $ub = 'Opera';
  1803.         }
  1804.         else if( preg_match( '!Netscape!i', $u_agent ) )
  1805.         {
  1806.             $bname = 'Netscape';
  1807.             $ub = 'Netscape';
  1808.         }
  1809.  
  1810.         // finally get the correct version number
  1811.         $known = array( 'Version', $ub, 'other' );
  1812.  
  1813.         $pattern = '#(?<browser>' . join('|', $known ) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
  1814.         if( ! @preg_match_all( $pattern, $u_agent, $matches ) )
  1815.         {
  1816.             // we have no matching number just continue
  1817.         }
  1818.  
  1819.         // see how many we have
  1820.         $i = count( $matches['browser'] );
  1821.         if( $i != 1 )
  1822.         {
  1823.             //we will have two since we are not using 'other' argument yet
  1824.             //see if version is before or after the name
  1825.             if( strripos( $u_agent,'Version' ) < strripos( $u_agent, $ub ) )
  1826.             {
  1827.                 $version = ! empty( $matches['version'][0] ) ? $matches['version'][0] : '';
  1828.             }
  1829.             else
  1830.             {
  1831.                 $version = ! empty( $matches['version'][1] ) ? $matches['version'][1] : '';
  1832.             }
  1833.         }
  1834.         else
  1835.         {
  1836.             $version = ! empty( $matches['version'][0] ) ? $matches['version'][0] : '';
  1837.         }
  1838.  
  1839.         // check if we have a number
  1840.         if( $version == null || $version == '' )
  1841.         {
  1842.             $version = '?';
  1843.         }
  1844.  
  1845.         $mainVersion = $version;
  1846.         if( strpos( $version, '.' ) !== false )
  1847.         {
  1848.             $mainVersion = explode( '.', $version );
  1849.             $mainVersion = $mainVersion[0];
  1850.         }
  1851.  
  1852.         if( $returnValue == 'class' )
  1853.         {
  1854.             if( $lowercase )
  1855.             {
  1856.                 return strtolower( $ub . ' ' . $ub . $mainVersion );
  1857.             }
  1858.  
  1859.             return $ub . ' ' . $ub . $mainVersion;
  1860.         }
  1861.         else
  1862.         {
  1863.             return array(
  1864.                 'userAgent'     => $u_agent,
  1865.                 'name'          => $bname,
  1866.                 'shortname'     => $ub,
  1867.                 'version'       => $version,
  1868.                 'mainversion'   => $mainVersion,
  1869.                 'platform'      => $platform,
  1870.                 'pattern'       => $pattern
  1871.             );
  1872.         }
  1873.     }
  1874. }
  1875.  
  1876.  
  1877. if( ! function_exists( 'avia_favicon' ) )
  1878. {
  1879.     /**
  1880.      *
  1881.      * @param string $url
  1882.      * @return string
  1883.      */
  1884.     function avia_favicon( $url = '' )
  1885.     {
  1886.         $icon_link = '';
  1887.         $type = '';
  1888.  
  1889.         if( $url )
  1890.         {
  1891.  
  1892.             if( strpos( $url, '.png' ) !== false )
  1893.             {
  1894.                 $type = 'image/png';
  1895.             }
  1896.             else if( strpos( $url, '.gif' ) !== false )
  1897.             {
  1898.                 $type = 'image/gif';
  1899.             }
  1900.             else
  1901.             {
  1902.                 $type = 'image/x-icon';
  1903.             }
  1904.  
  1905.             $icon_link = '<link rel="icon" href="'.$url.'" type="' . $type . '">';
  1906.         }
  1907.  
  1908.         /**
  1909.          * @param string $icon_link
  1910.          * @param string $url
  1911.          * @param string $type
  1912.          * @return string
  1913.          */
  1914.         $icon_link = apply_filters( 'avf_favicon_final_output', $icon_link, $url, $type );
  1915.  
  1916.         return $icon_link;
  1917.     }
  1918. }
  1919.  
  1920.  
  1921. if( ! function_exists( 'avia_regex' ) )
  1922. {
  1923.     /**
  1924.      * regex for url: http://mathiasbynens.be/demo/url-regex
  1925.      *
  1926.      * @param string $string
  1927.      * @param string|false $pattern
  1928.      * @param string $start
  1929.      * @param string $end
  1930.      * @return false|string
  1931.      */
  1932.     function avia_regex( $string, $pattern = false, $start = '^', $end = '' )
  1933.     {
  1934.         if( ! $pattern )
  1935.         {
  1936.             return false;
  1937.         }
  1938.  
  1939.         if( $pattern == 'url' )
  1940.         {
  1941.             $pattern = "!$start((https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?)$end!";
  1942.         }
  1943.         else if( $pattern == 'mail' )
  1944.         {
  1945.             $pattern = "!$start\w[\w|\.|\-]+@\w[\w|\.|\-]+\.[a-zA-Z]{2,4}$end!";
  1946.         }
  1947.         else if( $pattern == 'image' )
  1948.         {
  1949.             $pattern = "!$start(https?(?://([^/?#]*))?([^?#]*?\.(?:jpg|gif|png)))$end!";
  1950.         }
  1951.         else if( strpos( $pattern, '<' ) === 0 )
  1952.         {
  1953.             $pattern = str_replace( '<', '',$pattern );
  1954.             $pattern = str_replace( '>', '',$pattern );
  1955.  
  1956.             if( strpos( $pattern, '/' ) !== 0 )
  1957.             {
  1958.                 $close = "\/>";
  1959.                 $pattern = str_replace( '/', '', $pattern );
  1960.             }
  1961.  
  1962.             $pattern = trim( $pattern );
  1963.             if( ! isset( $close ) )
  1964.             {
  1965.                 $close = "<\/" . $pattern . ">";
  1966.             }
  1967.  
  1968.             $pattern = "!$start\<$pattern.+?$close!";
  1969.         }
  1970.  
  1971.         $result = array();
  1972.         preg_match( $pattern, $string, $result );
  1973.  
  1974.         if( empty( $result[0] ) )
  1975.         {
  1976.             return false;
  1977.         }
  1978.  
  1979.         return $result;
  1980.     }
  1981. }
  1982.  
  1983.  
  1984. if( ! function_exists( 'avia_debugging_info' ) )
  1985. {
  1986.     function avia_debugging_info()
  1987.     {
  1988.         if ( is_feed() )
  1989.         {
  1990.             return;
  1991.         }
  1992.  
  1993.         $theme = wp_get_theme();
  1994.         $child = '';
  1995.  
  1996.         if( is_child_theme() )
  1997.         {
  1998.             $child  = "- - - - - - - - - - -\n";
  1999.             $child .= 'ChildTheme: ' . $theme->get( 'Name' ) . "\n";
  2000.             $child .= 'ChildTheme Version: ' . $theme->get( 'Version' ) . "\n";
  2001.             $child .= 'ChildTheme Installed: ' . $theme->get( 'Template' ) . "\n\n";
  2002.             $child .= "- - - - - - - - - - -\n";
  2003.  
  2004.             $theme = wp_get_theme( $theme->get( 'Template' ) );
  2005.         }
  2006.  
  2007.         $info  = "\n\n<!--\n";
  2008.         $info .= "Debugging Info for Theme support: \n\n";
  2009.         $info .= 'Theme: ' . $theme->get( 'Name' ) . "\n";
  2010.         $info .= 'Version: ' . $theme->get( 'Version' ) . "\n";
  2011.         $info .= 'Installed: ' . $theme->get_template() . "\n";
  2012.         $info .= 'AviaFramework Version: ' . AV_FRAMEWORK_VERSION . "\n";
  2013.  
  2014.  
  2015.         if( class_exists( 'AviaBuilder', false ) )
  2016.         {
  2017.             $info .= 'AviaBuilder Version: ' . AviaBuilder::VERSION . "\n";
  2018.  
  2019.             if( class_exists( 'aviaElementManager', false ) )
  2020.             {
  2021.                 $info .= 'aviaElementManager Version: ' . aviaElementManager::VERSION . "\n";
  2022.                 $update_state = get_option( 'av_alb_element_mgr_update', '' );
  2023.                 if( '' != $update_state )
  2024.                 {
  2025.                     $info .= "aviaElementManager update state: in update \n";
  2026.                 }
  2027.             }
  2028.         }
  2029.  
  2030.  
  2031.         $info .= $child;
  2032.  
  2033.         //memory setting, peak usage and number of active plugins
  2034.         $info .= 'ML:' . trim( @ini_get( 'memory_limit' ) ,'M' ) . '-PU:' . ( ceil (memory_get_peak_usage() / 1000 / 1000 ) ) . '-PLA:' . avia_count_active_plugins() . "\n";
  2035.         $info .= 'WP:' . get_bloginfo( 'version' ) . "\n";
  2036.  
  2037.         $comp_levels = array(
  2038.                         'none'          => 'disabled',
  2039.                         'avia-module'   => 'modules only',
  2040.                         'avia'          => 'all theme files',
  2041.                         'all'           => 'all files',
  2042.                         'minified_only' => 'load minified only'
  2043.                     );
  2044.  
  2045.         $info .= 'Compress: CSS:' . $comp_levels[ avia_get_option( 'merge_css', 'avia-module' ) ] . ' - JS:' . $comp_levels[ avia_get_option( 'merge_js', 'avia-module' ) ] . "\n";
  2046.  
  2047.         $token = trim( avia_get_option( 'updates_envato_token' ) );
  2048.         $username = avia_get_option( 'updates_username' );
  2049.         $API = avia_get_option( 'updates_api_key' );
  2050.  
  2051.         $updates = 'disabled';
  2052.  
  2053.         if( ! empty( $token ) )
  2054.         {
  2055.             $token_state = trim( avia_get_option( 'updates_envato_token_state' ) );
  2056.             $verified_token = trim( avia_get_option( 'updates_envato_verified_token' ) );
  2057.  
  2058.             if( empty( $token_state ) )
  2059.             {
  2060.                 $updates = 'enabled - unverified Envato token';
  2061.             }
  2062.             else
  2063.             {
  2064.                 $updates = $token_state == $verified_token ? 'enabled - verified token' : 'enabled - token has changed and not verified';
  2065.             }
  2066.         }
  2067.         else if( $username && $API )
  2068.         {
  2069.             $updates = 'enabled';
  2070.             if( isset( $_GET['username'] ) )
  2071.             {
  2072.                 $updates .=  " ({$username})";
  2073.             }
  2074.  
  2075.             $updates .= ' - deprecated Envato API - register Envato Token';
  2076.         }
  2077.  
  2078.         $info .= 'Updates: ' . $updates . "\n";
  2079.  
  2080.         /**
  2081.          *
  2082.          * @used_by         enfold\includes\helper-assets.php av_untested_plugins_debugging_info()      10
  2083.          * @param string
  2084.          * @return string
  2085.          */
  2086.         $info  = apply_filters( 'avf_debugging_info_add', $info );
  2087.  
  2088.         $info .= '-->';
  2089.  
  2090.         echo apply_filters( 'avf_debugging_info', $info );
  2091.     }
  2092.  
  2093.     add_action( 'wp_head', 'avia_debugging_info', 9999999 );
  2094.     add_action( 'admin_print_scripts', 'avia_debugging_info', 9999999 );
  2095. }
  2096.  
  2097.  
  2098. if( ! function_exists( 'avia_count_active_plugins' ) )
  2099. {
  2100.     function avia_count_active_plugins()
  2101.     {
  2102.        $plugins = count( get_option( 'active_plugins', array() ) );
  2103.  
  2104.        if( is_multisite() && function_exists( 'get_site_option' ) )
  2105.        {
  2106.            $plugins += count( get_site_option( 'active_sitewide_plugins', array() ) );
  2107.        }
  2108.  
  2109.        return $plugins;
  2110.     }
  2111. }
  2112.  
  2113.  
  2114. if( ! function_exists( 'avia_clean_string' ) )
  2115. {
  2116.     /**
  2117.      *
  2118.      * @param string $string
  2119.      * @return string
  2120.      */
  2121.     function avia_clean_string( $string )
  2122.     {
  2123.        $string = str_replace( ' ', '_', $string ); // Replaces all spaces with underscores.
  2124.        $string = preg_replace( '/[^A-Za-z0-9\-]/', '', $string ); // Removes special chars.
  2125.  
  2126.        return preg_replace( '/-+/', '-', strtolower( $string ) ); // Replaces multiple hyphens with single one.
  2127.     }
  2128. }
  2129.  
  2130.  
  2131. if( ! function_exists('kriesi_backlink' ) )
  2132. {
  2133.     /**
  2134.      *
  2135.      * @param boolean $frontpage_only
  2136.      * @param string|false $theme_name_passed
  2137.      * @return string
  2138.      */
  2139.     function kriesi_backlink( $frontpage_only = false, $theme_name_passed = false )
  2140.     {
  2141.         $no = '';
  2142.         $theme_string = '';
  2143.         $theme_name = $theme_name_passed ? $theme_name_passed : THEMENAME;
  2144.  
  2145.         $random_number = get_option( THEMENAMECLEAN . '_fixed_random' );
  2146.  
  2147.         $check = $random_number % 3;
  2148.  
  2149.         switch( $check )
  2150.         {
  2151.             case 0:
  2152.                 $theme_string = $theme_name . ' Theme by Kriesi';
  2153.                 break;
  2154.             case 1:
  2155.                 $theme_string = $theme_name . ' WordPress Theme by Kriesi';
  2156.                 break;
  2157.             case 2:
  2158.             default:
  2159.                 $theme_string = 'powered by ' . $theme_name . ' WordPress Theme';
  2160.                 break;
  2161.         }
  2162.  
  2163.         if( ! empty( $frontpage_only ) && ! is_front_page() )
  2164.         {
  2165.             $no = "rel='nofollow'";
  2166.         }
  2167.  
  2168.         $link = " - <a {$no} href='https://kriesi.at'>{$theme_string}</a>";
  2169.  
  2170.         /**
  2171.          * @param string $link
  2172.          * @return string
  2173.          */
  2174.         $link = apply_filters( 'kriesi_backlink', $link );
  2175.  
  2176.         return $link;
  2177.     }
  2178. }
  2179.  
  2180.  
  2181. if( ! function_exists( 'avia_header_class_filter' ) )
  2182. {
  2183.     /**
  2184.      *
  2185.      * @param string $default
  2186.      * @return string
  2187.      */
  2188.     function avia_header_class_filter( $default = '' )
  2189.     {
  2190.         $default = apply_filters( 'avia_header_class_filter', $default );
  2191.         return $default;
  2192.     }
  2193. }
  2194.  
  2195.  
  2196. if( ! function_exists( 'avia_theme_version_higher_than' ) )
  2197. {
  2198.     /**
  2199.      * Checks for parent theme version >= a given version
  2200.      *
  2201.      * @since < 4.0
  2202.      * @param string $check_for_version
  2203.      * @return boolean
  2204.      */
  2205.     function avia_theme_version_higher_than( $check_for_version = '' )
  2206.     {
  2207.         $theme_version = avia_get_theme_version();
  2208.  
  2209.         if( version_compare( $theme_version, $check_for_version , '>=' ) )
  2210.         {
  2211.             return true;
  2212.         }
  2213.  
  2214.         return false;
  2215.     }
  2216. }
  2217.  
  2218. if( ! function_exists( 'avia_enqueue_style_conditionally' ) )
  2219. {
  2220.     /**
  2221.      * Enque a css file, based on theme options or other conditions that get passed and must be evaluated as true
  2222.      *
  2223.      * params are the same as in enque style, only the condition is first: https://core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/functions.wp-styles.php#L164
  2224.      *
  2225.      * @since 4.3
  2226.      * @added_by Kriesi
  2227.      * @param boolean $condition
  2228.      * @param string $handle
  2229.      * @param string $src
  2230.      * @param array $deps
  2231.      * @param boolean|string $ver
  2232.      * @param string $media
  2233.      * @param boolean $deregister
  2234.      * @return void
  2235.      */
  2236.     function avia_enqueue_style_conditionally( $condition = false, $handle = '', $src = '', $deps = array(), $ver = false, $media = 'all', $deregister = true )
  2237.     {
  2238.         if( $condition == false )
  2239.         {
  2240.             if( $deregister )
  2241.             {
  2242.                 wp_deregister_style( $handle );
  2243.             }
  2244.  
  2245.             return;
  2246.         }
  2247.  
  2248.         wp_enqueue_style( $handle, $src, $deps, $ver, $media );
  2249.     }
  2250. }
  2251.  
  2252.  
  2253. if( ! function_exists( 'avia_enqueue_script_conditionally' ) )
  2254. {
  2255.     /**
  2256.      * Enque a js file, based on theme options or other conditions that get passed and must be evaluated as true
  2257.      *
  2258.      * params are the same as in enque style, only the condition is first: https://core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/functions.wp-scripts.php#L264
  2259.      *
  2260.      * @since 4.3
  2261.      * @added_by Kriesi
  2262.      * @param boolean $condition
  2263.      * @param string $handle
  2264.      * @param string $src
  2265.      * @param array $deps
  2266.      * @param boolean|string $ver
  2267.      * @param boolean $in_footer
  2268.      * @param boolean $deregister
  2269.      * @return void
  2270.      */
  2271.     function avia_enqueue_script_conditionally( $condition = false, $handle = '', $src = '', $deps = array(), $ver = false, $in_footer = false, $deregister = true )
  2272.     {
  2273.         if( $condition == false )
  2274.         {
  2275.             if( $deregister )
  2276.             {
  2277.                 wp_deregister_script( $handle );
  2278.             }
  2279.  
  2280.             return;
  2281.         }
  2282.  
  2283.         wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer );
  2284.     }
  2285. }
  2286.  
  2287.  
  2288. if( ! function_exists( 'avia_disable_query_migrate' ) )
  2289. {
  2290.     /**
  2291.      * Makes sure that jquery no longer depends on jquery migrate.
  2292.      *
  2293.      * @since 4.3
  2294.      * @added_by Kriesi
  2295.      * @param array $condition
  2296.      * @return array
  2297.      */
  2298.     function avia_disable_query_migrate()
  2299.     {
  2300.         global $wp_scripts;
  2301.  
  2302.         if( ! is_admin() )
  2303.         {
  2304.             if( isset( $wp_scripts->registered['jquery'] ) )
  2305.             {
  2306.                 foreach( $wp_scripts->registered['jquery']->deps as $key => $dep )
  2307.                 {
  2308.                     if( $dep == 'jquery-migrate' )
  2309.                     {
  2310.                         unset( $wp_scripts->registered['jquery']->deps[ $key ] );
  2311.                     }
  2312.                 }
  2313.             }
  2314.         }
  2315.     }
  2316. }
  2317.  
  2318.  
  2319. if( ! function_exists( 'avia_get_submenu_count' ) )
  2320. {
  2321.     /**
  2322.      * Counts the number of submenu items of a menu
  2323.      *
  2324.      * @since 4.3
  2325.      * @added_by Kriesi
  2326.      * @param array $location
  2327.      * @return int $count
  2328.      */
  2329.     function avia_get_submenu_count( $location )
  2330.     {
  2331.         $menus = get_nav_menu_locations();
  2332.         $count  = 0;
  2333.  
  2334.         if( ! isset( $menus[ $location ] ) )
  2335.         {
  2336.             return $count;
  2337.         }
  2338.  
  2339.         $items = wp_get_nav_menu_items( $menus[ $location ] );
  2340.  
  2341.         //if no menu is set we dont know if the fallback menu will generate submenu items so we assume thats true
  2342.         if( ! $items )
  2343.         {
  2344.             return 1;
  2345.         }
  2346.  
  2347.         foreach( $items as $item )
  2348.         {
  2349.             if( isset( $item->menu_item_parent ) && $item->menu_item_parent > 0 )
  2350.             {
  2351.                 $count++;
  2352.             }
  2353.         }
  2354.  
  2355.         return $count;
  2356.     }
  2357. }
  2358.  
  2359.  
  2360. if( ! function_exists( 'avia_get_active_widget_count' ) )
  2361. {
  2362.     /**
  2363.      * Counts the number of active widget areas (widget areas that got a widget inside them are considered active)
  2364.      *
  2365.      * @since 4.3
  2366.      * @added_by Kriesi
  2367.      * @return int $count
  2368.      */
  2369.     function avia_get_active_widget_count()
  2370.     {
  2371.         global $_wp_sidebars_widgets;
  2372.  
  2373.         $count  = 0;
  2374.  
  2375.         foreach( $_wp_sidebars_widgets as $widget_area => $widgets )
  2376.         {
  2377.             if( $widget_area == 'wp_inactive_widgets' || $widget_area == 'array_version' )
  2378.             {
  2379.                 continue;
  2380.             }
  2381.  
  2382.             if( ! empty( $widgets ) )
  2383.             {
  2384.                 $count++;
  2385.             }
  2386.         }
  2387.  
  2388.         return $count;
  2389.     }
  2390. }
  2391.  
  2392.  
  2393. if( ! function_exists( 'avia_get_theme_version' ) )
  2394. {
  2395.     /**
  2396.      * Helper function that returns the (parent) theme version number to be added to scipts and css links
  2397.      *
  2398.      * @since 4.3.2
  2399.      * @added_by Günter
  2400.      * @return string
  2401.      */
  2402.     function avia_get_theme_version( $which = 'parent' )
  2403.     {
  2404.         $theme = wp_get_theme();
  2405.         if( false !== $theme->parent() && ( 'parent' == $which ) )
  2406.         {
  2407.             $theme = $theme->parent();
  2408.         }
  2409.         $vn = $theme->get( 'Version' );
  2410.  
  2411.         return $vn;
  2412.     }
  2413. }
  2414.  
  2415.  
  2416. if( ! function_exists( 'handler_wp_targeted_link_rel' ) )
  2417. {
  2418.     /**
  2419.      * Eliminates rel noreferrer and noopener from links that are not cross origin.
  2420.      *
  2421.      * @since 4.6.3
  2422.      * @added_by Günter
  2423.      * @param string $rel               'noopener noreferrer'
  2424.      * @param string $link_html         space separated string of a attributes
  2425.      * @return string
  2426.      */
  2427.     function handler_wp_targeted_link_rel( $rel, $link_html )
  2428.     {
  2429.         $url = get_bloginfo( 'url' );
  2430.         $url = str_ireplace( array( 'http://', 'https://' ), '', $url );
  2431.  
  2432.         $href = '';
  2433.         $found = preg_match( '/href=["\']?([^"\'>]+)["\']?/', $link_html, $href );
  2434.         if( empty( $found ) )
  2435.         {
  2436.             return $rel;
  2437.         }
  2438.  
  2439.         $info = explode( '?', $href[1] );
  2440.  
  2441.         if( false !== stripos( $info[0], $url ) )
  2442.         {
  2443.             return '';
  2444.         }
  2445.  
  2446.         return $rel;
  2447.     }
  2448.  
  2449.     add_filter( 'wp_targeted_link_rel', 'handler_wp_targeted_link_rel', 10, 2 );
  2450. }
  2451.  
  2452.  
  2453. if( ! function_exists( 'handler_wp_walker_nav_menu_start_el' ) )
  2454. {
  2455.     /**
  2456.      * Apply security fix for external links
  2457.      *
  2458.      * @since 4.6.3
  2459.      * @added_by Günter
  2460.      * @param string $item_output           The menu item's starting HTML output.
  2461.      * @param WP_Post|mixed $item           Menu item data object.
  2462.      * @param int $depth                    Depth of menu item. Used for padding.
  2463.      * @param stdClass $args                An object of wp_nav_menu() arguments.
  2464.      * @return type
  2465.      */
  2466.     function handler_wp_walker_nav_menu_start_el( $item_output, $item, $depth, $args )
  2467.     {
  2468.         $item_output = avia_targeted_link_rel( $item_output );
  2469.  
  2470.         return $item_output;
  2471.     }
  2472.  
  2473.     add_filter( 'walker_nav_menu_start_el', 'handler_wp_walker_nav_menu_start_el', 10, 4 );
  2474. }
  2475.  
  2476.  
  2477. if( ! function_exists( 'avia_targeted_link_rel' ) )
  2478. {
  2479.     /**
  2480.      * Wrapper function for backwards comp. with older WP vrsions
  2481.      *
  2482.      * @since 4.6.3
  2483.      * @uses wp_targeted_link_rel               @since 5.1.0
  2484.      * @uses handler_wp_targeted_link_rel       filter wp_targeted_link_rel
  2485.      * @added_by Günter
  2486.      * @param string $text
  2487.      * @param true|string $exec_call        true | 'translate' | 'reverse'
  2488.      * @return string
  2489.      */
  2490.     function avia_targeted_link_rel( $text, $exec_call = true )
  2491.     {
  2492.         /**
  2493.          * For older WP versions we skip this feature
  2494.          */
  2495.         if( ! function_exists( 'wp_targeted_link_rel' ) )
  2496.         {
  2497.             return $text;
  2498.         }
  2499.  
  2500.         global $wp_version;
  2501.  
  2502.         /**
  2503.          * WP changed the way it splits the attributes. '_' is not supported as a valid attribute and removes these attributes.
  2504.          * See wp-includes\kses.php wp_kses_hair( $attr, $allowed_protocols );
  2505.          * This breaks our data-xxx attributes like data-av_icon.
  2506.          *
  2507.          * This might change in a future version of WP.
  2508.          */
  2509.         if( version_compare( $wp_version, '5.3.1', '<' ) )
  2510.         {
  2511.             return true === $exec_call ? wp_targeted_link_rel( $text ) : $text;
  2512.         }
  2513.  
  2514.         /**
  2515.          * Do not run (more expensive) regex if no links with targets
  2516.          */
  2517.         if( stripos( $text, 'target' ) === false || stripos( $text, '<a ' ) === false || is_serialized( $text ) )
  2518.         {
  2519.             return $text;
  2520.         }
  2521.  
  2522.         $attr_translate = array(
  2523.                             'data-av_icon',
  2524.                             'data-av_iconfont',
  2525.                             'data-fbscript_id'
  2526.                         );
  2527.  
  2528.         /**
  2529.          * Add more custom attributes that are removed by WP
  2530.          *
  2531.          * @since 4.6.4
  2532.          * @param array
  2533.          * @retrun array
  2534.          */
  2535.         $attr_translate = apply_filters( 'avf_translate_targeted_link_rel_attributes', $attr_translate );
  2536.  
  2537.         $trans_attributes = array();
  2538.         foreach( $attr_translate as $value )
  2539.         {
  2540.             $trans_attributes[] = str_replace( '_', '----', $value);
  2541.         }
  2542.  
  2543.         //  Fallback - this might break page, but version is already outdated
  2544.         if( version_compare( phpversion(), '5.3', '<' ) )
  2545.         {
  2546.             $text_trans = str_replace( $attr_translate, $trans_attributes, $text );
  2547.             $text_trans = wp_targeted_link_rel( $text_trans );
  2548.             return str_replace( $trans_attributes, $attr_translate, $text_trans );
  2549.         }
  2550.  
  2551.         /**
  2552.          * To avoid breaking a page we do not replace the the attribute names with simple str_replace but
  2553.          * use the same way WP does to filter the a tags for replacing
  2554.          *
  2555.          * see wp-includes\formatting.php
  2556.          */
  2557.         $script_and_style_regex = '/<(script|style).*?<\/\\1>/si';
  2558.  
  2559.         $test_exec = true === $exec_call ? 'true' : $exec_call;
  2560.         switch( $test_exec )
  2561.         {
  2562.             case 'reverse':
  2563.                 $start = 1;
  2564.                 break;
  2565.             case 'translate':
  2566.             case 'true':
  2567.             default:
  2568.                 $start = 0;
  2569.                 break;
  2570.         }
  2571.  
  2572.         for( $iteration = $start; $iteration < 2; $iteration++ )
  2573.         {
  2574.             $matches = array();
  2575.             preg_match_all( $script_and_style_regex, $text, $matches );
  2576.             $extra_parts = $matches[0];
  2577.             $html_parts  = preg_split( $script_and_style_regex, $text );
  2578.  
  2579.             switch( $iteration )
  2580.             {
  2581.                 case 0;
  2582.                     $source = $attr_translate;
  2583.                     $replace = $trans_attributes;
  2584.                     break;
  2585.                 case 1:
  2586.                 default:
  2587.                     $source = $trans_attributes;
  2588.                     $replace = $attr_translate;
  2589.                     break;
  2590.             }
  2591.  
  2592.             foreach ( $html_parts as &$part )
  2593.             {
  2594.                 $part = preg_replace_callback( '|<a\s([^>]*target\s*=[^>]*)>|i', function ( $matches ) use( $source, $replace )
  2595.                         {
  2596.                             $link_html = $matches[1];
  2597.  
  2598.                             // Consider the html escaped if there are no unescaped quotes
  2599.                             $is_escaped = ! preg_match( '/(^|[^\\\\])[\'"]/', $link_html );
  2600.                             if ( $is_escaped )
  2601.                             {
  2602.                                 // Replace only the quotes so that they are parsable by wp_kses_hair, leave the rest as is
  2603.                                 $link_html = preg_replace( '/\\\\([\'"])/', '$1', $link_html );
  2604.                             }
  2605.  
  2606.                             foreach( $source as $key => $value )
  2607.                             {
  2608.                                 $link_html = preg_replace( '|' . $value . '\s*=|i', $replace[ $key ] . '=', $link_html );
  2609.                             }
  2610.  
  2611.                             if ( $is_escaped )
  2612.                             {
  2613.                                 $link_html = preg_replace( '/[\'"]/', '\\\\$0', $link_html );
  2614.                             }
  2615.  
  2616.                             return "<a {$link_html}>";
  2617.  
  2618.                         }, $part );
  2619.             }
  2620.  
  2621.             unset( $part );
  2622.  
  2623.             $text = '';
  2624.             for( $i = 0; $i < count( $html_parts ); $i++ )
  2625.             {
  2626.                 $text .= $html_parts[ $i ];
  2627.                 if( isset( $extra_parts[ $i ] ) )
  2628.                 {
  2629.                     $text .= $extra_parts[ $i ];
  2630.                 }
  2631.             }
  2632.  
  2633.             switch( $iteration )
  2634.             {
  2635.                 case 0;
  2636.                     if( true === $exec_call )
  2637.                     {
  2638.                         $text = wp_targeted_link_rel( $text );
  2639.                     }
  2640.                     break;
  2641.                 default:
  2642.                     break;
  2643.             }
  2644.  
  2645.             if( 'translate' == $test_exec )
  2646.             {
  2647.                 break;
  2648.             }
  2649.         }
  2650.  
  2651.         return $text;
  2652.     }
  2653. }
  2654.  
  2655.  
  2656. if( ! function_exists( 'handler_avia_widget_text' ) )
  2657. {
  2658.     /**
  2659.      * Replace attributes with _ that wp_targeted_link_rel() does not remove them
  2660.      *
  2661.      * @since 4.6.4
  2662.      * @param string $content
  2663.      * @param array $instance
  2664.      * @param WP_Widget $widget
  2665.      * @return type
  2666.      */
  2667.     function handler_avia_widget_text( $content = '', $instance = null, $widget = null )
  2668.     {
  2669.         /**
  2670.          * To support WP_Widget_Text:
  2671.          *
  2672.          * - Needs js code to replace translated attributes in frontend as this widget has no filter after call to wp_targeted_link_rel()
  2673.          * or
  2674.          * - Add a filter to wp-includes\widgets\class-wp-widget-text.php after wp_targeted_link_rel() call
  2675.          */
  2676.         if( ! $widget instanceof WP_Widget_Custom_HTML || ! is_string( $content ) )
  2677.         {
  2678.             return $content;
  2679.         }
  2680.  
  2681.         return avia_targeted_link_rel( $content, 'translate' );
  2682.     }
  2683.  
  2684.     add_filter( 'widget_text', 'handler_avia_widget_text', 90000, 3 );
  2685. }
  2686.  
  2687.  
  2688. if( ! function_exists( 'handler_avia_widget_custom_html_content' ) )
  2689. {
  2690.     /**
  2691.      * Revert changes to attributes with _
  2692.      *
  2693.      * @since 4.6.4
  2694.      * @param string $content
  2695.      * @param array $instance
  2696.      * @param WP_Widget $widget
  2697.      * @return string
  2698.      */
  2699.     function handler_avia_widget_custom_html_content( $content = '', $instance = null, $widget = null )
  2700.     {
  2701.         if( ! is_string( $content ) )
  2702.         {
  2703.             return $content;
  2704.         }
  2705.  
  2706.         return avia_targeted_link_rel( $content, 'reverse' );
  2707.     }
  2708.  
  2709.     add_filter( 'widget_custom_html_content', 'handler_avia_widget_custom_html_content', 90000, 3 );
  2710. }
  2711.  
  2712.  
  2713. if( ! function_exists( 'avia_accessibility_body_class' ) )
  2714. {
  2715.     /**
  2716.      * Add accessibility conformance classes to body to alter stylings without breaking existing sites
  2717.      * e.g. line-height is required to be larger than in theme settings
  2718.      *
  2719.      * @since 4.8.8
  2720.      * @param array $classes
  2721.      * @return array
  2722.      */
  2723.     function avia_accessibility_body_class( array $classes )
  2724.     {
  2725.         switch( avia_get_option( 'accessibility_conformance_option' ) )
  2726.         {
  2727.             case 'a_level':
  2728.                 $classes[] = 'av-accessibility-a';
  2729.                 break;
  2730.             case 'aa_level':
  2731.                 $classes[] = 'av-accessibility-a av-accessibility-aa';
  2732.                 break;
  2733.             case 'aaa_level':
  2734.                 $classes[] = 'av-accessibility-a av-accessibility-aa av-accessibility-aaa';
  2735.                 break;
  2736.         }
  2737.  
  2738.         return $classes;
  2739.     }
  2740.  
  2741.     add_filter( 'body_class', 'avia_accessibility_body_class' );
  2742. }
  2743.  
  2744.  
  2745.  
  2746. if( ! function_exists( 'avia_post_swipe_body_class' ) )
  2747. {
  2748.     /**
  2749.      * Swipe feature for post navigation.
  2750.      *
  2751.      * @since 5.5
  2752.      * @param array $classes
  2753.      * @return array
  2754.      */
  2755.     function avia_post_swipe_body_class( array $classes )
  2756.     {
  2757.         global $post;
  2758.  
  2759.         if( ! is_single() )
  2760.         {
  2761.             return $classes;
  2762.         }
  2763.  
  2764.         /**
  2765.          * Allows to disable swipe for certain post types
  2766.          *
  2767.          * @since 5.5
  2768.          * @param string $swipe_option
  2769.          * @param WP_Post $post
  2770.          * @return string           'post_nav_swipe' | ''
  2771.          */
  2772.         $swipe = apply_filters( 'avf_post_nav_swipe_support', avia_get_option( 'post_nav_swipe' ), $post );
  2773.  
  2774.         if( 'post_nav_swipe' == $swipe )
  2775.         {
  2776.             $classes[] = 'avia-post-nav-swipe-enabled';
  2777.         }
  2778.  
  2779.         return $classes;
  2780.     }
  2781.  
  2782.     add_filter( 'body_class', 'avia_post_swipe_body_class' );
  2783. }
  2784.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement