Leverage backtrace to find caller plugin file path.

@author Vova Feldman (@svovaf)
@since  1.0.6

@param  bool $is_init Is initiation sequence.

@return string
331087
private function _find_caller_plugin_file( $is_init = false ) {
            // Try to load the cached value of the file path.
            if ( isset( $this->_storage->plugin_main_file ) ) {
                $plugin_main_file = $this->_storage->plugin_main_file;
                if ( isset( $plugin_main_file->path ) ) {
                    $absolute_path = $this->get_absolute_path( $plugin_main_file->path );
                    if ( file_exists( $absolute_path ) ) {
                        return $absolute_path;
                    }
                }
            }

            /**
             * @since 1.2.1
             *
             * `clear_module_main_file_cache()` is clearing the plugin's cached path on
             * deactivation. Therefore, if any plugin/theme was initiating `Freemius`
             * with that plugin's slug, it was overriding the empty plugin path with a wrong path.
             *
             * So, we've added a special mechanism with a 2nd layer of cache that uses `prev_path`
             * when the class instantiator isn't the module.
             */
            if ( ! $is_init ) {
                // Fetch prev path cache.
                if ( isset( $this->_storage->plugin_main_file ) &&
                     isset( $this->_storage->plugin_main_file->prev_path )
                ) {
                    $absolute_path = $this->get_absolute_path( $this->_storage->plugin_main_file->prev_path );
                    if ( file_exists( $absolute_path ) ) {
                        return $absolute_path;
                    }
                }

                wp_die(
                    $this->get_text_inline( 'Freemius SDK couldn\'t find the plugin\'s main file. Please contact sdk@freemius.com with the current error.', 'failed-finding-main-path' ) .
                    " Module: {$this->_slug}; SDK: " . WP_FS__SDK_VERSION . ";",
                    $this->get_text_inline( 'Error', 'error' ),
                    array( 'back_link' => true )
                );
            }

            /**
             * @since 1.2.1
             *
             * Only the original instantiator that calls dynamic_init can modify the module's path.
             */
            // Find caller module.
            $id_slug_type_path_map            = self::$_accounts->get_option( 'id_slug_type_path_map', array() );
            $this->_storage->plugin_main_file = (object) array(
                'path' => $id_slug_type_path_map[ $this->_module_id ]['path'],
            );

            return $this->get_absolute_path( $id_slug_type_path_map[ $this->_module_id ]['path'] );
        }
665206
protected function getCallerFromStackTrace()
    {
        $trace = collect(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS))->forget(0);

        return $trace->first(function ($frame) {
            if (! isset($frame['file'])) {
                return false;
            }

            return ! Str::contains($frame['file'],
                base_path('vendor'.DIRECTORY_SEPARATOR.$this->ignoredVendorPath())
            );
        });
    }
849453
protected function _init()
    {
        if (!parent::_init()) {
            return false;
        }

        if (!Plugin::exists($this->_plugin['name'])) {
            $this->err(__d('installer', 'The plugin "{0}" is not installed, you cannot update a plugin that is not installed in your system.', $this->_plugin['name']));

            return false;
        } else {
            $plugin = plugin($this->_plugin['name']);
            if (!$this->canBeDeleted($plugin->path)) {
                $this->err(__d('installer', 'Unable to update, please check write permissions for "{0}".', $plugin->path));

                return false;
            }
        }

        return true;
    }
361429
protected static function get_calling_module_from_trace($backtrace)
    {
        if (!isset($backtrace[1]['file'])) {
            return null;
        }

        $callingfile = realpath($backtrace[1]['file']);

        return ModuleLoader::inst()->getManifest()->getModuleByPath($callingfile);
    }
281885
public function findPath($classname, $basepath = null)
    {
        $path = false;

        $word = preg_replace('/(?<=\\w)([A-Z])/', ' \\1', $classname);
        $parts = explode(' ', $word);

        // If class start with a 'An' it is a anahita framework class and we handle it
        if (array_shift($parts) == $this->_prefix) {
            $path = strtolower(implode('/', $parts));

            if (count($parts) == 1) {
                $path = $path.'/'.$path;
            }

            if (!is_file($this->_basepath.'/'.$path.'.php')) {
                $path = $path.'/'.strtolower(array_pop($parts));
            }

            $path = $this->_basepath.'/'.$path.'.php';
        }

        return $path;
    }
1326250
public static function withCallsite($s)
    {
        $bt = debug_backtrace();

        $caller = null;
        do {
            $caller = array_shift($bt);

        } while ($caller && !empty($caller['class']) && $caller['class'] == 'DebugHelper\Logger');

        $file = isset($caller['file']) ? basename($caller['file']) : 'null';
        $line = isset($caller['line']) ? $caller['line'] : 'null';

        return '['.$file.':'.$line.'] '.$s;
    }
