Development['enabled']; } return self::$isEnabled; } /** * Verifies whether a className of object implements the given method. It does not check whether the given method * is actually callable (public). * * @param string|object $classOrObject * @param string $method * * @return bool true if the method exists, false otherwise. */ public static function methodExists($classOrObject, $method) { if (is_string($classOrObject)) { return class_exists($classOrObject) && method_exists($classOrObject, $method); } return method_exists($classOrObject, $method); } /** * Formats a method call depending on the given class/object and method name. It does not perform any checks whether * does actually exists. * * @param string|object $classOrObject * @param string $method * * @return string Formatted method call. Example: "MyNamespace\MyClassname::methodName()" */ public static function formatMethodCall($classOrObject, $method) { if (is_object($classOrObject)) { $classOrObject = get_class($classOrObject); } return $classOrObject . '::' . $method . '()'; } /** * Checks whether the given method is actually callable on the given class/object if the development mode is * enabled. En error will be triggered if the method does not exist or is not callable (public) containing a useful * error message for the developer. * * @param string|object $classOrObject * @param string $method * @param string $prefixMessageIfError You can prepend any string to the error message in case the method is not * callable. */ public static function checkMethodIsCallable($classOrObject, $method, $prefixMessageIfError) { if (!self::isEnabled()) { return; } self::checkMethodExists($classOrObject, $method, $prefixMessageIfError); if (!self::isCallableMethod($classOrObject, $method)) { self::error($prefixMessageIfError . ' "' . self::formatMethodCall($classOrObject, $method) . '" is not callable. Please make sure to method is public'); } } /** * Checks whether the given method is actually callable on the given class/object if the development mode is * enabled. En error will be triggered if the method does not exist or is not callable (public) containing a useful * error message for the developer. * * @param string|object $classOrObject * @param string $method * @param string $prefixMessageIfError You can prepend any string to the error message in case the method is not * callable. */ public static function checkMethodExists($classOrObject, $method, $prefixMessageIfError) { if (!self::isEnabled()) { return; } if (!self::methodExists($classOrObject, $method)) { self::error($prefixMessageIfError . ' "' . self::formatMethodCall($classOrObject, $method) . '" does not exist. Please make sure to define such a method.'); } } /** * Verify whether the given method actually exists and is callable (public). * * @param string|object $classOrObject * @param string $method * @return bool */ public static function isCallableMethod($classOrObject, $method) { if (!self::methodExists($classOrObject, $method)) { return false; } $reflection = new \ReflectionMethod($classOrObject, $method); return $reflection->isPublic(); } /** * Triggers an error if the development mode is enabled. Depending on the current environment / mode it will either * log the given message or throw an exception to make sure it will be displayed in the Piwik UI. * * @param string $message * @throws Exception */ public static function error($message) { if (!self::isEnabled()) { return; } $message .= ' (This error is only shown in development mode)'; if (SettingsServer::isTrackerApiRequest() || Common::isPhpCliMode() ) { StaticContainer::get(LoggerInterface::class)->error($message, [ 'ignoreInScreenWriter' => true, ]); } else { throw new Exception($message); } } public static function getMethodSourceCode($className, $methodName) { $method = new \ReflectionMethod($className, $methodName); $file = new \SplFileObject($method->getFileName()); $offset = $method->getStartLine() - 1; $count = $method->getEndLine() - $method->getStartLine() + 1; $fileIterator = new \LimitIterator($file, $offset, $count); $methodCode = "\n " . $method->getDocComment() . "\n"; foreach ($fileIterator as $line) { $methodCode .= $line; } $methodCode .= "\n"; return $methodCode; } public static function getUseStatements($className) { $class = new \ReflectionClass($className); $file = new \SplFileObject($class->getFileName()); $fileIterator = new \LimitIterator($file, 0, $class->getStartLine()); $uses = array(); foreach ($fileIterator as $line) { if (preg_match('/(\s*)use (.+)/', $line, $match)) { $uses[] = trim($match[2]); } } return $uses; } }