update Piwik to version 2.16 (fixes #91)

This commit is contained in:
oliver 2016-04-10 18:55:57 +02:00
commit d885a4baa9
5833 changed files with 418860 additions and 226988 deletions

View file

@ -0,0 +1,16 @@
Copyright (C) 2012 Matthieu Napoli
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,57 @@
# PhpDocReader
[![Build Status](https://travis-ci.org/mnapoli/PhpDocReader.png?branch=master)](https://travis-ci.org/mnapoli/PhpDocReader) [![Coverage Status](https://coveralls.io/repos/mnapoli/PhpDocReader/badge.png)](https://coveralls.io/r/mnapoli/PhpDocReader)
This project is used by:
- [PHP-DI](http://php-di.org/)
- [phockito-unit-php-di](https://github.com/balihoo/phockito-unit-php-di)
Fork the README to add your project here.
## Features
PhpDocReader parses `@var` and `@param` values in PHP docblocks:
```php
use My\Cache\Backend;
class Cache
{
/**
* @var Backend
*/
protected $backend;
/**
* @param Backend $backend
*/
public function __construct($backend)
{
}
}
```
It supports namespaced class names with the same resolution rules as PHP:
- fully qualified name (starting with `\`)
- imported class name (eg. `use My\Cache\Backend;`)
- relative class name (from the current namespace, like `SubNamespace\MyClass`)
- aliased class name (eg. `use My\Cache\Backend as FooBar;`)
Primitive types (`@var string`) are ignored (returns null), only valid class names are returned.
## Usage
```php
$reader = new PhpDocReader();
// Read a property type (@var phpdoc)
$property = new ReflectionProperty($className, $propertyName);
$propertyClass = $reader->getPropertyClass($property);
// Read a parameter type (@param phpdoc)
$parameter = new ReflectionParameter(array($className, $methodName), $parameterName);
$parameterClass = $reader->getParameterClass($parameter);
```

View file

@ -0,0 +1,16 @@
{
"name": "mnapoli/phpdocreader",
"type": "library",
"keywords": ["phpdoc", "reflection"],
"license": "MIT",
"autoload": {
"psr-0": {
"PhpDocReader": "src/",
"UnitTest": "tests/"
}
},
"require": {
"php": ">=5.3.0",
"doctrine/annotations": "1.*"
}
}

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./tests/bootstrap.php">
<testsuites>
<testsuite name="PhpDocReader tests">
<directory>./tests/UnitTest/PhpDocReader/</directory>
</testsuite>
</testsuites>
</phpunit>

View file

@ -0,0 +1,10 @@
<?php
namespace PhpDocReader;
/**
* @author Matthieu Napoli <matthieu@mnapoli.fr>
*/
class AnnotationException extends \Exception
{
}

View file

@ -0,0 +1,270 @@
<?php
namespace PhpDocReader;
use Doctrine\Common\Annotations\PhpParser;
use ReflectionParameter;
use ReflectionProperty;
/**
* PhpDoc reader
*
* @author Matthieu Napoli <matthieu@mnapoli.fr>
*/
class PhpDocReader
{
/**
* @var PhpParser
*/
private $phpParser;
private $ignoredTypes = array(
'bool',
'boolean',
'string',
'int',
'integer',
'float',
'double',
'array',
'object',
'callable',
'resource',
);
/**
* Enable or disable throwing errors when PhpDoc Errors occur (when parsing annotations)
*
* @var bool
*/
private $ignorePhpDocErrors;
/**
*
* @param bool $ignorePhpDocErrors
*/
public function __construct($ignorePhpDocErrors = false)
{
$this->phpParser = new PhpParser();
$this->ignorePhpDocErrors = $ignorePhpDocErrors;
}
/**
* Parse the docblock of the property to get the class of the var annotation.
*
* @param ReflectionProperty $property
*
* @throws AnnotationException
* @return string|null Type of the property (content of var annotation)
*
* @deprecated Use getPropertyClass instead.
*/
public function getPropertyType(ReflectionProperty $property)
{
return $this->getPropertyClass($property);
}
/**
* Parse the docblock of the property to get the class of the var annotation.
*
* @param ReflectionProperty $property
*
* @throws AnnotationException
* @return string|null Type of the property (content of var annotation)
*/
public function getPropertyClass(ReflectionProperty $property)
{
// Get the content of the @var annotation
if (preg_match('/@var\s+([^\s]+)/', $property->getDocComment(), $matches)) {
list(, $type) = $matches;
} else {
return null;
}
// Ignore primitive types
if (in_array($type, $this->ignoredTypes)) {
return null;
}
// Ignore types containing special characters ([], <> ...)
if (! preg_match('/^[a-zA-Z0-9\\\\_]+$/', $type)) {
return null;
}
$class = $property->getDeclaringClass();
// If the class name is not fully qualified (i.e. doesn't start with a \)
if ($type[0] !== '\\') {
$alias = (false === $pos = strpos($type, '\\')) ? $type : substr($type, 0, $pos);
$loweredAlias = strtolower($alias);
// Retrieve "use" statements
$uses = $this->phpParser->parseClass($property->getDeclaringClass());
$found = false;
if (isset($uses[$loweredAlias])) {
// Imported classes
if (false !== $pos) {
$type = $uses[$loweredAlias] . substr($type, $pos);
} else {
$type = $uses[$loweredAlias];
}
$found = true;
} elseif ($this->classExists($class->getNamespaceName() . '\\' . $type)) {
$type = $class->getNamespaceName() . '\\' . $type;
$found = true;
} elseif (isset($uses['__NAMESPACE__']) && $this->classExists($uses['__NAMESPACE__'] . '\\' . $type)) {
// Class namespace
$type = $uses['__NAMESPACE__'] . '\\' . $type;
$found = true;
} elseif ($this->classExists($type)) {
// No namespace
$found = true;
}
if (!$found && !$this->ignorePhpDocErrors) {
throw new AnnotationException(sprintf(
'The @var annotation on %s::%s contains a non existent class "%s". '
. 'Did you maybe forget to add a "use" statement for this annotation?',
$class->name,
$property->getName(),
$type
));
}
}
if (!$this->classExists($type) && !$this->ignorePhpDocErrors) {
throw new AnnotationException(sprintf(
'The @var annotation on %s::%s contains a non existent class "%s"',
$class->name,
$property->getName(),
$type
));
}
// Remove the leading \ (FQN shouldn't contain it)
$type = ltrim($type, '\\');
return $type;
}
/**
* Parse the docblock of the property to get the class of the param annotation.
*
* @param ReflectionParameter $parameter
*
* @throws AnnotationException
* @return string|null Type of the property (content of var annotation)
*
* @deprecated Use getParameterClass instead.
*/
public function getParameterType(ReflectionParameter $parameter)
{
return $this->getParameterClass($parameter);
}
/**
* Parse the docblock of the property to get the class of the param annotation.
*
* @param ReflectionParameter $parameter
*
* @throws AnnotationException
* @return string|null Type of the property (content of var annotation)
*/
public function getParameterClass(ReflectionParameter $parameter)
{
// Use reflection
$parameterClass = $parameter->getClass();
if ($parameterClass !== null) {
return $parameterClass->name;
}
$parameterName = $parameter->name;
// Get the content of the @param annotation
$method = $parameter->getDeclaringFunction();
if (preg_match('/@param\s+([^\s]+)\s+\$' . $parameterName . '/', $method->getDocComment(), $matches)) {
list(, $type) = $matches;
} else {
return null;
}
// Ignore primitive types
if (in_array($type, $this->ignoredTypes)) {
return null;
}
// Ignore types containing special characters ([], <> ...)
if (! preg_match('/^[a-zA-Z0-9\\\\_]+$/', $type)) {
return null;
}
$class = $parameter->getDeclaringClass();
// If the class name is not fully qualified (i.e. doesn't start with a \)
if ($type[0] !== '\\') {
$alias = (false === $pos = strpos($type, '\\')) ? $type : substr($type, 0, $pos);
$loweredAlias = strtolower($alias);
// Retrieve "use" statements
$uses = $this->phpParser->parseClass($class);
$found = false;
if (isset($uses[$loweredAlias])) {
// Imported classes
if (false !== $pos) {
$type = $uses[$loweredAlias] . substr($type, $pos);
} else {
$type = $uses[$loweredAlias];
}
$found = true;
} elseif ($this->classExists($class->getNamespaceName() . '\\' . $type)) {
$type = $class->getNamespaceName() . '\\' . $type;
$found = true;
} elseif (isset($uses['__NAMESPACE__']) && $this->classExists($uses['__NAMESPACE__'] . '\\' . $type)) {
// Class namespace
$type = $uses['__NAMESPACE__'] . '\\' . $type;
$found = true;
} elseif ($this->classExists($type)) {
// No namespace
$found = true;
}
if (!$found && !$this->ignorePhpDocErrors) {
throw new AnnotationException(sprintf(
'The @param annotation for parameter "%s" of %s::%s contains a non existent class "%s". '
. 'Did you maybe forget to add a "use" statement for this annotation?',
$parameterName,
$class->name,
$method->name,
$type
));
}
}
if (!$this->classExists($type) && !$this->ignorePhpDocErrors) {
throw new AnnotationException(sprintf(
'The @param annotation for parameter "%s" of %s::%s contains a non existent class "%s"',
$parameterName,
$class->name,
$method->name,
$type
));
}
// Remove the leading \ (FQN shouldn't contain it)
$type = ltrim($type, '\\');
return $type;
}
/**
* @param string $class
* @return bool
*/
private function classExists($class)
{
return class_exists($class) || interface_exists($class);
}
}