132218
protected function _pluginPath($pluginName)
    {
        if (Plugin::isLoaded($pluginName)) {
            return Plugin::path($pluginName);
        }

        return current(App::path('Plugin')) . $pluginName . DIRECTORY_SEPARATOR;
    }
1315368
private static ClassLoader getInitParent(ClassLoader parent,
                                           boolean isRoot)
  {
    if (parent == null)
      parent = Thread.currentThread().getContextClassLoader();

    if (isRoot || parent instanceof DynamicClassLoader)
      return parent;
    else {
      //return RootDynamicClassLoader.create(parent);
      return parent;
    }
  }
1186824
public static function stacktrace( $stack = null, $withPre = false )
	{
		if ( is_null( $stack ) )
			$stack = debug_backtrace();
		$output = $withPre ? '<pre>' : '';

		$stackLen = count( $stack );
		for ( $i = 1; $i < $stackLen; $i++ )
		{
			$entry = $stack[$i];

			$func = $entry['function'] . '(';
			$argsLen = count( $entry['args'] );

			for ( $j = 0; $j < $argsLen; $j++ )
			{
				$my_entry = $entry['args'][$j];

				if ( is_string( $my_entry ) )
					$func .= $my_entry;

				if ( $j < $argsLen - 1 )
					$func .= ', ';
			}
			$func .= ')';

			$entry_file = 'NO_FILE';

			if ( array_key_exists( 'file', $entry ) )
				$entry_file = $entry['file'];

			$entry_line = 'NO_LINE';

			if ( array_key_exists( 'line', $entry ) )
				$entry_line = $entry['line'];

			$output .= $entry_file . ':' . $entry_line . ' - ' . $func . PHP_EOL;
		}

		if ( $withPre )
			$output .= $output . '</pre>';

		return $output;
	}
913777
public function getGitHookExecutionPath(): string
    {
        $gitPath = $this->getGitDir();

        return $this->fileSystem->makePathRelative($this->getWorkingDir(), $this->getAbsolutePath($gitPath));
    }
1373080
protected static function findSource()
    {
        $source = '';
        $trace = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false);
        foreach ($trace as $row) {
            if (isset($row['file']) === false) {
                continue;
            }

            if (isset($row['function']) === true && strpos($row['function'], 'call_user_func') === 0) {
                continue;
            }

            if (isset($row['class']) === true && (
                is_subclass_of($row['class'], '\Tracy\IBarPanel') === true ||
                strpos(str_replace('/', '\\', $row['file']), 'Illuminate\\') !== false
            )) {
                continue;
            }

            $source = [$row['file'], (int) $row['line']];
        }

        return $source;
    }
226449
protected function initDefault()
    {
        if ($this->isCli()) {
            return null;
        }

        $uri = (empty($_SERVER['HTTPS']) ? 'http' : 'https')
            . '://'
            . $_SERVER['HTTP_HOST']
            . $_SERVER['REQUEST_URI'];
        return  rtrim(preg_replace('/\?.*/', '', $uri), '/');
    }
925381
protected String idForPath(Path pluginPath) {
        for (PluginWrapper plugin : plugins.values()) {
            if (plugin.getPluginPath().equals(pluginPath)) {
                return plugin.getPluginId();
            }
        }

        return null;
    }
408575
public static function get_plugin_directory($plugintype, $pluginname) {
        if (empty($pluginname)) {
            // Invalid plugin name, sorry.
            return null;
        }

        self::init();

        if (!isset(self::$plugins[$plugintype][$pluginname])) {
            return null;
        }
        return self::$plugins[$plugintype][$pluginname];
    }
586261
private static function normalizerPath($path, $isfolder = false)
    {
        if (preg_match('/^\//', $path) == 0) {
            $path = '/'.$path;
        }

        if ($isfolder == true) {
            if (preg_match('/\/$/', $path) == 0) {
                $path = $path.'/';
            }
        }

        return $path;
    }
875340
public static function plugin_init() {
        //here we create a default instance for this type

        $id = repository::static_function('flickr_public','create', 'flickr_public', 0, context_system::instance(), array('name'=>'', 'email_address' => null, 'usewatermarks' => false), 0);
        if (empty($id)) {
            return false;
        } else {
            return true;
        }
    }
166343
public static function callerAsString( $back = 0, $fullpath = FALSE )
    {
        list( $file, $line ) = self::caller( $back );

        if ( $fullpath ){
            return "$file($line)";
        }

        $file = basename($file);

        return "$file($line)";
    }