php_Helpers.php

<?php
namespace FindStr;

class Helpers {

  /**
   * Check if this WordPress installation is multilingual
   * Should check various plugins.
   *
   * @return bool
   */
  public static function is_website_multilingual(): bool {

    if ( function_exists( 'icl_object_id' ) ) {
      return true;
    }

    if ( function_exists( 'pll_current_language' ) ) {
      return true;
    }

    return false;
  }

  /**
   * Get the current language code
   *
   * @return string
   */
  public static function get_language_code(): string {
    return substr( get_bloginfo( 'language' ), 0, 2 );
  }

  /**
   @param $post_id
   @return string|array
   */
  public static function get_language_code_by_post_id( int $post_id = null ) {

    if ( null === $post_id ) {
      $post_id = get_the_ID();
    }

    //default language code
    $language_code = self::get_language_code();

    if ( ! function_exists( 'is_plugin_active' ) ) {
      require_once ABSPATH . '/wp-admin/includes/plugin.php';
    }

    //wpml
    if ( true === is_plugin_active( 'sitepress-multilingual-cms/sitepress.php' ) ) {
      $wpml_language_code = apply_filters( 'wpml_post_language_details', null, $post_id )['language_code'];

      if ( empty( $wpml_language_code ) ) {
        $wpml_language_code = apply_filters( 'wpml_default_language', null );
      }

      $post_type = get_post_type( $post_id );

      $is_displayed_in_all_languages = apply_filters( 'wpml_is_display_as_translated_post_type', null, $post_type );
      if ( $is_displayed_in_all_languages ) {
        $has_translation = apply_filters( 'wpml_element_has_translations', null, $post_id, $post_type );
        if ( false === $has_translation ) {
          $languages         = array( $wpml_language_code );
          $actives_languages = apply_filters( 'wpml_active_languages', null, 'orderby=id&order=desc' );
          foreach ( $actives_languages as $language ) {
            $languages[] = $language['code'];
          }

          if ( ! empty( $languages ) ) {
            return array_unique( $languages );
          }
        }
      }

      if ( ! empty( $wpml_language_code ) ) {
        $language_code = $wpml_language_code;
      }
    }

    //polylang
    if ( function_exists( 'pll_get_post_language' ) ) {
      $polylang_language_code = pll_get_post_language( $post_id );
      if ( ! empty( $polylang_language_code ) ) {
        $language_code = $polylang_language_code;
      }
    }

    return $language_code;
  }


  /**
   * File put contents, for local files only
   *
   * @param $filename
   * @param $data
   *
   * @return mixed
   */
  public static function file_put_content( $filename, $data ) {

    require_once ABSPATH . '/wp-admin/includes/file.php';
    WP_Filesystem();
    global  $wp_filesystem;

    $directory = dirname( $filename );
    if ( ! is_dir( $directory ) ) {
      wp_mkdir_p( $directory );
    }

    return $wp_filesystem->put_contents(
      $filename,
      $data,
      FS_CHMOD_FILE // predefined mode settings for WP files
    );
  }

  /**
   * File get contents, for local files only
   *
   * @param $filename
   *
   * @return mixed
   */
  public static function file_get_contents( $filename ) {
    require_once ABSPATH . '/wp-admin/includes/file.php';
    WP_Filesystem();
    global  $wp_filesystem;

    return $wp_filesystem->get_contents( $filename );
  }

  public static function get_kses_svg_ruleset() {
    return array(
      'style'   => true,
      'svg'     => array(
        'class'           => true,
        'aria-hidden'     => true,
        'aria-labelledby' => true,
        'role'            => true,
        'xmlns'           => true,
        'width'           => true,
        'height'          => true,
        'viewbox'         => true,
        'viewBox'         => true,
        'fill'            => true,
        'stroke'          => true,
        'stroke-linecap'  => true,
        'stroke-linejoin' => true,
        'stroke-width'    => true,
      ),
      'g'       => array(
        'fill'              => true,
        'id'                => true,
        'polygon'           => true,
        'stroke'            => true,
        'stroke-width'      => true,
        'stroke-miterlimit' => true,
        'stroke-linecap'    => true,
        'stroke-linejoin'   => true,
      ),
      'title'   => array( 'title' => true ),
      'path'    => array(
        'd'                 => true,
        'fill'              => true,
        'id'                => true,
        'class'             => true,
        'stroke'            => true,
        'stroke-width'      => true,
        'stroke-miterlimit' => true,
        'stroke-linecap'    => true,
        'stroke-linejoin'   => true,
        'fill-rule'         => true,
        'clip-rule'         => true,
      ),
      'polygon' => array(
        'id'                => true,
        'class'             => true,
        'fill'              => true,
        'stroke'            => true,
        'stroke-width'      => true,
        'stroke-miterlimit' => true,
        'stroke-linecap'    => true,
        'stroke-linejoin'   => true,
      ),
      'line'    => array(
        'id' => true,
        'x1' => true,
        'y1' => true,
        'x2' => true,
        'y2' => true,
      ),
      'circle'  => array(
        'id' => true,
        'cx' => true,
        'cy' => true,
        'r'  => true,
      ),
    );
  }



