init
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace MailPoetVendor;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
// autoload.php @generated by Composer
|
||||
if (\PHP_VERSION_ID < 50600) {
|
||||
if (!\headers_sent()) {
|
||||
\header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running ' . \PHP_VERSION . ', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.' . \PHP_EOL;
|
||||
if (!\ini_get('display_errors')) {
|
||||
if (\PHP_SAPI === 'cli' || \PHP_SAPI === 'phpdbg') {
|
||||
\fwrite(\STDERR, $err);
|
||||
} elseif (!\headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
\trigger_error($err, \E_USER_ERROR);
|
||||
}
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
return ComposerAutoloaderInit2acd0a5fe4d1ffb701780b1aa523fb66::getLoader();
|
||||
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../nesbot/carbon/bin/carbon)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
namespace MailPoetVendor\Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..' . '/autoload.php';
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
if (!\class_exists('MailPoetVendor\\Composer\\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = \substr($path, 17);
|
||||
$this->realpath = \realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = \fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = \fread($this->handle, $count);
|
||||
if ($this->position === 0) {
|
||||
$data = \preg_replace('{^#!.*\\r?\\n}', '', $data);
|
||||
}
|
||||
$this->position += \strlen($data);
|
||||
return $data;
|
||||
}
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
public function stream_close()
|
||||
{
|
||||
\fclose($this->handle);
|
||||
}
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? \flock($this->handle, $operation) : \true;
|
||||
}
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === \fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = \ftell($this->handle);
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
public function stream_eof()
|
||||
{
|
||||
return \feof($this->handle);
|
||||
}
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return \true;
|
||||
}
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = \substr($path, 17);
|
||||
if (\file_exists($path)) {
|
||||
return \stat($path);
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (\function_exists('stream_get_wrappers') && \in_array('phpvfscomposer', \stream_get_wrappers(), \true) || \function_exists('stream_wrapper_register') && \stream_wrapper_register('phpvfscomposer', 'MailPoetVendor\\Composer\\BinProxyWrapper')) {
|
||||
return include "phpvfscomposer://" . __DIR__ . '/..' . '/nesbot/carbon/bin/carbon';
|
||||
}
|
||||
}
|
||||
return include __DIR__ . '/..' . '/nesbot/carbon/bin/carbon';
|
||||
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../doctrine/orm/bin/doctrine)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
namespace MailPoetVendor\Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..' . '/autoload.php';
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
if (!\class_exists('MailPoetVendor\\Composer\\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = \substr($path, 17);
|
||||
$this->realpath = \realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = \fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = \fread($this->handle, $count);
|
||||
if ($this->position === 0) {
|
||||
$data = \preg_replace('{^#!.*\\r?\\n}', '', $data);
|
||||
}
|
||||
$this->position += \strlen($data);
|
||||
return $data;
|
||||
}
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
public function stream_close()
|
||||
{
|
||||
\fclose($this->handle);
|
||||
}
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? \flock($this->handle, $operation) : \true;
|
||||
}
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === \fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = \ftell($this->handle);
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
public function stream_eof()
|
||||
{
|
||||
return \feof($this->handle);
|
||||
}
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return \true;
|
||||
}
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = \substr($path, 17);
|
||||
if (\file_exists($path)) {
|
||||
return \stat($path);
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (\function_exists('stream_get_wrappers') && \in_array('phpvfscomposer', \stream_get_wrappers(), \true) || \function_exists('stream_wrapper_register') && \stream_wrapper_register('phpvfscomposer', 'MailPoetVendor\\Composer\\BinProxyWrapper')) {
|
||||
return include "phpvfscomposer://" . __DIR__ . '/..' . '/doctrine/orm/bin/doctrine';
|
||||
}
|
||||
}
|
||||
return include __DIR__ . '/..' . '/doctrine/orm/bin/doctrine';
|
||||
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../doctrine/dbal/bin/doctrine-dbal)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
namespace MailPoetVendor\Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..' . '/autoload.php';
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
if (!\class_exists('MailPoetVendor\\Composer\\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = \substr($path, 17);
|
||||
$this->realpath = \realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = \fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = \fread($this->handle, $count);
|
||||
if ($this->position === 0) {
|
||||
$data = \preg_replace('{^#!.*\\r?\\n}', '', $data);
|
||||
}
|
||||
$this->position += \strlen($data);
|
||||
return $data;
|
||||
}
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
public function stream_close()
|
||||
{
|
||||
\fclose($this->handle);
|
||||
}
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? \flock($this->handle, $operation) : \true;
|
||||
}
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === \fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = \ftell($this->handle);
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
public function stream_eof()
|
||||
{
|
||||
return \feof($this->handle);
|
||||
}
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return \true;
|
||||
}
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = \substr($path, 17);
|
||||
if (\file_exists($path)) {
|
||||
return \stat($path);
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (\function_exists('stream_get_wrappers') && \in_array('phpvfscomposer', \stream_get_wrappers(), \true) || \function_exists('stream_wrapper_register') && \stream_wrapper_register('phpvfscomposer', 'MailPoetVendor\\Composer\\BinProxyWrapper')) {
|
||||
return include "phpvfscomposer://" . __DIR__ . '/..' . '/doctrine/dbal/bin/doctrine-dbal';
|
||||
}
|
||||
}
|
||||
return include __DIR__ . '/..' . '/doctrine/dbal/bin/doctrine-dbal';
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../cerdic/css-tidy/bin/pcsstidy)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
namespace MailPoetVendor\Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..' . '/autoload.php';
|
||||
if (\PHP_VERSION_ID < 80000) {
|
||||
if (!\class_exists('MailPoetVendor\\Composer\\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = \substr($path, 17);
|
||||
$this->realpath = \realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = \fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = \fread($this->handle, $count);
|
||||
if ($this->position === 0) {
|
||||
$data = \preg_replace('{^#!.*\\r?\\n}', '', $data);
|
||||
}
|
||||
$this->position += \strlen($data);
|
||||
return $data;
|
||||
}
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
public function stream_close()
|
||||
{
|
||||
\fclose($this->handle);
|
||||
}
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? \flock($this->handle, $operation) : \true;
|
||||
}
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === \fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = \ftell($this->handle);
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
public function stream_eof()
|
||||
{
|
||||
return \feof($this->handle);
|
||||
}
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return \true;
|
||||
}
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = \substr($path, 17);
|
||||
if (\file_exists($path)) {
|
||||
return \stat($path);
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (\function_exists('stream_get_wrappers') && \in_array('phpvfscomposer', \stream_get_wrappers(), \true) || \function_exists('stream_wrapper_register') && \stream_wrapper_register('phpvfscomposer', 'MailPoetVendor\\Composer\\BinProxyWrapper')) {
|
||||
return include "phpvfscomposer://" . __DIR__ . '/..' . '/cerdic/css-tidy/bin/pcsstidy';
|
||||
}
|
||||
}
|
||||
return include __DIR__ . '/..' . '/cerdic/css-tidy/bin/pcsstidy';
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Carbon\Doctrine;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
interface CarbonDoctrineType
|
||||
{
|
||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform);
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform);
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform);
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Carbon\Doctrine;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
class CarbonImmutableType extends DateTimeImmutableType implements CarbonDoctrineType
|
||||
{
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Carbon\Doctrine;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
class CarbonType extends DateTimeType implements CarbonDoctrineType
|
||||
{
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Carbon\Doctrine;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Carbon\Carbon;
|
||||
use MailPoetVendor\Carbon\CarbonInterface;
|
||||
use DateTimeInterface;
|
||||
use MailPoetVendor\Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use MailPoetVendor\Doctrine\DBAL\Platforms\DB2Platform;
|
||||
use MailPoetVendor\Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use MailPoetVendor\Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use MailPoetVendor\Doctrine\DBAL\Platforms\SQLServerPlatform;
|
||||
use MailPoetVendor\Doctrine\DBAL\Types\ConversionException;
|
||||
use Exception;
|
||||
trait CarbonTypeConverter
|
||||
{
|
||||
public bool $external = \true;
|
||||
protected function getCarbonClassName() : string
|
||||
{
|
||||
return Carbon::class;
|
||||
}
|
||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) : string
|
||||
{
|
||||
$precision = \min($fieldDeclaration['precision'] ?? DateTimeDefaultPrecision::get(), $this->getMaximumPrecision($platform));
|
||||
$type = parent::getSQLDeclaration($fieldDeclaration, $platform);
|
||||
if (!$precision) {
|
||||
return $type;
|
||||
}
|
||||
if (\str_contains($type, '(')) {
|
||||
return \preg_replace('/\\(\\d+\\)/', "({$precision})", $type);
|
||||
}
|
||||
[$before, $after] = \explode(' ', "{$type} ");
|
||||
return \trim("{$before}({$precision}) {$after}");
|
||||
}
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
$class = $this->getCarbonClassName();
|
||||
if ($value === null || \is_a($value, $class)) {
|
||||
return $value;
|
||||
}
|
||||
if ($value instanceof DateTimeInterface) {
|
||||
return $class::instance($value);
|
||||
}
|
||||
$date = null;
|
||||
$error = null;
|
||||
try {
|
||||
$date = $class::parse($value);
|
||||
} catch (Exception $exception) {
|
||||
$error = $exception;
|
||||
}
|
||||
if (!$date) {
|
||||
throw ConversionException::conversionFailedFormat($value, $this->getTypeName(), 'Y-m-d H:i:s.u or any format supported by ' . $class . '::parse()', $error);
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform) : ?string
|
||||
{
|
||||
if ($value === null) {
|
||||
return $value;
|
||||
}
|
||||
if ($value instanceof DateTimeInterface) {
|
||||
return $value->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
throw ConversionException::conversionFailedInvalidType($value, $this->getTypeName(), ['null', 'DateTime', 'Carbon']);
|
||||
}
|
||||
private function getTypeName() : string
|
||||
{
|
||||
$chunks = \explode('\\', static::class);
|
||||
$type = \preg_replace('/Type$/', '', \end($chunks));
|
||||
return \strtolower(\preg_replace('/([a-z])([A-Z])/', '$1_$2', $type));
|
||||
}
|
||||
private function getMaximumPrecision(AbstractPlatform $platform) : int
|
||||
{
|
||||
if ($platform instanceof DB2Platform) {
|
||||
return 12;
|
||||
}
|
||||
if ($platform instanceof OraclePlatform) {
|
||||
return 9;
|
||||
}
|
||||
if ($platform instanceof SQLServerPlatform || $platform instanceof SqlitePlatform) {
|
||||
return 3;
|
||||
}
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Carbon\Doctrine;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
class DateTimeDefaultPrecision
|
||||
{
|
||||
private static $precision = 6;
|
||||
public static function set(int $precision) : void
|
||||
{
|
||||
self::$precision = $precision;
|
||||
}
|
||||
public static function get() : int
|
||||
{
|
||||
return self::$precision;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Carbon\Doctrine;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Carbon\CarbonImmutable;
|
||||
use MailPoetVendor\Doctrine\DBAL\Types\VarDateTimeImmutableType;
|
||||
class DateTimeImmutableType extends VarDateTimeImmutableType implements CarbonDoctrineType
|
||||
{
|
||||
use CarbonTypeConverter;
|
||||
protected function getCarbonClassName() : string
|
||||
{
|
||||
return CarbonImmutable::class;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Carbon\Doctrine;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Carbon\Carbon;
|
||||
use MailPoetVendor\Doctrine\DBAL\Types\VarDateTimeType;
|
||||
class DateTimeType extends VarDateTimeType implements CarbonDoctrineType
|
||||
{
|
||||
use CarbonTypeConverter;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,820 @@
|
||||
<?php
|
||||
namespace MailPoetVendor;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
\define('AT_START', 1);
|
||||
\define('AT_END', 2);
|
||||
\define('SEL_START', 3);
|
||||
\define('SEL_END', 4);
|
||||
\define('PROPERTY', 5);
|
||||
\define('VALUE', 6);
|
||||
\define('COMMENT', 7);
|
||||
\define('IMPORTANT_COMMENT', 8);
|
||||
\define('DEFAULT_AT', 41);
|
||||
require __DIR__ . \DIRECTORY_SEPARATOR . 'class.csstidy_print.php';
|
||||
require __DIR__ . \DIRECTORY_SEPARATOR . 'class.csstidy_optimise.php';
|
||||
class csstidy
|
||||
{
|
||||
public $css = array();
|
||||
public $tokens = array();
|
||||
public $print;
|
||||
public $optimise;
|
||||
public $charset = '';
|
||||
public $import = array();
|
||||
public $namespace = '';
|
||||
public $version = '2.0.3';
|
||||
public $settings = array();
|
||||
public $status = 'is';
|
||||
public $at = '';
|
||||
public $next_selector_at = '';
|
||||
public $selector = '';
|
||||
public $property = '';
|
||||
public $sel_separate = array();
|
||||
public $value = '';
|
||||
public $sub_value = '';
|
||||
public $sub_value_arr = array();
|
||||
public $str_char = array();
|
||||
public $cur_string = array();
|
||||
public $from = array();
|
||||
public $invalid_at = \false;
|
||||
public $added = \false;
|
||||
public $log = array();
|
||||
public $line = 1;
|
||||
public $quoted_string = array();
|
||||
public $tokens_list = "";
|
||||
public $data = array();
|
||||
public $template;
|
||||
public function __construct()
|
||||
{
|
||||
$data = array();
|
||||
include __DIR__ . \DIRECTORY_SEPARATOR . 'data.inc.php';
|
||||
$this->data = $data;
|
||||
$this->settings['remove_bslash'] = \true;
|
||||
$this->settings['compress_colors'] = \true;
|
||||
$this->settings['compress_font-weight'] = \true;
|
||||
$this->settings['lowercase_s'] = \false;
|
||||
$this->settings['optimise_shorthands'] = 1;
|
||||
$this->settings['remove_last_;'] = \true;
|
||||
$this->settings['space_before_important'] = \false;
|
||||
$this->settings['case_properties'] = 1;
|
||||
$this->settings['sort_properties'] = \false;
|
||||
$this->settings['sort_selectors'] = 0;
|
||||
$this->settings['merge_selectors'] = 0;
|
||||
$this->settings['reverse_left_and_right'] = 0;
|
||||
$this->settings['discard_invalid_selectors'] = \false;
|
||||
$this->settings['discard_invalid_properties'] = \false;
|
||||
$this->settings['css_level'] = 'CSS3.0';
|
||||
$this->settings['preserve_css'] = \false;
|
||||
$this->settings['timestamp'] = \false;
|
||||
$this->settings['template'] = '';
|
||||
// say that propertie exist
|
||||
$this->set_cfg('template', 'default');
|
||||
// call load_template
|
||||
$this->optimise = new csstidy_optimise($this);
|
||||
$this->tokens_list =& $this->data['csstidy']['tokens'];
|
||||
}
|
||||
public function get_cfg($setting)
|
||||
{
|
||||
if (isset($this->settings[$setting])) {
|
||||
return $this->settings[$setting];
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function _load_template($template)
|
||||
{
|
||||
switch ($template) {
|
||||
case 'default':
|
||||
$this->load_template('default');
|
||||
break;
|
||||
case 'highest':
|
||||
$this->load_template('highest_compression');
|
||||
break;
|
||||
case 'high':
|
||||
$this->load_template('high_compression');
|
||||
break;
|
||||
case 'low':
|
||||
$this->load_template('low_compression');
|
||||
break;
|
||||
default:
|
||||
$this->load_template($template);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function set_cfg($setting, $value = null)
|
||||
{
|
||||
if (\is_array($setting) && $value === null) {
|
||||
foreach ($setting as $setprop => $setval) {
|
||||
$this->settings[$setprop] = $setval;
|
||||
}
|
||||
if (\array_key_exists('template', $setting)) {
|
||||
$this->_load_template($this->settings['template']);
|
||||
}
|
||||
return \true;
|
||||
} elseif (isset($this->settings[$setting]) && $value !== '') {
|
||||
$this->settings[$setting] = $value;
|
||||
if ($setting === 'template') {
|
||||
$this->_load_template($this->settings['template']);
|
||||
}
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function _add_token($type, $data, $do = \false)
|
||||
{
|
||||
if ($this->get_cfg('preserve_css') || $do) {
|
||||
// nested @... : if opening a new part we just closed, remove the previous closing instead of adding opening
|
||||
if ($type === \AT_START and \count($this->tokens) and $last = \end($this->tokens) and $last[0] === \AT_END and $last[1] === \trim($data)) {
|
||||
\array_pop($this->tokens);
|
||||
} else {
|
||||
$this->tokens[] = array($type, ($type == \COMMENT or $type == \IMPORTANT_COMMENT) ? $data : \trim($data));
|
||||
}
|
||||
}
|
||||
}
|
||||
public function log($message, $type, $line = -1)
|
||||
{
|
||||
if ($line === -1) {
|
||||
$line = $this->line;
|
||||
}
|
||||
$line = \intval($line);
|
||||
$add = array('m' => $message, 't' => $type);
|
||||
if (!isset($this->log[$line]) || !\in_array($add, $this->log[$line])) {
|
||||
$this->log[$line][] = $add;
|
||||
}
|
||||
}
|
||||
public function _unicode(&$string, &$i)
|
||||
{
|
||||
++$i;
|
||||
$add = '';
|
||||
$replaced = \false;
|
||||
while ($i < \strlen($string) && (\ctype_xdigit($string[$i]) || \ctype_space($string[$i])) && \strlen($add) < 6) {
|
||||
$add .= $string[$i];
|
||||
if (\ctype_space($string[$i])) {
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
if (\hexdec($add) > 47 && \hexdec($add) < 58 || \hexdec($add) > 64 && \hexdec($add) < 91 || \hexdec($add) > 96 && \hexdec($add) < 123) {
|
||||
$this->log('Replaced unicode notation: Changed \\' . $add . ' to ' . \chr(\hexdec($add)), 'Information');
|
||||
$add = \chr(\hexdec($add));
|
||||
$replaced = \true;
|
||||
} else {
|
||||
$add = \trim('\\' . $add);
|
||||
}
|
||||
if (@\ctype_xdigit($string[$i + 1]) && \ctype_space($string[$i]) && !$replaced || !\ctype_space($string[$i])) {
|
||||
$i--;
|
||||
}
|
||||
if ($add !== '\\' || !$this->get_cfg('remove_bslash') || \strpos($this->tokens_list, $string[$i + 1]) !== \false) {
|
||||
return $add;
|
||||
}
|
||||
if ($add === '\\') {
|
||||
$this->log('Removed unnecessary backslash', 'Information');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
public function write_page($filename, $doctype = 'xhtml1.1', $externalcss = \true, $title = '', $lang = 'en')
|
||||
{
|
||||
$this->write($filename, \true);
|
||||
}
|
||||
public function write($filename, $formatted = \false, $doctype = 'xhtml1.1', $externalcss = \true, $title = '', $lang = 'en', $pre_code = \true)
|
||||
{
|
||||
$filename .= $formatted ? '.xhtml' : '.css';
|
||||
if (!\is_dir('temp')) {
|
||||
$madedir = \mkdir('temp');
|
||||
if (!$madedir) {
|
||||
print 'Could not make directory "temp" in ' . \dirname(__FILE__);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
$handle = \fopen('temp/' . $filename, 'w');
|
||||
if ($handle) {
|
||||
if (!$formatted) {
|
||||
\fwrite($handle, $this->print->plain());
|
||||
} else {
|
||||
\fwrite($handle, $this->print->formatted_page($doctype, $externalcss, $title, $lang, $pre_code));
|
||||
}
|
||||
}
|
||||
\fclose($handle);
|
||||
}
|
||||
public function load_template($content, $from_file = \true)
|
||||
{
|
||||
$predefined_templates =& $this->data['csstidy']['predefined_templates'];
|
||||
if ($content === 'high_compression' || $content === 'default' || $content === 'highest_compression' || $content === 'low_compression') {
|
||||
$this->template = $predefined_templates[$content];
|
||||
return;
|
||||
}
|
||||
if ($from_file) {
|
||||
$content = \strip_tags(\file_get_contents($content), '<span>');
|
||||
}
|
||||
$content = \str_replace("\r\n", "\n", $content);
|
||||
// Unify newlines (because the output also only uses \n)
|
||||
$template = \explode('|', $content);
|
||||
for ($i = 0; $i < \count($template); $i++) {
|
||||
$this->template[$i] = $template[$i];
|
||||
}
|
||||
}
|
||||
public function parse_from_url($url)
|
||||
{
|
||||
return $this->parse(@\file_get_contents($url));
|
||||
}
|
||||
public function is_token(&$string, $i)
|
||||
{
|
||||
return \strpos($this->tokens_list, $string[$i]) !== \false && !$this->escaped($string, $i);
|
||||
}
|
||||
public function parse($string)
|
||||
{
|
||||
// Temporarily set locale to en_US in order to handle floats properly
|
||||
$old = @\setlocale(\LC_ALL, 0);
|
||||
@\setlocale(\LC_ALL, 'C');
|
||||
// PHP bug? Settings need to be refreshed in PHP4
|
||||
$this->print = new csstidy_print($this);
|
||||
$this->optimise = new csstidy_optimise($this);
|
||||
$all_properties =& $this->data['csstidy']['all_properties'];
|
||||
$at_rules =& $this->data['csstidy']['at_rules'];
|
||||
$quoted_string_properties =& $this->data['csstidy']['quoted_string_properties'];
|
||||
$this->css = array();
|
||||
$this->print->input_css = $string;
|
||||
$string = \str_replace("\r\n", "\n", $string) . ' ';
|
||||
$cur_comment = '';
|
||||
$cur_at = '';
|
||||
for ($i = 0, $size = \strlen($string); $i < $size; $i++) {
|
||||
if ($string[$i] === "\n" || $string[$i] === "\r") {
|
||||
++$this->line;
|
||||
}
|
||||
switch ($this->status) {
|
||||
case 'at':
|
||||
if ($this->is_token($string, $i)) {
|
||||
if ($string[$i] === '/' && @$string[$i + 1] === '*') {
|
||||
$this->status = 'ic';
|
||||
++$i;
|
||||
$this->from[] = 'at';
|
||||
} elseif ($string[$i] === '{') {
|
||||
$this->status = 'is';
|
||||
$this->at = $this->css_new_media_section($this->at, $cur_at);
|
||||
$this->_add_token(\AT_START, $this->at);
|
||||
} elseif ($string[$i] === ',') {
|
||||
$cur_at = \trim($cur_at) . ',';
|
||||
} elseif ($string[$i] === '\\') {
|
||||
$cur_at .= $this->_unicode($string, $i);
|
||||
} elseif (\in_array($string[$i], array('(', ')', ':', '.', '/'))) {
|
||||
$cur_at .= $string[$i];
|
||||
}
|
||||
} else {
|
||||
$lastpos = \strlen($cur_at) - 1;
|
||||
if (!((\ctype_space($cur_at[$lastpos]) || $this->is_token($cur_at, $lastpos) && $cur_at[$lastpos] === ',') && \ctype_space($string[$i]))) {
|
||||
$cur_at .= $string[$i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'is':
|
||||
if ($this->is_token($string, $i)) {
|
||||
if ($string[$i] === '/' && @$string[$i + 1] === '*' && \trim($this->selector) == '') {
|
||||
$this->status = 'ic';
|
||||
++$i;
|
||||
$this->from[] = 'is';
|
||||
} elseif ($string[$i] === '@' && \trim($this->selector) == '') {
|
||||
// Check for at-rule
|
||||
$this->invalid_at = \true;
|
||||
foreach ($at_rules as $name => $type) {
|
||||
if (!\strcasecmp(\substr($string, $i + 1, \strlen($name)), $name)) {
|
||||
$type === 'at' ? $cur_at = '@' . $name : ($this->selector = '@' . $name);
|
||||
if ($type === 'atis') {
|
||||
$this->next_selector_at = $this->next_selector_at ? $this->next_selector_at : ($this->at ? $this->at : \DEFAULT_AT);
|
||||
$this->at = $this->css_new_media_section($this->at, ' ', \true);
|
||||
$type = 'is';
|
||||
}
|
||||
$this->status = $type;
|
||||
$i += \strlen($name);
|
||||
$this->invalid_at = \false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($this->invalid_at) {
|
||||
$this->selector = '@';
|
||||
$invalid_at_name = '';
|
||||
for ($j = $i + 1; $j < $size; ++$j) {
|
||||
if (!\ctype_alpha($string[$j])) {
|
||||
break;
|
||||
}
|
||||
$invalid_at_name .= $string[$j];
|
||||
}
|
||||
$this->log('Invalid @-rule: ' . $invalid_at_name . ' (removed)', 'Warning');
|
||||
}
|
||||
} elseif ($string[$i] === '"' || $string[$i] === "'") {
|
||||
$this->cur_string[] = $string[$i];
|
||||
$this->status = 'instr';
|
||||
$this->str_char[] = $string[$i];
|
||||
$this->from[] = 'is';
|
||||
$this->quoted_string[] = $string[$i - 1] === '=';
|
||||
} elseif ($this->invalid_at && $string[$i] === ';') {
|
||||
$this->invalid_at = \false;
|
||||
$this->status = 'is';
|
||||
if ($this->next_selector_at) {
|
||||
$this->at = $this->css_close_media_section($this->at);
|
||||
$this->at = $this->css_new_media_section($this->at, $this->next_selector_at);
|
||||
$this->next_selector_at = '';
|
||||
}
|
||||
} elseif ($string[$i] === '{') {
|
||||
$this->status = 'ip';
|
||||
if ($this->at == '') {
|
||||
$this->at = $this->css_new_media_section($this->at, \DEFAULT_AT);
|
||||
}
|
||||
$this->selector = $this->css_new_selector($this->at, $this->selector);
|
||||
$this->_add_token(\SEL_START, $this->selector);
|
||||
$this->added = \false;
|
||||
} elseif ($string[$i] === '}') {
|
||||
$this->_add_token(\AT_END, $this->at);
|
||||
$this->at = $this->css_close_media_section($this->at);
|
||||
$this->selector = '';
|
||||
$this->sel_separate = array();
|
||||
} elseif ($string[$i] === ',') {
|
||||
$this->selector = \trim($this->selector) . ',';
|
||||
$this->sel_separate[] = \strlen($this->selector);
|
||||
} elseif ($string[$i] === '\\') {
|
||||
$this->selector .= $this->_unicode($string, $i);
|
||||
} elseif ($string[$i] === '*' && @\in_array($string[$i + 1], array('.', '#', '[', ':')) && ($i == 0 or $string[$i - 1] !== '/')) {
|
||||
// remove unnecessary universal selector, FS#147, but not comment in selector
|
||||
} else {
|
||||
$this->selector .= $string[$i];
|
||||
}
|
||||
} else {
|
||||
$lastpos = \strlen($this->selector) - 1;
|
||||
if ($lastpos == -1 || !((\ctype_space($this->selector[$lastpos]) || $this->is_token($this->selector, $lastpos) && $this->selector[$lastpos] === ',') && \ctype_space($string[$i]))) {
|
||||
$this->selector .= $string[$i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'ip':
|
||||
if ($this->is_token($string, $i)) {
|
||||
if (($string[$i] === ':' || $string[$i] === '=') && $this->property != '') {
|
||||
$this->status = 'iv';
|
||||
if (!$this->get_cfg('discard_invalid_properties') || $this->property_is_valid($this->property)) {
|
||||
$this->property = $this->css_new_property($this->at, $this->selector, $this->property);
|
||||
$this->_add_token(\PROPERTY, $this->property);
|
||||
}
|
||||
} elseif ($string[$i] === '/' && @$string[$i + 1] === '*' && $this->property == '') {
|
||||
$this->status = 'ic';
|
||||
++$i;
|
||||
$this->from[] = 'ip';
|
||||
} elseif ($string[$i] === '}') {
|
||||
$this->explode_selectors();
|
||||
$this->status = 'is';
|
||||
$this->invalid_at = \false;
|
||||
$this->_add_token(\SEL_END, $this->selector);
|
||||
$this->selector = '';
|
||||
$this->property = '';
|
||||
if ($this->next_selector_at) {
|
||||
$this->at = $this->css_close_media_section($this->at);
|
||||
$this->at = $this->css_new_media_section($this->at, $this->next_selector_at);
|
||||
$this->next_selector_at = '';
|
||||
}
|
||||
} elseif ($string[$i] === ';') {
|
||||
$this->property = '';
|
||||
} elseif ($string[$i] === '\\') {
|
||||
$this->property .= $this->_unicode($string, $i);
|
||||
} elseif ($this->property === '' && !\ctype_space($string[$i]) || ($this->property === '/' || $string[$i] === '/')) {
|
||||
$this->property .= $string[$i];
|
||||
}
|
||||
} elseif (!\ctype_space($string[$i])) {
|
||||
$this->property .= $string[$i];
|
||||
}
|
||||
break;
|
||||
case 'iv':
|
||||
$pn = ($string[$i] === "\n" || $string[$i] === "\r") && $this->property_is_next($string, $i + 1) || $i == \strlen($string) - 1;
|
||||
if ($this->is_token($string, $i) || $pn) {
|
||||
if ($string[$i] === '/' && @$string[$i + 1] === '*') {
|
||||
$this->status = 'ic';
|
||||
++$i;
|
||||
$this->from[] = 'iv';
|
||||
} elseif ($string[$i] === '"' || $string[$i] === "'" || $string[$i] === '(') {
|
||||
$this->cur_string[] = $string[$i];
|
||||
$this->str_char[] = $string[$i] === '(' ? ')' : $string[$i];
|
||||
$this->status = 'instr';
|
||||
$this->from[] = 'iv';
|
||||
$this->quoted_string[] = \in_array(\strtolower($this->property), $quoted_string_properties);
|
||||
} elseif ($string[$i] === ',') {
|
||||
$this->sub_value = \trim($this->sub_value) . ',';
|
||||
} elseif ($string[$i] === '\\') {
|
||||
$this->sub_value .= $this->_unicode($string, $i);
|
||||
} elseif ($string[$i] === ';' || $pn) {
|
||||
if ($this->selector[0] === '@' && isset($at_rules[\substr($this->selector, 1)]) && $at_rules[\substr($this->selector, 1)] === 'iv') {
|
||||
$this->sub_value_arr[] = \trim($this->sub_value);
|
||||
$this->status = 'is';
|
||||
switch ($this->selector) {
|
||||
case '@charset':
|
||||
$this->charset = '"' . $this->sub_value_arr[0] . '"';
|
||||
break;
|
||||
case '@namespace':
|
||||
$this->namespace = \implode(' ', $this->sub_value_arr);
|
||||
break;
|
||||
case '@import':
|
||||
$this->import[] = \implode(' ', $this->sub_value_arr);
|
||||
break;
|
||||
}
|
||||
$this->sub_value_arr = array();
|
||||
$this->sub_value = '';
|
||||
$this->selector = '';
|
||||
$this->sel_separate = array();
|
||||
} else {
|
||||
$this->status = 'ip';
|
||||
}
|
||||
} elseif ($string[$i] !== '}') {
|
||||
$this->sub_value .= $string[$i];
|
||||
}
|
||||
if (($string[$i] === '}' || $string[$i] === ';' || $pn) && !empty($this->selector)) {
|
||||
if ($this->at == '') {
|
||||
$this->at = $this->css_new_media_section($this->at, \DEFAULT_AT);
|
||||
}
|
||||
// case settings
|
||||
if ($this->get_cfg('lowercase_s')) {
|
||||
$this->selector = \strtolower($this->selector);
|
||||
}
|
||||
$this->property = \strtolower($this->property);
|
||||
$this->optimise->subvalue();
|
||||
if ($this->sub_value != '') {
|
||||
$this->sub_value_arr[] = $this->sub_value;
|
||||
$this->sub_value = '';
|
||||
}
|
||||
$this->value = '';
|
||||
while (\count($this->sub_value_arr)) {
|
||||
$sub = \array_shift($this->sub_value_arr);
|
||||
if (\strstr($this->selector, 'font-face')) {
|
||||
$sub = $this->quote_font_format($sub);
|
||||
}
|
||||
if ($sub != '') {
|
||||
$this->value .= (!\strlen($this->value) || \substr($this->value, -1, 1) === ',' ? '' : ' ') . $sub;
|
||||
}
|
||||
}
|
||||
$this->optimise->value();
|
||||
$valid = $this->property_is_valid($this->property);
|
||||
if ((!$this->invalid_at || $this->get_cfg('preserve_css')) && (!$this->get_cfg('discard_invalid_properties') || $valid)) {
|
||||
$this->css_add_property($this->at, $this->selector, $this->property, $this->value);
|
||||
$this->_add_token(\VALUE, $this->value);
|
||||
$this->optimise->shorthands();
|
||||
}
|
||||
if (!$valid) {
|
||||
if ($this->get_cfg('discard_invalid_properties')) {
|
||||
$this->log('Removed invalid property: ' . $this->property, 'Warning');
|
||||
} else {
|
||||
$this->log('Invalid property in ' . \strtoupper($this->get_cfg('css_level')) . ': ' . $this->property, 'Warning');
|
||||
}
|
||||
}
|
||||
$this->property = '';
|
||||
$this->sub_value_arr = array();
|
||||
$this->value = '';
|
||||
}
|
||||
if ($string[$i] === '}') {
|
||||
$this->explode_selectors();
|
||||
$this->_add_token(\SEL_END, $this->selector);
|
||||
$this->status = 'is';
|
||||
$this->invalid_at = \false;
|
||||
$this->selector = '';
|
||||
if ($this->next_selector_at) {
|
||||
$this->at = $this->css_close_media_section($this->at);
|
||||
$this->at = $this->css_new_media_section($this->at, $this->next_selector_at);
|
||||
$this->next_selector_at = '';
|
||||
}
|
||||
}
|
||||
} elseif (!$pn) {
|
||||
$this->sub_value .= $string[$i];
|
||||
if (\ctype_space($string[$i])) {
|
||||
$this->optimise->subvalue();
|
||||
if ($this->sub_value != '') {
|
||||
$this->sub_value_arr[] = $this->sub_value;
|
||||
$this->sub_value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'instr':
|
||||
$_str_char = $this->str_char[\count($this->str_char) - 1];
|
||||
$_cur_string = $this->cur_string[\count($this->cur_string) - 1];
|
||||
$_quoted_string = $this->quoted_string[\count($this->quoted_string) - 1];
|
||||
$temp_add = $string[$i];
|
||||
// Add another string to the stack. Strings can't be nested inside of quotes, only parentheses, but
|
||||
// parentheticals can be nested more than once.
|
||||
if ($_str_char === ")" && ($string[$i] === "(" || $string[$i] === '"' || $string[$i] === '\'') && !$this->escaped($string, $i)) {
|
||||
$this->cur_string[] = $string[$i];
|
||||
$this->str_char[] = $string[$i] === '(' ? ')' : $string[$i];
|
||||
$this->from[] = 'instr';
|
||||
$this->quoted_string[] = $_str_char === ')' && $string[$i] !== '(' && \trim($_cur_string) === '(' ? $_quoted_string : !($string[$i] === '(');
|
||||
continue 2;
|
||||
}
|
||||
if ($_str_char !== ")" && ($string[$i] === "\n" || $string[$i] === "\r") && !($string[$i - 1] === '\\' && !$this->escaped($string, $i - 1))) {
|
||||
$temp_add = "\\A";
|
||||
$this->log('Fixed incorrect newline in string', 'Warning');
|
||||
}
|
||||
$_cur_string .= $temp_add;
|
||||
if ($string[$i] === $_str_char && !$this->escaped($string, $i)) {
|
||||
$this->status = \array_pop($this->from);
|
||||
if (!\preg_match('|[' . \implode('', $this->data['csstidy']['whitespace']) . ']|uis', $_cur_string) && $this->property !== 'content') {
|
||||
if (!$_quoted_string) {
|
||||
if ($_str_char !== ')') {
|
||||
// Convert properties like
|
||||
// font-family: 'Arial';
|
||||
// to
|
||||
// font-family: Arial;
|
||||
// or
|
||||
// url("abc")
|
||||
// to
|
||||
// url(abc)
|
||||
$_cur_string = \substr($_cur_string, 1, -1);
|
||||
}
|
||||
} else {
|
||||
$_quoted_string = \false;
|
||||
}
|
||||
}
|
||||
\array_pop($this->cur_string);
|
||||
\array_pop($this->quoted_string);
|
||||
\array_pop($this->str_char);
|
||||
if ($_str_char === ')') {
|
||||
$_cur_string = '(' . \trim(\substr($_cur_string, 1, -1)) . ')';
|
||||
}
|
||||
if ($this->status === 'iv') {
|
||||
if (!$_quoted_string) {
|
||||
if (\strpos($_cur_string, ',') !== \false) {
|
||||
// we can on only remove space next to ','
|
||||
$_cur_string = \implode(',', \array_map('trim', \explode(',', $_cur_string)));
|
||||
}
|
||||
// and multiple spaces (too expensive)
|
||||
if (\strpos($_cur_string, ' ') !== \false) {
|
||||
$_cur_string = \preg_replace(",\\s+,", ' ', $_cur_string);
|
||||
}
|
||||
}
|
||||
$this->sub_value .= $_cur_string;
|
||||
} elseif ($this->status === 'is') {
|
||||
$this->selector .= $_cur_string;
|
||||
} elseif ($this->status === 'instr') {
|
||||
$this->cur_string[\count($this->cur_string) - 1] .= $_cur_string;
|
||||
}
|
||||
} else {
|
||||
$this->cur_string[\count($this->cur_string) - 1] = $_cur_string;
|
||||
}
|
||||
break;
|
||||
case 'ic':
|
||||
if ($string[$i] === '*' && $string[$i + 1] === '/') {
|
||||
$this->status = \array_pop($this->from);
|
||||
$i++;
|
||||
if (\strlen($cur_comment) > 1 and \strncmp($cur_comment, '!', 1) === 0) {
|
||||
$this->_add_token(\IMPORTANT_COMMENT, $cur_comment);
|
||||
$this->css_add_important_comment($cur_comment);
|
||||
} else {
|
||||
$this->_add_token(\COMMENT, $cur_comment);
|
||||
}
|
||||
$cur_comment = '';
|
||||
} else {
|
||||
$cur_comment .= $string[$i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->optimise->postparse();
|
||||
$this->print->_reset();
|
||||
@\setlocale(\LC_ALL, $old);
|
||||
// Set locale back to original setting
|
||||
return !(empty($this->css) && empty($this->import) && empty($this->charset) && empty($this->tokens) && empty($this->namespace));
|
||||
}
|
||||
public function quote_font_format($value)
|
||||
{
|
||||
if (\strncmp($value, 'format', 6) == 0) {
|
||||
$p = \strpos($value, ')', 7);
|
||||
$end = \substr($value, $p);
|
||||
$format_strings = $this->parse_string_list(\substr($value, 7, $p - 7));
|
||||
if (!$format_strings) {
|
||||
$value = '';
|
||||
} else {
|
||||
$value = 'format(';
|
||||
foreach ($format_strings as $format_string) {
|
||||
$value .= '"' . \str_replace('"', '\\"', $format_string) . '",';
|
||||
}
|
||||
$value = \substr($value, 0, -1) . $end;
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
public function explode_selectors()
|
||||
{
|
||||
// Explode multiple selectors
|
||||
if ($this->get_cfg('merge_selectors') === 1) {
|
||||
$new_sels = array();
|
||||
$lastpos = 0;
|
||||
$this->sel_separate[] = \strlen($this->selector);
|
||||
foreach ($this->sel_separate as $num => $pos) {
|
||||
if ($num == \count($this->sel_separate) - 1) {
|
||||
$pos += 1;
|
||||
}
|
||||
$new_sels[] = \substr($this->selector, $lastpos, $pos - $lastpos - 1);
|
||||
$lastpos = $pos;
|
||||
}
|
||||
if (\count($new_sels) > 1) {
|
||||
foreach ($new_sels as $selector) {
|
||||
if (isset($this->css[$this->at][$this->selector])) {
|
||||
$this->merge_css_blocks($this->at, $selector, $this->css[$this->at][$this->selector]);
|
||||
}
|
||||
}
|
||||
unset($this->css[$this->at][$this->selector]);
|
||||
}
|
||||
}
|
||||
$this->sel_separate = array();
|
||||
}
|
||||
static function escaped(&$string, $pos)
|
||||
{
|
||||
return !(@($string[$pos - 1] !== '\\') || csstidy::escaped($string, $pos - 1));
|
||||
}
|
||||
public function css_add_important_comment($comment)
|
||||
{
|
||||
if ($this->get_cfg('preserve_css') || \trim($comment) == '') {
|
||||
return;
|
||||
}
|
||||
if (!isset($this->css['!'])) {
|
||||
$this->css['!'] = '';
|
||||
} else {
|
||||
$this->css['!'] .= "\n";
|
||||
}
|
||||
$this->css['!'] .= $comment;
|
||||
}
|
||||
public function css_add_property($media, $selector, $property, $new_val)
|
||||
{
|
||||
if ($this->get_cfg('preserve_css') || \trim($new_val) == '') {
|
||||
return;
|
||||
}
|
||||
$this->added = \true;
|
||||
if (isset($this->css[$media][$selector][$property])) {
|
||||
if ($this->is_important($this->css[$media][$selector][$property]) && $this->is_important($new_val) || !$this->is_important($this->css[$media][$selector][$property])) {
|
||||
$this->css[$media][$selector][$property] = \trim($new_val);
|
||||
}
|
||||
} else {
|
||||
$this->css[$media][$selector][$property] = \trim($new_val);
|
||||
}
|
||||
}
|
||||
public function css_check_last_media_section_or_inc($media)
|
||||
{
|
||||
// are we starting?
|
||||
if (!$this->css || !\is_array($this->css) || empty($this->css)) {
|
||||
return $media;
|
||||
}
|
||||
// if the last @media is the same as this
|
||||
// keep it
|
||||
\end($this->css);
|
||||
$at = \key($this->css);
|
||||
if ($at == $media) {
|
||||
return $media;
|
||||
}
|
||||
// else inc the section in the array
|
||||
while (isset($this->css[$media])) {
|
||||
if (\is_numeric($media)) {
|
||||
$media++;
|
||||
} else {
|
||||
$media .= ' ';
|
||||
}
|
||||
}
|
||||
return $media;
|
||||
}
|
||||
public function css_new_media_section($current_media, $new_media, $at_root = \false)
|
||||
{
|
||||
if ($this->get_cfg('preserve_css')) {
|
||||
return $new_media;
|
||||
}
|
||||
// if we already are in a media and CSS level is 3, manage nested medias
|
||||
if ($current_media && !$at_root && !\is_numeric($current_media) && \strncmp($this->get_cfg('css_level'), 'CSS3', 4) == 0) {
|
||||
$new_media = \rtrim($current_media) . "{" . \rtrim($new_media);
|
||||
}
|
||||
return $this->css_check_last_media_section_or_inc($new_media);
|
||||
}
|
||||
public function css_close_media_section($current_media)
|
||||
{
|
||||
if ($this->get_cfg('preserve_css')) {
|
||||
return '';
|
||||
}
|
||||
if (\strpos($current_media, '{') !== \false) {
|
||||
$current_media = \explode('{', $current_media);
|
||||
\array_pop($current_media);
|
||||
$current_media = \implode('{', $current_media);
|
||||
return $current_media;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
public function css_new_selector($media, $selector)
|
||||
{
|
||||
if ($this->get_cfg('preserve_css')) {
|
||||
return $selector;
|
||||
}
|
||||
$selector = \trim($selector);
|
||||
if (\strncmp($selector, '@font-face', 10) != 0) {
|
||||
if ($this->settings['merge_selectors'] != \false) {
|
||||
return $selector;
|
||||
}
|
||||
if (!$this->css || !isset($this->css[$media]) || !$this->css[$media]) {
|
||||
return $selector;
|
||||
}
|
||||
// if last is the same, keep it
|
||||
\end($this->css[$media]);
|
||||
$sel = \key($this->css[$media]);
|
||||
if ($sel == $selector) {
|
||||
return $selector;
|
||||
}
|
||||
}
|
||||
while (isset($this->css[$media][$selector])) {
|
||||
$selector .= ' ';
|
||||
}
|
||||
return $selector;
|
||||
}
|
||||
public function css_new_property($media, $selector, $property)
|
||||
{
|
||||
if ($this->get_cfg('preserve_css')) {
|
||||
return $property;
|
||||
}
|
||||
if (!$this->css || !isset($this->css[$media][$selector]) || !$this->css[$media][$selector]) {
|
||||
return $property;
|
||||
}
|
||||
while (isset($this->css[$media][$selector][$property])) {
|
||||
$property .= ' ';
|
||||
}
|
||||
return $property;
|
||||
}
|
||||
public function merge_css_blocks($media, $selector, $css_add)
|
||||
{
|
||||
foreach ($css_add as $property => $value) {
|
||||
$this->css_add_property($media, $selector, $property, $value, \false);
|
||||
}
|
||||
}
|
||||
public function is_important(&$value)
|
||||
{
|
||||
return \strpos($value, '!') !== \false and !\strcasecmp(\substr(\str_replace($this->data['csstidy']['whitespace'], '', $value), -10, 10), '!important');
|
||||
}
|
||||
public function gvw_important($value)
|
||||
{
|
||||
if ($this->is_important($value)) {
|
||||
$value = \trim($value);
|
||||
$value = \substr($value, 0, -9);
|
||||
$value = \trim($value);
|
||||
$value = \substr($value, 0, -1);
|
||||
$value = \trim($value);
|
||||
return $value;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
public function property_is_next($istring, $pos)
|
||||
{
|
||||
$all_properties =& $this->data['csstidy']['all_properties'];
|
||||
$istring = \substr($istring, $pos, \strlen($istring) - $pos);
|
||||
$pos = \strpos($istring, ':');
|
||||
if ($pos === \false) {
|
||||
return \false;
|
||||
}
|
||||
$istring = \strtolower(\trim(\substr($istring, 0, $pos)));
|
||||
if (isset($all_properties[$istring])) {
|
||||
$this->log('Added semicolon to the end of declaration', 'Warning');
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function property_is_valid($property)
|
||||
{
|
||||
if (\strpos($property, '--') === 0) {
|
||||
$property = "--custom";
|
||||
} elseif (\in_array(\trim($property), $this->data['csstidy']['multiple_properties'])) {
|
||||
$property = \trim($property);
|
||||
}
|
||||
$all_properties =& $this->data['csstidy']['all_properties'];
|
||||
return isset($all_properties[$property]) && \strpos($all_properties[$property], \strtoupper($this->get_cfg('css_level'))) !== \false;
|
||||
}
|
||||
public function parse_string_list($value)
|
||||
{
|
||||
$value = \trim($value);
|
||||
// Case: empty
|
||||
if (!$value) {
|
||||
return array();
|
||||
}
|
||||
$strings = array();
|
||||
$in_str = \false;
|
||||
$current_string = '';
|
||||
for ($i = 0, $_len = \strlen($value); $i < $_len; $i++) {
|
||||
if (($value[$i] === ',' || $value[$i] === ' ') && $in_str === \true) {
|
||||
$in_str = \false;
|
||||
$strings[] = $current_string;
|
||||
$current_string = '';
|
||||
} elseif ($value[$i] === '"' || $value[$i] === "'") {
|
||||
if ($in_str === $value[$i]) {
|
||||
$strings[] = $current_string;
|
||||
$in_str = \false;
|
||||
$current_string = '';
|
||||
continue;
|
||||
} elseif (!$in_str) {
|
||||
$in_str = $value[$i];
|
||||
}
|
||||
} else {
|
||||
if ($in_str) {
|
||||
$current_string .= $value[$i];
|
||||
} else {
|
||||
if (!\preg_match("/[\\s,]/", $value[$i])) {
|
||||
$in_str = \true;
|
||||
$current_string = $value[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($current_string) {
|
||||
$strings[] = $current_string;
|
||||
}
|
||||
return $strings;
|
||||
}
|
||||
}
|
||||
+991
@@ -0,0 +1,991 @@
|
||||
<?php
|
||||
namespace MailPoetVendor;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
class csstidy_optimise
|
||||
{
|
||||
public $parser;
|
||||
public $css;
|
||||
public $sub_value;
|
||||
public $at;
|
||||
public $selector;
|
||||
public $property;
|
||||
public $value;
|
||||
public function __construct($css)
|
||||
{
|
||||
$this->parser = $css;
|
||||
$this->css =& $css->css;
|
||||
$this->sub_value =& $css->sub_value;
|
||||
$this->at =& $css->at;
|
||||
$this->selector =& $css->selector;
|
||||
$this->property =& $css->property;
|
||||
$this->value =& $css->value;
|
||||
}
|
||||
public function postparse()
|
||||
{
|
||||
if ($this->parser->get_cfg('reverse_left_and_right') > 0) {
|
||||
foreach ($this->css as $medium => $selectors) {
|
||||
if (\is_array($selectors)) {
|
||||
foreach ($selectors as $selector => $properties) {
|
||||
$this->css[$medium][$selector] = $this->reverse_left_and_right($this->css[$medium][$selector]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->parser->get_cfg('preserve_css')) {
|
||||
return;
|
||||
}
|
||||
if ((int) $this->parser->get_cfg('merge_selectors') === 2) {
|
||||
foreach ($this->css as $medium => $value) {
|
||||
if (\is_array($value)) {
|
||||
$this->merge_selectors($this->css[$medium]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->parser->get_cfg('discard_invalid_selectors')) {
|
||||
foreach ($this->css as $medium => $value) {
|
||||
if (\is_array($value)) {
|
||||
$this->discard_invalid_selectors($this->css[$medium]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->parser->get_cfg('optimise_shorthands') > 0) {
|
||||
foreach ($this->css as $medium => $value) {
|
||||
if (\is_array($value)) {
|
||||
foreach ($value as $selector => $value1) {
|
||||
$this->css[$medium][$selector] = $this->merge_4value_shorthands($this->css[$medium][$selector]);
|
||||
$this->css[$medium][$selector] = $this->merge_4value_radius_shorthands($this->css[$medium][$selector]);
|
||||
if ($this->parser->get_cfg('optimise_shorthands') < 2) {
|
||||
continue;
|
||||
}
|
||||
$this->css[$medium][$selector] = $this->merge_font($this->css[$medium][$selector]);
|
||||
if ($this->parser->get_cfg('optimise_shorthands') < 3) {
|
||||
continue;
|
||||
}
|
||||
$this->css[$medium][$selector] = $this->merge_bg($this->css[$medium][$selector]);
|
||||
if (empty($this->css[$medium][$selector])) {
|
||||
unset($this->css[$medium][$selector]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public function value()
|
||||
{
|
||||
$shorthands =& $this->parser->data['csstidy']['shorthands'];
|
||||
// optimise shorthand properties
|
||||
if (isset($shorthands[$this->property])) {
|
||||
$temp = $this->shorthand($this->value);
|
||||
// FIXME - move
|
||||
if ($temp != $this->value) {
|
||||
$this->parser->log('Optimised shorthand notation (' . $this->property . '): Changed "' . $this->value . '" to "' . $temp . '"', 'Information');
|
||||
}
|
||||
$this->value = $temp;
|
||||
}
|
||||
// Remove whitespace at ! important
|
||||
if ($this->value != $this->compress_important($this->value)) {
|
||||
$this->parser->log('Optimised !important', 'Information');
|
||||
}
|
||||
}
|
||||
public function shorthands()
|
||||
{
|
||||
$shorthands =& $this->parser->data['csstidy']['shorthands'];
|
||||
if (!$this->parser->get_cfg('optimise_shorthands') || $this->parser->get_cfg('preserve_css')) {
|
||||
return;
|
||||
}
|
||||
if ($this->property === 'font' && $this->parser->get_cfg('optimise_shorthands') > 1) {
|
||||
$this->css[$this->at][$this->selector]['font'] = '';
|
||||
$this->parser->merge_css_blocks($this->at, $this->selector, $this->dissolve_short_font($this->value));
|
||||
}
|
||||
if ($this->property === 'background' && $this->parser->get_cfg('optimise_shorthands') > 2) {
|
||||
$this->css[$this->at][$this->selector]['background'] = '';
|
||||
$this->parser->merge_css_blocks($this->at, $this->selector, $this->dissolve_short_bg($this->value));
|
||||
}
|
||||
if (isset($shorthands[$this->property])) {
|
||||
$this->parser->merge_css_blocks($this->at, $this->selector, $this->dissolve_4value_shorthands($this->property, $this->value));
|
||||
if (\is_array($shorthands[$this->property])) {
|
||||
$this->css[$this->at][$this->selector][$this->property] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
public function subvalue()
|
||||
{
|
||||
$replace_colors =& $this->parser->data['csstidy']['replace_colors'];
|
||||
$this->sub_value = \trim($this->sub_value);
|
||||
if ($this->sub_value == '') {
|
||||
// caution : '0'
|
||||
return;
|
||||
}
|
||||
$important = '';
|
||||
if ($this->parser->is_important($this->sub_value)) {
|
||||
$important = '!important';
|
||||
}
|
||||
$this->sub_value = $this->parser->gvw_important($this->sub_value);
|
||||
// Compress font-weight
|
||||
if ($this->property === 'font-weight' && $this->parser->get_cfg('compress_font-weight')) {
|
||||
if ($this->sub_value === 'bold') {
|
||||
$this->sub_value = '700';
|
||||
$this->parser->log('Optimised font-weight: Changed "bold" to "700"', 'Information');
|
||||
} elseif ($this->sub_value === 'normal') {
|
||||
$this->sub_value = '400';
|
||||
$this->parser->log('Optimised font-weight: Changed "normal" to "400"', 'Information');
|
||||
}
|
||||
}
|
||||
$temp = $this->compress_numbers($this->sub_value);
|
||||
if (\strcasecmp($temp, $this->sub_value) !== 0) {
|
||||
if (\strlen($temp) > \strlen($this->sub_value)) {
|
||||
$this->parser->log('Fixed invalid number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
|
||||
} else {
|
||||
$this->parser->log('Optimised number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
|
||||
}
|
||||
$this->sub_value = $temp;
|
||||
}
|
||||
if ($this->parser->get_cfg('compress_colors')) {
|
||||
$temp = $this->cut_color($this->sub_value);
|
||||
if ($temp !== $this->sub_value) {
|
||||
if (isset($replace_colors[$this->sub_value])) {
|
||||
$this->parser->log('Fixed invalid color name: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
|
||||
} else {
|
||||
$this->parser->log('Optimised color: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
|
||||
}
|
||||
$this->sub_value = $temp;
|
||||
}
|
||||
}
|
||||
$this->sub_value .= $important;
|
||||
}
|
||||
public function shorthand($value)
|
||||
{
|
||||
$important = '';
|
||||
if ($this->parser->is_important($value)) {
|
||||
$values = $this->parser->gvw_important($value);
|
||||
$important = '!important';
|
||||
} else {
|
||||
$values = $value;
|
||||
}
|
||||
$values = \explode(' ', $values);
|
||||
switch (\count($values)) {
|
||||
case 4:
|
||||
if ($values[0] == $values[1] && $values[0] == $values[2] && $values[0] == $values[3]) {
|
||||
return $values[0] . $important;
|
||||
} elseif ($values[1] == $values[3] && $values[0] == $values[2]) {
|
||||
return $values[0] . ' ' . $values[1] . $important;
|
||||
} elseif ($values[1] == $values[3]) {
|
||||
return $values[0] . ' ' . $values[1] . ' ' . $values[2] . $important;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if ($values[0] == $values[1] && $values[0] == $values[2]) {
|
||||
return $values[0] . $important;
|
||||
} elseif ($values[0] == $values[2]) {
|
||||
return $values[0] . ' ' . $values[1] . $important;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if ($values[0] == $values[1]) {
|
||||
return $values[0] . $important;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
public function compress_important(&$string)
|
||||
{
|
||||
if ($this->parser->is_important($string)) {
|
||||
$important = $this->parser->get_cfg('space_before_important') ? ' !important' : '!important';
|
||||
$string = $this->parser->gvw_important($string) . $important;
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
public function cut_color($color)
|
||||
{
|
||||
$replace_colors =& $this->parser->data['csstidy']['replace_colors'];
|
||||
// if it's a string, don't touch !
|
||||
if (\strncmp($color, "'", 1) == 0 || \strncmp($color, '"', 1) == 0) {
|
||||
return $color;
|
||||
}
|
||||
if (\strpos($color, '(') !== \false && (\strncasecmp($color, 'rgb(', 4) !== 0 and \strncasecmp($color, 'rgba(', 5) !== 0)) {
|
||||
// on ne touche pas aux couleurs dans les expression ms, c'est trop sensible
|
||||
if (\stripos($color, 'progid:') !== \false) {
|
||||
return $color;
|
||||
}
|
||||
\preg_match_all(",rgba?\\([^)]+\\),i", $color, $matches, \PREG_SET_ORDER);
|
||||
if (\count($matches)) {
|
||||
foreach ($matches as $m) {
|
||||
$color = \str_replace($m[0], $this->cut_color($m[0]), $color);
|
||||
}
|
||||
}
|
||||
\preg_match_all(",#[0-9a-f]{6}(?=[^0-9a-f]),i", $color, $matches, \PREG_SET_ORDER);
|
||||
if (\count($matches)) {
|
||||
foreach ($matches as $m) {
|
||||
$color = \str_replace($m[0], $this->cut_color($m[0]), $color);
|
||||
}
|
||||
}
|
||||
return $color;
|
||||
}
|
||||
// rgb(0,0,0) -> #000000 (or #000 in this case later)
|
||||
if (\strncasecmp($color, 'rgb(', 4) == 0 and \strpos($color, '(', 4) === \false or \strncasecmp($color, 'rgba(', 5) == 0 and \strpos($color, '(', 5) === \false) {
|
||||
$color_tmp = \explode('(', $color, 2);
|
||||
$color_tmp = \rtrim(\end($color_tmp), ')');
|
||||
if (\strpos($color_tmp, '/') !== \false) {
|
||||
$color_tmp = \explode('/', $color_tmp, 2);
|
||||
$color_parts = \explode(' ', \trim(\reset($color_tmp)), 3);
|
||||
while (\count($color_parts) < 3) {
|
||||
$color_parts[] = 0;
|
||||
}
|
||||
$color_parts[] = \end($color_tmp);
|
||||
} else {
|
||||
$color_parts = \explode(',', $color_tmp, 4);
|
||||
}
|
||||
for ($i = 0; $i < \count($color_parts); $i++) {
|
||||
$color_parts[$i] = \trim($color_parts[$i]);
|
||||
if (\substr($color_parts[$i], -1) === '%') {
|
||||
$color_parts[$i] = \round(255 * \intval($color_parts[$i]) / 100);
|
||||
} elseif ($i > 2) {
|
||||
// 4th argument is alpga layer between 0 and 1 (if not %)
|
||||
$color_parts[$i] = \round(255 * \floatval($color_parts[$i]));
|
||||
}
|
||||
$color_parts[$i] = \intval($color_parts[$i]);
|
||||
if ($color_parts[$i] > 255) {
|
||||
$color_parts[$i] = 255;
|
||||
}
|
||||
}
|
||||
$color = '#';
|
||||
// 3 or 4 parts depending on alpha layer
|
||||
$nb = \min(\max(\count($color_parts), 3), 4);
|
||||
for ($i = 0; $i < $nb; $i++) {
|
||||
if (!isset($color_parts[$i])) {
|
||||
$color_parts[$i] = 0;
|
||||
}
|
||||
if ($color_parts[$i] < 16) {
|
||||
$color .= '0' . \dechex($color_parts[$i]);
|
||||
} else {
|
||||
$color .= \dechex($color_parts[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fix bad color names
|
||||
if (isset($replace_colors[\strtolower($color)])) {
|
||||
$color = $replace_colors[\strtolower($color)];
|
||||
}
|
||||
// #aabbcc -> #abc
|
||||
if (\strlen($color) == 7) {
|
||||
$color_temp = \strtolower($color);
|
||||
if ($color_temp[0] === '#' && $color_temp[1] == $color_temp[2] && $color_temp[3] == $color_temp[4] && $color_temp[5] == $color_temp[6]) {
|
||||
$color = '#' . $color[1] . $color[3] . $color[5];
|
||||
}
|
||||
} elseif (\strlen($color) == 9) {
|
||||
$color_temp = \strtolower($color);
|
||||
if ($color_temp[0] === '#' && $color_temp[1] == $color_temp[2] && $color_temp[3] == $color_temp[4] && $color_temp[5] == $color_temp[6] && $color_temp[7] == $color_temp[8]) {
|
||||
$color = '#' . $color[1] . $color[3] . $color[5] . $color[7];
|
||||
}
|
||||
}
|
||||
switch (\strtolower($color)) {
|
||||
case 'black':
|
||||
return '#000';
|
||||
case 'fuchsia':
|
||||
return '#f0f';
|
||||
case 'white':
|
||||
return '#fff';
|
||||
case 'yellow':
|
||||
return '#ff0';
|
||||
case '#800000':
|
||||
return 'maroon';
|
||||
case '#ffa500':
|
||||
return 'orange';
|
||||
case '#808000':
|
||||
return 'olive';
|
||||
case '#800080':
|
||||
return 'purple';
|
||||
case '#008000':
|
||||
return 'green';
|
||||
case '#000080':
|
||||
return 'navy';
|
||||
case '#008080':
|
||||
return 'teal';
|
||||
case '#c0c0c0':
|
||||
return 'silver';
|
||||
case '#808080':
|
||||
return 'gray';
|
||||
case '#f00':
|
||||
return 'red';
|
||||
}
|
||||
return $color;
|
||||
}
|
||||
public function compress_numbers($subvalue)
|
||||
{
|
||||
$unit_values =& $this->parser->data['csstidy']['unit_values'];
|
||||
$color_values =& $this->parser->data['csstidy']['color_values'];
|
||||
// for font:1em/1em sans-serif...;
|
||||
if ($this->property === 'font') {
|
||||
$temp = \explode('/', $subvalue);
|
||||
} else {
|
||||
$temp = array($subvalue);
|
||||
}
|
||||
for ($l = 0; $l < \count($temp); $l++) {
|
||||
// if we are not dealing with a number at this point, do not optimise anything
|
||||
$number = $this->AnalyseCssNumber($temp[$l]);
|
||||
if ($number === \false) {
|
||||
return $subvalue;
|
||||
}
|
||||
// Fix bad colors
|
||||
if (\in_array($this->property, $color_values)) {
|
||||
$temp[$l] = '#' . $temp[$l];
|
||||
continue;
|
||||
}
|
||||
if (\abs($number[0]) > 0) {
|
||||
if ($number[1] == '' && \in_array($this->property, $unit_values, \true)) {
|
||||
$number[1] = 'px';
|
||||
}
|
||||
} elseif ($number[1] != 's' && $number[1] != 'ms') {
|
||||
$number[1] = '';
|
||||
}
|
||||
$temp[$l] = $number[0] . $number[1];
|
||||
}
|
||||
return \count($temp) > 1 ? $temp[0] . '/' . $temp[1] : $temp[0];
|
||||
}
|
||||
public function AnalyseCssNumber($string)
|
||||
{
|
||||
// most simple checks first
|
||||
if (\strlen($string) == 0 || \ctype_alpha($string[0])) {
|
||||
return \false;
|
||||
}
|
||||
$units =& $this->parser->data['csstidy']['units'];
|
||||
$return = array(0, '');
|
||||
$return[0] = \floatval($string);
|
||||
if (\abs($return[0]) > 0 && \abs($return[0]) < 1) {
|
||||
if ($return[0] < 0) {
|
||||
$return[0] = '-' . \ltrim(\substr($return[0], 1), '0');
|
||||
} else {
|
||||
$return[0] = \ltrim($return[0], '0');
|
||||
}
|
||||
}
|
||||
// Look for unit and split from value if exists
|
||||
foreach ($units as $unit) {
|
||||
$expectUnitAt = \strlen($string) - \strlen($unit);
|
||||
if (!($unitInString = \stristr($string, $unit))) {
|
||||
// mb_strpos() fails with "false"
|
||||
continue;
|
||||
}
|
||||
$actualPosition = \strpos($string, $unitInString);
|
||||
if ($expectUnitAt === $actualPosition) {
|
||||
$return[1] = $unit;
|
||||
$string = \substr($string, 0, -\strlen($unit));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!\is_numeric($string)) {
|
||||
return \false;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public function merge_selectors(&$array)
|
||||
{
|
||||
$css = $array;
|
||||
foreach ($css as $key => $value) {
|
||||
if (!isset($css[$key])) {
|
||||
continue;
|
||||
}
|
||||
$newsel = '';
|
||||
// Check if properties also exist in another selector
|
||||
$keys = array();
|
||||
// PHP bug (?) without $css = $array; here
|
||||
foreach ($css as $selector => $vali) {
|
||||
if ($selector == $key) {
|
||||
continue;
|
||||
}
|
||||
if ($css[$key] === $vali) {
|
||||
$keys[] = $selector;
|
||||
}
|
||||
}
|
||||
if (!empty($keys)) {
|
||||
$newsel = $key;
|
||||
unset($css[$key]);
|
||||
foreach ($keys as $selector) {
|
||||
unset($css[$selector]);
|
||||
$newsel .= ',' . $selector;
|
||||
}
|
||||
$css[$newsel] = $value;
|
||||
}
|
||||
}
|
||||
$array = $css;
|
||||
}
|
||||
public function discard_invalid_selectors(&$array)
|
||||
{
|
||||
$invalid = array('+' => \true, '~' => \true, ',' => \true, '>' => \true);
|
||||
foreach ($array as $selector => $decls) {
|
||||
$ok = \true;
|
||||
$selectors = \array_map('trim', \explode(',', $selector));
|
||||
foreach ($selectors as $s) {
|
||||
$simple_selectors = \preg_split('/\\s*[+>~\\s]\\s*/', $s);
|
||||
foreach ($simple_selectors as $ss) {
|
||||
if ($ss === '') {
|
||||
$ok = \false;
|
||||
}
|
||||
// could also check $ss for internal structure,
|
||||
// but that probably would be too slow
|
||||
}
|
||||
}
|
||||
if (!$ok) {
|
||||
unset($array[$selector]);
|
||||
}
|
||||
}
|
||||
}
|
||||
public function dissolve_4value_shorthands($property, $value, $shorthands = null)
|
||||
{
|
||||
if (\is_null($shorthands)) {
|
||||
$shorthands =& $this->parser->data['csstidy']['shorthands'];
|
||||
}
|
||||
if (!\is_array($shorthands[$property])) {
|
||||
$return[$property] = $value;
|
||||
return $return;
|
||||
}
|
||||
$important = '';
|
||||
if ($this->parser->is_important($value)) {
|
||||
$value = $this->parser->gvw_important($value);
|
||||
$important = '!important';
|
||||
}
|
||||
$values = \explode(' ', $value);
|
||||
$return = array();
|
||||
if (\count($values) == 4) {
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$return[$shorthands[$property][$i]] = $values[$i] . $important;
|
||||
}
|
||||
} elseif (\count($values) == 3) {
|
||||
$return[$shorthands[$property][0]] = $values[0] . $important;
|
||||
$return[$shorthands[$property][1]] = $values[1] . $important;
|
||||
$return[$shorthands[$property][3]] = $values[1] . $important;
|
||||
$return[$shorthands[$property][2]] = $values[2] . $important;
|
||||
} elseif (\count($values) == 2) {
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$return[$shorthands[$property][$i]] = $i % 2 != 0 ? $values[1] . $important : $values[0] . $important;
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$return[$shorthands[$property][$i]] = $values[0] . $important;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public function dissolve_4value_radius_shorthands($property, $value)
|
||||
{
|
||||
$shorthands =& $this->parser->data['csstidy']['radius_shorthands'];
|
||||
if (!\is_array($shorthands[$property])) {
|
||||
$return[$property] = $value;
|
||||
return $return;
|
||||
}
|
||||
if (\strpos($value, '/') !== \false) {
|
||||
$values = $this->explode_ws('/', $value);
|
||||
if (\count($values) == 2) {
|
||||
$r[0] = $this->dissolve_4value_shorthands($property, \trim($values[0]), $shorthands);
|
||||
$r[1] = $this->dissolve_4value_shorthands($property, \trim($values[1]), $shorthands);
|
||||
$return = array();
|
||||
foreach ($r[0] as $p => $v) {
|
||||
$return[$p] = $v;
|
||||
if ($r[1][$p] !== $v) {
|
||||
$return[$p] .= ' ' . $r[1][$p];
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
$return = $this->dissolve_4value_shorthands($property, $value, $shorthands);
|
||||
return $return;
|
||||
}
|
||||
public function explode_ws($sep, $string, $explode_in_parenthesis = \false)
|
||||
{
|
||||
$status = 'st';
|
||||
$to = '';
|
||||
$output = array(0 => '');
|
||||
$num = 0;
|
||||
for ($i = 0, $len = \strlen($string); $i < $len; $i++) {
|
||||
switch ($status) {
|
||||
case 'st':
|
||||
if ($string[$i] == $sep && !$this->parser->escaped($string, $i)) {
|
||||
++$num;
|
||||
} elseif ($string[$i] === '"' || $string[$i] === '\'' || !$explode_in_parenthesis && $string[$i] === '(' && !$this->parser->escaped($string, $i)) {
|
||||
$status = 'str';
|
||||
$to = $string[$i] === '(' ? ')' : $string[$i];
|
||||
isset($output[$num]) ? $output[$num] .= $string[$i] : ($output[$num] = $string[$i]);
|
||||
} else {
|
||||
isset($output[$num]) ? $output[$num] .= $string[$i] : ($output[$num] = $string[$i]);
|
||||
}
|
||||
break;
|
||||
case 'str':
|
||||
if ($string[$i] == $to && !$this->parser->escaped($string, $i)) {
|
||||
$status = 'st';
|
||||
}
|
||||
isset($output[$num]) ? $output[$num] .= $string[$i] : ($output[$num] = $string[$i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
public function merge_4value_shorthands($array, $shorthands = null)
|
||||
{
|
||||
$return = $array;
|
||||
if (\is_null($shorthands)) {
|
||||
$shorthands =& $this->parser->data['csstidy']['shorthands'];
|
||||
}
|
||||
foreach ($shorthands as $key => $value) {
|
||||
if ($value !== 0 && isset($array[$value[0]]) && isset($array[$value[1]]) && isset($array[$value[2]]) && isset($array[$value[3]])) {
|
||||
$return[$key] = '';
|
||||
$important = '';
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$val = $array[$value[$i]];
|
||||
if ($this->parser->is_important($val)) {
|
||||
$important = '!important';
|
||||
$return[$key] .= $this->parser->gvw_important($val) . ' ';
|
||||
} else {
|
||||
$return[$key] .= $val . ' ';
|
||||
}
|
||||
unset($return[$value[$i]]);
|
||||
}
|
||||
$return[$key] = $this->shorthand(\trim($return[$key] . $important));
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public function merge_4value_radius_shorthands($array)
|
||||
{
|
||||
$return = $array;
|
||||
$shorthands =& $this->parser->data['csstidy']['radius_shorthands'];
|
||||
foreach ($shorthands as $key => $value) {
|
||||
if (isset($array[$value[0]]) && isset($array[$value[1]]) && isset($array[$value[2]]) && isset($array[$value[3]]) && $value !== 0) {
|
||||
$return[$key] = '';
|
||||
$a = array();
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$v = $this->explode_ws(' ', \trim($array[$value[$i]]));
|
||||
$a[0][$value[$i]] = \reset($v);
|
||||
$a[1][$value[$i]] = \end($v);
|
||||
}
|
||||
$r = array();
|
||||
$r[0] = $this->merge_4value_shorthands($a[0], $shorthands);
|
||||
$r[1] = $this->merge_4value_shorthands($a[1], $shorthands);
|
||||
if (isset($r[0][$key]) and isset($r[1][$key])) {
|
||||
$return[$key] = $r[0][$key];
|
||||
if ($r[1][$key] !== $r[0][$key]) {
|
||||
$return[$key] .= ' / ' . $r[1][$key];
|
||||
}
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
unset($return[$value[$i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public function dissolve_short_bg($str_value)
|
||||
{
|
||||
// don't try to explose background gradient !
|
||||
if (\stripos($str_value, 'gradient(') !== \false) {
|
||||
return array('background' => $str_value);
|
||||
}
|
||||
$background_prop_default =& $this->parser->data['csstidy']['background_prop_default'];
|
||||
$repeat = array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space');
|
||||
$attachment = array('scroll', 'fixed', 'local');
|
||||
$clip = array('border', 'padding');
|
||||
$origin = array('border', 'padding', 'content');
|
||||
$pos = array('top', 'center', 'bottom', 'left', 'right');
|
||||
$important = '';
|
||||
$return = array('background-image' => null, 'background-size' => null, 'background-repeat' => null, 'background-position' => null, 'background-attachment' => null, 'background-clip' => null, 'background-origin' => null, 'background-color' => null);
|
||||
if ($this->parser->is_important($str_value)) {
|
||||
$important = ' !important';
|
||||
$str_value = $this->parser->gvw_important($str_value);
|
||||
}
|
||||
$str_value = $this->explode_ws(',', $str_value);
|
||||
for ($i = 0; $i < \count($str_value); $i++) {
|
||||
$have['clip'] = \false;
|
||||
$have['pos'] = \false;
|
||||
$have['color'] = \false;
|
||||
$have['bg'] = \false;
|
||||
if (\is_array($str_value[$i])) {
|
||||
$str_value[$i] = $str_value[$i][0];
|
||||
}
|
||||
$str_value[$i] = $this->explode_ws(' ', \trim($str_value[$i]));
|
||||
for ($j = 0; $j < \count($str_value[$i]); $j++) {
|
||||
if ($have['bg'] === \false && (\substr($str_value[$i][$j], 0, 4) === 'url(' || $str_value[$i][$j] === 'none')) {
|
||||
$return['background-image'] .= $str_value[$i][$j] . ',';
|
||||
$have['bg'] = \true;
|
||||
} elseif (\in_array($str_value[$i][$j], $repeat, \true)) {
|
||||
$return['background-repeat'] .= $str_value[$i][$j] . ',';
|
||||
} elseif (\in_array($str_value[$i][$j], $attachment, \true)) {
|
||||
$return['background-attachment'] .= $str_value[$i][$j] . ',';
|
||||
} elseif (\in_array($str_value[$i][$j], $clip, \true) && !$have['clip']) {
|
||||
$return['background-clip'] .= $str_value[$i][$j] . ',';
|
||||
$have['clip'] = \true;
|
||||
} elseif (\in_array($str_value[$i][$j], $origin, \true)) {
|
||||
$return['background-origin'] .= $str_value[$i][$j] . ',';
|
||||
} elseif ($str_value[$i][$j][0] === '(') {
|
||||
$return['background-size'] .= \substr($str_value[$i][$j], 1, -1) . ',';
|
||||
} elseif (\in_array($str_value[$i][$j], $pos, \true) || \is_numeric($str_value[$i][$j][0]) || $str_value[$i][$j][0] === null || $str_value[$i][$j][0] === '-' || $str_value[$i][$j][0] === '.') {
|
||||
$return['background-position'] .= $str_value[$i][$j];
|
||||
if (!$have['pos']) {
|
||||
$return['background-position'] .= ' ';
|
||||
} else {
|
||||
$return['background-position'] .= ',';
|
||||
}
|
||||
$have['pos'] = \true;
|
||||
} elseif (!$have['color']) {
|
||||
$return['background-color'] .= $str_value[$i][$j] . ',';
|
||||
$have['color'] = \true;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($background_prop_default as $bg_prop => $default_value) {
|
||||
if ($return[$bg_prop] !== null) {
|
||||
$return[$bg_prop] = \substr($return[$bg_prop], 0, -1) . $important;
|
||||
} else {
|
||||
$return[$bg_prop] = $default_value . $important;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public function merge_bg($input_css)
|
||||
{
|
||||
$background_prop_default =& $this->parser->data['csstidy']['background_prop_default'];
|
||||
// Max number of background images. CSS3 not yet fully implemented
|
||||
$number_of_values = @\max(\count($this->explode_ws(',', $input_css['background-image'])), \count($this->explode_ws(',', $input_css['background-color'])), 1);
|
||||
// Array with background images to check if BG image exists
|
||||
$bg_img_array = @$this->explode_ws(',', $this->parser->gvw_important($input_css['background-image']));
|
||||
$new_bg_value = '';
|
||||
$important = '';
|
||||
// if background properties is here and not empty, don't try anything
|
||||
if (isset($input_css['background']) && $input_css['background']) {
|
||||
return $input_css;
|
||||
}
|
||||
for ($i = 0; $i < $number_of_values; $i++) {
|
||||
foreach ($background_prop_default as $bg_property => $default_value) {
|
||||
// Skip if property does not exist
|
||||
if (!isset($input_css[$bg_property])) {
|
||||
continue;
|
||||
}
|
||||
$cur_value = $input_css[$bg_property];
|
||||
// skip all optimisation if gradient() somewhere
|
||||
if (\stripos($cur_value, 'gradient(') !== \false) {
|
||||
return $input_css;
|
||||
}
|
||||
// Skip some properties if there is no background image
|
||||
if ((!isset($bg_img_array[$i]) || $bg_img_array[$i] === 'none') && ($bg_property === 'background-size' || $bg_property === 'background-position' || $bg_property === 'background-attachment' || $bg_property === 'background-repeat')) {
|
||||
continue;
|
||||
}
|
||||
// Remove !important
|
||||
if ($this->parser->is_important($cur_value)) {
|
||||
$important = ' !important';
|
||||
$cur_value = $this->parser->gvw_important($cur_value);
|
||||
}
|
||||
// Do not add default values
|
||||
if ($cur_value === $default_value) {
|
||||
continue;
|
||||
}
|
||||
$temp = $this->explode_ws(',', $cur_value);
|
||||
if (isset($temp[$i])) {
|
||||
if ($bg_property === 'background-size') {
|
||||
$new_bg_value .= '(' . $temp[$i] . ') ';
|
||||
} else {
|
||||
$new_bg_value .= $temp[$i] . ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
$new_bg_value = \trim($new_bg_value);
|
||||
if ($i != $number_of_values - 1) {
|
||||
$new_bg_value .= ',';
|
||||
}
|
||||
}
|
||||
// Delete all background-properties
|
||||
foreach ($background_prop_default as $bg_property => $default_value) {
|
||||
unset($input_css[$bg_property]);
|
||||
}
|
||||
// Add new background property
|
||||
if ($new_bg_value !== '') {
|
||||
$input_css['background'] = $new_bg_value . $important;
|
||||
} elseif (isset($input_css['background'])) {
|
||||
$input_css['background'] = 'none';
|
||||
}
|
||||
return $input_css;
|
||||
}
|
||||
public function dissolve_short_font($str_value)
|
||||
{
|
||||
$font_prop_default =& $this->parser->data['csstidy']['font_prop_default'];
|
||||
$font_weight = array('normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900);
|
||||
$font_variant = array('normal', 'small-caps');
|
||||
$font_style = array('normal', 'italic', 'oblique');
|
||||
$important = '';
|
||||
$return = array('font-style' => null, 'font-variant' => null, 'font-weight' => null, 'font-size' => null, 'line-height' => null, 'font-family' => null);
|
||||
if ($this->parser->is_important($str_value)) {
|
||||
$important = '!important';
|
||||
$str_value = $this->parser->gvw_important($str_value);
|
||||
}
|
||||
$have['style'] = \false;
|
||||
$have['variant'] = \false;
|
||||
$have['weight'] = \false;
|
||||
$have['size'] = \false;
|
||||
// Detects if font-family consists of several words w/o quotes
|
||||
$multiwords = \false;
|
||||
// Workaround with multiple font-family
|
||||
$str_value = $this->explode_ws(',', \trim($str_value));
|
||||
$str_value[0] = $this->explode_ws(' ', \trim($str_value[0]));
|
||||
for ($j = 0; $j < \count($str_value[0]); $j++) {
|
||||
if ($have['weight'] === \false && \in_array($str_value[0][$j], $font_weight)) {
|
||||
$return['font-weight'] = $str_value[0][$j];
|
||||
$have['weight'] = \true;
|
||||
} elseif ($have['variant'] === \false && \in_array($str_value[0][$j], $font_variant)) {
|
||||
$return['font-variant'] = $str_value[0][$j];
|
||||
$have['variant'] = \true;
|
||||
} elseif ($have['style'] === \false && \in_array($str_value[0][$j], $font_style)) {
|
||||
$return['font-style'] = $str_value[0][$j];
|
||||
$have['style'] = \true;
|
||||
} elseif ($have['size'] === \false && (\is_numeric($str_value[0][$j][0]) || $str_value[0][$j][0] === null || $str_value[0][$j][0] === '.')) {
|
||||
$size = $this->explode_ws('/', \trim($str_value[0][$j]));
|
||||
$return['font-size'] = $size[0];
|
||||
if (isset($size[1])) {
|
||||
$return['line-height'] = $size[1];
|
||||
} else {
|
||||
$return['line-height'] = '';
|
||||
// don't add 'normal' !
|
||||
}
|
||||
$have['size'] = \true;
|
||||
} else {
|
||||
if (isset($return['font-family'])) {
|
||||
$return['font-family'] .= ' ' . $str_value[0][$j];
|
||||
$multiwords = \true;
|
||||
} else {
|
||||
$return['font-family'] = $str_value[0][$j];
|
||||
}
|
||||
}
|
||||
}
|
||||
// add quotes if we have several qords in font-family
|
||||
if ($multiwords !== \false) {
|
||||
$return['font-family'] = '"' . $return['font-family'] . '"';
|
||||
}
|
||||
$i = 1;
|
||||
while (isset($str_value[$i])) {
|
||||
$return['font-family'] .= ',' . \trim($str_value[$i]);
|
||||
$i++;
|
||||
}
|
||||
// Fix for 100 and more font-size
|
||||
if ($have['size'] === \false && isset($return['font-weight']) && \is_numeric($return['font-weight'][0])) {
|
||||
$return['font-size'] = $return['font-weight'];
|
||||
unset($return['font-weight']);
|
||||
}
|
||||
foreach ($font_prop_default as $font_prop => $default_value) {
|
||||
if ($return[$font_prop] !== null) {
|
||||
$return[$font_prop] = $return[$font_prop] . $important;
|
||||
} else {
|
||||
$return[$font_prop] = $default_value . $important;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public function merge_font($input_css)
|
||||
{
|
||||
$font_prop_default =& $this->parser->data['csstidy']['font_prop_default'];
|
||||
$new_font_value = '';
|
||||
$important = '';
|
||||
// Skip if not font-family and font-size set
|
||||
if (isset($input_css['font-family']) && isset($input_css['font-size']) && $input_css['font-family'] != 'inherit') {
|
||||
// fix several words in font-family - add quotes
|
||||
if (isset($input_css['font-family'])) {
|
||||
$families = \explode(',', $input_css['font-family']);
|
||||
$result_families = array();
|
||||
foreach ($families as $family) {
|
||||
$family = \trim($family);
|
||||
$len = \strlen($family);
|
||||
if (\strpos($family, ' ') && !($family[0] === '"' && $family[$len - 1] === '"' || $family[0] === "'" && $family[$len - 1] === "'")) {
|
||||
$family = '"' . $family . '"';
|
||||
}
|
||||
$result_families[] = $family;
|
||||
}
|
||||
$input_css['font-family'] = \implode(',', $result_families);
|
||||
}
|
||||
foreach ($font_prop_default as $font_property => $default_value) {
|
||||
// Skip if property does not exist
|
||||
if (!isset($input_css[$font_property])) {
|
||||
continue;
|
||||
}
|
||||
$cur_value = $input_css[$font_property];
|
||||
// Skip if default value is used
|
||||
if ($cur_value === $default_value) {
|
||||
continue;
|
||||
}
|
||||
// Remove !important
|
||||
if ($this->parser->is_important($cur_value)) {
|
||||
$important = '!important';
|
||||
$cur_value = $this->parser->gvw_important($cur_value);
|
||||
}
|
||||
$new_font_value .= $cur_value;
|
||||
// Add delimiter
|
||||
$new_font_value .= $font_property === 'font-size' && isset($input_css['line-height']) ? '/' : ' ';
|
||||
}
|
||||
$new_font_value = \trim($new_font_value);
|
||||
// Delete all font-properties
|
||||
foreach ($font_prop_default as $font_property => $default_value) {
|
||||
if ($font_property !== 'font' || !$new_font_value) {
|
||||
unset($input_css[$font_property]);
|
||||
}
|
||||
}
|
||||
// Add new font property
|
||||
if ($new_font_value !== '') {
|
||||
$input_css['font'] = $new_font_value . $important;
|
||||
}
|
||||
}
|
||||
return $input_css;
|
||||
}
|
||||
public function reverse_left_and_right($array)
|
||||
{
|
||||
$return = array();
|
||||
// change left <-> right in properties name and values
|
||||
foreach ($array as $propertie => $value) {
|
||||
if (\method_exists($this, $m = 'reverse_left_and_right_' . \str_replace('-', '_', \trim($propertie)))) {
|
||||
$value = $this->{$m}($value);
|
||||
}
|
||||
// simple replacement for properties
|
||||
$propertie = \str_ireplace(array('left', 'right', "\x01"), array("\x01", 'left', 'right'), $propertie);
|
||||
// be careful for values, not modifying protected or quoted valued
|
||||
foreach (array('left' => "\x01", 'right' => 'left', "\x01" => 'right') as $v => $r) {
|
||||
if (\strpos($value, $v) !== \false) {
|
||||
// attraper les left et right separes du reste (pas au milieu d'un mot)
|
||||
if (\in_array($v, array('left', 'right'))) {
|
||||
$value = \preg_replace(",\\b{$v}\\b,", "\x00", $value);
|
||||
} else {
|
||||
$value = \str_replace($v, "\x00", $value);
|
||||
}
|
||||
$value = $this->explode_ws("\x00", $value . ' ', \true);
|
||||
$value = \rtrim(\implode($r, $value));
|
||||
$value = \str_replace("\x00", $v, $value);
|
||||
}
|
||||
}
|
||||
$return[$propertie] = $value;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public function reverse_left_and_right_4value_shorthands($property, $value)
|
||||
{
|
||||
$shorthands =& $this->parser->data['csstidy']['shorthands'];
|
||||
if (isset($shorthands[$property])) {
|
||||
$property_right = $shorthands[$property][1];
|
||||
$property_left = $shorthands[$property][3];
|
||||
$v = $this->dissolve_4value_shorthands($property, $value);
|
||||
if ($v[$property_left] !== $v[$property_right]) {
|
||||
$r = $v[$property_right];
|
||||
$v[$property_right] = $v[$property_left];
|
||||
$v[$property_left] = $r;
|
||||
$v = $this->merge_4value_shorthands($v);
|
||||
if (isset($v[$property])) {
|
||||
return $v[$property];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
public function reverse_left_and_right_4value_radius_shorthands($property, $value)
|
||||
{
|
||||
$shorthands =& $this->parser->data['csstidy']['radius_shorthands'];
|
||||
if (isset($shorthands[$property])) {
|
||||
$v = $this->dissolve_4value_radius_shorthands($property, $value);
|
||||
if ($v[$shorthands[$property][0]] !== $v[$shorthands[$property][1]] or $v[$shorthands[$property][2]] !== $v[$shorthands[$property][3]]) {
|
||||
$r = array($shorthands[$property][0] => $v[$shorthands[$property][1]], $shorthands[$property][1] => $v[$shorthands[$property][0]], $shorthands[$property][2] => $v[$shorthands[$property][3]], $shorthands[$property][3] => $v[$shorthands[$property][2]]);
|
||||
$v = $this->merge_4value_radius_shorthands($r);
|
||||
if (isset($v[$property])) {
|
||||
return $v[$property];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
public function reverse_left_and_right_margin($value)
|
||||
{
|
||||
return $this->reverse_left_and_right_4value_shorthands('margin', $value);
|
||||
}
|
||||
public function reverse_left_and_right_padding($value)
|
||||
{
|
||||
return $this->reverse_left_and_right_4value_shorthands('padding', $value);
|
||||
}
|
||||
public function reverse_left_and_right_border_color($value)
|
||||
{
|
||||
return $this->reverse_left_and_right_4value_shorthands('border-color', $value);
|
||||
}
|
||||
public function reverse_left_and_right_border_style($value)
|
||||
{
|
||||
return $this->reverse_left_and_right_4value_shorthands('border-style', $value);
|
||||
}
|
||||
public function reverse_left_and_right_border_width($value)
|
||||
{
|
||||
return $this->reverse_left_and_right_4value_shorthands('border-width', $value);
|
||||
}
|
||||
public function reverse_left_and_right_border_radius($value)
|
||||
{
|
||||
return $this->reverse_left_and_right_4value_radius_shorthands('border-radius', $value);
|
||||
}
|
||||
public function reverse_left_and_right__moz_border_radius($value)
|
||||
{
|
||||
return $this->reverse_left_and_right_4value_radius_shorthands('border-radius', $value);
|
||||
}
|
||||
public function reverse_left_and_right__webkit_border_radius($value)
|
||||
{
|
||||
return $this->reverse_left_and_right_4value_radius_shorthands('border-radius', $value);
|
||||
}
|
||||
public function reverse_left_and_right_background($value)
|
||||
{
|
||||
$values = $this->dissolve_short_bg($value);
|
||||
if (isset($values['background-position']) and $values['background-position']) {
|
||||
$v = $this->reverse_left_and_right_background_position($values['background-position']);
|
||||
if ($v !== $values['background-position']) {
|
||||
if ($value == $values['background-position']) {
|
||||
return $v;
|
||||
} else {
|
||||
$values['background-position'] = $v;
|
||||
$x = $this->merge_bg($values);
|
||||
if (isset($x['background'])) {
|
||||
return $x['background'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
public function reverse_left_and_right_background_position_x($value)
|
||||
{
|
||||
return $this->reverse_left_and_right_background_position($value);
|
||||
}
|
||||
public function reverse_left_and_right_background_position($value)
|
||||
{
|
||||
// multiple background case
|
||||
if (\strpos($value, ',') !== \false) {
|
||||
$values = $this->explode_ws(',', $value);
|
||||
if (\count($values) > 1) {
|
||||
foreach ($values as $k => $v) {
|
||||
$values[$k] = $this->reverse_left_and_right_background_position($v);
|
||||
}
|
||||
return \implode(',', $values);
|
||||
}
|
||||
}
|
||||
// if no explicit left or right value
|
||||
if (\stripos($value, 'left') === \false and \stripos($value, 'right') === \false) {
|
||||
$values = $this->explode_ws(' ', \trim($value));
|
||||
$values = \array_map('trim', $values);
|
||||
$values = \array_filter($values, function ($v) {
|
||||
return \strlen($v);
|
||||
});
|
||||
$values = \array_values($values);
|
||||
if (\count($values) == 1) {
|
||||
if (\in_array($value, array('center', 'top', 'bottom', 'inherit', 'initial', 'unset'))) {
|
||||
return $value;
|
||||
}
|
||||
return "left {$value}";
|
||||
}
|
||||
if ($values[1] == 'top' or $values[1] == 'bottom') {
|
||||
if ($values[0] === 'center') {
|
||||
return $value;
|
||||
}
|
||||
return 'left ' . \implode(' ', $values);
|
||||
} else {
|
||||
$last = \array_pop($values);
|
||||
if ($last === 'center') {
|
||||
return $value;
|
||||
}
|
||||
return \implode(' ', $values) . ' left ' . $last;
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
namespace MailPoetVendor;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
class csstidy_print
|
||||
{
|
||||
public $parser;
|
||||
public $input_css = '';
|
||||
public $output_css = '';
|
||||
public $output_css_plain = '';
|
||||
public $css;
|
||||
public $template;
|
||||
public $tokens;
|
||||
public $charset;
|
||||
public $import;
|
||||
public $namespace;
|
||||
public function __construct($css)
|
||||
{
|
||||
$this->parser = $css;
|
||||
$this->css =& $css->css;
|
||||
$this->template =& $css->template;
|
||||
$this->tokens =& $css->tokens;
|
||||
$this->charset =& $css->charset;
|
||||
$this->import =& $css->import;
|
||||
$this->namespace =& $css->namespace;
|
||||
}
|
||||
public function _reset()
|
||||
{
|
||||
$this->output_css = '';
|
||||
$this->output_css_plain = '';
|
||||
}
|
||||
public function plain($default_media = '')
|
||||
{
|
||||
$this->_print(\true, $default_media);
|
||||
return $this->output_css_plain;
|
||||
}
|
||||
public function formatted($default_media = '')
|
||||
{
|
||||
$this->_print(\false, $default_media);
|
||||
return $this->output_css;
|
||||
}
|
||||
public function formatted_page($doctype = 'html5', $externalcss = \true, $title = '', $lang = 'en')
|
||||
{
|
||||
switch ($doctype) {
|
||||
case 'html5':
|
||||
$doctype_output = '<!DOCTYPE html>';
|
||||
break;
|
||||
case 'xhtml1.0strict':
|
||||
$doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
|
||||
break;
|
||||
case 'xhtml1.1':
|
||||
default:
|
||||
$doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
|
||||
break;
|
||||
}
|
||||
$output = $cssparsed = '';
|
||||
$this->output_css_plain =& $output;
|
||||
$output .= $doctype_output . "\n" . '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="' . $lang . '"';
|
||||
$output .= $doctype === 'xhtml1.1' ? '>' : ' lang="' . $lang . '">';
|
||||
$output .= "\n<head>\n <title>{$title}</title>";
|
||||
if ($externalcss) {
|
||||
$output .= "\n <style type=\"text/css\">\n";
|
||||
$cssparsed = \file_get_contents('cssparsed.css');
|
||||
$output .= $cssparsed;
|
||||
// Adds an invisible BOM or something, but not in css_optimised.php
|
||||
$output .= "\n</style>";
|
||||
} else {
|
||||
$output .= "\n" . ' <link rel="stylesheet" type="text/css" href="cssparsed.css" />';
|
||||
}
|
||||
$output .= "\n</head>\n<body><code id=\"copytext\">";
|
||||
$output .= $this->formatted();
|
||||
$output .= '</code>' . "\n" . '</body></html>';
|
||||
return $this->output_css_plain;
|
||||
}
|
||||
public function _print($plain = \false, $default_media = '')
|
||||
{
|
||||
if ($this->output_css && $this->output_css_plain) {
|
||||
return;
|
||||
}
|
||||
$output = '';
|
||||
if (!$this->parser->get_cfg('preserve_css')) {
|
||||
$this->_convert_raw_css($default_media);
|
||||
}
|
||||
$template =& $this->template;
|
||||
if ($plain) {
|
||||
$template = \array_map('strip_tags', $template);
|
||||
}
|
||||
if ($this->parser->get_cfg('timestamp')) {
|
||||
\array_unshift($this->tokens, array(\COMMENT, ' CSSTidy ' . $this->parser->version . ': ' . \date('r') . ' '));
|
||||
}
|
||||
if (!empty($this->charset)) {
|
||||
$output .= $template[0] . '@charset ' . $template[5] . $this->charset . $template[6] . $template[13];
|
||||
}
|
||||
if (!empty($this->import)) {
|
||||
for ($i = 0, $size = \count($this->import); $i < $size; $i++) {
|
||||
if (\substr($this->import[$i], 0, 4) === 'url(' && \substr($this->import[$i], -1, 1) === ')') {
|
||||
$this->import[$i] = '"' . \substr($this->import[$i], 4, -1) . '"';
|
||||
$this->parser->log('Optimised @import : Removed "url("', 'Information');
|
||||
} else {
|
||||
if (!\preg_match('/^".+"$/', $this->import[$i])) {
|
||||
// fixes a bug for @import ".." instead of the expected @import url("..")
|
||||
// If it comes in due to @import ".." the "" will be missing and the output will become @import .. (which is an error)
|
||||
$this->import[$i] = '"' . $this->import[$i] . '"';
|
||||
}
|
||||
}
|
||||
$output .= $template[0] . '@import ' . $template[5] . $this->import[$i] . $template[6] . $template[13];
|
||||
}
|
||||
}
|
||||
if (!empty($this->namespace)) {
|
||||
if (($p = \strpos($this->namespace, "url(")) !== \false && \substr($this->namespace, -1, 1) === ')') {
|
||||
$this->namespace = \substr_replace($this->namespace, '"', $p, 4);
|
||||
$this->namespace = \substr($this->namespace, 0, -1) . '"';
|
||||
$this->parser->log('Optimised @namespace : Removed "url("', 'Information');
|
||||
}
|
||||
$output .= $template[0] . '@namespace ' . $template[5] . $this->namespace . $template[6] . $template[13];
|
||||
}
|
||||
$in_at_out = [];
|
||||
$out =& $output;
|
||||
$indent_level = 0;
|
||||
foreach ($this->tokens as $key => $token) {
|
||||
switch ($token[0]) {
|
||||
case \AT_START:
|
||||
$out .= $template[0] . $this->_htmlsp($token[1], $plain) . $template[1];
|
||||
$indent_level++;
|
||||
if (!isset($in_at_out[$indent_level])) {
|
||||
$in_at_out[$indent_level] = '';
|
||||
}
|
||||
$out =& $in_at_out[$indent_level];
|
||||
break;
|
||||
case \SEL_START:
|
||||
if ($this->parser->get_cfg('lowercase_s')) {
|
||||
$token[1] = \strtolower($token[1]);
|
||||
}
|
||||
$out .= $token[1][0] !== '@' ? $template[2] . $this->_htmlsp($token[1], $plain) : $template[0] . $this->_htmlsp($token[1], $plain);
|
||||
$out .= $template[3];
|
||||
break;
|
||||
case \PROPERTY:
|
||||
if ($this->parser->get_cfg('case_properties') === 2) {
|
||||
$token[1] = \strtoupper($token[1]);
|
||||
} elseif ($this->parser->get_cfg('case_properties') === 1) {
|
||||
$token[1] = \strtolower($token[1]);
|
||||
}
|
||||
$out .= $template[4] . $this->_htmlsp($token[1], $plain) . ':' . $template[5];
|
||||
break;
|
||||
case \VALUE:
|
||||
$out .= $this->_htmlsp($token[1], $plain);
|
||||
if ($this->_seeknocomment($key, 1) == \SEL_END && $this->parser->get_cfg('remove_last_;')) {
|
||||
$out .= \str_replace(';', '', $template[6]);
|
||||
} else {
|
||||
$out .= $template[6];
|
||||
}
|
||||
break;
|
||||
case \SEL_END:
|
||||
$out .= $template[7];
|
||||
if ($this->_seeknocomment($key, 1) != \AT_END) {
|
||||
$out .= $template[8];
|
||||
}
|
||||
break;
|
||||
case \AT_END:
|
||||
if (\strlen($template[10])) {
|
||||
// indent the bloc we are closing
|
||||
$out = \str_replace("\n\n", "\r\n", $out);
|
||||
// don't fill empty lines
|
||||
$out = \str_replace("\n", "\n" . $template[10], $out);
|
||||
$out = \str_replace("\r\n", "\n\n", $out);
|
||||
}
|
||||
if ($indent_level > 1) {
|
||||
$out =& $in_at_out[$indent_level - 1];
|
||||
} else {
|
||||
$out =& $output;
|
||||
}
|
||||
$out .= $template[10] . $in_at_out[$indent_level];
|
||||
if ($this->_seeknocomment($key, 1) != \AT_END) {
|
||||
$out .= $template[9];
|
||||
} else {
|
||||
$out .= \rtrim($template[9]);
|
||||
}
|
||||
unset($in_at_out[$indent_level]);
|
||||
$indent_level--;
|
||||
break;
|
||||
case \IMPORTANT_COMMENT:
|
||||
case \COMMENT:
|
||||
$out .= $template[11] . '/*' . $this->_htmlsp($token[1], $plain) . '*/' . $template[12];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$output = \trim($output);
|
||||
if (!$plain) {
|
||||
$this->output_css = $output;
|
||||
$this->_print(\true);
|
||||
} else {
|
||||
// If using spaces in the template, don't want these to appear in the plain output
|
||||
$this->output_css_plain = \str_replace(' ', '', $output);
|
||||
}
|
||||
}
|
||||
public function _seeknocomment($key, $move)
|
||||
{
|
||||
$go = $move > 0 ? 1 : -1;
|
||||
for ($i = $key + 1; \abs($key - $i) - 1 < \abs($move); $i += $go) {
|
||||
if (!isset($this->tokens[$i])) {
|
||||
return;
|
||||
}
|
||||
if ($this->tokens[$i][0] == \COMMENT) {
|
||||
$move += 1;
|
||||
continue;
|
||||
}
|
||||
return $this->tokens[$i][0];
|
||||
}
|
||||
}
|
||||
public function _convert_raw_css($default_media = '')
|
||||
{
|
||||
$this->tokens = array();
|
||||
$sort_selectors = $this->parser->get_cfg('sort_selectors');
|
||||
$sort_properties = $this->parser->get_cfg('sort_properties');
|
||||
// important comment section ?
|
||||
if (isset($this->css['!'])) {
|
||||
$this->parser->_add_token(\IMPORTANT_COMMENT, \rtrim($this->css['!']), \true);
|
||||
unset($this->css['!']);
|
||||
}
|
||||
foreach ($this->css as $medium => $val) {
|
||||
if ($sort_selectors) {
|
||||
\ksort($val);
|
||||
}
|
||||
if (\intval($medium) < \DEFAULT_AT) {
|
||||
// un medium vide (contenant @font-face ou autre @) ne produit aucun conteneur
|
||||
if (\strlen(\trim($medium))) {
|
||||
$parts_to_open = \explode('{', $medium);
|
||||
foreach ($parts_to_open as $part) {
|
||||
$this->parser->_add_token(\AT_START, $part, \true);
|
||||
}
|
||||
}
|
||||
} elseif ($default_media) {
|
||||
$this->parser->_add_token(\AT_START, $default_media, \true);
|
||||
}
|
||||
foreach ($val as $selector => $vali) {
|
||||
if ($sort_properties) {
|
||||
\ksort($vali);
|
||||
}
|
||||
$this->parser->_add_token(\SEL_START, $selector, \true);
|
||||
$invalid = array(
|
||||
'*' => array(),
|
||||
// IE7 hacks first
|
||||
'_' => array(),
|
||||
// IE6 hacks
|
||||
'/' => array(),
|
||||
// IE6 hacks
|
||||
'-' => array(),
|
||||
);
|
||||
foreach ($vali as $property => $valj) {
|
||||
if (\strncmp($property, "//", 2) !== 0) {
|
||||
$matches = array();
|
||||
if ($sort_properties && \preg_match('/^(\\*|_|\\/|-)(?!(ms|moz|o\\b|xv|atsc|wap|khtml|webkit|ah|hp|ro|rim|tc)-)/', $property, $matches)) {
|
||||
$invalid[$matches[1]][$property] = $valj;
|
||||
} else {
|
||||
$this->parser->_add_token(\PROPERTY, $property, \true);
|
||||
$this->parser->_add_token(\VALUE, $valj, \true);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($invalid as $prefix => $props) {
|
||||
foreach ($props as $property => $valj) {
|
||||
$this->parser->_add_token(\PROPERTY, $property, \true);
|
||||
$this->parser->_add_token(\VALUE, $valj, \true);
|
||||
}
|
||||
}
|
||||
$this->parser->_add_token(\SEL_END, $selector, \true);
|
||||
}
|
||||
if (\intval($medium) < \DEFAULT_AT) {
|
||||
// un medium vide (contenant @font-face ou autre @) ne produit aucun conteneur
|
||||
if (\strlen(\trim($medium))) {
|
||||
$parts_to_close = \explode('{', $medium);
|
||||
foreach (\array_reverse($parts_to_close) as $part) {
|
||||
$this->parser->_add_token(\AT_END, $part, \true);
|
||||
}
|
||||
}
|
||||
} elseif ($default_media) {
|
||||
$this->parser->_add_token(\AT_END, $default_media, \true);
|
||||
}
|
||||
}
|
||||
}
|
||||
public function _htmlsp($string, $plain)
|
||||
{
|
||||
if (!$plain) {
|
||||
return \htmlspecialchars($string, \ENT_QUOTES, 'utf-8');
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
public function get_ratio()
|
||||
{
|
||||
if (!$this->output_css_plain) {
|
||||
$this->formatted();
|
||||
}
|
||||
return \round((\strlen($this->input_css) - \strlen($this->output_css_plain)) / \strlen($this->input_css), 3) * 100;
|
||||
}
|
||||
public function get_diff()
|
||||
{
|
||||
if (!$this->output_css_plain) {
|
||||
$this->formatted();
|
||||
}
|
||||
$diff = \strlen($this->output_css_plain) - \strlen($this->input_css);
|
||||
if ($diff > 0) {
|
||||
return '+' . $diff;
|
||||
} elseif ($diff == 0) {
|
||||
return '+-' . $diff;
|
||||
}
|
||||
return $diff;
|
||||
}
|
||||
public function size($loc = 'output')
|
||||
{
|
||||
if ($loc === 'output' && !$this->output_css) {
|
||||
$this->formatted();
|
||||
}
|
||||
if ($loc === 'input') {
|
||||
return \strlen($this->input_css) / 1000;
|
||||
} else {
|
||||
return \strlen($this->output_css_plain) / 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
@import "cssparsed.css";
|
||||
|
||||
html,body {
|
||||
font:.8em Verdana,Helvetica,sans-serif;
|
||||
background:#f8f8f6
|
||||
}
|
||||
|
||||
code {
|
||||
font-size:1.2em
|
||||
}
|
||||
|
||||
div#rightcol {
|
||||
padding-left:32em
|
||||
}
|
||||
|
||||
fieldset {
|
||||
display:block;
|
||||
margin:.5em 0;
|
||||
padding:1em;
|
||||
border:solid #7284ab 2px
|
||||
}
|
||||
|
||||
fieldset.code_output {
|
||||
display:inline
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size:2em
|
||||
}
|
||||
|
||||
small {
|
||||
font-size:.7em
|
||||
}
|
||||
|
||||
fieldset#field_input {
|
||||
float:left;
|
||||
margin:0 .5em 1em 0
|
||||
}
|
||||
|
||||
fieldset#options,fieldset#code_layout {
|
||||
width:31em
|
||||
}
|
||||
|
||||
input#submit {
|
||||
clear:both;
|
||||
display:block;
|
||||
margin:1em
|
||||
}
|
||||
|
||||
select {
|
||||
margin:2px 0 0
|
||||
}
|
||||
|
||||
label.block {
|
||||
display:block
|
||||
}
|
||||
|
||||
legend {
|
||||
background:#c4e1c3;
|
||||
padding:2px 4px;
|
||||
border:dashed 1px
|
||||
}
|
||||
|
||||
textarea#css_text {
|
||||
width:27em;
|
||||
height:370px;
|
||||
display:block;
|
||||
margin-right:1em
|
||||
}
|
||||
|
||||
.help {
|
||||
cursor:help
|
||||
}
|
||||
|
||||
p.important {
|
||||
border:solid 1px red;
|
||||
font-weight:700;
|
||||
padding:1em;
|
||||
background:#fff
|
||||
}
|
||||
|
||||
p {
|
||||
margin:1em 0
|
||||
}
|
||||
|
||||
dl {
|
||||
padding-left:.5em
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight:700;
|
||||
margin:0;
|
||||
float:left;
|
||||
clear:both;
|
||||
height:1.5em
|
||||
}
|
||||
|
||||
dd {
|
||||
margin:0 0 0 4em;
|
||||
height:1.5em
|
||||
}
|
||||
|
||||
fieldset#messages {
|
||||
background:#fff;
|
||||
padding:0 0 0 1em
|
||||
}
|
||||
|
||||
fieldset#messages div {
|
||||
height:10em;
|
||||
overflow:auto
|
||||
}
|
||||
|
||||
dd.Warning {
|
||||
color:orange
|
||||
}
|
||||
|
||||
dd.Information {
|
||||
color:green
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
code#copytext {
|
||||
white-space:pre;
|
||||
font-family:Verdana
|
||||
}
|
||||
|
||||
.at {
|
||||
color:#00008b
|
||||
}
|
||||
|
||||
.format {
|
||||
color:gray
|
||||
}
|
||||
|
||||
.property {
|
||||
color:green
|
||||
}
|
||||
|
||||
.selector {
|
||||
color:blue
|
||||
}
|
||||
|
||||
.value {
|
||||
color:red;
|
||||
left:500px
|
||||
}
|
||||
|
||||
.comment {
|
||||
color:orange
|
||||
}
|
||||
@@ -0,0 +1,529 @@
|
||||
<?php
|
||||
namespace MailPoetVendor;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
$data['csstidy']['whitespace'] = array(' ', "\n", "\t", "\r", "\v");
|
||||
$data['csstidy']['tokens'] = '/@}{;:=\'"(,\\!$%&)*+.<>?[]^`|~';
|
||||
$data['csstidy']['units'] = array('in', 'cm', 'mm', 'pt', 'pc', 'px', 'rem', 'em', '%', 'ex', 'gd', 'vw', 'vh', 'vm', 'deg', 'grad', 'rad', 'turn', 'ms', 's', 'khz', 'hz', 'ch', 'vmin', 'vmax', 'dpi', 'dpcm', 'dppx');
|
||||
$data['csstidy']['at_rules'] = array('page' => 'is', 'font-face' => 'atis', 'charset' => 'iv', 'import' => 'iv', 'namespace' => 'iv', 'media' => 'at', 'supports' => 'at', 'keyframes' => 'at', '-moz-keyframes' => 'at', '-o-keyframes' => 'at', '-webkit-keyframes' => 'at', '-ms-keyframes' => 'at');
|
||||
$data['csstidy']['unit_values'] = array('background', 'background-position', 'background-size', 'border', 'border-top', 'border-right', 'border-bottom', 'border-left', 'border-width', 'border-top-width', 'border-right-width', 'border-left-width', 'border-bottom-width', 'bottom', 'border-spacing', 'column-gap', 'column-width', 'font-size', 'height', 'left', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'max-height', 'max-width', 'min-height', 'min-width', 'outline', 'outline-width', 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left', 'perspective', 'right', 'top', 'text-indent', 'letter-spacing', 'word-spacing', 'width');
|
||||
$data['csstidy']['color_values'] = array();
|
||||
$data['csstidy']['color_values'][] = 'background-color';
|
||||
$data['csstidy']['color_values'][] = 'border-color';
|
||||
$data['csstidy']['color_values'][] = 'border-top-color';
|
||||
$data['csstidy']['color_values'][] = 'border-right-color';
|
||||
$data['csstidy']['color_values'][] = 'border-bottom-color';
|
||||
$data['csstidy']['color_values'][] = 'border-left-color';
|
||||
$data['csstidy']['color_values'][] = 'color';
|
||||
$data['csstidy']['color_values'][] = 'outline-color';
|
||||
$data['csstidy']['color_values'][] = 'column-rule-color';
|
||||
$data['csstidy']['background_prop_default'] = array();
|
||||
$data['csstidy']['background_prop_default']['background-image'] = 'none';
|
||||
$data['csstidy']['background_prop_default']['background-size'] = 'auto';
|
||||
$data['csstidy']['background_prop_default']['background-repeat'] = 'repeat';
|
||||
$data['csstidy']['background_prop_default']['background-position'] = '0 0';
|
||||
$data['csstidy']['background_prop_default']['background-attachment'] = 'scroll';
|
||||
$data['csstidy']['background_prop_default']['background-clip'] = 'border';
|
||||
$data['csstidy']['background_prop_default']['background-origin'] = 'padding';
|
||||
$data['csstidy']['background_prop_default']['background-color'] = 'transparent';
|
||||
$data['csstidy']['font_prop_default'] = array();
|
||||
$data['csstidy']['font_prop_default']['font-style'] = 'normal';
|
||||
$data['csstidy']['font_prop_default']['font-variant'] = 'normal';
|
||||
$data['csstidy']['font_prop_default']['font-weight'] = 'normal';
|
||||
$data['csstidy']['font_prop_default']['font-size'] = '';
|
||||
$data['csstidy']['font_prop_default']['line-height'] = '';
|
||||
$data['csstidy']['font_prop_default']['font-family'] = '';
|
||||
$data['csstidy']['replace_colors'] = array();
|
||||
$data['csstidy']['replace_colors']['aliceblue'] = '#f0f8ff';
|
||||
$data['csstidy']['replace_colors']['antiquewhite'] = '#faebd7';
|
||||
$data['csstidy']['replace_colors']['aquamarine'] = '#7fffd4';
|
||||
$data['csstidy']['replace_colors']['azure'] = '#f0ffff';
|
||||
$data['csstidy']['replace_colors']['beige'] = '#f5f5dc';
|
||||
$data['csstidy']['replace_colors']['bisque'] = '#ffe4c4';
|
||||
$data['csstidy']['replace_colors']['blanchedalmond'] = '#ffebcd';
|
||||
$data['csstidy']['replace_colors']['blueviolet'] = '#8a2be2';
|
||||
$data['csstidy']['replace_colors']['brown'] = '#a52a2a';
|
||||
$data['csstidy']['replace_colors']['burlywood'] = '#deb887';
|
||||
$data['csstidy']['replace_colors']['cadetblue'] = '#5f9ea0';
|
||||
$data['csstidy']['replace_colors']['chartreuse'] = '#7fff00';
|
||||
$data['csstidy']['replace_colors']['chocolate'] = '#d2691e';
|
||||
$data['csstidy']['replace_colors']['coral'] = '#ff7f50';
|
||||
$data['csstidy']['replace_colors']['cornflowerblue'] = '#6495ed';
|
||||
$data['csstidy']['replace_colors']['cornsilk'] = '#fff8dc';
|
||||
$data['csstidy']['replace_colors']['crimson'] = '#dc143c';
|
||||
$data['csstidy']['replace_colors']['cyan'] = '#00ffff';
|
||||
$data['csstidy']['replace_colors']['darkblue'] = '#00008b';
|
||||
$data['csstidy']['replace_colors']['darkcyan'] = '#008b8b';
|
||||
$data['csstidy']['replace_colors']['darkgoldenrod'] = '#b8860b';
|
||||
$data['csstidy']['replace_colors']['darkgray'] = '#a9a9a9';
|
||||
$data['csstidy']['replace_colors']['darkgreen'] = '#006400';
|
||||
$data['csstidy']['replace_colors']['darkkhaki'] = '#bdb76b';
|
||||
$data['csstidy']['replace_colors']['darkmagenta'] = '#8b008b';
|
||||
$data['csstidy']['replace_colors']['darkolivegreen'] = '#556b2f';
|
||||
$data['csstidy']['replace_colors']['darkorange'] = '#ff8c00';
|
||||
$data['csstidy']['replace_colors']['darkorchid'] = '#9932cc';
|
||||
$data['csstidy']['replace_colors']['darkred'] = '#8b0000';
|
||||
$data['csstidy']['replace_colors']['darksalmon'] = '#e9967a';
|
||||
$data['csstidy']['replace_colors']['darkseagreen'] = '#8fbc8f';
|
||||
$data['csstidy']['replace_colors']['darkslateblue'] = '#483d8b';
|
||||
$data['csstidy']['replace_colors']['darkslategray'] = '#2f4f4f';
|
||||
$data['csstidy']['replace_colors']['darkturquoise'] = '#00ced1';
|
||||
$data['csstidy']['replace_colors']['darkviolet'] = '#9400d3';
|
||||
$data['csstidy']['replace_colors']['deeppink'] = '#ff1493';
|
||||
$data['csstidy']['replace_colors']['deepskyblue'] = '#00bfff';
|
||||
$data['csstidy']['replace_colors']['dimgray'] = '#696969';
|
||||
$data['csstidy']['replace_colors']['dodgerblue'] = '#1e90ff';
|
||||
$data['csstidy']['replace_colors']['feldspar'] = '#d19275';
|
||||
$data['csstidy']['replace_colors']['firebrick'] = '#b22222';
|
||||
$data['csstidy']['replace_colors']['floralwhite'] = '#fffaf0';
|
||||
$data['csstidy']['replace_colors']['forestgreen'] = '#228b22';
|
||||
$data['csstidy']['replace_colors']['gainsboro'] = '#dcdcdc';
|
||||
$data['csstidy']['replace_colors']['ghostwhite'] = '#f8f8ff';
|
||||
$data['csstidy']['replace_colors']['gold'] = '#ffd700';
|
||||
$data['csstidy']['replace_colors']['goldenrod'] = '#daa520';
|
||||
$data['csstidy']['replace_colors']['greenyellow'] = '#adff2f';
|
||||
$data['csstidy']['replace_colors']['honeydew'] = '#f0fff0';
|
||||
$data['csstidy']['replace_colors']['hotpink'] = '#ff69b4';
|
||||
$data['csstidy']['replace_colors']['indianred'] = '#cd5c5c';
|
||||
$data['csstidy']['replace_colors']['indigo'] = '#4b0082';
|
||||
$data['csstidy']['replace_colors']['ivory'] = '#fffff0';
|
||||
$data['csstidy']['replace_colors']['khaki'] = '#f0e68c';
|
||||
$data['csstidy']['replace_colors']['lavender'] = '#e6e6fa';
|
||||
$data['csstidy']['replace_colors']['lavenderblush'] = '#fff0f5';
|
||||
$data['csstidy']['replace_colors']['lawngreen'] = '#7cfc00';
|
||||
$data['csstidy']['replace_colors']['lemonchiffon'] = '#fffacd';
|
||||
$data['csstidy']['replace_colors']['lightblue'] = '#add8e6';
|
||||
$data['csstidy']['replace_colors']['lightcoral'] = '#f08080';
|
||||
$data['csstidy']['replace_colors']['lightcyan'] = '#e0ffff';
|
||||
$data['csstidy']['replace_colors']['lightgoldenrodyellow'] = '#fafad2';
|
||||
$data['csstidy']['replace_colors']['lightgrey'] = '#d3d3d3';
|
||||
$data['csstidy']['replace_colors']['lightgreen'] = '#90ee90';
|
||||
$data['csstidy']['replace_colors']['lightpink'] = '#ffb6c1';
|
||||
$data['csstidy']['replace_colors']['lightsalmon'] = '#ffa07a';
|
||||
$data['csstidy']['replace_colors']['lightseagreen'] = '#20b2aa';
|
||||
$data['csstidy']['replace_colors']['lightskyblue'] = '#87cefa';
|
||||
$data['csstidy']['replace_colors']['lightslateblue'] = '#8470ff';
|
||||
$data['csstidy']['replace_colors']['lightslategray'] = '#778899';
|
||||
$data['csstidy']['replace_colors']['lightsteelblue'] = '#b0c4de';
|
||||
$data['csstidy']['replace_colors']['lightyellow'] = '#ffffe0';
|
||||
$data['csstidy']['replace_colors']['limegreen'] = '#32cd32';
|
||||
$data['csstidy']['replace_colors']['linen'] = '#faf0e6';
|
||||
$data['csstidy']['replace_colors']['magenta'] = '#ff00ff';
|
||||
$data['csstidy']['replace_colors']['mediumaquamarine'] = '#66cdaa';
|
||||
$data['csstidy']['replace_colors']['mediumblue'] = '#0000cd';
|
||||
$data['csstidy']['replace_colors']['mediumorchid'] = '#ba55d3';
|
||||
$data['csstidy']['replace_colors']['mediumpurple'] = '#9370d8';
|
||||
$data['csstidy']['replace_colors']['mediumseagreen'] = '#3cb371';
|
||||
$data['csstidy']['replace_colors']['mediumslateblue'] = '#7b68ee';
|
||||
$data['csstidy']['replace_colors']['mediumspringgreen'] = '#00fa9a';
|
||||
$data['csstidy']['replace_colors']['mediumturquoise'] = '#48d1cc';
|
||||
$data['csstidy']['replace_colors']['mediumvioletred'] = '#c71585';
|
||||
$data['csstidy']['replace_colors']['midnightblue'] = '#191970';
|
||||
$data['csstidy']['replace_colors']['mintcream'] = '#f5fffa';
|
||||
$data['csstidy']['replace_colors']['mistyrose'] = '#ffe4e1';
|
||||
$data['csstidy']['replace_colors']['moccasin'] = '#ffe4b5';
|
||||
$data['csstidy']['replace_colors']['navajowhite'] = '#ffdead';
|
||||
$data['csstidy']['replace_colors']['oldlace'] = '#fdf5e6';
|
||||
$data['csstidy']['replace_colors']['olivedrab'] = '#6b8e23';
|
||||
$data['csstidy']['replace_colors']['orangered'] = '#ff4500';
|
||||
$data['csstidy']['replace_colors']['orchid'] = '#da70d6';
|
||||
$data['csstidy']['replace_colors']['palegoldenrod'] = '#eee8aa';
|
||||
$data['csstidy']['replace_colors']['palegreen'] = '#98fb98';
|
||||
$data['csstidy']['replace_colors']['paleturquoise'] = '#afeeee';
|
||||
$data['csstidy']['replace_colors']['palevioletred'] = '#d87093';
|
||||
$data['csstidy']['replace_colors']['papayawhip'] = '#ffefd5';
|
||||
$data['csstidy']['replace_colors']['peachpuff'] = '#ffdab9';
|
||||
$data['csstidy']['replace_colors']['peru'] = '#cd853f';
|
||||
$data['csstidy']['replace_colors']['pink'] = '#ffc0cb';
|
||||
$data['csstidy']['replace_colors']['plum'] = '#dda0dd';
|
||||
$data['csstidy']['replace_colors']['powderblue'] = '#b0e0e6';
|
||||
$data['csstidy']['replace_colors']['rosybrown'] = '#bc8f8f';
|
||||
$data['csstidy']['replace_colors']['royalblue'] = '#4169e1';
|
||||
$data['csstidy']['replace_colors']['saddlebrown'] = '#8b4513';
|
||||
$data['csstidy']['replace_colors']['salmon'] = '#fa8072';
|
||||
$data['csstidy']['replace_colors']['sandybrown'] = '#f4a460';
|
||||
$data['csstidy']['replace_colors']['seagreen'] = '#2e8b57';
|
||||
$data['csstidy']['replace_colors']['seashell'] = '#fff5ee';
|
||||
$data['csstidy']['replace_colors']['sienna'] = '#a0522d';
|
||||
$data['csstidy']['replace_colors']['skyblue'] = '#87ceeb';
|
||||
$data['csstidy']['replace_colors']['slateblue'] = '#6a5acd';
|
||||
$data['csstidy']['replace_colors']['slategray'] = '#708090';
|
||||
$data['csstidy']['replace_colors']['snow'] = '#fffafa';
|
||||
$data['csstidy']['replace_colors']['springgreen'] = '#00ff7f';
|
||||
$data['csstidy']['replace_colors']['steelblue'] = '#4682b4';
|
||||
$data['csstidy']['replace_colors']['tan'] = '#d2b48c';
|
||||
$data['csstidy']['replace_colors']['thistle'] = '#d8bfd8';
|
||||
$data['csstidy']['replace_colors']['tomato'] = '#ff6347';
|
||||
$data['csstidy']['replace_colors']['turquoise'] = '#40e0d0';
|
||||
$data['csstidy']['replace_colors']['violet'] = '#ee82ee';
|
||||
$data['csstidy']['replace_colors']['violetred'] = '#d02090';
|
||||
$data['csstidy']['replace_colors']['wheat'] = '#f5deb3';
|
||||
$data['csstidy']['replace_colors']['whitesmoke'] = '#f5f5f5';
|
||||
$data['csstidy']['replace_colors']['yellowgreen'] = '#9acd32';
|
||||
$data['csstidy']['shorthands'] = array();
|
||||
$data['csstidy']['shorthands']['border-color'] = array('border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color');
|
||||
$data['csstidy']['shorthands']['border-style'] = array('border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style');
|
||||
$data['csstidy']['shorthands']['border-width'] = array('border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width');
|
||||
$data['csstidy']['shorthands']['margin'] = array('margin-top', 'margin-right', 'margin-bottom', 'margin-left');
|
||||
$data['csstidy']['shorthands']['padding'] = array('padding-top', 'padding-right', 'padding-bottom', 'padding-left');
|
||||
$data['csstidy']['radius_shorthands']['border-radius'] = array('border-top-left-radius', 'border-top-right-radius', 'border-bottom-right-radius', 'border-bottom-left-radius');
|
||||
$data['csstidy']['radius_shorthands']['-webkit-border-radius'] = array('-webkit-border-top-left-radius', '-webkit-border-top-right-radius', '-webkit-border-bottom-right-radius', '-webkit-border-bottom-left-radius');
|
||||
$data['csstidy']['radius_shorthands']['-moz-border-radius'] = array('-moz-border-radius-topleft', '-moz-border-radius-topright', '-moz-border-radius-bottomright', '-moz-border-radius-bottomleft');
|
||||
$data['csstidy']['all_properties']['alignment-adjust'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['alignment-baseline'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['animation'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['animation-delay'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['animation-direction'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['animation-duration'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['animation-iteration-count'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['animation-name'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['animation-play-state'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['animation-timing-function'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['appearance'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['azimuth'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['backface-visibility'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['background'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['background-attachment'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['background-clip'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['background-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['background-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['background-origin'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['background-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['background-repeat'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['background-size'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['baseline-shift'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['binding'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['bleed'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['bookmark-label'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['bookmark-level'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['bookmark-state'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['bookmark-target'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-bottom-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-bottom-left-radius'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-bottom-right-radius'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-bottom-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-bottom-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-collapse'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-image'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-image-outset'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-image-repeat'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-image-slice'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-image-source'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-image-width'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-left-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-left-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-left-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-radius'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-right-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-right-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-right-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-spacing'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-top-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-top-left-radius'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-top-right-radius'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-top-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-top-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['border-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['bottom'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['box-decoration-break'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['box-shadow'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['box-sizing'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['break-after'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['break-before'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['break-inside'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['caption-side'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['clear'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['clip'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['color-profile'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['column-count'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['column-fill'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['column-gap'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['column-rule'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['column-rule-color'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['column-rule-style'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['column-rule-width'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['column-span'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['column-width'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['columns'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['content'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['counter-increment'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['counter-reset'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['crop'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['cue'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['cue-after'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['cue-before'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['cursor'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['direction'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['display'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['dominant-baseline'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['drop-initial-after-adjust'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['drop-initial-after-align'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['drop-initial-before-adjust'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['drop-initial-before-align'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['drop-initial-size'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['drop-initial-value'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['elevation'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['empty-cells'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['fit'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['fit-position'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['flex-align'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['flex-flow'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['flex-line-pack'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['flex-order'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['flex-pack'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['float'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['float-offset'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['font'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['font-family'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['font-size'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['font-size-adjust'] = 'CSS2.0,CSS3.0';
|
||||
$data['csstidy']['all_properties']['font-stretch'] = 'CSS2.0,CSS3.0';
|
||||
$data['csstidy']['all_properties']['font-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['font-variant'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['font-weight'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['grid-columns'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['grid-rows'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['hanging-punctuation'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['hyphenate-after'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['hyphenate-before'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['hyphenate-character'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['hyphenate-lines'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['hyphenate-resource'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['hyphens'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['icon'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['image-orientation'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['image-rendering'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['image-resolution'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['inline-box-align'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['left'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['letter-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['line-break'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['line-height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['line-stacking'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['line-stacking-ruby'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['line-stacking-shift'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['line-stacking-strategy'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['list-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['list-style-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['list-style-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['list-style-type'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['margin'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['margin-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['margin-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['margin-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['margin-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['marker-offset'] = 'CSS2.0,CSS3.0';
|
||||
$data['csstidy']['all_properties']['marks'] = 'CSS2.0,CSS3.0';
|
||||
$data['csstidy']['all_properties']['marquee-direction'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['marquee-loop'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['marquee-play-count'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['marquee-speed'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['marquee-style'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['max-height'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['max-width'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['min-height'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['min-width'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['move-to'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['nav-down'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['nav-index'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['nav-left'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['nav-right'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['nav-up'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['opacity'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['orphans'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['outline'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['outline-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['outline-offset'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['outline-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['outline-width'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['overflow'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['overflow-style'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['overflow-wrap'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['overflow-x'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['overflow-y'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['padding'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['padding-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['padding-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['padding-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['padding-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['page'] = 'CSS2.0,CSS3.0';
|
||||
$data['csstidy']['all_properties']['page-break-after'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['page-break-before'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['page-break-inside'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['page-policy'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['pause'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['pause-after'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['pause-before'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['perspective'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['perspective-origin'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['phonemes'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['pitch'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['pitch-range'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['play-during'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['position'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['presentation-level'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['punctuation-trim'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['quotes'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['rendering-intent'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['resize'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['rest'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['rest-after'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['rest-before'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['richness'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['right'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['rotation'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['rotation-point'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['ruby-align'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['ruby-overhang'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['ruby-position'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['ruby-span'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['size'] = 'CSS2.0,CSS3.0';
|
||||
$data['csstidy']['all_properties']['speak'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['speak-header'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['speak-numeral'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['speak-punctuation'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['speech-rate'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['src'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['stress'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['string-set'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['tab-size'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['table-layout'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['target'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['target-name'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['target-new'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['target-position'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-align-last'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-decoration'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-decoration-color'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-decoration-line'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-decoration-skip'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-decoration-style'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-emphasis'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-emphasis-color'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-emphasis-position'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-emphasis-style'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-height'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-indent'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-justify'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-outline'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-shadow'] = 'CSS2.0,CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-space-collapse'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-transform'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-underline-position'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['text-wrap'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['top'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['transform'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['transform-origin'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['transform-style'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['transition'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['transition-delay'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['transition-duration'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['transition-property'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['transition-timing-function'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['unicode-bidi'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['vertical-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['visibility'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['voice-balance'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['voice-duration'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['voice-family'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['voice-pitch'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['voice-pitch-range'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['voice-rate'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['voice-stress'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['voice-volume'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['volume'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['white-space'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['widows'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['word-break'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['word-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['word-wrap'] = 'CSS3.0';
|
||||
$data['csstidy']['all_properties']['z-index'] = 'CSS2.0,CSS2.1,CSS3.0';
|
||||
$data['csstidy']['all_properties']['--custom'] = 'CSS3.0';
|
||||
$data['csstidy']['quoted_string_properties'] = array('content', 'font-family', 'quotes');
|
||||
$data['csstidy']['multiple_properties'] = array('background', 'background-image');
|
||||
$data['csstidy']['predefined_templates']['default'][0] = '<span class="at">';
|
||||
//string before @rule
|
||||
$data['csstidy']['predefined_templates']['default'][1] = '</span> <span class="format">{</span>' . "\n";
|
||||
//bracket after @-rule
|
||||
$data['csstidy']['predefined_templates']['default'][2] = '<span class="selector">';
|
||||
//string before selector
|
||||
$data['csstidy']['predefined_templates']['default'][3] = '</span> <span class="format">{</span>' . "\n";
|
||||
//bracket after selector
|
||||
$data['csstidy']['predefined_templates']['default'][4] = '<span class="property">';
|
||||
//string before property
|
||||
$data['csstidy']['predefined_templates']['default'][5] = '</span><span class="value">';
|
||||
//string after property+before value
|
||||
$data['csstidy']['predefined_templates']['default'][6] = '</span><span class="format">;</span>' . "\n";
|
||||
//string after value
|
||||
$data['csstidy']['predefined_templates']['default'][7] = '<span class="format">}</span>';
|
||||
//closing bracket - selector
|
||||
$data['csstidy']['predefined_templates']['default'][8] = "\n\n";
|
||||
//space between blocks {...}
|
||||
$data['csstidy']['predefined_templates']['default'][9] = "\n" . '<span class="format">}</span>' . "\n\n";
|
||||
//closing bracket @-rule
|
||||
$data['csstidy']['predefined_templates']['default'][10] = '';
|
||||
//indent in @-rule
|
||||
$data['csstidy']['predefined_templates']['default'][11] = '<span class="comment">';
|
||||
// before comment
|
||||
$data['csstidy']['predefined_templates']['default'][12] = '</span>' . "\n";
|
||||
// after comment
|
||||
$data['csstidy']['predefined_templates']['default'][13] = "\n";
|
||||
// after each line @-rule
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '<span class="at">';
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '</span> <span class="format">{</span>' . "\n";
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '<span class="selector">';
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">{</span>';
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '<span class="property">';
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="value">';
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">;</span>';
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '<span class="format">}</span>';
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = "\n";
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = "\n" . '<span class="format">}' . "\n" . '</span>';
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '';
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '<span class="comment">';
|
||||
// before comment
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = '</span>' . "\n";
|
||||
// after comment
|
||||
$data['csstidy']['predefined_templates']['high_compression'][] = "\n";
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="at">';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="selector">';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="property">';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="value">';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">;</span>';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '';
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '<span class="comment">';
|
||||
// before comment
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '</span>';
|
||||
// after comment
|
||||
$data['csstidy']['predefined_templates']['highest_compression'][] = '';
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = '<span class="at">';
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = '</span> <span class="format">{</span>' . "\n";
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = '<span class="selector">';
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = '</span>' . "\n" . '<span class="format">{</span>' . "\n";
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = ' <span class="property">';
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="value">';
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="format">;</span>' . "\n";
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = '<span class="format">}</span>';
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = "\n\n";
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = "\n" . '<span class="format">}</span>' . "\n\n";
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = ' ';
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = '<span class="comment">';
|
||||
// before comment
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = '</span>' . "\n";
|
||||
// after comment
|
||||
$data['csstidy']['predefined_templates']['low_compression'][] = "\n";
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
namespace MailPoetVendor;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
if (isset($_GET['lang'])) {
|
||||
$l = $_GET['lang'];
|
||||
} elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
||||
$l = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
||||
$l = \strtolower(\substr($l, 0, 2));
|
||||
} else {
|
||||
$l = '';
|
||||
}
|
||||
$l = \in_array($l, array('de', 'fr', 'zh')) ? $l : 'en';
|
||||
// note 67 in all but English&French, and 5 and 40 in all are orphaned
|
||||
$lang = array();
|
||||
$lang['en'][0] = 'CSS Formatter and Optimiser/Optimizer (based on CSSTidy ';
|
||||
$lang['en'][1] = 'CSS Formatter and Optimiser';
|
||||
$lang['en'][2] = '(based on';
|
||||
$lang['en'][3] = '(plaintext)';
|
||||
$lang['en'][4] = 'Important Note:';
|
||||
$lang['en'][6] = 'Your code should be well-formed. This is <strong>not a validator</strong> which points out errors in your CSS code. To make sure that your code is valid, use the <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
|
||||
$lang['en'][7] = 'all comments are removed';
|
||||
$lang['en'][8] = 'CSS Input:';
|
||||
$lang['en'][9] = 'CSS-Code:';
|
||||
$lang['en'][10] = 'CSS from URL:';
|
||||
$lang['en'][11] = 'Code Layout:';
|
||||
$lang['en'][12] = 'Compression (code layout):';
|
||||
$lang['en'][13] = 'Highest (no readability, smallest size)';
|
||||
$lang['en'][14] = 'High (moderate readability, smaller size)';
|
||||
$lang['en'][15] = 'Standard (balance between readability and size)';
|
||||
$lang['en'][16] = 'Low (higher readability)';
|
||||
$lang['en'][17] = 'Custom (enter below)';
|
||||
$lang['en'][18] = 'Custom <a href="http://csstidy.sourceforge.net/templates.php">template</a>';
|
||||
$lang['en'][19] = 'Options';
|
||||
$lang['en'][20] = 'Sort Selectors (caution)';
|
||||
$lang['en'][21] = 'Sort Properties';
|
||||
$lang['en'][22] = 'Regroup selectors';
|
||||
$lang['en'][23] = 'Optimise shorthands';
|
||||
$lang['en'][24] = 'Compress colors';
|
||||
$lang['en'][25] = 'Lowercase selectors';
|
||||
$lang['en'][26] = 'Case for properties:';
|
||||
$lang['en'][27] = 'Lowercase';
|
||||
$lang['en'][28] = 'No or invalid CSS input or wrong URL!';
|
||||
$lang['en'][29] = 'Uppercase';
|
||||
$lang['en'][30] = 'lowercase elementnames needed for XHTML';
|
||||
$lang['en'][31] = 'Remove unnecessary backslashes';
|
||||
$lang['en'][32] = 'convert !important-hack';
|
||||
$lang['en'][33] = 'Output as file';
|
||||
$lang['en'][34] = 'Bigger compression because of smaller newlines (copy & paste doesn\'t work)';
|
||||
$lang['en'][35] = 'Process CSS';
|
||||
$lang['en'][36] = 'Compression Ratio';
|
||||
$lang['en'][37] = 'Input';
|
||||
$lang['en'][38] = 'Output';
|
||||
$lang['en'][39] = 'Language';
|
||||
$lang['en'][41] = 'Attention: This may change the behaviour of your CSS Code!';
|
||||
$lang['en'][42] = 'Remove last ;';
|
||||
$lang['en'][43] = 'Discard invalid properties';
|
||||
$lang['en'][44] = 'Only safe optimisations';
|
||||
$lang['en'][45] = 'Compress font-weight';
|
||||
$lang['en'][46] = 'Save comments';
|
||||
$lang['en'][47] = 'Do not change anything';
|
||||
$lang['en'][48] = 'Only seperate selectors (split at ,)';
|
||||
$lang['en'][49] = 'Merge selectors with the same properties (fast)';
|
||||
$lang['en'][50] = 'Merge selectors intelligently (slow)';
|
||||
$lang['en'][51] = 'Preserve CSS';
|
||||
$lang['en'][52] = 'Save comments, hacks, etc. Most optimisations can *not* be applied if this is enabled.';
|
||||
$lang['en'][53] = 'None';
|
||||
$lang['en'][54] = 'Don\'t optimise';
|
||||
$lang['en'][55] = 'Safe optimisations';
|
||||
$lang['en'][56] = 'All optimisations';
|
||||
$lang['en'][57] = 'Add timestamp';
|
||||
$lang['en'][58] = 'Copy to clipboard';
|
||||
$lang['en'][59] = 'Back to top';
|
||||
$lang['en'][60] = 'Your browser doesn\'t support copy to clipboard.';
|
||||
$lang['en'][61] = 'For bugs and suggestions feel free to';
|
||||
$lang['en'][62] = 'contact me';
|
||||
$lang['en'][63] = 'Output CSS code as complete HTML document';
|
||||
$lang['en'][64] = 'Code';
|
||||
$lang['en'][65] = 'CSS to style CSS output';
|
||||
$lang['en'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
|
||||
$lang['en'][67] = 'Reverse left and right directions';
|
||||
$lang['de'][0] = 'CSS Formatierer und Optimierer (basierend auf CSSTidy ';
|
||||
$lang['de'][1] = 'CSS Formatierer und Optimierer';
|
||||
$lang['de'][2] = '(basierend auf';
|
||||
$lang['de'][3] = '(Textversion)';
|
||||
$lang['de'][4] = 'Wichtiger Hinweis:';
|
||||
$lang['de'][6] = 'Der CSS Code sollte wohlgeformt sein. Der CSS Code wird <strong>nicht auf Gültigkeit überprüft</strong>. Um sicherzugehen dass dein Code valide ist, benutze den <a href="http://jigsaw.w3.org/css-validator/">W3C Validierungsservice</a>.';
|
||||
$lang['de'][7] = 'alle Kommentare werden entfernt';
|
||||
$lang['de'][8] = 'CSS Eingabe:';
|
||||
$lang['de'][9] = 'CSS-Code:';
|
||||
$lang['de'][10] = 'CSS von URL:';
|
||||
$lang['de'][11] = 'Code Layout:';
|
||||
$lang['de'][12] = 'Komprimierung (Code Layout):';
|
||||
$lang['de'][13] = 'Höchste (keine Lesbarkeit, niedrigste Größe)';
|
||||
$lang['de'][14] = 'Hoch (mittelmäßige Lesbarkeit, geringe Größe)';
|
||||
$lang['de'][15] = 'Standard (Kompromiss zwischen Lesbarkeit und Größe)';
|
||||
$lang['de'][16] = 'Niedrig (höhere Lesbarkeit)';
|
||||
$lang['de'][17] = 'Benutzerdefiniert (unten eingeben)';
|
||||
$lang['de'][18] = 'Benutzerdefinierte <a href="http://csstidy.sourceforge.net/templates.php">Vorlage</a>';
|
||||
$lang['de'][19] = 'Optionen';
|
||||
$lang['de'][20] = 'Selektoren sortieren (Vorsicht)';
|
||||
$lang['de'][21] = 'Eigenschaften sortieren';
|
||||
$lang['de'][22] = 'Selektoren umgruppieren';
|
||||
$lang['de'][23] = 'Shorthands optimieren';
|
||||
$lang['de'][24] = 'Farben komprimieren';
|
||||
$lang['de'][25] = 'Selektoren in Kleinbuchstaben';
|
||||
$lang['de'][26] = 'Groß-/Kleinschreibung für Eigenschaften';
|
||||
$lang['de'][27] = 'Kleinbuchstaben';
|
||||
$lang['de'][28] = 'Keine oder ungültige CSS Eingabe oder falsche URL!';
|
||||
$lang['de'][29] = 'Großbuchstaben';
|
||||
$lang['de'][30] = 'kleingeschriebene Elementnamen benötigt für XHTML';
|
||||
$lang['de'][31] = 'Unnötige Backslashes entfernen';
|
||||
$lang['de'][32] = '!important-Hack konvertieren';
|
||||
$lang['de'][33] = 'Als Datei ausgeben';
|
||||
$lang['de'][34] = 'Größere Komprimierung augrund von kleineren Neuezeile-Zeichen';
|
||||
$lang['de'][35] = 'CSS verarbeiten';
|
||||
$lang['de'][36] = 'Komprimierungsrate';
|
||||
$lang['de'][37] = 'Eingabe';
|
||||
$lang['de'][38] = 'Ausgabe';
|
||||
$lang['de'][39] = 'Sprache';
|
||||
$lang['de'][41] = 'Achtung: Dies könnte das Verhalten ihres CSS-Codes verändern!';
|
||||
$lang['de'][42] = 'Letztes ; entfernen';
|
||||
$lang['de'][43] = 'Ungültige Eigenschaften entfernen';
|
||||
$lang['de'][44] = 'Nur sichere Optimierungen';
|
||||
$lang['de'][45] = 'font-weight komprimieren';
|
||||
$lang['de'][46] = 'Kommentare beibehalten';
|
||||
$lang['de'][47] = 'Nichts ändern';
|
||||
$lang['de'][48] = 'Selektoren nur trennen (am Komma)';
|
||||
$lang['de'][49] = 'Selektoren mit gleichen Eigenschaften zusammenfassen (schnell)';
|
||||
$lang['de'][50] = 'Selektoren intelligent zusammenfassen (langsam!)';
|
||||
$lang['de'][51] = 'CSS erhalten';
|
||||
$lang['de'][52] = 'Kommentare, Hacks, etc. speichern. Viele Optimierungen sind dann aber nicht mehr möglich.';
|
||||
$lang['de'][53] = 'Keine';
|
||||
$lang['de'][54] = 'Nicht optimieren';
|
||||
$lang['de'][55] = 'Sichere Optimierungen';
|
||||
$lang['de'][56] = 'Alle Optimierungen';
|
||||
$lang['de'][57] = 'Zeitstempel hinzufügen';
|
||||
$lang['de'][58] = 'Copy to clipboard';
|
||||
$lang['de'][59] = 'Back to top';
|
||||
$lang['de'][60] = 'Your browser doesn\'t support copy to clipboard.';
|
||||
$lang['de'][61] = 'For bugs and suggestions feel free to';
|
||||
$lang['de'][62] = 'contact me';
|
||||
$lang['de'][63] = 'Output CSS code as complete HTML document';
|
||||
$lang['de'][64] = 'Code';
|
||||
$lang['de'][65] = 'CSS to style CSS output';
|
||||
$lang['de'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
|
||||
$lang['fr'][0] = 'CSS Formateur et Optimiseur (basé sur CSSTidy ';
|
||||
$lang['fr'][1] = 'CSS Formateur et Optimiseur';
|
||||
$lang['fr'][2] = '(basé sur ';
|
||||
$lang['fr'][3] = '(Version texte)';
|
||||
$lang['fr'][4] = 'Note Importante :';
|
||||
$lang['fr'][6] = 'Votre code doit être valide. Ce n’est <strong>pas un validateur</strong> qui signale les erreurs dans votre code CSS. Pour être sûr que votre code est correct, utilisez le validateur : <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
|
||||
$lang['fr'][7] = 'tous les commentaires sont enlevés';
|
||||
$lang['fr'][8] = 'Champ CSS :';
|
||||
$lang['fr'][9] = 'Code CSS :';
|
||||
$lang['fr'][10] = 'CSS en provenance d’une URL :<br />';
|
||||
$lang['fr'][11] = 'Mise en page du code :';
|
||||
$lang['fr'][12] = 'Compression (mise en page du code) :';
|
||||
$lang['fr'][13] = 'La plus élevée (aucune lisibilité, taille minimale)';
|
||||
$lang['fr'][14] = 'Élevée (lisibilité modérée, petite taille)';
|
||||
$lang['fr'][15] = 'Normale (équilibre entre lisibilité et taille)';
|
||||
$lang['fr'][16] = 'Faible (lisibilité élevée)';
|
||||
$lang['fr'][17] = 'Sur mesure (entrer ci-dessous)';
|
||||
$lang['fr'][18] = '<a href="http://csstidy.sourceforge.net/templates.php">Gabarit</a> sur mesure';
|
||||
$lang['fr'][19] = 'Options';
|
||||
$lang['fr'][20] = 'Trier les sélecteurs (attention)';
|
||||
$lang['fr'][21] = 'Trier les propriétés';
|
||||
$lang['fr'][22] = 'Regrouper les sélecteurs';
|
||||
$lang['fr'][23] = 'Propriétés raccourcies';
|
||||
$lang['fr'][24] = 'Compresser les couleurs';
|
||||
$lang['fr'][25] = 'Sélecteurs en minuscules';
|
||||
$lang['fr'][26] = 'Case pour les propriétés :';
|
||||
$lang['fr'][27] = 'Minuscule';
|
||||
$lang['fr'][28] = 'CSS non valide ou URL incorrecte !';
|
||||
$lang['fr'][29] = 'Majuscule';
|
||||
$lang['fr'][30] = 'les noms des éléments en minuscules (indispensables pour XHTML)';
|
||||
$lang['fr'][31] = 'enlever les antislashs inutiles';
|
||||
$lang['fr'][32] = 'convertir !important-hack';
|
||||
$lang['fr'][33] = 'Sauver en tant que fichier';
|
||||
$lang['fr'][34] = 'Meilleure compression grâce aux caractères de saut de ligne plus petits (copier & coller ne marche pas)';
|
||||
$lang['fr'][35] = 'Compresser la CSS';
|
||||
$lang['fr'][36] = 'Facteur de Compression';
|
||||
$lang['fr'][37] = 'Entrée';
|
||||
$lang['fr'][38] = 'Sortie';
|
||||
$lang['fr'][39] = 'Langue';
|
||||
$lang['fr'][41] = 'Attention : ceci peut changer le comportement de votre code CSS !';
|
||||
$lang['fr'][42] = 'Enlever le dernier ;';
|
||||
$lang['fr'][43] = 'Supprimer les propriétés non valide';
|
||||
$lang['fr'][44] = 'Seulement les optimisations sûres';
|
||||
$lang['fr'][45] = 'Compresser font-weight';
|
||||
$lang['fr'][46] = 'Sauvegarder les commentaires ';
|
||||
$lang['fr'][47] = 'Ne rien changer';
|
||||
$lang['fr'][48] = 'Sépare les sélecteurs (sépare au niveau de ,)';
|
||||
$lang['fr'][49] = 'Fusionne les sélecteurs avec les mêmes propriétés (rapide)';
|
||||
$lang['fr'][50] = 'Fusionne les sélecteurs intelligemment (lent)';
|
||||
$lang['fr'][51] = 'Préserver la CSS';
|
||||
$lang['fr'][52] = 'Sauvegarder les commentaires, hacks, etc. La plupart des optimisations ne peuvent *pas* être appliquées si cela est activé.';
|
||||
$lang['fr'][53] = 'Aucun';
|
||||
$lang['fr'][54] = 'Ne pas optimiser';
|
||||
$lang['fr'][55] = 'Optimisations sûres';
|
||||
$lang['fr'][56] = 'Toutes les optimisations';
|
||||
$lang['fr'][57] = 'Ajouter un timestamp';
|
||||
$lang['fr'][58] = 'Copier dans le presse-papiers';
|
||||
$lang['fr'][59] = 'Retour en haut';
|
||||
$lang['fr'][60] = 'Votre navigateur ne supporte pas la copie vers le presse-papiers.';
|
||||
$lang['fr'][61] = 'Pour signaler des bugs ou pour des suggestions,';
|
||||
$lang['fr'][62] = 'contactez-moi';
|
||||
$lang['fr'][63] = 'Sauver le code CSS comme document complet HTML';
|
||||
$lang['fr'][64] = 'Code';
|
||||
$lang['fr'][65] = 'CSS pour colorier la sortie CSS';
|
||||
$lang['fr'][66] = 'Vous devez aller dans about:config dans votre barre d’adresse, sélectionner \'signed.applets.codebase_principal_support\' dans le champ Filtre et attribuez-lui la valeur \'true\' pour utiliser cette fonctionnalité; toutefois, soyez conscient que cela augmente les risques de sécurité.';
|
||||
$lang['fr'][67] = 'Inverser gauche et droite';
|
||||
$lang['zh'][0] = 'CSS整形與最佳化工具(使用 CSSTidy ';
|
||||
$lang['zh'][1] = 'CSS整形與最佳化工具';
|
||||
$lang['zh'][2] = '(使用';
|
||||
$lang['zh'][3] = '(純文字)';
|
||||
$lang['zh'][4] = '重要事項:';
|
||||
$lang['zh'][6] = '你的原始碼必須是良構的(well-formed). 這個工具<strong>沒有內建驗證器(validator)</strong>. 驗證器能夠指出你CSS原始碼裡的錯誤. 請使用 <a href="http://jigsaw.w3.org/css-validator/">W3C 驗證器</a>, 確保你的原始碼合乎規範.';
|
||||
$lang['zh'][7] = '所有註解都移除了';
|
||||
$lang['zh'][8] = 'CSS 輸入:';
|
||||
$lang['zh'][9] = 'CSS 原始碼:';
|
||||
$lang['zh'][10] = 'CSS 檔案網址(URL):';
|
||||
$lang['zh'][11] = '原始碼規劃:';
|
||||
$lang['zh'][12] = '壓縮程度(原始碼規劃):';
|
||||
$lang['zh'][13] = '最高 (沒有辦法讀, 檔案最小)';
|
||||
$lang['zh'][14] = '高 (適度的可讀性, 檔案小)';
|
||||
$lang['zh'][15] = '標準 (兼顧可讀性與檔案大小)';
|
||||
$lang['zh'][16] = '低 (注重可讀性)';
|
||||
$lang['zh'][17] = '自訂 (在下方設定)';
|
||||
$lang['zh'][18] = '自訂<a href="http://csstidy.sourceforge.net/templates.php">樣板</a>';
|
||||
$lang['zh'][19] = '選項';
|
||||
$lang['zh'][20] = '整理選擇符(請謹慎使用)';
|
||||
$lang['zh'][21] = '整理屬性';
|
||||
$lang['zh'][22] = '重組選擇符';
|
||||
$lang['zh'][23] = '速記法(shorthand)最佳化';
|
||||
$lang['zh'][24] = '壓縮色彩語法';
|
||||
$lang['zh'][25] = '改用小寫選擇符';
|
||||
$lang['zh'][26] = '屬性的字形:';
|
||||
$lang['zh'][27] = '小寫';
|
||||
$lang['zh'][28] = '沒有輸入CSS, 語法不符合規定, 或是網址錯誤!';
|
||||
$lang['zh'][29] = '大寫';
|
||||
$lang['zh'][30] = 'XHTML必須使用小寫的元素名稱';
|
||||
$lang['zh'][31] = '移除不必要的反斜線';
|
||||
$lang['zh'][32] = '轉換 !important-hack';
|
||||
$lang['zh'][33] = '輸出成檔案形式';
|
||||
$lang['zh'][34] = '由於比較少換行字元, 會有更大的壓縮比率(複製&貼上沒有用)';
|
||||
$lang['zh'][35] = '執行';
|
||||
$lang['zh'][36] = '壓縮比率';
|
||||
$lang['zh'][37] = '輸入';
|
||||
$lang['zh'][38] = '輸出';
|
||||
$lang['zh'][39] = '語言';
|
||||
$lang['zh'][41] = '注意: 這或許會變更你CSS原始碼的行為!';
|
||||
$lang['zh'][42] = '除去最後一個分號';
|
||||
$lang['zh'][43] = '拋棄不符合規定的屬性';
|
||||
$lang['zh'][44] = '只安全地最佳化';
|
||||
$lang['zh'][45] = '壓縮 font-weight';
|
||||
$lang['zh'][46] = '保留註解';
|
||||
$lang['zh'][47] = '什麼都不要改';
|
||||
$lang['zh'][48] = '只分開原本用逗號分隔的選擇符';
|
||||
$lang['zh'][49] = '合併有相同屬性的選擇符(快速)';
|
||||
$lang['zh'][50] = '聰明地合併選擇符(慢速)';
|
||||
$lang['zh'][51] = '保護CSS';
|
||||
$lang['zh'][52] = '保留註解與 hack 等等. 如果啟用這個選項, 大多數的最佳化程序都不會執行.';
|
||||
$lang['zh'][53] = '不改變';
|
||||
$lang['zh'][54] = '不做最佳化';
|
||||
$lang['zh'][55] = '安全地最佳化';
|
||||
$lang['zh'][56] = '全部最佳化';
|
||||
$lang['zh'][57] = '加上時間戳記';
|
||||
$lang['zh'][58] = '复制到剪贴板';
|
||||
$lang['zh'][59] = '回到页面上方';
|
||||
$lang['zh'][60] = '你的浏览器不支持复制到剪贴板。';
|
||||
$lang['zh'][61] = '如果程序有错误或你有建议,欢迎';
|
||||
$lang['zh'][62] = '和我联系';
|
||||
$lang['zh'][63] = 'Output CSS code as complete HTML document';
|
||||
$lang['zh'][64] = '代码';
|
||||
$lang['zh'][65] = 'CSS to style CSS output';
|
||||
$lang['zh'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
|
||||
@@ -0,0 +1,10 @@
|
||||
<span class="at">|</span> <span class="format">{</span>
|
||||
|<span class="selector">|</span> <span class="format">{</span>
|
||||
|<span class="property">|</span><span class="value">|</span><span class="format">;</span>
|
||||
|<span class="format">}</span>|
|
||||
|
||||
|
|
||||
<span class="format">}</span>
|
||||
|
||||
||<span class="comment">|</span>
|
||||
|
|
||||
@@ -0,0 +1,12 @@
|
||||
<span class="at">|</span> <span class="format">{</span>
|
||||
|<span class="selector">|</span>
|
||||
<span class="format">{</span>
|
||||
| <span class="property">|</span><span class="value">|</span><span class="format">;</span>
|
||||
|<span class="format">}</span>|
|
||||
|
||||
|
|
||||
|
||||
<span class="format">}</span>
|
||||
|
||||
| |<span class="comment">|</span>
|
||||
|
|
||||
@@ -0,0 +1,5 @@
|
||||
<span class="at">|</span> <span class="format">{</span>
|
||||
|<span class="selector">|</span><span class="format">{</span>|<span class="property">|</span><span class="value">|</span><span class="format">;</span>|<span class="format">}</span>|
|
||||
|
|
||||
<span class="format">}
|
||||
</span>||<span class="comment">|</span>|
|
||||
@@ -0,0 +1 @@
|
||||
<span class="at">|</span><span class="format">{</span>|<span class="selector">|</span><span class="format">{</span>|<span class="property">|</span><span class="value">|</span><span class="format">;</span>|<span class="format">}</span>||<span class="format">}</span>||<span class="comment">|</span>|
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface Cache
|
||||
{
|
||||
public const STATS_HITS = 'hits';
|
||||
public const STATS_MISSES = 'misses';
|
||||
public const STATS_UPTIME = 'uptime';
|
||||
public const STATS_MEMORY_USAGE = 'memory_usage';
|
||||
public const STATS_MEMORY_AVAILABLE = 'memory_available';
|
||||
public const STATS_MEMORY_AVAILIABLE = 'memory_available';
|
||||
public function fetch($id);
|
||||
public function contains($id);
|
||||
public function save($id, $data, $lifeTime = 0);
|
||||
public function delete($id);
|
||||
public function getStats();
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use function array_combine;
|
||||
use function array_key_exists;
|
||||
use function array_map;
|
||||
use function sprintf;
|
||||
abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiOperationCache
|
||||
{
|
||||
public const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
|
||||
private $namespace = '';
|
||||
private $namespaceVersion;
|
||||
public function setNamespace($namespace)
|
||||
{
|
||||
$this->namespace = (string) $namespace;
|
||||
$this->namespaceVersion = null;
|
||||
}
|
||||
public function getNamespace()
|
||||
{
|
||||
return $this->namespace;
|
||||
}
|
||||
public function fetch($id)
|
||||
{
|
||||
return $this->doFetch($this->getNamespacedId($id));
|
||||
}
|
||||
public function fetchMultiple(array $keys)
|
||||
{
|
||||
if (empty($keys)) {
|
||||
return [];
|
||||
}
|
||||
// note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
|
||||
$namespacedKeys = array_combine($keys, array_map([$this, 'getNamespacedId'], $keys));
|
||||
$items = $this->doFetchMultiple($namespacedKeys);
|
||||
$foundItems = [];
|
||||
// no internal array function supports this sort of mapping: needs to be iterative
|
||||
// this filters and combines keys in one pass
|
||||
foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
|
||||
if (!isset($items[$namespacedKey]) && !array_key_exists($namespacedKey, $items)) {
|
||||
continue;
|
||||
}
|
||||
$foundItems[$requestedKey] = $items[$namespacedKey];
|
||||
}
|
||||
return $foundItems;
|
||||
}
|
||||
public function saveMultiple(array $keysAndValues, $lifetime = 0)
|
||||
{
|
||||
$namespacedKeysAndValues = [];
|
||||
foreach ($keysAndValues as $key => $value) {
|
||||
$namespacedKeysAndValues[$this->getNamespacedId($key)] = $value;
|
||||
}
|
||||
return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime);
|
||||
}
|
||||
public function contains($id)
|
||||
{
|
||||
return $this->doContains($this->getNamespacedId($id));
|
||||
}
|
||||
public function save($id, $data, $lifeTime = 0)
|
||||
{
|
||||
return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
|
||||
}
|
||||
public function deleteMultiple(array $keys)
|
||||
{
|
||||
return $this->doDeleteMultiple(array_map([$this, 'getNamespacedId'], $keys));
|
||||
}
|
||||
public function delete($id)
|
||||
{
|
||||
return $this->doDelete($this->getNamespacedId($id));
|
||||
}
|
||||
public function getStats()
|
||||
{
|
||||
return $this->doGetStats();
|
||||
}
|
||||
public function flushAll()
|
||||
{
|
||||
return $this->doFlush();
|
||||
}
|
||||
public function deleteAll()
|
||||
{
|
||||
$namespaceCacheKey = $this->getNamespaceCacheKey();
|
||||
$namespaceVersion = $this->getNamespaceVersion() + 1;
|
||||
if ($this->doSave($namespaceCacheKey, $namespaceVersion)) {
|
||||
$this->namespaceVersion = $namespaceVersion;
|
||||
return \true;
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
private function getNamespacedId(string $id) : string
|
||||
{
|
||||
$namespaceVersion = $this->getNamespaceVersion();
|
||||
return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
|
||||
}
|
||||
private function getNamespaceCacheKey() : string
|
||||
{
|
||||
return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
|
||||
}
|
||||
private function getNamespaceVersion() : int
|
||||
{
|
||||
if ($this->namespaceVersion !== null) {
|
||||
return $this->namespaceVersion;
|
||||
}
|
||||
$namespaceCacheKey = $this->getNamespaceCacheKey();
|
||||
$this->namespaceVersion = (int) $this->doFetch($namespaceCacheKey) ?: 1;
|
||||
return $this->namespaceVersion;
|
||||
}
|
||||
protected function doFetchMultiple(array $keys)
|
||||
{
|
||||
$returnValues = [];
|
||||
foreach ($keys as $key) {
|
||||
$item = $this->doFetch($key);
|
||||
if ($item === \false && !$this->doContains($key)) {
|
||||
continue;
|
||||
}
|
||||
$returnValues[$key] = $item;
|
||||
}
|
||||
return $returnValues;
|
||||
}
|
||||
protected abstract function doFetch($id);
|
||||
protected abstract function doContains($id);
|
||||
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
|
||||
{
|
||||
$success = \true;
|
||||
foreach ($keysAndValues as $key => $value) {
|
||||
if ($this->doSave($key, $value, $lifetime)) {
|
||||
continue;
|
||||
}
|
||||
$success = \false;
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
protected abstract function doSave($id, $data, $lifeTime = 0);
|
||||
protected function doDeleteMultiple(array $keys)
|
||||
{
|
||||
$success = \true;
|
||||
foreach ($keys as $key) {
|
||||
if ($this->doDelete($key)) {
|
||||
continue;
|
||||
}
|
||||
$success = \false;
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
protected abstract function doDelete($id);
|
||||
protected abstract function doFlush();
|
||||
protected abstract function doGetStats();
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface ClearableCache
|
||||
{
|
||||
public function deleteAll();
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface FlushableCache
|
||||
{
|
||||
public function flushAll();
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface MultiDeleteCache
|
||||
{
|
||||
public function deleteMultiple(array $keys);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface MultiGetCache
|
||||
{
|
||||
public function fetchMultiple(array $keys);
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface MultiOperationCache extends MultiGetCache, MultiDeleteCache, MultiPutCache
|
||||
{
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface MultiPutCache
|
||||
{
|
||||
public function saveMultiple(array $keysAndValues, $lifetime = 0);
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache\Psr6;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Cache;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\ClearableCache;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\MultiDeleteCache;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\MultiGetCache;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\MultiPutCache;
|
||||
use MailPoetVendor\Psr\Cache\CacheItemInterface;
|
||||
use MailPoetVendor\Psr\Cache\CacheItemPoolInterface;
|
||||
use MailPoetVendor\Symfony\Component\Cache\DoctrineProvider as SymfonyDoctrineProvider;
|
||||
use function array_key_exists;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function current;
|
||||
use function get_class;
|
||||
use function gettype;
|
||||
use function is_object;
|
||||
use function is_string;
|
||||
use function microtime;
|
||||
use function sprintf;
|
||||
use function strpbrk;
|
||||
use const PHP_VERSION_ID;
|
||||
final class CacheAdapter implements CacheItemPoolInterface
|
||||
{
|
||||
private const RESERVED_CHARACTERS = '{}()/\\@:';
|
||||
private $cache;
|
||||
private $deferredItems = [];
|
||||
public static function wrap(Cache $cache) : CacheItemPoolInterface
|
||||
{
|
||||
if ($cache instanceof DoctrineProvider && !$cache->getNamespace()) {
|
||||
return $cache->getPool();
|
||||
}
|
||||
if ($cache instanceof SymfonyDoctrineProvider && !$cache->getNamespace()) {
|
||||
$getPool = function () {
|
||||
// phpcs:ignore Squiz.Scope.StaticThisUsage.Found
|
||||
return $this->pool;
|
||||
};
|
||||
return $getPool->bindTo($cache, SymfonyDoctrineProvider::class)();
|
||||
}
|
||||
return new self($cache);
|
||||
}
|
||||
private function __construct(Cache $cache)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
}
|
||||
public function getCache() : Cache
|
||||
{
|
||||
return $this->cache;
|
||||
}
|
||||
public function getItem($key) : CacheItemInterface
|
||||
{
|
||||
assert(self::validKey($key));
|
||||
if (isset($this->deferredItems[$key])) {
|
||||
$this->commit();
|
||||
}
|
||||
$value = $this->cache->fetch($key);
|
||||
if (PHP_VERSION_ID >= 80000) {
|
||||
if ($value !== \false) {
|
||||
return new TypedCacheItem($key, $value, \true);
|
||||
}
|
||||
return new TypedCacheItem($key, null, \false);
|
||||
}
|
||||
if ($value !== \false) {
|
||||
return new CacheItem($key, $value, \true);
|
||||
}
|
||||
return new CacheItem($key, null, \false);
|
||||
}
|
||||
public function getItems(array $keys = []) : array
|
||||
{
|
||||
if ($this->deferredItems) {
|
||||
$this->commit();
|
||||
}
|
||||
assert(self::validKeys($keys));
|
||||
$values = $this->doFetchMultiple($keys);
|
||||
$items = [];
|
||||
if (PHP_VERSION_ID >= 80000) {
|
||||
foreach ($keys as $key) {
|
||||
if (array_key_exists($key, $values)) {
|
||||
$items[$key] = new TypedCacheItem($key, $values[$key], \true);
|
||||
} else {
|
||||
$items[$key] = new TypedCacheItem($key, null, \false);
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
foreach ($keys as $key) {
|
||||
if (array_key_exists($key, $values)) {
|
||||
$items[$key] = new CacheItem($key, $values[$key], \true);
|
||||
} else {
|
||||
$items[$key] = new CacheItem($key, null, \false);
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
public function hasItem($key) : bool
|
||||
{
|
||||
assert(self::validKey($key));
|
||||
if (isset($this->deferredItems[$key])) {
|
||||
$this->commit();
|
||||
}
|
||||
return $this->cache->contains($key);
|
||||
}
|
||||
public function clear() : bool
|
||||
{
|
||||
$this->deferredItems = [];
|
||||
if (!$this->cache instanceof ClearableCache) {
|
||||
return \false;
|
||||
}
|
||||
return $this->cache->deleteAll();
|
||||
}
|
||||
public function deleteItem($key) : bool
|
||||
{
|
||||
assert(self::validKey($key));
|
||||
unset($this->deferredItems[$key]);
|
||||
return $this->cache->delete($key);
|
||||
}
|
||||
public function deleteItems(array $keys) : bool
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
assert(self::validKey($key));
|
||||
unset($this->deferredItems[$key]);
|
||||
}
|
||||
return $this->doDeleteMultiple($keys);
|
||||
}
|
||||
public function save(CacheItemInterface $item) : bool
|
||||
{
|
||||
return $this->saveDeferred($item) && $this->commit();
|
||||
}
|
||||
public function saveDeferred(CacheItemInterface $item) : bool
|
||||
{
|
||||
if (!$item instanceof CacheItem && !$item instanceof TypedCacheItem) {
|
||||
return \false;
|
||||
}
|
||||
$this->deferredItems[$item->getKey()] = $item;
|
||||
return \true;
|
||||
}
|
||||
public function commit() : bool
|
||||
{
|
||||
if (!$this->deferredItems) {
|
||||
return \true;
|
||||
}
|
||||
$now = microtime(\true);
|
||||
$itemsCount = 0;
|
||||
$byLifetime = [];
|
||||
$expiredKeys = [];
|
||||
foreach ($this->deferredItems as $key => $item) {
|
||||
$lifetime = ($item->getExpiry() ?? $now) - $now;
|
||||
if ($lifetime < 0) {
|
||||
$expiredKeys[] = $key;
|
||||
continue;
|
||||
}
|
||||
++$itemsCount;
|
||||
$byLifetime[(int) $lifetime][$key] = $item->get();
|
||||
}
|
||||
$this->deferredItems = [];
|
||||
switch (count($expiredKeys)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
$this->cache->delete(current($expiredKeys));
|
||||
break;
|
||||
default:
|
||||
$this->doDeleteMultiple($expiredKeys);
|
||||
break;
|
||||
}
|
||||
if ($itemsCount === 1) {
|
||||
return $this->cache->save($key, $item->get(), (int) $lifetime);
|
||||
}
|
||||
$success = \true;
|
||||
foreach ($byLifetime as $lifetime => $values) {
|
||||
$success = $this->doSaveMultiple($values, $lifetime) && $success;
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
public function __destruct()
|
||||
{
|
||||
$this->commit();
|
||||
}
|
||||
private static function validKey($key) : bool
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
throw new InvalidArgument(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key)));
|
||||
}
|
||||
if ($key === '') {
|
||||
throw new InvalidArgument('Cache key length must be greater than zero.');
|
||||
}
|
||||
if (strpbrk($key, self::RESERVED_CHARACTERS) !== \false) {
|
||||
throw new InvalidArgument(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS));
|
||||
}
|
||||
return \true;
|
||||
}
|
||||
private static function validKeys(array $keys) : bool
|
||||
{
|
||||
foreach ($keys as $key) {
|
||||
self::validKey($key);
|
||||
}
|
||||
return \true;
|
||||
}
|
||||
private function doDeleteMultiple(array $keys) : bool
|
||||
{
|
||||
if ($this->cache instanceof MultiDeleteCache) {
|
||||
return $this->cache->deleteMultiple($keys);
|
||||
}
|
||||
$success = \true;
|
||||
foreach ($keys as $key) {
|
||||
$success = $this->cache->delete($key) && $success;
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
private function doFetchMultiple(array $keys) : array
|
||||
{
|
||||
if ($this->cache instanceof MultiGetCache) {
|
||||
return $this->cache->fetchMultiple($keys);
|
||||
}
|
||||
$values = [];
|
||||
foreach ($keys as $key) {
|
||||
$value = $this->cache->fetch($key);
|
||||
if (!$value) {
|
||||
continue;
|
||||
}
|
||||
$values[$key] = $value;
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
private function doSaveMultiple(array $keysAndValues, int $lifetime = 0) : bool
|
||||
{
|
||||
if ($this->cache instanceof MultiPutCache) {
|
||||
return $this->cache->saveMultiple($keysAndValues, $lifetime);
|
||||
}
|
||||
$success = \true;
|
||||
foreach ($keysAndValues as $key => $value) {
|
||||
$success = $this->cache->save($key, $value, $lifetime) && $success;
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache\Psr6;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
use MailPoetVendor\Psr\Cache\CacheItemInterface;
|
||||
use TypeError;
|
||||
use function get_class;
|
||||
use function gettype;
|
||||
use function is_int;
|
||||
use function is_object;
|
||||
use function microtime;
|
||||
use function sprintf;
|
||||
final class CacheItem implements CacheItemInterface
|
||||
{
|
||||
private $key;
|
||||
private $value;
|
||||
private $isHit;
|
||||
private $expiry;
|
||||
public function __construct(string $key, $data, bool $isHit)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->value = $data;
|
||||
$this->isHit = $isHit;
|
||||
}
|
||||
public function getKey() : string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
public function get()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
public function isHit() : bool
|
||||
{
|
||||
return $this->isHit;
|
||||
}
|
||||
public function set($value) : self
|
||||
{
|
||||
$this->value = $value;
|
||||
return $this;
|
||||
}
|
||||
public function expiresAt($expiration) : self
|
||||
{
|
||||
if ($expiration === null) {
|
||||
$this->expiry = null;
|
||||
} elseif ($expiration instanceof DateTimeInterface) {
|
||||
$this->expiry = (float) $expiration->format('U.u');
|
||||
} else {
|
||||
throw new TypeError(sprintf('Expected $expiration to be an instance of DateTimeInterface or null, got %s', is_object($expiration) ? get_class($expiration) : gettype($expiration)));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function expiresAfter($time) : self
|
||||
{
|
||||
if ($time === null) {
|
||||
$this->expiry = null;
|
||||
} elseif ($time instanceof DateInterval) {
|
||||
$this->expiry = microtime(\true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
|
||||
} elseif (is_int($time)) {
|
||||
$this->expiry = $time + microtime(\true);
|
||||
} else {
|
||||
throw new TypeError(sprintf('Expected $time to be either an integer, an instance of DateInterval or null, got %s', is_object($time) ? get_class($time) : gettype($time)));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function getExpiry() : ?float
|
||||
{
|
||||
return $this->expiry;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache\Psr6;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Cache;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\CacheProvider;
|
||||
use MailPoetVendor\Psr\Cache\CacheItemPoolInterface;
|
||||
use MailPoetVendor\Symfony\Component\Cache\Adapter\DoctrineAdapter as SymfonyDoctrineAdapter;
|
||||
use MailPoetVendor\Symfony\Contracts\Service\ResetInterface;
|
||||
use function rawurlencode;
|
||||
final class DoctrineProvider extends CacheProvider
|
||||
{
|
||||
private $pool;
|
||||
public static function wrap(CacheItemPoolInterface $pool) : Cache
|
||||
{
|
||||
if ($pool instanceof CacheAdapter) {
|
||||
return $pool->getCache();
|
||||
}
|
||||
if ($pool instanceof SymfonyDoctrineAdapter) {
|
||||
$getCache = function () {
|
||||
// phpcs:ignore Squiz.Scope.StaticThisUsage.Found
|
||||
return $this->provider;
|
||||
};
|
||||
return $getCache->bindTo($pool, SymfonyDoctrineAdapter::class)();
|
||||
}
|
||||
return new self($pool);
|
||||
}
|
||||
private function __construct(CacheItemPoolInterface $pool)
|
||||
{
|
||||
$this->pool = $pool;
|
||||
}
|
||||
public function getPool() : CacheItemPoolInterface
|
||||
{
|
||||
return $this->pool;
|
||||
}
|
||||
public function reset() : void
|
||||
{
|
||||
if ($this->pool instanceof ResetInterface) {
|
||||
$this->pool->reset();
|
||||
}
|
||||
$this->setNamespace($this->getNamespace());
|
||||
}
|
||||
protected function doFetch($id)
|
||||
{
|
||||
$item = $this->pool->getItem(rawurlencode($id));
|
||||
return $item->isHit() ? $item->get() : \false;
|
||||
}
|
||||
protected function doContains($id)
|
||||
{
|
||||
return $this->pool->hasItem(rawurlencode($id));
|
||||
}
|
||||
protected function doSave($id, $data, $lifeTime = 0)
|
||||
{
|
||||
$item = $this->pool->getItem(rawurlencode($id));
|
||||
if (0 < $lifeTime) {
|
||||
$item->expiresAfter($lifeTime);
|
||||
}
|
||||
return $this->pool->save($item->set($data));
|
||||
}
|
||||
protected function doDelete($id)
|
||||
{
|
||||
return $this->pool->deleteItem(rawurlencode($id));
|
||||
}
|
||||
protected function doFlush()
|
||||
{
|
||||
return $this->pool->clear();
|
||||
}
|
||||
protected function doGetStats()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache\Psr6;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use InvalidArgumentException;
|
||||
use MailPoetVendor\Psr\Cache\InvalidArgumentException as PsrInvalidArgumentException;
|
||||
final class InvalidArgument extends InvalidArgumentException implements PsrInvalidArgumentException
|
||||
{
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Cache\Psr6;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
use MailPoetVendor\Psr\Cache\CacheItemInterface;
|
||||
use TypeError;
|
||||
use function get_debug_type;
|
||||
use function is_int;
|
||||
use function microtime;
|
||||
use function sprintf;
|
||||
final class TypedCacheItem implements CacheItemInterface
|
||||
{
|
||||
private ?float $expiry = null;
|
||||
public function __construct(private string $key, private mixed $value, private bool $isHit)
|
||||
{
|
||||
}
|
||||
public function getKey() : string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
public function get() : mixed
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
public function isHit() : bool
|
||||
{
|
||||
return $this->isHit;
|
||||
}
|
||||
public function set(mixed $value) : static
|
||||
{
|
||||
$this->value = $value;
|
||||
return $this;
|
||||
}
|
||||
public function expiresAt($expiration) : static
|
||||
{
|
||||
if ($expiration === null) {
|
||||
$this->expiry = null;
|
||||
} elseif ($expiration instanceof DateTimeInterface) {
|
||||
$this->expiry = (float) $expiration->format('U.u');
|
||||
} else {
|
||||
throw new TypeError(sprintf('Expected $expiration to be an instance of DateTimeInterface or null, got %s', get_debug_type($expiration)));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function expiresAfter($time) : static
|
||||
{
|
||||
if ($time === null) {
|
||||
$this->expiry = null;
|
||||
} elseif ($time instanceof DateInterval) {
|
||||
$this->expiry = microtime(\true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
|
||||
} elseif (is_int($time)) {
|
||||
$this->expiry = $time + microtime(\true);
|
||||
} else {
|
||||
throw new TypeError(sprintf('Expected $time to be either an integer, an instance of DateInterval or null, got %s', get_debug_type($time)));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function getExpiry() : ?float
|
||||
{
|
||||
return $this->expiry;
|
||||
}
|
||||
}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use Closure;
|
||||
use ReturnTypeWillChange;
|
||||
use Traversable;
|
||||
abstract class AbstractLazyCollection implements Collection
|
||||
{
|
||||
protected $collection;
|
||||
protected $initialized = \false;
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->count();
|
||||
}
|
||||
public function add($element)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->add($element);
|
||||
}
|
||||
public function clear()
|
||||
{
|
||||
$this->initialize();
|
||||
$this->collection->clear();
|
||||
}
|
||||
public function contains($element)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->contains($element);
|
||||
}
|
||||
public function isEmpty()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->isEmpty();
|
||||
}
|
||||
public function remove($key)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->remove($key);
|
||||
}
|
||||
public function removeElement($element)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->removeElement($element);
|
||||
}
|
||||
public function containsKey($key)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->containsKey($key);
|
||||
}
|
||||
public function get($key)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->get($key);
|
||||
}
|
||||
public function getKeys()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->getKeys();
|
||||
}
|
||||
public function getValues()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->getValues();
|
||||
}
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->initialize();
|
||||
$this->collection->set($key, $value);
|
||||
}
|
||||
public function toArray()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->toArray();
|
||||
}
|
||||
public function first()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->first();
|
||||
}
|
||||
public function last()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->last();
|
||||
}
|
||||
public function key()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->key();
|
||||
}
|
||||
public function current()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->current();
|
||||
}
|
||||
public function next()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->next();
|
||||
}
|
||||
public function exists(Closure $p)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->exists($p);
|
||||
}
|
||||
public function filter(Closure $p)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->filter($p);
|
||||
}
|
||||
public function forAll(Closure $p)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->forAll($p);
|
||||
}
|
||||
public function map(Closure $func)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->map($func);
|
||||
}
|
||||
public function partition(Closure $p)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->partition($p);
|
||||
}
|
||||
public function indexOf($element)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->indexOf($element);
|
||||
}
|
||||
public function slice($offset, $length = null)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->slice($offset, $length);
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->getIterator();
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->offsetExists($offset);
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$this->initialize();
|
||||
return $this->collection->offsetGet($offset);
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->initialize();
|
||||
$this->collection->offsetSet($offset, $value);
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->initialize();
|
||||
$this->collection->offsetUnset($offset);
|
||||
}
|
||||
public function isInitialized()
|
||||
{
|
||||
return $this->initialized;
|
||||
}
|
||||
protected function initialize()
|
||||
{
|
||||
if ($this->initialized) {
|
||||
return;
|
||||
}
|
||||
$this->doInitialize();
|
||||
$this->initialized = \true;
|
||||
}
|
||||
protected abstract function doInitialize();
|
||||
}
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use ArrayIterator;
|
||||
use Closure;
|
||||
use MailPoetVendor\Doctrine\Common\Collections\Expr\ClosureExpressionVisitor;
|
||||
use ReturnTypeWillChange;
|
||||
use Traversable;
|
||||
use function array_filter;
|
||||
use function array_key_exists;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function array_reverse;
|
||||
use function array_search;
|
||||
use function array_slice;
|
||||
use function array_values;
|
||||
use function count;
|
||||
use function current;
|
||||
use function end;
|
||||
use function in_array;
|
||||
use function key;
|
||||
use function next;
|
||||
use function reset;
|
||||
use function spl_object_hash;
|
||||
use function uasort;
|
||||
use const ARRAY_FILTER_USE_BOTH;
|
||||
class ArrayCollection implements Collection, Selectable
|
||||
{
|
||||
private $elements;
|
||||
public function __construct(array $elements = [])
|
||||
{
|
||||
$this->elements = $elements;
|
||||
}
|
||||
public function toArray()
|
||||
{
|
||||
return $this->elements;
|
||||
}
|
||||
public function first()
|
||||
{
|
||||
return reset($this->elements);
|
||||
}
|
||||
protected function createFrom(array $elements)
|
||||
{
|
||||
return new static($elements);
|
||||
}
|
||||
public function last()
|
||||
{
|
||||
return end($this->elements);
|
||||
}
|
||||
public function key()
|
||||
{
|
||||
return key($this->elements);
|
||||
}
|
||||
public function next()
|
||||
{
|
||||
return next($this->elements);
|
||||
}
|
||||
public function current()
|
||||
{
|
||||
return current($this->elements);
|
||||
}
|
||||
public function remove($key)
|
||||
{
|
||||
if (!isset($this->elements[$key]) && !array_key_exists($key, $this->elements)) {
|
||||
return null;
|
||||
}
|
||||
$removed = $this->elements[$key];
|
||||
unset($this->elements[$key]);
|
||||
return $removed;
|
||||
}
|
||||
public function removeElement($element)
|
||||
{
|
||||
$key = array_search($element, $this->elements, \true);
|
||||
if ($key === \false) {
|
||||
return \false;
|
||||
}
|
||||
unset($this->elements[$key]);
|
||||
return \true;
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->containsKey($offset);
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (!isset($offset)) {
|
||||
$this->add($value);
|
||||
return;
|
||||
}
|
||||
$this->set($offset, $value);
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->remove($offset);
|
||||
}
|
||||
public function containsKey($key)
|
||||
{
|
||||
return isset($this->elements[$key]) || array_key_exists($key, $this->elements);
|
||||
}
|
||||
public function contains($element)
|
||||
{
|
||||
return in_array($element, $this->elements, \true);
|
||||
}
|
||||
public function exists(Closure $p)
|
||||
{
|
||||
foreach ($this->elements as $key => $element) {
|
||||
if ($p($key, $element)) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
public function indexOf($element)
|
||||
{
|
||||
return array_search($element, $this->elements, \true);
|
||||
}
|
||||
public function get($key)
|
||||
{
|
||||
return $this->elements[$key] ?? null;
|
||||
}
|
||||
public function getKeys()
|
||||
{
|
||||
return array_keys($this->elements);
|
||||
}
|
||||
public function getValues()
|
||||
{
|
||||
return array_values($this->elements);
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return count($this->elements);
|
||||
}
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->elements[$key] = $value;
|
||||
}
|
||||
public function add($element)
|
||||
{
|
||||
$this->elements[] = $element;
|
||||
return \true;
|
||||
}
|
||||
public function isEmpty()
|
||||
{
|
||||
return empty($this->elements);
|
||||
}
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->elements);
|
||||
}
|
||||
public function map(Closure $func)
|
||||
{
|
||||
return $this->createFrom(array_map($func, $this->elements));
|
||||
}
|
||||
public function filter(Closure $p)
|
||||
{
|
||||
return $this->createFrom(array_filter($this->elements, $p, ARRAY_FILTER_USE_BOTH));
|
||||
}
|
||||
public function forAll(Closure $p)
|
||||
{
|
||||
foreach ($this->elements as $key => $element) {
|
||||
if (!$p($key, $element)) {
|
||||
return \false;
|
||||
}
|
||||
}
|
||||
return \true;
|
||||
}
|
||||
public function partition(Closure $p)
|
||||
{
|
||||
$matches = $noMatches = [];
|
||||
foreach ($this->elements as $key => $element) {
|
||||
if ($p($key, $element)) {
|
||||
$matches[$key] = $element;
|
||||
} else {
|
||||
$noMatches[$key] = $element;
|
||||
}
|
||||
}
|
||||
return [$this->createFrom($matches), $this->createFrom($noMatches)];
|
||||
}
|
||||
public function __toString()
|
||||
{
|
||||
return self::class . '@' . spl_object_hash($this);
|
||||
}
|
||||
public function clear()
|
||||
{
|
||||
$this->elements = [];
|
||||
}
|
||||
public function slice($offset, $length = null)
|
||||
{
|
||||
return array_slice($this->elements, $offset, $length, \true);
|
||||
}
|
||||
public function matching(Criteria $criteria)
|
||||
{
|
||||
$expr = $criteria->getWhereExpression();
|
||||
$filtered = $this->elements;
|
||||
if ($expr) {
|
||||
$visitor = new ClosureExpressionVisitor();
|
||||
$filter = $visitor->dispatch($expr);
|
||||
$filtered = array_filter($filtered, $filter);
|
||||
}
|
||||
$orderings = $criteria->getOrderings();
|
||||
if ($orderings) {
|
||||
$next = null;
|
||||
foreach (array_reverse($orderings) as $field => $ordering) {
|
||||
$next = ClosureExpressionVisitor::sortByField($field, $ordering === Criteria::DESC ? -1 : 1, $next);
|
||||
}
|
||||
uasort($filtered, $next);
|
||||
}
|
||||
$offset = $criteria->getFirstResult();
|
||||
$length = $criteria->getMaxResults();
|
||||
if ($offset || $length) {
|
||||
$filtered = array_slice($filtered, (int) $offset, $length);
|
||||
}
|
||||
return $this->createFrom($filtered);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use ArrayAccess;
|
||||
use Closure;
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
interface Collection extends Countable, IteratorAggregate, ArrayAccess
|
||||
{
|
||||
public function add($element);
|
||||
public function clear();
|
||||
public function contains($element);
|
||||
public function isEmpty();
|
||||
public function remove($key);
|
||||
public function removeElement($element);
|
||||
public function containsKey($key);
|
||||
public function get($key);
|
||||
public function getKeys();
|
||||
public function getValues();
|
||||
public function set($key, $value);
|
||||
public function toArray();
|
||||
public function first();
|
||||
public function last();
|
||||
public function key();
|
||||
public function current();
|
||||
public function next();
|
||||
public function exists(Closure $p);
|
||||
public function filter(Closure $p);
|
||||
public function forAll(Closure $p);
|
||||
public function map(Closure $func);
|
||||
public function partition(Closure $p);
|
||||
public function indexOf($element);
|
||||
public function slice($offset, $length = null);
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Collections\Expr\CompositeExpression;
|
||||
use MailPoetVendor\Doctrine\Common\Collections\Expr\Expression;
|
||||
use function array_map;
|
||||
use function strtoupper;
|
||||
class Criteria
|
||||
{
|
||||
public const ASC = 'ASC';
|
||||
public const DESC = 'DESC';
|
||||
private static $expressionBuilder;
|
||||
private $expression;
|
||||
private $orderings = [];
|
||||
private $firstResult;
|
||||
private $maxResults;
|
||||
public static function create()
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
public static function expr()
|
||||
{
|
||||
if (self::$expressionBuilder === null) {
|
||||
self::$expressionBuilder = new ExpressionBuilder();
|
||||
}
|
||||
return self::$expressionBuilder;
|
||||
}
|
||||
public function __construct(?Expression $expression = null, ?array $orderings = null, $firstResult = null, $maxResults = null)
|
||||
{
|
||||
$this->expression = $expression;
|
||||
$this->setFirstResult($firstResult);
|
||||
$this->setMaxResults($maxResults);
|
||||
if ($orderings === null) {
|
||||
return;
|
||||
}
|
||||
$this->orderBy($orderings);
|
||||
}
|
||||
public function where(Expression $expression)
|
||||
{
|
||||
$this->expression = $expression;
|
||||
return $this;
|
||||
}
|
||||
public function andWhere(Expression $expression)
|
||||
{
|
||||
if ($this->expression === null) {
|
||||
return $this->where($expression);
|
||||
}
|
||||
$this->expression = new CompositeExpression(CompositeExpression::TYPE_AND, [$this->expression, $expression]);
|
||||
return $this;
|
||||
}
|
||||
public function orWhere(Expression $expression)
|
||||
{
|
||||
if ($this->expression === null) {
|
||||
return $this->where($expression);
|
||||
}
|
||||
$this->expression = new CompositeExpression(CompositeExpression::TYPE_OR, [$this->expression, $expression]);
|
||||
return $this;
|
||||
}
|
||||
public function getWhereExpression()
|
||||
{
|
||||
return $this->expression;
|
||||
}
|
||||
public function getOrderings()
|
||||
{
|
||||
return $this->orderings;
|
||||
}
|
||||
public function orderBy(array $orderings)
|
||||
{
|
||||
$this->orderings = array_map(static function (string $ordering) : string {
|
||||
return strtoupper($ordering) === Criteria::ASC ? Criteria::ASC : Criteria::DESC;
|
||||
}, $orderings);
|
||||
return $this;
|
||||
}
|
||||
public function getFirstResult()
|
||||
{
|
||||
return $this->firstResult;
|
||||
}
|
||||
public function setFirstResult($firstResult)
|
||||
{
|
||||
$this->firstResult = $firstResult;
|
||||
return $this;
|
||||
}
|
||||
public function getMaxResults()
|
||||
{
|
||||
return $this->maxResults;
|
||||
}
|
||||
public function setMaxResults($maxResults)
|
||||
{
|
||||
$this->maxResults = $maxResults;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections\Expr;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use ArrayAccess;
|
||||
use Closure;
|
||||
use RuntimeException;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_scalar;
|
||||
use function iterator_to_array;
|
||||
use function method_exists;
|
||||
use function preg_match;
|
||||
use function preg_replace_callback;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function strtoupper;
|
||||
use function substr;
|
||||
class ClosureExpressionVisitor extends ExpressionVisitor
|
||||
{
|
||||
public static function getObjectFieldValue($object, $field)
|
||||
{
|
||||
if (is_array($object)) {
|
||||
return $object[$field];
|
||||
}
|
||||
$accessors = ['get', 'is'];
|
||||
foreach ($accessors as $accessor) {
|
||||
$accessor .= $field;
|
||||
if (method_exists($object, $accessor)) {
|
||||
return $object->{$accessor}();
|
||||
}
|
||||
}
|
||||
if (preg_match('/^is[A-Z]+/', $field) === 1 && method_exists($object, $field)) {
|
||||
return $object->{$field}();
|
||||
}
|
||||
// __call should be triggered for get.
|
||||
$accessor = $accessors[0] . $field;
|
||||
if (method_exists($object, '__call')) {
|
||||
return $object->{$accessor}();
|
||||
}
|
||||
if ($object instanceof ArrayAccess) {
|
||||
return $object[$field];
|
||||
}
|
||||
if (isset($object->{$field})) {
|
||||
return $object->{$field};
|
||||
}
|
||||
// camelcase field name to support different variable naming conventions
|
||||
$ccField = preg_replace_callback('/_(.?)/', static function ($matches) {
|
||||
return strtoupper($matches[1]);
|
||||
}, $field);
|
||||
foreach ($accessors as $accessor) {
|
||||
$accessor .= $ccField;
|
||||
if (method_exists($object, $accessor)) {
|
||||
return $object->{$accessor}();
|
||||
}
|
||||
}
|
||||
return $object->{$field};
|
||||
}
|
||||
public static function sortByField($name, $orientation = 1, ?Closure $next = null)
|
||||
{
|
||||
if (!$next) {
|
||||
$next = static function () : int {
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
return static function ($a, $b) use($name, $next, $orientation) : int {
|
||||
$aValue = ClosureExpressionVisitor::getObjectFieldValue($a, $name);
|
||||
$bValue = ClosureExpressionVisitor::getObjectFieldValue($b, $name);
|
||||
if ($aValue === $bValue) {
|
||||
return $next($a, $b);
|
||||
}
|
||||
return ($aValue > $bValue ? 1 : -1) * $orientation;
|
||||
};
|
||||
}
|
||||
public function walkComparison(Comparison $comparison)
|
||||
{
|
||||
$field = $comparison->getField();
|
||||
$value = $comparison->getValue()->getValue();
|
||||
// shortcut for walkValue()
|
||||
switch ($comparison->getOperator()) {
|
||||
case Comparison::EQ:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) === $value;
|
||||
};
|
||||
case Comparison::NEQ:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) !== $value;
|
||||
};
|
||||
case Comparison::LT:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) < $value;
|
||||
};
|
||||
case Comparison::LTE:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) <= $value;
|
||||
};
|
||||
case Comparison::GT:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) > $value;
|
||||
};
|
||||
case Comparison::GTE:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) >= $value;
|
||||
};
|
||||
case Comparison::IN:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
$fieldValue = ClosureExpressionVisitor::getObjectFieldValue($object, $field);
|
||||
return in_array($fieldValue, $value, is_scalar($fieldValue));
|
||||
};
|
||||
case Comparison::NIN:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
$fieldValue = ClosureExpressionVisitor::getObjectFieldValue($object, $field);
|
||||
return !in_array($fieldValue, $value, is_scalar($fieldValue));
|
||||
};
|
||||
case Comparison::CONTAINS:
|
||||
return static function ($object) use($field, $value) {
|
||||
return strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value) !== \false;
|
||||
};
|
||||
case Comparison::MEMBER_OF:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
$fieldValues = ClosureExpressionVisitor::getObjectFieldValue($object, $field);
|
||||
if (!is_array($fieldValues)) {
|
||||
$fieldValues = iterator_to_array($fieldValues);
|
||||
}
|
||||
return in_array($value, $fieldValues, \true);
|
||||
};
|
||||
case Comparison::STARTS_WITH:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
return strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value) === 0;
|
||||
};
|
||||
case Comparison::ENDS_WITH:
|
||||
return static function ($object) use($field, $value) : bool {
|
||||
return $value === substr(ClosureExpressionVisitor::getObjectFieldValue($object, $field), -strlen($value));
|
||||
};
|
||||
default:
|
||||
throw new RuntimeException('Unknown comparison operator: ' . $comparison->getOperator());
|
||||
}
|
||||
}
|
||||
public function walkValue(Value $value)
|
||||
{
|
||||
return $value->getValue();
|
||||
}
|
||||
public function walkCompositeExpression(CompositeExpression $expr)
|
||||
{
|
||||
$expressionList = [];
|
||||
foreach ($expr->getExpressionList() as $child) {
|
||||
$expressionList[] = $this->dispatch($child);
|
||||
}
|
||||
switch ($expr->getType()) {
|
||||
case CompositeExpression::TYPE_AND:
|
||||
return $this->andExpressions($expressionList);
|
||||
case CompositeExpression::TYPE_OR:
|
||||
return $this->orExpressions($expressionList);
|
||||
default:
|
||||
throw new RuntimeException('Unknown composite ' . $expr->getType());
|
||||
}
|
||||
}
|
||||
private function andExpressions(array $expressions) : callable
|
||||
{
|
||||
return static function ($object) use($expressions) : bool {
|
||||
foreach ($expressions as $expression) {
|
||||
if (!$expression($object)) {
|
||||
return \false;
|
||||
}
|
||||
}
|
||||
return \true;
|
||||
};
|
||||
}
|
||||
private function orExpressions(array $expressions) : callable
|
||||
{
|
||||
return static function ($object) use($expressions) : bool {
|
||||
foreach ($expressions as $expression) {
|
||||
if ($expression($object)) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
};
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections\Expr;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
class Comparison implements Expression
|
||||
{
|
||||
public const EQ = '=';
|
||||
public const NEQ = '<>';
|
||||
public const LT = '<';
|
||||
public const LTE = '<=';
|
||||
public const GT = '>';
|
||||
public const GTE = '>=';
|
||||
public const IS = '=';
|
||||
// no difference with EQ
|
||||
public const IN = 'IN';
|
||||
public const NIN = 'NIN';
|
||||
public const CONTAINS = 'CONTAINS';
|
||||
public const MEMBER_OF = 'MEMBER_OF';
|
||||
public const STARTS_WITH = 'STARTS_WITH';
|
||||
public const ENDS_WITH = 'ENDS_WITH';
|
||||
private $field;
|
||||
private $op;
|
||||
private $value;
|
||||
public function __construct($field, $operator, $value)
|
||||
{
|
||||
if (!$value instanceof Value) {
|
||||
$value = new Value($value);
|
||||
}
|
||||
$this->field = $field;
|
||||
$this->op = $operator;
|
||||
$this->value = $value;
|
||||
}
|
||||
public function getField()
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
public function getOperator()
|
||||
{
|
||||
return $this->op;
|
||||
}
|
||||
public function visit(ExpressionVisitor $visitor)
|
||||
{
|
||||
return $visitor->walkComparison($this);
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections\Expr;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use RuntimeException;
|
||||
class CompositeExpression implements Expression
|
||||
{
|
||||
public const TYPE_AND = 'AND';
|
||||
public const TYPE_OR = 'OR';
|
||||
private $type;
|
||||
private $expressions = [];
|
||||
public function __construct($type, array $expressions)
|
||||
{
|
||||
$this->type = $type;
|
||||
foreach ($expressions as $expr) {
|
||||
if ($expr instanceof Value) {
|
||||
throw new RuntimeException('Values are not supported expressions as children of and/or expressions.');
|
||||
}
|
||||
if (!$expr instanceof Expression) {
|
||||
throw new RuntimeException('No expression given to CompositeExpression.');
|
||||
}
|
||||
$this->expressions[] = $expr;
|
||||
}
|
||||
}
|
||||
public function getExpressionList()
|
||||
{
|
||||
return $this->expressions;
|
||||
}
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
public function visit(ExpressionVisitor $visitor)
|
||||
{
|
||||
return $visitor->walkCompositeExpression($this);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections\Expr;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface Expression
|
||||
{
|
||||
public function visit(ExpressionVisitor $visitor);
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections\Expr;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use RuntimeException;
|
||||
use function get_class;
|
||||
abstract class ExpressionVisitor
|
||||
{
|
||||
public abstract function walkComparison(Comparison $comparison);
|
||||
public abstract function walkValue(Value $value);
|
||||
public abstract function walkCompositeExpression(CompositeExpression $expr);
|
||||
public function dispatch(Expression $expr)
|
||||
{
|
||||
switch (\true) {
|
||||
case $expr instanceof Comparison:
|
||||
return $this->walkComparison($expr);
|
||||
case $expr instanceof Value:
|
||||
return $this->walkValue($expr);
|
||||
case $expr instanceof CompositeExpression:
|
||||
return $this->walkCompositeExpression($expr);
|
||||
default:
|
||||
throw new RuntimeException('Unknown Expression ' . get_class($expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections\Expr;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
class Value implements Expression
|
||||
{
|
||||
private $value;
|
||||
public function __construct($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
public function visit(ExpressionVisitor $visitor)
|
||||
{
|
||||
return $visitor->walkValue($this);
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Collections\Expr\Comparison;
|
||||
use MailPoetVendor\Doctrine\Common\Collections\Expr\CompositeExpression;
|
||||
use MailPoetVendor\Doctrine\Common\Collections\Expr\Value;
|
||||
use function func_get_args;
|
||||
class ExpressionBuilder
|
||||
{
|
||||
public function andX($x = null)
|
||||
{
|
||||
return new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
|
||||
}
|
||||
public function orX($x = null)
|
||||
{
|
||||
return new CompositeExpression(CompositeExpression::TYPE_OR, func_get_args());
|
||||
}
|
||||
public function eq($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::EQ, new Value($value));
|
||||
}
|
||||
public function gt($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::GT, new Value($value));
|
||||
}
|
||||
public function lt($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::LT, new Value($value));
|
||||
}
|
||||
public function gte($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::GTE, new Value($value));
|
||||
}
|
||||
public function lte($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::LTE, new Value($value));
|
||||
}
|
||||
public function neq($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::NEQ, new Value($value));
|
||||
}
|
||||
public function isNull($field)
|
||||
{
|
||||
return new Comparison($field, Comparison::EQ, new Value(null));
|
||||
}
|
||||
public function in($field, array $values)
|
||||
{
|
||||
return new Comparison($field, Comparison::IN, new Value($values));
|
||||
}
|
||||
public function notIn($field, array $values)
|
||||
{
|
||||
return new Comparison($field, Comparison::NIN, new Value($values));
|
||||
}
|
||||
public function contains($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::CONTAINS, new Value($value));
|
||||
}
|
||||
public function memberOf($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::MEMBER_OF, new Value($value));
|
||||
}
|
||||
public function startsWith($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::STARTS_WITH, new Value($value));
|
||||
}
|
||||
public function endsWith($field, $value)
|
||||
{
|
||||
return new Comparison($field, Comparison::ENDS_WITH, new Value($value));
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Collections;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface Selectable
|
||||
{
|
||||
public function matching(Criteria $criteria);
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use function class_exists;
|
||||
use function interface_exists;
|
||||
use function is_array;
|
||||
use function is_file;
|
||||
use function reset;
|
||||
use function spl_autoload_functions;
|
||||
use function spl_autoload_register;
|
||||
use function spl_autoload_unregister;
|
||||
use function str_replace;
|
||||
use function stream_resolve_include_path;
|
||||
use function strpos;
|
||||
use function trait_exists;
|
||||
use function trigger_error;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const E_USER_DEPRECATED;
|
||||
@trigger_error(ClassLoader::class . ' is deprecated.', E_USER_DEPRECATED);
|
||||
class ClassLoader
|
||||
{
|
||||
protected $fileExtension = '.php';
|
||||
protected $namespace;
|
||||
protected $includePath;
|
||||
protected $namespaceSeparator = '\\';
|
||||
public function __construct($ns = null, $includePath = null)
|
||||
{
|
||||
$this->namespace = $ns;
|
||||
$this->includePath = $includePath;
|
||||
}
|
||||
public function setNamespaceSeparator($sep)
|
||||
{
|
||||
$this->namespaceSeparator = $sep;
|
||||
}
|
||||
public function getNamespaceSeparator()
|
||||
{
|
||||
return $this->namespaceSeparator;
|
||||
}
|
||||
public function setIncludePath($includePath)
|
||||
{
|
||||
$this->includePath = $includePath;
|
||||
}
|
||||
public function getIncludePath()
|
||||
{
|
||||
return $this->includePath;
|
||||
}
|
||||
public function setFileExtension($fileExtension)
|
||||
{
|
||||
$this->fileExtension = $fileExtension;
|
||||
}
|
||||
public function getFileExtension()
|
||||
{
|
||||
return $this->fileExtension;
|
||||
}
|
||||
public function register()
|
||||
{
|
||||
spl_autoload_register([$this, 'loadClass']);
|
||||
}
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister([$this, 'loadClass']);
|
||||
}
|
||||
public function loadClass($className)
|
||||
{
|
||||
if (self::typeExists($className)) {
|
||||
return \true;
|
||||
}
|
||||
if (!$this->canLoadClass($className)) {
|
||||
return \false;
|
||||
}
|
||||
require ($this->includePath !== null ? $this->includePath . DIRECTORY_SEPARATOR : '') . str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension;
|
||||
return self::typeExists($className);
|
||||
}
|
||||
public function canLoadClass($className)
|
||||
{
|
||||
if ($this->namespace !== null && strpos($className, $this->namespace . $this->namespaceSeparator) !== 0) {
|
||||
return \false;
|
||||
}
|
||||
$file = str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension;
|
||||
if ($this->includePath !== null) {
|
||||
return is_file($this->includePath . DIRECTORY_SEPARATOR . $file);
|
||||
}
|
||||
return stream_resolve_include_path($file) !== \false;
|
||||
}
|
||||
public static function classExists($className)
|
||||
{
|
||||
return self::typeExists($className, \true);
|
||||
}
|
||||
public static function getClassLoader($className)
|
||||
{
|
||||
foreach (spl_autoload_functions() as $loader) {
|
||||
if (!is_array($loader)) {
|
||||
continue;
|
||||
}
|
||||
$classLoader = reset($loader);
|
||||
if ($classLoader instanceof ClassLoader && $classLoader->canLoadClass($className)) {
|
||||
return $classLoader;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static function typeExists($type, $autoload = \false)
|
||||
{
|
||||
return class_exists($type, $autoload) || interface_exists($type, $autoload) || trait_exists($type, $autoload);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use Exception;
|
||||
class CommonException extends Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface Comparable
|
||||
{
|
||||
public function compareTo($other);
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Proxy;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Proxy\Exception\InvalidArgumentException;
|
||||
use MailPoetVendor\Doctrine\Common\Proxy\Exception\OutOfBoundsException;
|
||||
use MailPoetVendor\Doctrine\Common\Util\ClassUtils;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadataFactory;
|
||||
use function class_exists;
|
||||
use function file_exists;
|
||||
use function filemtime;
|
||||
use function in_array;
|
||||
abstract class AbstractProxyFactory
|
||||
{
|
||||
public const AUTOGENERATE_NEVER = 0;
|
||||
public const AUTOGENERATE_ALWAYS = 1;
|
||||
public const AUTOGENERATE_FILE_NOT_EXISTS = 2;
|
||||
public const AUTOGENERATE_EVAL = 3;
|
||||
public const AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED = 4;
|
||||
private const AUTOGENERATE_MODES = [self::AUTOGENERATE_NEVER, self::AUTOGENERATE_ALWAYS, self::AUTOGENERATE_FILE_NOT_EXISTS, self::AUTOGENERATE_EVAL, self::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED];
|
||||
private $metadataFactory;
|
||||
private $proxyGenerator;
|
||||
private $autoGenerate;
|
||||
private $definitions = [];
|
||||
public function __construct(ProxyGenerator $proxyGenerator, ClassMetadataFactory $metadataFactory, $autoGenerate)
|
||||
{
|
||||
$this->proxyGenerator = $proxyGenerator;
|
||||
$this->metadataFactory = $metadataFactory;
|
||||
$this->autoGenerate = (int) $autoGenerate;
|
||||
if (!in_array($this->autoGenerate, self::AUTOGENERATE_MODES, \true)) {
|
||||
throw InvalidArgumentException::invalidAutoGenerateMode($autoGenerate);
|
||||
}
|
||||
}
|
||||
public function getProxy($className, array $identifier)
|
||||
{
|
||||
$definition = $this->definitions[$className] ?? $this->getProxyDefinition($className);
|
||||
$fqcn = $definition->proxyClassName;
|
||||
$proxy = new $fqcn($definition->initializer, $definition->cloner);
|
||||
foreach ($definition->identifierFields as $idField) {
|
||||
if (!isset($identifier[$idField])) {
|
||||
throw OutOfBoundsException::missingPrimaryKeyValue($className, $idField);
|
||||
}
|
||||
$definition->reflectionFields[$idField]->setValue($proxy, $identifier[$idField]);
|
||||
}
|
||||
return $proxy;
|
||||
}
|
||||
public function generateProxyClasses(array $classes, $proxyDir = null)
|
||||
{
|
||||
$generated = 0;
|
||||
foreach ($classes as $class) {
|
||||
if ($this->skipClass($class)) {
|
||||
continue;
|
||||
}
|
||||
$proxyFileName = $this->proxyGenerator->getProxyFileName($class->getName(), $proxyDir);
|
||||
$this->proxyGenerator->generateProxyClass($class, $proxyFileName);
|
||||
$generated += 1;
|
||||
}
|
||||
return $generated;
|
||||
}
|
||||
public function resetUninitializedProxy(Proxy $proxy)
|
||||
{
|
||||
if ($proxy->__isInitialized()) {
|
||||
throw InvalidArgumentException::unitializedProxyExpected($proxy);
|
||||
}
|
||||
$className = ClassUtils::getClass($proxy);
|
||||
$definition = $this->definitions[$className] ?? $this->getProxyDefinition($className);
|
||||
$proxy->__setInitializer($definition->initializer);
|
||||
$proxy->__setCloner($definition->cloner);
|
||||
return $proxy;
|
||||
}
|
||||
private function getProxyDefinition($className)
|
||||
{
|
||||
$classMetadata = $this->metadataFactory->getMetadataFor($className);
|
||||
$className = $classMetadata->getName();
|
||||
// aliases and case sensitivity
|
||||
$this->definitions[$className] = $this->createProxyDefinition($className);
|
||||
$proxyClassName = $this->definitions[$className]->proxyClassName;
|
||||
if (!class_exists($proxyClassName, \false)) {
|
||||
$fileName = $this->proxyGenerator->getProxyFileName($className);
|
||||
switch ($this->autoGenerate) {
|
||||
case self::AUTOGENERATE_NEVER:
|
||||
require $fileName;
|
||||
break;
|
||||
case self::AUTOGENERATE_FILE_NOT_EXISTS:
|
||||
if (!file_exists($fileName)) {
|
||||
$this->proxyGenerator->generateProxyClass($classMetadata, $fileName);
|
||||
}
|
||||
require $fileName;
|
||||
break;
|
||||
case self::AUTOGENERATE_ALWAYS:
|
||||
$this->proxyGenerator->generateProxyClass($classMetadata, $fileName);
|
||||
require $fileName;
|
||||
break;
|
||||
case self::AUTOGENERATE_EVAL:
|
||||
$this->proxyGenerator->generateProxyClass($classMetadata, \false);
|
||||
break;
|
||||
case self::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED:
|
||||
if (!file_exists($fileName) || filemtime($fileName) < filemtime($classMetadata->getReflectionClass()->getFileName())) {
|
||||
$this->proxyGenerator->generateProxyClass($classMetadata, $fileName);
|
||||
}
|
||||
require $fileName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $this->definitions[$className];
|
||||
}
|
||||
protected abstract function skipClass(ClassMetadata $metadata);
|
||||
protected abstract function createProxyDefinition($className);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Proxy;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use Closure;
|
||||
use MailPoetVendor\Doctrine\Common\Proxy\Exception\InvalidArgumentException;
|
||||
use function call_user_func;
|
||||
use function file_exists;
|
||||
use function is_callable;
|
||||
use function ltrim;
|
||||
use function spl_autoload_register;
|
||||
use function str_replace;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
class Autoloader
|
||||
{
|
||||
public static function resolveFile($proxyDir, $proxyNamespace, $className)
|
||||
{
|
||||
if (strpos($className, $proxyNamespace) !== 0) {
|
||||
throw InvalidArgumentException::notProxyClass($className, $proxyNamespace);
|
||||
}
|
||||
// remove proxy namespace from class name
|
||||
$classNameRelativeToProxyNamespace = substr($className, strlen($proxyNamespace));
|
||||
// remove namespace separators from remaining class name
|
||||
$fileName = str_replace('\\', '', $classNameRelativeToProxyNamespace);
|
||||
return $proxyDir . DIRECTORY_SEPARATOR . $fileName . '.php';
|
||||
}
|
||||
public static function register($proxyDir, $proxyNamespace, $notFoundCallback = null)
|
||||
{
|
||||
$proxyNamespace = ltrim($proxyNamespace, '\\');
|
||||
if ($notFoundCallback !== null && !is_callable($notFoundCallback)) {
|
||||
throw InvalidArgumentException::invalidClassNotFoundCallback($notFoundCallback);
|
||||
}
|
||||
$autoloader = static function ($className) use($proxyDir, $proxyNamespace, $notFoundCallback) {
|
||||
if ($proxyNamespace === '') {
|
||||
return;
|
||||
}
|
||||
if (strpos($className, $proxyNamespace) !== 0) {
|
||||
return;
|
||||
}
|
||||
$file = Autoloader::resolveFile($proxyDir, $proxyNamespace, $className);
|
||||
if ($notFoundCallback && !file_exists($file)) {
|
||||
call_user_func($notFoundCallback, $proxyDir, $proxyNamespace, $className);
|
||||
}
|
||||
require $file;
|
||||
};
|
||||
spl_autoload_register($autoloader);
|
||||
return $autoloader;
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Proxy\Exception;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Proxy;
|
||||
use InvalidArgumentException as BaseInvalidArgumentException;
|
||||
use function get_class;
|
||||
use function gettype;
|
||||
use function is_object;
|
||||
use function sprintf;
|
||||
class InvalidArgumentException extends BaseInvalidArgumentException implements ProxyException
|
||||
{
|
||||
public static function proxyDirectoryRequired()
|
||||
{
|
||||
return new self('You must configure a proxy directory. See docs for details');
|
||||
}
|
||||
public static function notProxyClass($className, $proxyNamespace)
|
||||
{
|
||||
return new self(sprintf('The class "%s" is not part of the proxy namespace "%s"', $className, $proxyNamespace));
|
||||
}
|
||||
public static function invalidPlaceholder($name)
|
||||
{
|
||||
return new self(sprintf('Provided placeholder for "%s" must be either a string or a valid callable', $name));
|
||||
}
|
||||
public static function proxyNamespaceRequired()
|
||||
{
|
||||
return new self('You must configure a proxy namespace');
|
||||
}
|
||||
public static function unitializedProxyExpected(Proxy $proxy)
|
||||
{
|
||||
return new self(sprintf('Provided proxy of type "%s" must not be initialized.', get_class($proxy)));
|
||||
}
|
||||
public static function invalidClassNotFoundCallback($callback)
|
||||
{
|
||||
$type = is_object($callback) ? get_class($callback) : gettype($callback);
|
||||
return new self(sprintf('Invalid \\$notFoundCallback given: must be a callable, "%s" given', $type));
|
||||
}
|
||||
public static function classMustNotBeAbstract($className)
|
||||
{
|
||||
return new self(sprintf('Unable to create a proxy for an abstract class "%s".', $className));
|
||||
}
|
||||
public static function classMustNotBeFinal($className)
|
||||
{
|
||||
return new self(sprintf('Unable to create a proxy for a final class "%s".', $className));
|
||||
}
|
||||
public static function classMustNotBeReadOnly($className)
|
||||
{
|
||||
return new self(sprintf('Unable to create a proxy for a readonly class "%s".', $className));
|
||||
}
|
||||
public static function invalidAutoGenerateMode($value) : self
|
||||
{
|
||||
return new self(sprintf('Invalid auto generate mode "%s" given.', $value));
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Proxy\Exception;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use OutOfBoundsException as BaseOutOfBoundsException;
|
||||
use function sprintf;
|
||||
class OutOfBoundsException extends BaseOutOfBoundsException implements ProxyException
|
||||
{
|
||||
public static function missingPrimaryKeyValue($className, $idField)
|
||||
{
|
||||
return new self(sprintf('Missing value for primary key %s on %s', $idField, $className));
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Proxy\Exception;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
interface ProxyException
|
||||
{
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Proxy\Exception;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use Throwable;
|
||||
use UnexpectedValueException as BaseUnexpectedValueException;
|
||||
use function sprintf;
|
||||
class UnexpectedValueException extends BaseUnexpectedValueException implements ProxyException
|
||||
{
|
||||
public static function proxyDirectoryNotWritable($proxyDirectory)
|
||||
{
|
||||
return new self(sprintf('Your proxy directory "%s" must be writable', $proxyDirectory));
|
||||
}
|
||||
public static function invalidParameterTypeHint($className, $methodName, $parameterName, ?Throwable $previous = null)
|
||||
{
|
||||
return new self(sprintf('The type hint of parameter "%s" in method "%s" in class "%s" is invalid.', $parameterName, $methodName, $className), 0, $previous);
|
||||
}
|
||||
public static function invalidReturnTypeHint($className, $methodName, ?Throwable $previous = null)
|
||||
{
|
||||
return new self(sprintf('The return type of method "%s" in class "%s" is invalid.', $methodName, $className), 0, $previous);
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Proxy;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use Closure;
|
||||
use MailPoetVendor\Doctrine\Persistence\Proxy as BaseProxy;
|
||||
interface Proxy extends BaseProxy
|
||||
{
|
||||
public function __setInitialized($initialized);
|
||||
public function __setInitializer(?Closure $initializer = null);
|
||||
public function __getInitializer();
|
||||
public function __setCloner(?Closure $cloner = null);
|
||||
public function __getCloner();
|
||||
public function __getLazyProperties();
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Proxy;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use ReflectionProperty;
|
||||
class ProxyDefinition
|
||||
{
|
||||
public $proxyClassName;
|
||||
public $identifierFields;
|
||||
public $reflectionFields;
|
||||
public $initializer;
|
||||
public $cloner;
|
||||
public function __construct($proxyClassName, array $identifierFields, array $reflectionFields, $initializer, $cloner)
|
||||
{
|
||||
$this->proxyClassName = $proxyClassName;
|
||||
$this->identifierFields = $identifierFields;
|
||||
$this->reflectionFields = $reflectionFields;
|
||||
$this->initializer = $initializer;
|
||||
$this->cloner = $cloner;
|
||||
}
|
||||
}
|
||||
+733
@@ -0,0 +1,733 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Proxy;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use BackedEnum;
|
||||
use MailPoetVendor\Doctrine\Common\Proxy\Exception\InvalidArgumentException;
|
||||
use MailPoetVendor\Doctrine\Common\Proxy\Exception\UnexpectedValueException;
|
||||
use MailPoetVendor\Doctrine\Common\Util\ClassUtils;
|
||||
use MailPoetVendor\Doctrine\Persistence\Mapping\ClassMetadata;
|
||||
use ReflectionIntersectionType;
|
||||
use ReflectionMethod;
|
||||
use ReflectionNamedType;
|
||||
use ReflectionParameter;
|
||||
use ReflectionProperty;
|
||||
use ReflectionType;
|
||||
use ReflectionUnionType;
|
||||
use function array_combine;
|
||||
use function array_diff;
|
||||
use function array_key_exists;
|
||||
use function array_map;
|
||||
use function array_slice;
|
||||
use function array_unique;
|
||||
use function assert;
|
||||
use function bin2hex;
|
||||
use function call_user_func;
|
||||
use function chmod;
|
||||
use function class_exists;
|
||||
use function dirname;
|
||||
use function explode;
|
||||
use function file;
|
||||
use function file_put_contents;
|
||||
use function get_class;
|
||||
use function implode;
|
||||
use function in_array;
|
||||
use function interface_exists;
|
||||
use function is_callable;
|
||||
use function is_dir;
|
||||
use function is_scalar;
|
||||
use function is_string;
|
||||
use function is_writable;
|
||||
use function lcfirst;
|
||||
use function ltrim;
|
||||
use function method_exists;
|
||||
use function mkdir;
|
||||
use function preg_match;
|
||||
use function preg_match_all;
|
||||
use function preg_replace;
|
||||
use function preg_split;
|
||||
use function random_bytes;
|
||||
use function rename;
|
||||
use function rtrim;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
use function strpos;
|
||||
use function strrev;
|
||||
use function strtolower;
|
||||
use function strtr;
|
||||
use function substr;
|
||||
use function trim;
|
||||
use function var_export;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const PHP_VERSION_ID;
|
||||
use const PREG_SPLIT_DELIM_CAPTURE;
|
||||
class ProxyGenerator
|
||||
{
|
||||
public const PATTERN_MATCH_ID_METHOD = <<<'EOT'
|
||||
((?(DEFINE)
|
||||
(?<type>\\?[a-z_\x7f-\xff][\w\x7f-\xff]*(?:\\[a-z_\x7f-\xff][\w\x7f-\xff]*)*)
|
||||
(?<intersection_type>(?&type)\s*&\s*(?&type))
|
||||
(?<union_type>(?:(?:\(\s*(?&intersection_type)\s*\))|(?&type))(?:\s*\|\s*(?:(?:\(\s*(?&intersection_type)\s*\))|(?&type)))+)
|
||||
)(?:public\s+)?(?:function\s+%s\s*\(\)\s*)\s*(?::\s*(?:(?&union_type)|(?&intersection_type)|(?:\??(?&type)))\s*)?{\s*return\s*\$this->%s;\s*})i
|
||||
EOT;
|
||||
private $proxyNamespace;
|
||||
private $proxyDirectory;
|
||||
protected $placeholders = ['baseProxyInterface' => Proxy::class, 'additionalProperties' => ''];
|
||||
protected $proxyClassTemplate = '<?php
|
||||
namespace <namespace>;
|
||||
<enumUseStatements>
|
||||
class <proxyShortClassName> extends \\<className> implements \\<baseProxyInterface>
|
||||
{
|
||||
public $__initializer__;
|
||||
public $__cloner__;
|
||||
public $__isInitialized__ = false;
|
||||
public static $lazyPropertiesNames = <lazyPropertiesNames>;
|
||||
public static $lazyPropertiesDefaults = <lazyPropertiesDefaults>;
|
||||
<additionalProperties>
|
||||
<constructorImpl>
|
||||
<magicGet>
|
||||
<magicSet>
|
||||
<magicIsset>
|
||||
<sleepImpl>
|
||||
<wakeupImpl>
|
||||
<cloneImpl>
|
||||
public function __load(): void
|
||||
{
|
||||
$this->__initializer__ && $this->__initializer__->__invoke($this, \'__load\', []);
|
||||
}
|
||||
public function __isInitialized(): bool
|
||||
{
|
||||
return $this->__isInitialized__;
|
||||
}
|
||||
public function __setInitialized($initialized): void
|
||||
{
|
||||
$this->__isInitialized__ = $initialized;
|
||||
}
|
||||
public function __setInitializer(?\\Closure $initializer = null): void
|
||||
{
|
||||
$this->__initializer__ = $initializer;
|
||||
}
|
||||
public function __getInitializer(): ?\\Closure
|
||||
{
|
||||
return $this->__initializer__;
|
||||
}
|
||||
public function __setCloner(?\\Closure $cloner = null): void
|
||||
{
|
||||
$this->__cloner__ = $cloner;
|
||||
}
|
||||
public function __getCloner(): ?\\Closure
|
||||
{
|
||||
return $this->__cloner__;
|
||||
}
|
||||
public function __getLazyProperties(): array
|
||||
{
|
||||
return self::$lazyPropertiesDefaults;
|
||||
}
|
||||
<methods>
|
||||
}
|
||||
';
|
||||
public function __construct($proxyDirectory, $proxyNamespace)
|
||||
{
|
||||
if (!$proxyDirectory) {
|
||||
throw InvalidArgumentException::proxyDirectoryRequired();
|
||||
}
|
||||
if (!$proxyNamespace) {
|
||||
throw InvalidArgumentException::proxyNamespaceRequired();
|
||||
}
|
||||
$this->proxyDirectory = $proxyDirectory;
|
||||
$this->proxyNamespace = $proxyNamespace;
|
||||
}
|
||||
public function setPlaceholder($name, $placeholder)
|
||||
{
|
||||
if (!is_string($placeholder) && !is_callable($placeholder)) {
|
||||
throw InvalidArgumentException::invalidPlaceholder($name);
|
||||
}
|
||||
$this->placeholders[$name] = $placeholder;
|
||||
}
|
||||
public function setProxyClassTemplate($proxyClassTemplate)
|
||||
{
|
||||
$this->proxyClassTemplate = (string) $proxyClassTemplate;
|
||||
}
|
||||
public function generateProxyClass(ClassMetadata $class, $fileName = \false)
|
||||
{
|
||||
$this->verifyClassCanBeProxied($class);
|
||||
preg_match_all('(<([a-zA-Z]+)>)', $this->proxyClassTemplate, $placeholderMatches);
|
||||
$placeholderMatches = array_combine($placeholderMatches[0], $placeholderMatches[1]);
|
||||
$placeholders = [];
|
||||
foreach ($placeholderMatches as $placeholder => $name) {
|
||||
$placeholders[$placeholder] = $this->placeholders[$name] ?? [$this, 'generate' . $name];
|
||||
}
|
||||
foreach ($placeholders as &$placeholder) {
|
||||
if (!is_callable($placeholder)) {
|
||||
continue;
|
||||
}
|
||||
$placeholder = call_user_func($placeholder, $class);
|
||||
}
|
||||
$proxyCode = strtr($this->proxyClassTemplate, $placeholders);
|
||||
if (!$fileName) {
|
||||
$proxyClassName = $this->generateNamespace($class) . '\\' . $this->generateProxyShortClassName($class);
|
||||
if (!class_exists($proxyClassName)) {
|
||||
eval(substr($proxyCode, 5));
|
||||
}
|
||||
return;
|
||||
}
|
||||
$parentDirectory = dirname($fileName);
|
||||
if (!is_dir($parentDirectory) && @mkdir($parentDirectory, 0775, \true) === \false) {
|
||||
throw UnexpectedValueException::proxyDirectoryNotWritable($this->proxyDirectory);
|
||||
}
|
||||
if (!is_writable($parentDirectory)) {
|
||||
throw UnexpectedValueException::proxyDirectoryNotWritable($this->proxyDirectory);
|
||||
}
|
||||
$tmpFileName = $fileName . '.' . bin2hex(random_bytes(12));
|
||||
file_put_contents($tmpFileName, $proxyCode);
|
||||
@chmod($tmpFileName, 0664);
|
||||
rename($tmpFileName, $fileName);
|
||||
}
|
||||
private function verifyClassCanBeProxied(ClassMetadata $class)
|
||||
{
|
||||
if ($class->getReflectionClass()->isFinal()) {
|
||||
throw InvalidArgumentException::classMustNotBeFinal($class->getName());
|
||||
}
|
||||
if ($class->getReflectionClass()->isAbstract()) {
|
||||
throw InvalidArgumentException::classMustNotBeAbstract($class->getName());
|
||||
}
|
||||
if (PHP_VERSION_ID >= 80200 && $class->getReflectionClass()->isReadOnly()) {
|
||||
throw InvalidArgumentException::classMustNotBeReadOnly($class->getName());
|
||||
}
|
||||
}
|
||||
private function generateProxyShortClassName(ClassMetadata $class)
|
||||
{
|
||||
$proxyClassName = ClassUtils::generateProxyClassName($class->getName(), $this->proxyNamespace);
|
||||
$parts = explode('\\', strrev($proxyClassName), 2);
|
||||
return strrev($parts[0]);
|
||||
}
|
||||
private function generateNamespace(ClassMetadata $class)
|
||||
{
|
||||
$proxyClassName = ClassUtils::generateProxyClassName($class->getName(), $this->proxyNamespace);
|
||||
$parts = explode('\\', strrev($proxyClassName), 2);
|
||||
return strrev($parts[1]);
|
||||
}
|
||||
public function generateEnumUseStatements(ClassMetadata $class) : string
|
||||
{
|
||||
if (PHP_VERSION_ID < 80100) {
|
||||
return "\n";
|
||||
}
|
||||
$defaultProperties = $class->getReflectionClass()->getDefaultProperties();
|
||||
$lazyLoadedPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class);
|
||||
$enumClasses = [];
|
||||
foreach ($class->getReflectionClass()->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
|
||||
$name = $property->getName();
|
||||
if (!in_array($name, $lazyLoadedPublicProperties, \true)) {
|
||||
continue;
|
||||
}
|
||||
if (array_key_exists($name, $defaultProperties) && $defaultProperties[$name] instanceof BackedEnum) {
|
||||
$enumClassNameParts = explode('\\', get_class($defaultProperties[$name]));
|
||||
$enumClasses[] = $enumClassNameParts[0];
|
||||
}
|
||||
}
|
||||
return implode("\n", array_map(static function ($className) {
|
||||
return 'use ' . $className . ';';
|
||||
}, array_unique($enumClasses))) . "\n";
|
||||
}
|
||||
private function generateClassName(ClassMetadata $class)
|
||||
{
|
||||
return ltrim($class->getName(), '\\');
|
||||
}
|
||||
private function generateLazyPropertiesNames(ClassMetadata $class)
|
||||
{
|
||||
$lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class);
|
||||
$values = [];
|
||||
foreach ($lazyPublicProperties as $name) {
|
||||
$values[$name] = null;
|
||||
}
|
||||
return var_export($values, \true);
|
||||
}
|
||||
private function generateLazyPropertiesDefaults(ClassMetadata $class)
|
||||
{
|
||||
return var_export($this->getLazyLoadedPublicProperties($class), \true);
|
||||
}
|
||||
private function generateConstructorImpl(ClassMetadata $class)
|
||||
{
|
||||
$constructorImpl = <<<'EOT'
|
||||
public function __construct(?\Closure $initializer = null, ?\Closure $cloner = null)
|
||||
{
|
||||
EOT;
|
||||
$toUnset = array_map(static function (string $name) : string {
|
||||
return '$this->' . $name;
|
||||
}, $this->getLazyLoadedPublicPropertiesNames($class));
|
||||
return $constructorImpl . ($toUnset === [] ? '' : ' unset(' . implode(', ', $toUnset) . ");\n") . <<<'EOT'
|
||||
$this->__initializer__ = $initializer;
|
||||
$this->__cloner__ = $cloner;
|
||||
}
|
||||
EOT;
|
||||
}
|
||||
private function generateMagicGet(ClassMetadata $class)
|
||||
{
|
||||
$lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class);
|
||||
$reflectionClass = $class->getReflectionClass();
|
||||
$hasParentGet = \false;
|
||||
$returnReference = '';
|
||||
$inheritDoc = '';
|
||||
$name = '$name';
|
||||
$parametersString = '$name';
|
||||
$returnTypeHint = null;
|
||||
if ($reflectionClass->hasMethod('__get')) {
|
||||
$hasParentGet = \true;
|
||||
$inheritDoc = '{@inheritDoc}';
|
||||
$methodReflection = $reflectionClass->getMethod('__get');
|
||||
if ($methodReflection->returnsReference()) {
|
||||
$returnReference = '& ';
|
||||
}
|
||||
$methodParameters = $methodReflection->getParameters();
|
||||
$name = '$' . $methodParameters[0]->getName();
|
||||
$parametersString = $this->buildParametersString($methodReflection->getParameters(), ['name']);
|
||||
$returnTypeHint = $this->getMethodReturnType($methodReflection);
|
||||
}
|
||||
if (empty($lazyPublicProperties) && !$hasParentGet) {
|
||||
return '';
|
||||
}
|
||||
$magicGet = <<<EOT
|
||||
public function {$returnReference}__get({$parametersString}){$returnTypeHint}
|
||||
{
|
||||
EOT;
|
||||
if (!empty($lazyPublicProperties)) {
|
||||
$magicGet .= <<<'EOT'
|
||||
if (\array_key_exists($name, self::$lazyPropertiesNames)) {
|
||||
$this->__initializer__ && $this->__initializer__->__invoke($this, '__get', [$name]);
|
||||
EOT;
|
||||
if ($returnTypeHint === ': void') {
|
||||
$magicGet .= "\n return;";
|
||||
} else {
|
||||
$magicGet .= "\n return \$this->\$name;";
|
||||
}
|
||||
$magicGet .= <<<'EOT'
|
||||
}
|
||||
EOT;
|
||||
}
|
||||
if ($hasParentGet) {
|
||||
$magicGet .= <<<'EOT'
|
||||
$this->__initializer__ && $this->__initializer__->__invoke($this, '__get', [$name]);
|
||||
EOT;
|
||||
if ($returnTypeHint === ': void') {
|
||||
$magicGet .= <<<'EOT'
|
||||
parent::__get($name);
|
||||
return;
|
||||
EOT;
|
||||
} elseif ($returnTypeHint === ': never') {
|
||||
$magicGet .= <<<'EOT'
|
||||
parent::__get($name);
|
||||
EOT;
|
||||
} else {
|
||||
$magicGet .= <<<'EOT'
|
||||
return parent::__get($name);
|
||||
EOT;
|
||||
}
|
||||
} else {
|
||||
$magicGet .= sprintf(<<<EOT
|
||||
trigger_error(sprintf('Undefined property: %%s::\$%%s', __CLASS__, %s), E_USER_NOTICE);
|
||||
EOT
|
||||
, $name);
|
||||
}
|
||||
return $magicGet . "\n }";
|
||||
}
|
||||
private function generateMagicSet(ClassMetadata $class)
|
||||
{
|
||||
$lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class);
|
||||
$reflectionClass = $class->getReflectionClass();
|
||||
$hasParentSet = \false;
|
||||
$inheritDoc = '';
|
||||
$parametersString = '$name, $value';
|
||||
$returnTypeHint = null;
|
||||
if ($reflectionClass->hasMethod('__set')) {
|
||||
$hasParentSet = \true;
|
||||
$inheritDoc = '{@inheritDoc}';
|
||||
$methodReflection = $reflectionClass->getMethod('__set');
|
||||
$parametersString = $this->buildParametersString($methodReflection->getParameters(), ['name', 'value']);
|
||||
$returnTypeHint = $this->getMethodReturnType($methodReflection);
|
||||
}
|
||||
if (empty($lazyPublicProperties) && !$hasParentSet) {
|
||||
return '';
|
||||
}
|
||||
$magicSet = <<<EOT
|
||||
public function __set({$parametersString}){$returnTypeHint}
|
||||
{
|
||||
EOT;
|
||||
if (!empty($lazyPublicProperties)) {
|
||||
$magicSet .= <<<'EOT'
|
||||
if (\array_key_exists($name, self::$lazyPropertiesNames)) {
|
||||
$this->__initializer__ && $this->__initializer__->__invoke($this, '__set', [$name, $value]);
|
||||
$this->$name = $value;
|
||||
return;
|
||||
}
|
||||
EOT;
|
||||
}
|
||||
if ($hasParentSet) {
|
||||
$magicSet .= <<<'EOT'
|
||||
$this->__initializer__ && $this->__initializer__->__invoke($this, '__set', [$name, $value]);
|
||||
EOT;
|
||||
if ($returnTypeHint === ': void') {
|
||||
$magicSet .= <<<'EOT'
|
||||
parent::__set($name, $value);
|
||||
return;
|
||||
EOT;
|
||||
} elseif ($returnTypeHint === ': never') {
|
||||
$magicSet .= <<<'EOT'
|
||||
parent::__set($name, $value);
|
||||
EOT;
|
||||
} else {
|
||||
$magicSet .= <<<'EOT'
|
||||
return parent::__set($name, $value);
|
||||
EOT;
|
||||
}
|
||||
} else {
|
||||
$magicSet .= ' $this->$name = $value;';
|
||||
}
|
||||
return $magicSet . "\n }";
|
||||
}
|
||||
private function generateMagicIsset(ClassMetadata $class)
|
||||
{
|
||||
$lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class);
|
||||
$hasParentIsset = $class->getReflectionClass()->hasMethod('__isset');
|
||||
$parametersString = '$name';
|
||||
$returnTypeHint = null;
|
||||
if ($hasParentIsset) {
|
||||
$methodReflection = $class->getReflectionClass()->getMethod('__isset');
|
||||
$parametersString = $this->buildParametersString($methodReflection->getParameters(), ['name']);
|
||||
$returnTypeHint = $this->getMethodReturnType($methodReflection);
|
||||
}
|
||||
if (empty($lazyPublicProperties) && !$hasParentIsset) {
|
||||
return '';
|
||||
}
|
||||
$inheritDoc = $hasParentIsset ? '{@inheritDoc}' : '';
|
||||
$magicIsset = <<<EOT
|
||||
public function __isset({$parametersString}){$returnTypeHint}
|
||||
{
|
||||
EOT;
|
||||
if (!empty($lazyPublicProperties)) {
|
||||
$magicIsset .= <<<'EOT'
|
||||
if (\array_key_exists($name, self::$lazyPropertiesNames)) {
|
||||
$this->__initializer__ && $this->__initializer__->__invoke($this, '__isset', [$name]);
|
||||
return isset($this->$name);
|
||||
}
|
||||
EOT;
|
||||
}
|
||||
if ($hasParentIsset) {
|
||||
$magicIsset .= <<<'EOT'
|
||||
$this->__initializer__ && $this->__initializer__->__invoke($this, '__isset', [$name]);
|
||||
return parent::__isset($name);
|
||||
EOT;
|
||||
} else {
|
||||
$magicIsset .= ' return false;';
|
||||
}
|
||||
return $magicIsset . "\n }";
|
||||
}
|
||||
private function generateSleepImpl(ClassMetadata $class)
|
||||
{
|
||||
$reflectionClass = $class->getReflectionClass();
|
||||
$hasParentSleep = $reflectionClass->hasMethod('__sleep');
|
||||
$inheritDoc = $hasParentSleep ? '{@inheritDoc}' : '';
|
||||
$returnTypeHint = $hasParentSleep ? $this->getMethodReturnType($reflectionClass->getMethod('__sleep')) : '';
|
||||
$sleepImpl = <<<EOT
|
||||
public function __sleep(){$returnTypeHint}
|
||||
{
|
||||
EOT;
|
||||
if ($hasParentSleep) {
|
||||
return $sleepImpl . <<<'EOT'
|
||||
$properties = array_merge(['__isInitialized__'], parent::__sleep());
|
||||
if ($this->__isInitialized__) {
|
||||
$properties = array_diff($properties, array_keys(self::$lazyPropertiesNames));
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
EOT;
|
||||
}
|
||||
$allProperties = ['__isInitialized__'];
|
||||
foreach ($class->getReflectionClass()->getProperties() as $prop) {
|
||||
assert($prop instanceof ReflectionProperty);
|
||||
if ($prop->isStatic()) {
|
||||
continue;
|
||||
}
|
||||
$allProperties[] = $prop->isPrivate() ? "\x00" . $prop->getDeclaringClass()->getName() . "\x00" . $prop->getName() : $prop->getName();
|
||||
}
|
||||
$lazyPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class);
|
||||
$protectedProperties = array_diff($allProperties, $lazyPublicProperties);
|
||||
foreach ($allProperties as &$property) {
|
||||
$property = var_export($property, \true);
|
||||
}
|
||||
foreach ($protectedProperties as &$property) {
|
||||
$property = var_export($property, \true);
|
||||
}
|
||||
$allProperties = implode(', ', $allProperties);
|
||||
$protectedProperties = implode(', ', $protectedProperties);
|
||||
return $sleepImpl . <<<EOT
|
||||
if (\$this->__isInitialized__) {
|
||||
return [{$allProperties}];
|
||||
}
|
||||
return [{$protectedProperties}];
|
||||
}
|
||||
EOT;
|
||||
}
|
||||
private function generateWakeupImpl(ClassMetadata $class)
|
||||
{
|
||||
$reflectionClass = $class->getReflectionClass();
|
||||
$hasParentWakeup = $reflectionClass->hasMethod('__wakeup');
|
||||
$unsetPublicProperties = [];
|
||||
foreach ($this->getLazyLoadedPublicPropertiesNames($class) as $lazyPublicProperty) {
|
||||
$unsetPublicProperties[] = '$this->' . $lazyPublicProperty;
|
||||
}
|
||||
$shortName = $this->generateProxyShortClassName($class);
|
||||
$inheritDoc = $hasParentWakeup ? '{@inheritDoc}' : '';
|
||||
$returnTypeHint = $hasParentWakeup ? $this->getMethodReturnType($reflectionClass->getMethod('__wakeup')) : '';
|
||||
$wakeupImpl = <<<EOT
|
||||
public function __wakeup(){$returnTypeHint}
|
||||
{
|
||||
if ( ! \$this->__isInitialized__) {
|
||||
\$this->__initializer__ = function ({$shortName} \$proxy) {
|
||||
\$proxy->__setInitializer(null);
|
||||
\$proxy->__setCloner(null);
|
||||
\$existingProperties = get_object_vars(\$proxy);
|
||||
foreach (\$proxy::\$lazyPropertiesDefaults as \$property => \$defaultValue) {
|
||||
if ( ! array_key_exists(\$property, \$existingProperties)) {
|
||||
\$proxy->\$property = \$defaultValue;
|
||||
}
|
||||
}
|
||||
};
|
||||
EOT;
|
||||
if (!empty($unsetPublicProperties)) {
|
||||
$wakeupImpl .= "\n unset(" . implode(', ', $unsetPublicProperties) . ');';
|
||||
}
|
||||
$wakeupImpl .= "\n }";
|
||||
if ($hasParentWakeup) {
|
||||
$wakeupImpl .= "\n parent::__wakeup();";
|
||||
}
|
||||
$wakeupImpl .= "\n }";
|
||||
return $wakeupImpl;
|
||||
}
|
||||
private function generateCloneImpl(ClassMetadata $class)
|
||||
{
|
||||
$reflectionClass = $class->getReflectionClass();
|
||||
$hasParentClone = $reflectionClass->hasMethod('__clone');
|
||||
$returnTypeHint = $hasParentClone ? $this->getMethodReturnType($reflectionClass->getMethod('__clone')) : '';
|
||||
$inheritDoc = $hasParentClone ? '{@inheritDoc}' : '';
|
||||
$callParentClone = $hasParentClone ? "\n parent::__clone();\n" : '';
|
||||
return <<<EOT
|
||||
public function __clone(){$returnTypeHint}
|
||||
{
|
||||
\$this->__cloner__ && \$this->__cloner__->__invoke(\$this, '__clone', []);
|
||||
{$callParentClone} }
|
||||
EOT;
|
||||
}
|
||||
private function generateMethods(ClassMetadata $class)
|
||||
{
|
||||
$methods = '';
|
||||
$methodNames = [];
|
||||
$reflectionMethods = $class->getReflectionClass()->getMethods(ReflectionMethod::IS_PUBLIC);
|
||||
$skippedMethods = ['__sleep' => \true, '__clone' => \true, '__wakeup' => \true, '__get' => \true, '__set' => \true, '__isset' => \true];
|
||||
foreach ($reflectionMethods as $method) {
|
||||
$name = $method->getName();
|
||||
if ($method->isConstructor() || isset($skippedMethods[strtolower($name)]) || isset($methodNames[$name]) || $method->isFinal() || $method->isStatic() || !$method->isPublic()) {
|
||||
continue;
|
||||
}
|
||||
$methodNames[$name] = \true;
|
||||
$methods .= "\n /**\n" . " * {@inheritDoc}\n" . " */\n" . ' public function ';
|
||||
if ($method->returnsReference()) {
|
||||
$methods .= '&';
|
||||
}
|
||||
$methods .= $name . '(' . $this->buildParametersString($method->getParameters()) . ')';
|
||||
$methods .= $this->getMethodReturnType($method);
|
||||
$methods .= "\n" . ' {' . "\n";
|
||||
if ($this->isShortIdentifierGetter($method, $class)) {
|
||||
$identifier = lcfirst(substr($name, 3));
|
||||
$fieldType = $class->getTypeOfField($identifier);
|
||||
$cast = in_array($fieldType, ['integer', 'smallint'], \true) ? '(int) ' : '';
|
||||
$methods .= ' if ($this->__isInitialized__ === false) {' . "\n";
|
||||
$methods .= ' ';
|
||||
$methods .= $this->shouldProxiedMethodReturn($method) ? 'return ' : '';
|
||||
$methods .= $cast . ' parent::' . $method->getName() . "();\n";
|
||||
$methods .= ' }' . "\n\n";
|
||||
}
|
||||
$invokeParamsString = implode(', ', $this->getParameterNamesForInvoke($method->getParameters()));
|
||||
$callParamsString = implode(', ', $this->getParameterNamesForParentCall($method->getParameters()));
|
||||
$methods .= "\n \$this->__initializer__ " . '&& $this->__initializer__->__invoke($this, ' . var_export($name, \true) . ', [' . $invokeParamsString . ']);' . "\n\n " . ($this->shouldProxiedMethodReturn($method) ? 'return ' : '') . 'parent::' . $name . '(' . $callParamsString . ');' . "\n" . ' }' . "\n";
|
||||
}
|
||||
return $methods;
|
||||
}
|
||||
public function getProxyFileName($className, $baseDirectory = null)
|
||||
{
|
||||
$baseDirectory = $baseDirectory ?: $this->proxyDirectory;
|
||||
return rtrim($baseDirectory, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . Proxy::MARKER . str_replace('\\', '', $className) . '.php';
|
||||
}
|
||||
private function isShortIdentifierGetter($method, ClassMetadata $class)
|
||||
{
|
||||
$identifier = lcfirst(substr($method->getName(), 3));
|
||||
$startLine = $method->getStartLine();
|
||||
$endLine = $method->getEndLine();
|
||||
$cheapCheck = $method->getNumberOfParameters() === 0 && substr($method->getName(), 0, 3) === 'get' && in_array($identifier, $class->getIdentifier(), \true) && $class->hasField($identifier) && $endLine - $startLine <= 4;
|
||||
if ($cheapCheck) {
|
||||
$code = file($method->getFileName());
|
||||
$code = trim(implode(' ', array_slice($code, $startLine - 1, $endLine - $startLine + 1)));
|
||||
$pattern = sprintf(self::PATTERN_MATCH_ID_METHOD, $method->getName(), $identifier);
|
||||
if (preg_match($pattern, $code)) {
|
||||
return \true;
|
||||
}
|
||||
}
|
||||
return \false;
|
||||
}
|
||||
private function getLazyLoadedPublicPropertiesNames(ClassMetadata $class) : array
|
||||
{
|
||||
$properties = [];
|
||||
foreach ($class->getReflectionClass()->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
|
||||
$name = $property->getName();
|
||||
if (!$class->hasField($name) && !$class->hasAssociation($name) || $class->isIdentifier($name)) {
|
||||
continue;
|
||||
}
|
||||
$properties[] = $name;
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
private function getLazyLoadedPublicProperties(ClassMetadata $class)
|
||||
{
|
||||
$defaultProperties = $class->getReflectionClass()->getDefaultProperties();
|
||||
$lazyLoadedPublicProperties = $this->getLazyLoadedPublicPropertiesNames($class);
|
||||
$defaultValues = [];
|
||||
foreach ($class->getReflectionClass()->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
|
||||
$name = $property->getName();
|
||||
if (!in_array($name, $lazyLoadedPublicProperties, \true)) {
|
||||
continue;
|
||||
}
|
||||
if (array_key_exists($name, $defaultProperties)) {
|
||||
$defaultValues[$name] = $defaultProperties[$name];
|
||||
} elseif (method_exists($property, 'getType')) {
|
||||
$propertyType = $property->getType();
|
||||
if ($propertyType !== null && $propertyType->allowsNull()) {
|
||||
$defaultValues[$name] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $defaultValues;
|
||||
}
|
||||
private function buildParametersString(array $parameters, array $renameParameters = [])
|
||||
{
|
||||
$parameterDefinitions = [];
|
||||
$i = -1;
|
||||
foreach ($parameters as $param) {
|
||||
assert($param instanceof ReflectionParameter);
|
||||
$i++;
|
||||
$parameterDefinition = '';
|
||||
$parameterType = $this->getParameterType($param);
|
||||
if ($parameterType !== null) {
|
||||
$parameterDefinition .= $parameterType . ' ';
|
||||
}
|
||||
if ($param->isPassedByReference()) {
|
||||
$parameterDefinition .= '&';
|
||||
}
|
||||
if ($param->isVariadic()) {
|
||||
$parameterDefinition .= '...';
|
||||
}
|
||||
$parameterDefinition .= '$' . ($renameParameters ? $renameParameters[$i] : $param->getName());
|
||||
$parameterDefinition .= $this->getParameterDefaultValue($param);
|
||||
$parameterDefinitions[] = $parameterDefinition;
|
||||
}
|
||||
return implode(', ', $parameterDefinitions);
|
||||
}
|
||||
private function getParameterType(ReflectionParameter $parameter)
|
||||
{
|
||||
if (!$parameter->hasType()) {
|
||||
return null;
|
||||
}
|
||||
$declaringFunction = $parameter->getDeclaringFunction();
|
||||
assert($declaringFunction instanceof ReflectionMethod);
|
||||
return $this->formatType($parameter->getType(), $declaringFunction, $parameter);
|
||||
}
|
||||
private function getParameterDefaultValue(ReflectionParameter $parameter)
|
||||
{
|
||||
if (!$parameter->isDefaultValueAvailable()) {
|
||||
return '';
|
||||
}
|
||||
if (PHP_VERSION_ID < 80100 || is_scalar($parameter->getDefaultValue())) {
|
||||
return ' = ' . var_export($parameter->getDefaultValue(), \true);
|
||||
}
|
||||
$value = rtrim(substr(explode('$' . $parameter->getName() . ' = ', (string) $parameter, 2)[1], 0, -2));
|
||||
if (strpos($value, '\\') !== \false || strpos($value, '::') !== \false) {
|
||||
$value = preg_split("/('(?:[^'\\\\]*+(?:\\\\.)*+)*+')/", $value, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
foreach ($value as $i => $part) {
|
||||
if ($i % 2 === 0) {
|
||||
$value[$i] = preg_replace('/(?<![a-zA-Z0-9_\\x7f-\\xff\\\\])[a-zA-Z0-9_\\x7f-\\xff]++(?:\\\\[a-zA-Z0-9_\\x7f-\\xff]++|::)++/', '\\\\\\0', $part);
|
||||
}
|
||||
}
|
||||
$value = implode('', $value);
|
||||
}
|
||||
return ' = ' . $value;
|
||||
}
|
||||
private function getParameterNamesForInvoke(array $parameters)
|
||||
{
|
||||
return array_map(static function (ReflectionParameter $parameter) {
|
||||
return '$' . $parameter->getName();
|
||||
}, $parameters);
|
||||
}
|
||||
private function getParameterNamesForParentCall(array $parameters)
|
||||
{
|
||||
return array_map(static function (ReflectionParameter $parameter) {
|
||||
$name = '';
|
||||
if ($parameter->isVariadic()) {
|
||||
$name .= '...';
|
||||
}
|
||||
$name .= '$' . $parameter->getName();
|
||||
return $name;
|
||||
}, $parameters);
|
||||
}
|
||||
private function getMethodReturnType(ReflectionMethod $method)
|
||||
{
|
||||
if (!$method->hasReturnType()) {
|
||||
return '';
|
||||
}
|
||||
return ': ' . $this->formatType($method->getReturnType(), $method);
|
||||
}
|
||||
private function shouldProxiedMethodReturn(ReflectionMethod $method)
|
||||
{
|
||||
if (!$method->hasReturnType()) {
|
||||
return \true;
|
||||
}
|
||||
return !in_array(strtolower($this->formatType($method->getReturnType(), $method)), ['void', 'never'], \true);
|
||||
}
|
||||
private function formatType(ReflectionType $type, ReflectionMethod $method, ?ReflectionParameter $parameter = null)
|
||||
{
|
||||
if ($type instanceof ReflectionUnionType) {
|
||||
return implode('|', array_map(function (ReflectionType $unionedType) use($method, $parameter) {
|
||||
if ($unionedType instanceof ReflectionIntersectionType) {
|
||||
return '(' . $this->formatType($unionedType, $method, $parameter) . ')';
|
||||
}
|
||||
return $this->formatType($unionedType, $method, $parameter);
|
||||
}, $type->getTypes()));
|
||||
}
|
||||
if ($type instanceof ReflectionIntersectionType) {
|
||||
return implode('&', array_map(function (ReflectionType $intersectedType) use($method, $parameter) {
|
||||
return $this->formatType($intersectedType, $method, $parameter);
|
||||
}, $type->getTypes()));
|
||||
}
|
||||
assert($type instanceof ReflectionNamedType);
|
||||
$name = $type->getName();
|
||||
$nameLower = strtolower($name);
|
||||
if ($nameLower === 'static') {
|
||||
$name = 'static';
|
||||
}
|
||||
if ($nameLower === 'self') {
|
||||
$name = $method->getDeclaringClass()->getName();
|
||||
}
|
||||
if ($nameLower === 'parent') {
|
||||
$name = $method->getDeclaringClass()->getParentClass()->getName();
|
||||
}
|
||||
if (!$type->isBuiltin() && !class_exists($name) && !interface_exists($name) && $name !== 'static') {
|
||||
if ($parameter !== null) {
|
||||
throw UnexpectedValueException::invalidParameterTypeHint($method->getDeclaringClass()->getName(), $method->getName(), $parameter->getName());
|
||||
}
|
||||
throw UnexpectedValueException::invalidReturnTypeHint($method->getDeclaringClass()->getName(), $method->getName());
|
||||
}
|
||||
if (!$type->isBuiltin() && $name !== 'static') {
|
||||
$name = '\\' . $name;
|
||||
}
|
||||
if ($type->allowsNull() && !in_array($name, ['mixed', 'null'], \true) && ($parameter === null || !$parameter->isDefaultValueAvailable() || $parameter->getDefaultValue() !== null)) {
|
||||
$name = '?' . $name;
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Util;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Persistence\Proxy;
|
||||
use ReflectionClass;
|
||||
use function get_class;
|
||||
use function get_parent_class;
|
||||
use function ltrim;
|
||||
use function rtrim;
|
||||
use function strrpos;
|
||||
use function substr;
|
||||
class ClassUtils
|
||||
{
|
||||
public static function getRealClass($className)
|
||||
{
|
||||
$pos = strrpos($className, '\\' . Proxy::MARKER . '\\');
|
||||
if ($pos === \false) {
|
||||
return $className;
|
||||
}
|
||||
return substr($className, $pos + Proxy::MARKER_LENGTH + 2);
|
||||
}
|
||||
public static function getClass($object)
|
||||
{
|
||||
return self::getRealClass(get_class($object));
|
||||
}
|
||||
public static function getParentClass($className)
|
||||
{
|
||||
return get_parent_class(self::getRealClass($className));
|
||||
}
|
||||
public static function newReflectionClass($className)
|
||||
{
|
||||
return new ReflectionClass(self::getRealClass($className));
|
||||
}
|
||||
public static function newReflectionObject($object)
|
||||
{
|
||||
return self::newReflectionClass(self::getClass($object));
|
||||
}
|
||||
public static function generateProxyClassName($className, $proxyNamespace)
|
||||
{
|
||||
return rtrim($proxyNamespace, '\\') . '\\' . Proxy::MARKER . '\\' . ltrim($className, '\\');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\Common\Util;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use ArrayIterator;
|
||||
use ArrayObject;
|
||||
use DateTimeInterface;
|
||||
use MailPoetVendor\Doctrine\Common\Collections\Collection;
|
||||
use MailPoetVendor\Doctrine\Persistence\Proxy;
|
||||
use stdClass;
|
||||
use function array_keys;
|
||||
use function count;
|
||||
use function end;
|
||||
use function explode;
|
||||
use function extension_loaded;
|
||||
use function get_class;
|
||||
use function html_entity_decode;
|
||||
use function ini_get;
|
||||
use function ini_set;
|
||||
use function is_array;
|
||||
use function is_object;
|
||||
use function method_exists;
|
||||
use function ob_end_clean;
|
||||
use function ob_get_contents;
|
||||
use function ob_start;
|
||||
use function spl_object_hash;
|
||||
use function strip_tags;
|
||||
use function var_dump;
|
||||
final class Debug
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
public static function dump($var, $maxDepth = 2, $stripTags = \true, $echo = \true)
|
||||
{
|
||||
$html = ini_get('html_errors');
|
||||
if ($html !== \true) {
|
||||
ini_set('html_errors', 'on');
|
||||
}
|
||||
if (extension_loaded('xdebug')) {
|
||||
ini_set('xdebug.var_display_max_depth', $maxDepth);
|
||||
}
|
||||
$var = self::export($var, $maxDepth);
|
||||
ob_start();
|
||||
var_dump($var);
|
||||
$dump = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$dumpText = $stripTags ? strip_tags(html_entity_decode($dump)) : $dump;
|
||||
ini_set('html_errors', $html);
|
||||
if ($echo) {
|
||||
echo $dumpText;
|
||||
}
|
||||
return $dumpText;
|
||||
}
|
||||
public static function export($var, $maxDepth)
|
||||
{
|
||||
$return = null;
|
||||
$isObj = is_object($var);
|
||||
if ($var instanceof Collection) {
|
||||
$var = $var->toArray();
|
||||
}
|
||||
if (!$maxDepth) {
|
||||
return is_object($var) ? get_class($var) : (is_array($var) ? 'Array(' . count($var) . ')' : $var);
|
||||
}
|
||||
if (is_array($var)) {
|
||||
$return = [];
|
||||
foreach ($var as $k => $v) {
|
||||
$return[$k] = self::export($v, $maxDepth - 1);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
if (!$isObj) {
|
||||
return $var;
|
||||
}
|
||||
$return = new stdClass();
|
||||
if ($var instanceof DateTimeInterface) {
|
||||
$return->__CLASS__ = get_class($var);
|
||||
$return->date = $var->format('c');
|
||||
$return->timezone = $var->getTimezone()->getName();
|
||||
return $return;
|
||||
}
|
||||
$return->__CLASS__ = ClassUtils::getClass($var);
|
||||
if ($var instanceof Proxy) {
|
||||
$return->__IS_PROXY__ = \true;
|
||||
$return->__PROXY_INITIALIZED__ = $var->__isInitialized();
|
||||
}
|
||||
if ($var instanceof ArrayObject || $var instanceof ArrayIterator) {
|
||||
$return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1);
|
||||
}
|
||||
return self::fillReturnWithClassAttributes($var, $return, $maxDepth);
|
||||
}
|
||||
private static function fillReturnWithClassAttributes($var, stdClass $return, $maxDepth)
|
||||
{
|
||||
$clone = (array) $var;
|
||||
foreach (array_keys($clone) as $key) {
|
||||
$aux = explode("\x00", $key);
|
||||
$name = end($aux);
|
||||
if ($aux[0] === '') {
|
||||
$name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private');
|
||||
}
|
||||
$return->{$name} = self::export($clone[$key], $maxDepth - 1);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
public static function toString($obj)
|
||||
{
|
||||
return method_exists($obj, '__toString') ? (string) $obj : get_class($obj) . '@' . spl_object_hash($obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\DBAL;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
final class ArrayParameterType
|
||||
{
|
||||
public const INTEGER = ParameterType::INTEGER + Connection::ARRAY_PARAM_OFFSET;
|
||||
public const STRING = ParameterType::STRING + Connection::ARRAY_PARAM_OFFSET;
|
||||
public const ASCII = ParameterType::ASCII + Connection::ARRAY_PARAM_OFFSET;
|
||||
public const BINARY = ParameterType::BINARY + Connection::ARRAY_PARAM_OFFSET;
|
||||
public static function toElementParameterType(int $type) : int
|
||||
{
|
||||
return $type - Connection::ARRAY_PARAM_OFFSET;
|
||||
}
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\DBAL\ArrayParameters;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use Throwable;
|
||||
interface Exception extends Throwable
|
||||
{
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\DBAL\ArrayParameters\Exception;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\DBAL\ArrayParameters\Exception;
|
||||
use LogicException;
|
||||
use function sprintf;
|
||||
class MissingNamedParameter extends LogicException implements Exception
|
||||
{
|
||||
public static function new(string $name) : self
|
||||
{
|
||||
return new self(sprintf('Named parameter "%s" does not have a bound value.', $name));
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\DBAL\ArrayParameters\Exception;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\DBAL\ArrayParameters\Exception;
|
||||
use LogicException;
|
||||
use function sprintf;
|
||||
class MissingPositionalParameter extends LogicException implements Exception
|
||||
{
|
||||
public static function new(int $index) : self
|
||||
{
|
||||
return new self(sprintf('Positional parameter at index %d does not have a bound value.', $index));
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
+1
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\DBAL\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\DBAL\Driver\FetchUtils;
|
||||
use MailPoetVendor\Doctrine\DBAL\Driver\Result;
|
||||
use function array_values;
|
||||
use function count;
|
||||
use function reset;
|
||||
final class ArrayResult implements Result
|
||||
{
|
||||
private array $data;
|
||||
private int $columnCount = 0;
|
||||
private int $num = 0;
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
if (count($data) === 0) {
|
||||
return;
|
||||
}
|
||||
$this->columnCount = count($data[0]);
|
||||
}
|
||||
public function fetchNumeric()
|
||||
{
|
||||
$row = $this->fetch();
|
||||
if ($row === \false) {
|
||||
return \false;
|
||||
}
|
||||
return array_values($row);
|
||||
}
|
||||
public function fetchAssociative()
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
public function fetchOne()
|
||||
{
|
||||
$row = $this->fetch();
|
||||
if ($row === \false) {
|
||||
return \false;
|
||||
}
|
||||
return reset($row);
|
||||
}
|
||||
public function fetchAllNumeric() : array
|
||||
{
|
||||
return FetchUtils::fetchAllNumeric($this);
|
||||
}
|
||||
public function fetchAllAssociative() : array
|
||||
{
|
||||
return FetchUtils::fetchAllAssociative($this);
|
||||
}
|
||||
public function fetchFirstColumn() : array
|
||||
{
|
||||
return FetchUtils::fetchFirstColumn($this);
|
||||
}
|
||||
public function rowCount() : int
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
public function columnCount() : int
|
||||
{
|
||||
return $this->columnCount;
|
||||
}
|
||||
public function free() : void
|
||||
{
|
||||
$this->data = [];
|
||||
}
|
||||
private function fetch()
|
||||
{
|
||||
if (!isset($this->data[$this->num])) {
|
||||
return \false;
|
||||
}
|
||||
return $this->data[$this->num++];
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\DBAL\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\DBAL\Exception;
|
||||
class CacheException extends Exception
|
||||
{
|
||||
public static function noCacheKey()
|
||||
{
|
||||
return new self('No cache key was set.');
|
||||
}
|
||||
public static function noResultDriverConfigured()
|
||||
{
|
||||
return new self('Trying to cache a query but no result driver is configured.');
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\DBAL\Cache;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Cache;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Psr6\CacheAdapter;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Psr6\DoctrineProvider;
|
||||
use MailPoetVendor\Doctrine\DBAL\Types\Type;
|
||||
use MailPoetVendor\Doctrine\Deprecations\Deprecation;
|
||||
use MailPoetVendor\Psr\Cache\CacheItemPoolInterface;
|
||||
use TypeError;
|
||||
use function get_class;
|
||||
use function hash;
|
||||
use function serialize;
|
||||
use function sha1;
|
||||
use function sprintf;
|
||||
class QueryCacheProfile
|
||||
{
|
||||
private ?CacheItemPoolInterface $resultCache = null;
|
||||
private $lifetime;
|
||||
private $cacheKey;
|
||||
public function __construct($lifetime = 0, $cacheKey = null, ?object $resultCache = null)
|
||||
{
|
||||
$this->lifetime = $lifetime;
|
||||
$this->cacheKey = $cacheKey;
|
||||
if ($resultCache instanceof CacheItemPoolInterface) {
|
||||
$this->resultCache = $resultCache;
|
||||
} elseif ($resultCache instanceof Cache) {
|
||||
Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4620', 'Passing an instance of %s to %s as $resultCache is deprecated. Pass an instance of %s instead.', Cache::class, __METHOD__, CacheItemPoolInterface::class);
|
||||
$this->resultCache = CacheAdapter::wrap($resultCache);
|
||||
} elseif ($resultCache !== null) {
|
||||
throw new TypeError(sprintf('$resultCache: Expected either null or an instance of %s or %s, got %s.', CacheItemPoolInterface::class, Cache::class, get_class($resultCache)));
|
||||
}
|
||||
}
|
||||
public function getResultCache() : ?CacheItemPoolInterface
|
||||
{
|
||||
return $this->resultCache;
|
||||
}
|
||||
public function getResultCacheDriver()
|
||||
{
|
||||
Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4620', '%s is deprecated, call getResultCache() instead.', __METHOD__);
|
||||
return $this->resultCache !== null ? DoctrineProvider::wrap($this->resultCache) : null;
|
||||
}
|
||||
public function getLifetime()
|
||||
{
|
||||
return $this->lifetime;
|
||||
}
|
||||
public function getCacheKey()
|
||||
{
|
||||
if ($this->cacheKey === null) {
|
||||
throw CacheException::noCacheKey();
|
||||
}
|
||||
return $this->cacheKey;
|
||||
}
|
||||
public function generateCacheKeys($sql, $params, $types, array $connectionParams = [])
|
||||
{
|
||||
if (isset($connectionParams['password'])) {
|
||||
unset($connectionParams['password']);
|
||||
}
|
||||
$realCacheKey = 'query=' . $sql . '¶ms=' . serialize($params) . '&types=' . serialize($types) . '&connectionParams=' . hash('sha256', serialize($connectionParams));
|
||||
// should the key be automatically generated using the inputs or is the cache key set?
|
||||
$cacheKey = $this->cacheKey ?? sha1($realCacheKey);
|
||||
return [$cacheKey, $realCacheKey];
|
||||
}
|
||||
public function setResultCache(CacheItemPoolInterface $cache) : QueryCacheProfile
|
||||
{
|
||||
return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache);
|
||||
}
|
||||
public function setResultCacheDriver(Cache $cache)
|
||||
{
|
||||
Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4620', '%s is deprecated, call setResultCache() instead.', __METHOD__);
|
||||
return new QueryCacheProfile($this->lifetime, $this->cacheKey, CacheAdapter::wrap($cache));
|
||||
}
|
||||
public function setCacheKey($cacheKey)
|
||||
{
|
||||
return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCache);
|
||||
}
|
||||
public function setLifetime($lifetime)
|
||||
{
|
||||
return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCache);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\DBAL;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
final class ColumnCase
|
||||
{
|
||||
public const UPPER = 1;
|
||||
public const LOWER = 2;
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
namespace MailPoetVendor\Doctrine\DBAL;
|
||||
if (!defined('ABSPATH')) exit;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Cache;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Psr6\CacheAdapter;
|
||||
use MailPoetVendor\Doctrine\Common\Cache\Psr6\DoctrineProvider;
|
||||
use MailPoetVendor\Doctrine\DBAL\Driver\Middleware;
|
||||
use MailPoetVendor\Doctrine\DBAL\Logging\SQLLogger;
|
||||
use MailPoetVendor\Doctrine\DBAL\Schema\SchemaManagerFactory;
|
||||
use MailPoetVendor\Doctrine\Deprecations\Deprecation;
|
||||
use MailPoetVendor\Psr\Cache\CacheItemPoolInterface;
|
||||
use function func_num_args;
|
||||
class Configuration
|
||||
{
|
||||
private array $middlewares = [];
|
||||
protected $sqlLogger;
|
||||
private ?CacheItemPoolInterface $resultCache = null;
|
||||
protected $resultCacheImpl;
|
||||
protected $schemaAssetsFilter;
|
||||
protected $autoCommit = \true;
|
||||
private bool $disableTypeComments = \false;
|
||||
private ?SchemaManagerFactory $schemaManagerFactory = null;
|
||||
public function __construct()
|
||||
{
|
||||
$this->schemaAssetsFilter = static function () : bool {
|
||||
return \true;
|
||||
};
|
||||
}
|
||||
public function setSQLLogger(?SQLLogger $logger = null) : void
|
||||
{
|
||||
Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4967', '%s is deprecated, use setMiddlewares() and Logging\\Middleware instead.', __METHOD__);
|
||||
$this->sqlLogger = $logger;
|
||||
}
|
||||
public function getSQLLogger() : ?SQLLogger
|
||||
{
|
||||
Deprecation::triggerIfCalledFromOutside('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4967', '%s is deprecated.', __METHOD__);
|
||||
return $this->sqlLogger;
|
||||
}
|
||||
public function getResultCache() : ?CacheItemPoolInterface
|
||||
{
|
||||
return $this->resultCache;
|
||||
}
|
||||
public function getResultCacheImpl() : ?Cache
|
||||
{
|
||||
Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4620', '%s is deprecated, call getResultCache() instead.', __METHOD__);
|
||||
return $this->resultCacheImpl;
|
||||
}
|
||||
public function setResultCache(CacheItemPoolInterface $cache) : void
|
||||
{
|
||||
$this->resultCacheImpl = DoctrineProvider::wrap($cache);
|
||||
$this->resultCache = $cache;
|
||||
}
|
||||
public function setResultCacheImpl(Cache $cacheImpl) : void
|
||||
{
|
||||
Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4620', '%s is deprecated, call setResultCache() instead.', __METHOD__);
|
||||
$this->resultCacheImpl = $cacheImpl;
|
||||
$this->resultCache = CacheAdapter::wrap($cacheImpl);
|
||||
}
|
||||
public function setSchemaAssetsFilter(?callable $callable = null) : void
|
||||
{
|
||||
if (func_num_args() < 1) {
|
||||
Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5483', 'Not passing an argument to %s is deprecated.', __METHOD__);
|
||||
} elseif ($callable === null) {
|
||||
Deprecation::trigger('doctrine/dbal', 'https://github.com/doctrine/dbal/pull/5483', 'Using NULL as a schema asset filter is deprecated.' . ' Use a callable that always returns true instead.');
|
||||
}
|
||||
$this->schemaAssetsFilter = $callable;
|
||||
}
|
||||
public function getSchemaAssetsFilter() : ?callable
|
||||
{
|
||||
return $this->schemaAssetsFilter;
|
||||
}
|
||||
public function setAutoCommit(bool $autoCommit) : void
|
||||
{
|
||||
$this->autoCommit = $autoCommit;
|
||||
}
|
||||
public function getAutoCommit() : bool
|
||||
{
|
||||
return $this->autoCommit;
|
||||
}
|
||||
public function setMiddlewares(array $middlewares) : self
|
||||
{
|
||||
$this->middlewares = $middlewares;
|
||||
return $this;
|
||||
}
|
||||
public function getMiddlewares() : array
|
||||
{
|
||||
return $this->middlewares;
|
||||
}
|
||||
public function getSchemaManagerFactory() : ?SchemaManagerFactory
|
||||
{
|
||||
return $this->schemaManagerFactory;
|
||||
}
|
||||
public function setSchemaManagerFactory(SchemaManagerFactory $schemaManagerFactory) : self
|
||||
{
|
||||
$this->schemaManagerFactory = $schemaManagerFactory;
|
||||
return $this;
|
||||
}
|
||||
public function getDisableTypeComments() : bool
|
||||
{
|
||||
return $this->disableTypeComments;
|
||||
}
|
||||
public function setDisableTypeComments(bool $disableTypeComments) : self
|
||||
{
|
||||
$this->disableTypeComments = $disableTypeComments;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user