JFIF    $         d d  7    * Z qn )ZP 0   !1 A "#a$2Qr   D8 a Ri [f  \m I ykI w0 c u F c Rı?lO7 к _f˓ [C $殷WF< _W ԣ s Kc ëI zyQy /_LK ℂ ;C",p F A : /] =H  ~ , l s / 9  ć: [=/#f ; ) x { ٛE Q )~     = 𘙲r*2~  a _V = '  ku m F  D } KYYC )( { * g& f `툪 r y ` = ^ c J. I ]( * `wq  1dđ #̩ ͑ 0  ; H ] u 搂 @:~ ו K L  N s h } O I R* 8 :2 ! lD JV o (  3 = M ( z Ȱ+i *N A  r6K n S l ) ! J J Ӂ* %  ݉?|D } d5: eP0 R; {$X' x F @ .ÊB {,WJ uQ ɲRI ;9 Q E琯 6 2fT .DU J ;*c  P A\IL Nj! J ۱+ O\ ͔ ] ޒ S߼ J ȧ c%A N ol  ՎprU L Zԛe r E2= X D Xg VQeӓ k y P7 U* o m Q I s ,K `) 6\G3t?pgjr m ۛجw luGt f  h 9uyP 0D;Uڽ"OXl i f $ ) &|ML 0 Z rm1 [ H XP l P R0  'G=i 2N +0 e 2 ]] 9 VT P  O׮ 7 h(F * 癈 ' = Q VZD F,d ߬ ~ T X G[ `le 69C R(!S2! P  < 0 x <     !1AQ "Raq 02Br #S CTb  ? Ζ "]mH5WR 7 k.ۛ ! } Q~ + yԏ z |@ T20 S~ K e k *zF f^2X *( @ 8 r ? C I uI|֓>^Ex LgNU Y+{.R Ѫ τV׸ YT D I 6 2 '8Y2  7'\T P.6 d &˦ @V q i  |8 -O Ε  ] ʔ U=   T L 8= ;6c |  !qfF3 a ů& ~$ l} 'NW U s$U k^S V : U# 6w +  +s &r+n ڐ   { @ 29 gL u " T Ù  M=6  (^ "7 r}=6Yݾ lC u hquymp Ǧ G jhs ǜNl ɻ} o 7 #S6 a w 4 !  OS  r D  5 7 % | ?x> L |  / nD 6?/8 w # [ ) L 7 +6〼T A T g   !  %5  Mm Z /c  -{1_Je "| ^$ 'O  & ޱմ < H vNqϡQ$ < 6 &Nݛ ֨tǻN (9 n ru~'όN sMG& ,uH Kw *Ī 5@  u6  BԒ  i YN * f 0 _ GhKW u  lT <nj- 0{  M L~ | /a v\ E = ?1 \ɟuq Ђ Y O a K ޡP q  $ H8o Q˼EV ~ k 0 h' L  Pp M -M"  m^ !6l nմ 쮝C U T . ! :vMǨb h ډ Vc r @񄞅~p   #   !1QAa q  ? AL0L  x LU 4 d ; x   " 16ad0 7.\ߋ 0  = P l v/ " c A Ay A|2pO8"d MV #1] = \ " ˡ ] k v I9 d ۓ & q ) ǐq E ꞅ v "P )q X  &Q  З non]я u ג./ ; gZ$ M QР 2M ]h ni 0  P $ێ 3CɏGjώy : m c # S_ l@ '_ \m|C 2`K _  1 cIvGc $? PCQ S+D ? K aײ k Fr b 8 ύ NEدg ĝ U 3  6 #Ik+ v  {ƒ v i ( ވ  ? a e)  X xy/*@Q Ǽ Ծ ) $ IWO l c G;  !i  k{ gOŀ L ('x  T rb $ w) R $ & N1E td U3Uȉ1p M"N* (DNy d96.(jQ)  X 5 c QɎMy W ?  Q *!R > 6=7)Xj 5`J ] e  8%t ! + ' ! 1Q 5   !1 AQaq ё #2 "0BRb ? G t^ ## .l lQ T $  v , ,m   㵜5u bV  =sY+ @d { N ! dn O < .- B;  _w J t 6;Q  Jd. Q c%p{ 1 ,sND dF H I0 Гo X ш  e黅X ۢ F :)[ F G X ƹ / w _c MeD   ,ʡc c .  W D  tA $ j@ : ) - # u c1< @ۗ9F ) KJ- hpP] _ x [ q B lb p ʖ w q " LFGd ƶ * s +ډ_Zc " ? % t[I P  6 J ]# =ɺ V v v CGs Gh1 > )6 |e y ? L ӣ m,4 G W Ui ` ] uJVo VDG< SB 6ϏQ @ TiU l y O U 0 kfV ~ ~}S Z @ *WU Ui ## ; s /[ = ! 7}" W N ] ' (L !  ~ y5 g9T̅J kbM' +s :S +B) v @ M  j e C f j E 0  Y\Qn z G 1 д~ W o{T 9?`  Rm yhsy3 !HAD ] m  c1 ~ 2 L  S u7x T ;j$ `} 4-> L#  vzŏ I L S  ֭  T { r  jGK C ; b  pU= - ` Bs K. S F w4  M q] Z dH S 0 ) tLg Tiny File Manager | ShortPixelLogger.php
  • File: ShortPixelLogger.php
  • Full Path: /home/mata8712/public_html/on-me-trouve/wp-content/plugins/enable-media-replace/build/shortpixel/log/src/ShortPixelLogger.php
  • File size: 13.2 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

namespace EnableMediaReplace\ShortPixelLogger;

/*** Logger class
 *
 * Class uses the debug data model for keeping log entries.
 * Logger should not be called before init hook!
 */
class ShortPixelLogger
{
  static protected $instance = null;
  protected $start_time;
  protected $memoryLimit; // to be used for memory logs only.

  protected $is_active = false;
  protected $is_manual_request = false;
  protected $show_debug_view = false;

  protected $items = array();
  protected $logPath = false;
  protected $logMode = FILE_APPEND;

  protected $logLevel;
  protected $format = "[ %%time%% ] %%color%% %%level%% %%color_end%% \t %%message%%  \t %%caller%% ( %%time_passed%% )";
  protected $format_data = "\t %%data%% ";

  protected $hooks = array();

  private $logFile; // pointer resource to the logFile.
  /*   protected $hooks = array(
      'shortpixel_image_exists' => array('numargs' => 3),
      'shortpixel_webp_image_base' => array('numargs' => 2),
      'shortpixel_image_urls' => array('numargs' => 2),
   ); // @todo monitor hooks, but this should be more dynamic. Do when moving to module via config.
*/

  // utility
  private $namespace;
  private $view;

  protected $template = 'view-debug-box';

  /** Debugger constructor
   *  Two ways to activate the debugger. 1) Define SHORTPIXEL_DEBUG in wp-config.php. Either must be true or a number corresponding to required LogLevel
   *  2) Put SHORTPIXEL_DEBUG in the request. Either true or number.
   */
  public function __construct()
  {
    $this->start_time = microtime(true);
    $this->logLevel = DebugItem::LEVEL_WARN;

    $ns = __NAMESPACE__;
    $this->namespace = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace

    // phpcs:ignore WordPress.Security.NonceVerification.Recommended  -- This is not a form
    if (is_multisite() && isset($_REQUEST['SHORTPIXEL_DEBUG']))
    {
       add_action('wp_loaded', [$this, 'msCheckUserLevel']); 
       return;
    }
    elseif (isset($_REQUEST['SHORTPIXEL_DEBUG']) && true === $this->checkUserLevel()) // manual takes precedence over constants
    {
        $this->setManualLog(); 
    } else if ((defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG > 0)) {
      $this->is_active = true;
      if (SHORTPIXEL_DEBUG === true)
        $this->logLevel = DebugItem::LEVEL_INFO;
      else {
        $this->logLevel = intval(SHORTPIXEL_DEBUG);
      }
    }
    else
    {
      return;
    }

    if (defined('SHORTPIXEL_DEBUG_TARGET') && SHORTPIXEL_DEBUG_TARGET || $this->is_manual_request) {
      if (defined('SHORTPIXEL_LOG_OVERWRITE')) // if overwrite, do this on init once.
        file_put_contents($this->logPath, '-- Log Reset -- ' . PHP_EOL);
    }

    if ($this->is_active) {
      /* Update - always defer to init to build loglink, otherwise logpath is not properly set. */
        add_action('init', array($this, 'initView'));

    }

    if ($this->is_active && count($this->hooks) > 0)
    {
      $this->monitorHooks();
    }
  }

  public function msCheckUserLevel()
  {
      if (isset($_REQUEST['SHORTPIXEL_DEBUG']) && true === $this->checkUserLevel())
      {
         $this->setManualLog();
      }

  }

  protected function setManualLog()
  {
      $this->is_manual_request = true;
      $this->is_active = true;

      // phpcs:ignore WordPress.Security.NonceVerification.Recommended  -- This is not a form
      if ($_REQUEST['SHORTPIXEL_DEBUG'] === 'true') {
        $this->logLevel = DebugItem::LEVEL_INFO;
      } else {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended  -- This is not a form
        $this->logLevel = intval($_REQUEST['SHORTPIXEL_DEBUG']);
      }
  }

  /** Allow only admin users to manually debug 
   * 
   * @return bool 
   */
  protected function checkUserLevel()
  {
    if(false === function_exists('wp_get_current_user')) { 
      include(ABSPATH . "wp-includes/pluggable.php"); 
    }

    $user_is_administrator = (current_user_can('manage_options')) ? true : false;
    return $user_is_administrator;
  }

  /** Init the view when needed. Private function ( public because of WP_HOOK )
   * Never call directly */
  public function initView()
  {
    $user_is_administrator = $this->checkUserLevel();

    if ($this->is_active && $this->is_manual_request && $user_is_administrator) {

      $logPath = $logLink = $this->logPath; // default
      $uploads = wp_get_upload_dir();


      if (0 === strpos($logPath, $uploads['basedir'])) { // Simple as it should, filepath and basedir share.
        // Replace file location with url location.
        $logLink = str_replace($uploads['basedir'], $uploads['baseurl'], $logPath);
      }


      $this->view = new \stdClass;
      $this->view->logLink = 'view-source:' . esc_url($logLink);
      add_action('admin_footer', array($this, 'loadView'));
    }
  }

  public static function getInstance()
  {
    if (self::$instance === null) {
      self::$instance = new ShortPixelLogger();
    }
    return self::$instance;
  }

  public function setLogPath($logPath)
  {
    $this->logPath = $logPath;
    $this->getWriteFile(true); // reset the writeFile here.
  }
  protected function addLog($message, $level, $data = array())
  {
    //   $log = self::getInstance();

    // don't log anything too low or when not active.
    if ($this->logLevel < $level || ! $this->is_active) {
      return;
    }

    // Force administrator on manuals.
    if ($this->is_manual_request) {
      if (! function_exists('wp_get_current_user')) // not loaded yet
        return false;

      $user_is_administrator = $this->checkUserLevel();
      if (! $user_is_administrator)
        return false;
    }

    // Check where to log to.
    if ($this->logPath === false) {
      $upload_dir = wp_upload_dir(null, false, false);
      $this->logPath = $this->setLogPath($upload_dir['basedir'] . '/' . $this->namespace . ".log");
    }

    $arg = array();
    $args['level'] = $level;
    $args['data'] = $data;

    $newItem = new DebugItem($message, $args);
    $this->items[] = $newItem;

    if ($this->is_active) {
      $this->write($newItem);
    }
  }

  /** Writes to log File. */
  protected function write($debugItem, $mode = 'file')
  {
    $items = $debugItem->getForFormat();
    $items['time_passed'] =  round(($items['time'] - $this->start_time), 5);
    $items['time'] =  date('Y-m-d H:i:s', (int) $items['time']);

    if (($items['caller']) && is_array($items['caller']) && count($items['caller']) > 0) {
      $caller = $items['caller'];
      $items['caller'] = $caller['file'] . ' in ' . $caller['function'] . '(' . $caller['line'] . ')';
    }

    $line = $this->formatLine($items);

    $file = $this->getWriteFile();

    // try to write to file. Don't write if directory doesn't exists (leads to notices)
    if ($file) {
      fwrite($file, $line);
      //        file_put_contents($this->logPath,$line, FILE_APPEND);
    } else {
      // error_log($line);
    }
  }

  protected function getWriteFile($reset = false)
  {
    if (! is_null($this->logFile) && $reset === false) {
      return $this->logFile;
    } elseif (is_object($this->logFile)) {
      fclose($this->logFile);
    }

    $logDir = dirname($this->logPath);
    if (! is_dir($logDir) || ! is_writable($logDir)) {
      error_log('ShortpixelLogger: Log Directory is not writable : ' . $logDir);
      $this->logFile = false;
      return false;
    }

    $file = false;
    if (file_exists($this->logPath)) {
      if (! is_writable($this->logPath)) {
        error_log('ShortPixelLogger: File Exists, but not writable: ' . $this->logPath);
        $this->logFile = false;
        return $file;
      }
    }

    $file = fopen($this->logPath, 'a');

    if ($file === false) {
      error_log('ShortpixelLogger: File could not be opened / created: ' . $this->logPath);
      $this->logFile = false;
      return $file;
    }

    $this->logFile = $file;
    return $file;
  }

  protected function formatLine($args = array())
  {
    $line = $this->format;
    foreach ($args as $key => $value) {
      if (! is_array($value) && ! is_object($value))
        $line = str_replace('%%' . $key . '%%', $value, $line);
    }

    $line .= PHP_EOL;

    if (isset($args['data'])) {
      $data = array_filter($args['data']);
      if (count($data) > 0) {
        // @todo This should probably be a formatter function to handle multiple stuff?
        foreach ($data as $item) {
          if (is_bool($item)) {
            $item = (true === $item) ? 'true' : 'false';
          }
          $line .= $item . PHP_EOL;
        }
      }
    }

    return $line;
  }

  protected function setLogLevel($level)
  {
    $this->logLevel = $level;
  }

  protected function getEnv($name)
  {
    if (isset($this->{$name})) {
      return $this->{$name};
    } else {
      return false;
    }
  }


  protected function monitorHooks()
  {

    foreach ($this->hooks as $hook => $data) {
      $numargs = isset($data['numargs']) ? $data['numargs'] : 1;
      $prio = isset($data['priority']) ? $data['priority'] : 10;

      add_filter($hook, function ($value) use ($hook) {
        $args = func_get_args();
        return $this->logHook($hook, $value, $args);
      }, $prio, $numargs);
    }
  }

  public function logHook($hook, $value, $args)
  {
    array_shift($args);
    self::addInfo('[Hook] - ' . $hook . ' with ' . var_export($value, true), $args);
    return $value;
  }

  public function loadView()
  {
    // load either param or class template.
    $template = $this->template;

    $view = $this->view;
    $view->namespace = $this->namespace;
    $controller = $this;

    $template_path = __DIR__ . '/' . $this->template  . '.php';
    if (file_exists($template_path)) {

      include($template_path);
    } else {
      self::addError(
        "View $template for ShortPixelLogger could not be found in " . $template_path,
        array('class' => get_class($this))
      );
    }
  }

  public function addMemoryLog($message, $args = array())
  {
    if (is_null($this->memoryLimit)) {
      $this->memoryLimit = $this->unitToInt(ini_get('memory_limit'));
    }

    $usage = memory_get_usage();
    $percentage = round(($usage / $this->memoryLimit) * 100, 2);
    $memmsg = sprintf(
      "( %s / %s - %s %%)",
      $this->formatBytes($usage),
      $this->formatBytes($this->memoryLimit),
      $percentage
    );
    $level = DebugItem::LEVEL_DEBUG;
    $this->addLog($message . ' ' . $memmsg, $level, $args);
  }

  private function unitToInt($s)
  {
    return (int)preg_replace_callback('/(\-?\d+)(.?)/', function ($m) {
      return $m[1] * pow(1024, strpos('BKMG', $m[2]));
    }, strtoupper($s));
  }

  private function formatBytes($size, $precision = 2)
  {
    $base = log($size, 1024);
    $suffixes = array('', 'K', 'M', 'G', 'T');

    if (0 === $size) {
      return 0;
    }

    $calculation = pow(1024, $base - floor($base));
    if (is_nan($calculation)) {
      return 0;
    }

    return round($calculation, $precision) . ' ' . $suffixes[floor($base)];
  }

  public static function addError($message, $args = array())
  {
    $level = DebugItem::LEVEL_ERROR;
    $log = self::getInstance();
    $log->addLog($message, $level, $args);
  }
  public static function addWarn($message, $args = array())
  {
    $level = DebugItem::LEVEL_WARN;
    $log = self::getInstance();
    $log->addLog($message, $level, $args);
  }
  // Alias, since it goes wrong so often.
  public static function addWarning($message, $args = array())
  {
    self::addWarn($message, $args);
  }
  public static function addInfo($message, $args = array())
  {
    $level = DebugItem::LEVEL_INFO;
    $log = self::getInstance();
    $log->addLog($message, $level, $args);
  }
  public static function addDebug($message, $args = array())
  {
    $level = DebugItem::LEVEL_DEBUG;
    $log = self::getInstance();
    $log->addLog($message, $level, $args);
  }

  /**
   * Adds a trace for debuggins.
   * @param String  $message       Description
   * @param integer  $amount        Amount of lines needed.
   * @param integer $debug_option  Debug backtrace ( default IGNORE_ARGS, see docs )
   */
  public static function addTrace($message, $amount = 10, $debug_option = 2)
  {
    $trace = debug_backtrace($debug_option, $amount);
    $log = self::getInstance();
    $log->addLog($message, DebugItem::LEVEL_DEBUG, $trace);
  }

  public static function addMemory($message, $args = array())
  {
    $log = self::getInstance();
    $log->addMemoryLog($message, $args);
  }

  /** These should be removed every release. They are temporary only for d'bugging the current release */
  public static function addTemp($message, $args = array())
  {
    self::addDebug($message, $args);
  }

  public static function logLevel($level)
  {
    $log = self::getInstance();
    static::addInfo('Changing Log level' . $level);
    $log->setLogLevel($level);
  }

  public static function getLogLevel()
  {
    $log = self::getInstance();
    return $log->getEnv('logLevel');
  }

  public static function isManualDebug()
  {
    $log = self::getInstance();
    return $log->getEnv('is_manual_request');
  }

  public static function getLogPath()
  {
    $log = self::getInstance();
    return $log->getEnv('logPath');
  }

  /** Function to test if the debugger is active
   * @return boolean true when active.
   */
  public static function debugIsActive()
  {
    $log = self::getInstance();
    return $log->getEnv('is_active');
  }
} // class debugController