  /**
   * Merge arrays recursively
   *
   * @author Sariha Chabert <[email protected]>
   * @date 10/07/2018
   *
   * @param array $args
   * @param array $default
   *
   * @return array
   */
  public static function merge_args( array &$args, array &$default ): array {

    $merged = $default;
    foreach ( $args as $k => &$v ) {

      if ( is_array( $v ) && ! empty( $merged[ $k ] ) && is_array( $merged[ $k ] ) ) {

        $merged[ $k ] = self::merge_args( $v, $merged[ $k ] );

      } elseif ( is_numeric( $k ) ) {

        if ( ! in_array( $v, $merged, true ) ) {
          $merged[] = $v;
        }
      } else {
        $merged[ $k ] = $v;
      }

      //if merged value is a sequential array we need to remove duplicates.
      if ( is_array( $merged[ $k ] ) && ! self::is_assoc_array( $merged[ $k ] ) ) {
        $merged[ $k ] = array_map( 'unserialize', array_unique( array_map( 'serialize', $merged[ $k ] ) ) );
      }
    }

    return $merged;
  }

  /**
   * Check if array is associative or sequential
   * https://stackoverflow.com/a/173479
   *
   * @param array $arr
   *
   * @return bool
   */
  public static function is_assoc_array( array $arr ): bool {
    if ( array() === $arr ) {
      return false;
    }
    return array_keys( $arr ) !== range( 0, count( $arr ) - 1 );
  }


  public static function get_index_status_path( $url = false, $filename = 'findstr_status.json' ): string {
    $upload_dir = wp_upload_dir();

    $key = ( true === $url ) ? 'baseurl' : 'basedir';

    $upload_dir = $upload_dir[ $key ] . '/findstr-logs';

    //create the directory if it doesn't exist
    if ( ! $url && ! file_exists( $upload_dir ) ) {
      mkdir( $upload_dir, 0755, true );

      //put empty content
      self::file_put_content( $upload_dir . '/' . $filename, wp_json_encode( array() ) );
    }

    return $upload_dir . '/' . $filename;
  }

  public static function get_update_channel(): string {
    $channel = 'stable';

    if ( defined( 'FINDSTR_UPDATE_CHANNEL' ) ) {
      $channel = FINDSTR_UPDATE_CHANNEL;
    } else {
      $channel = get_option( 'findstr_update_channel', $channel );
    }

    /**
     * Filter the update channel
     *
     * By now, the only available channels are 'stable' or 'beta'.
     *
     * @hook findstr_plugin_update_channel
     *
     * @param string $channel
     *
     *
     * @return string $channel
     *
     */
    return apply_filters( 'findstr_plugin_update_channel', $channel );

  }

  public static function camel2dash( $name ): string {
    return ltrim( strtolower( preg_replace( '/[A-Z]([A-Z](?![a-z]))*/', '-$0', $name ) ), '-' );
  }

  public static function switch_language( $language_code ) {

    do_action( 'wpml_switch_language', $language_code );

    $active_languages = apply_filters( 'wpml_active_languages', null, 'orderby=id&order=desc' );
    foreach ( $active_languages as $language ) {
      if ( $language['code'] === $language_code ) {
        $switched = switch_to_locale( $language['default_locale'] );
        if ( $switched ) {
          load_default_textdomain();
          wp_load_translations_early();
        }
      }
    }

  }

  /**
   * Get active languages
   * This function checks for WPML and Polylang support and returns an array of active languages.
   *
   * @return array
   */
  public static function get_active_languages(): array {

    // Languages
    $available_languages = array();

    // WPML support
    if ( function_exists( 'icl_get_languages' ) ) {
      $languages = icl_get_languages( 0 );
      if ( is_array( $languages ) ) {
        foreach ( $languages as $lang ) {
          if ( ! empty( $lang['code'] ) ) {
            $available_languages[ $lang['code'] ] = array(
              'name' => $lang['native_name'],
              'code' => $lang['code'],
            );
          } elseif ( ! empty( $lang['language_code'] ) ) {
            // Polylang support 'icl_get_languages' but 'language_code' instead of 'code'
            $available_languages[ $lang['language_code'] ] = array(
              'name' => $lang['native_name'],
              'code' => $lang['language_code'],
            );
          }
        }
      }
      return $available_languages;
    }

    return $available_languages;
  }

}