From b24b68bf31fce379c82d7612cc4d150a3809cc8b Mon Sep 17 00:00:00 2001 From: Anvit Srivastav Date: Wed, 27 Dec 2023 13:55:43 -0800 Subject: [PATCH 01/15] Update Symfony to PHP 8.0 Updating Symfony to PHP 8.0. This commit pulls changes from from FriendsOfSymfony's repo (https://github.com/FriendsOfSymfony1/symfony1) for the following fixes: - Ensure use of string instead of null/false by casting to a string this (FriendsOfSymfony1/symfony1@029b0e7) - Fix fread/count with 0 lengths (FriendsOfSymfony1/symfony1@df2ec65) - mktime fixes (FriendsOfSymfony1/symfony1@29ab2a7) - Fix is_numeric behaviour with trailing empty chars (FriendsOfSymfony1/symfony1@7341b43) - String to number comparisons (FriendsOfSymfony1/symfony1@b191cb8) - Fix Uncaught ArgumentCountError (FriendsOfSymfony1/symfony1@89c24cf) - Fix attempting to access array offset on bool value type (FriendsOfSymfony1/symfony1@754c940) - Fix undefined array key (FriendsOfSymfony1/symfony1@c55d53c) - Fix invalid classname if no controller exists in sfController (FriendsOfSymfony1/symfony1@4820ada) - Fix passing null to strpos function (FriendsOfSymfony1/symfony1@13bfee2) --- vendor/symfony/lib/cache/sfFileCache.class.php | 6 +++++- vendor/symfony/lib/controller/sfController.class.php | 5 ++++- .../escaper/sfOutputEscaperArrayDecorator.class.php | 3 ++- .../escaper/sfOutputEscaperObjectDecorator.class.php | 7 +++++-- vendor/symfony/lib/helper/DateHelper.php | 2 +- vendor/symfony/lib/helper/I18NHelper.php | 2 +- vendor/symfony/lib/i18n/sfCultureInfo.class.php | 2 +- vendor/symfony/lib/i18n/sfDateFormat.class.php | 3 ++- vendor/symfony/lib/i18n/sfI18N.class.php | 10 ++++++++++ .../database/sfDoctrineConnectionProfiler.class.php | 2 +- .../lib/debug/sfWebDebugPanelDoctrine.class.php | 4 ++-- vendor/symfony/lib/response/sfWebResponse.class.php | 3 ++- vendor/symfony/lib/routing/sfRoute.class.php | 4 ++-- .../task/project/sfProjectPermissionsTask.class.php | 2 +- vendor/symfony/lib/util/sfBrowserBase.class.php | 2 +- vendor/symfony/lib/util/sfInflector.class.php | 4 ++-- vendor/symfony/lib/util/sfToolkit.class.php | 2 +- vendor/symfony/lib/vendor/lime/lime.php | 12 ++++++------ vendor/symfony/lib/widget/sfWidgetFormTime.class.php | 4 ++-- vendor/symfony/lib/yaml/sfYamlInline.php | 6 +++--- vendor/symfony/lib/yaml/sfYamlParser.php | 4 ++-- .../frontend/config/frontendConfiguration.class.php | 2 +- 22 files changed, 57 insertions(+), 34 deletions(-) diff --git a/vendor/symfony/lib/cache/sfFileCache.class.php b/vendor/symfony/lib/cache/sfFileCache.class.php index 879929d271..68f6fe7793 100644 --- a/vendor/symfony/lib/cache/sfFileCache.class.php +++ b/vendor/symfony/lib/cache/sfFileCache.class.php @@ -246,7 +246,11 @@ protected function read($path, $type = self::READ_DATA) fseek($fp, 0, SEEK_END); $length = ftell($fp) - 24; fseek($fp, 24); - $data[self::READ_DATA] = @fread($fp, $length); + if($length > 0) { + $data[self::READ_DATA] = @fread($fp, $length); + } else { + $data[self::READ_DATA] = ''; + } } } else diff --git a/vendor/symfony/lib/controller/sfController.class.php b/vendor/symfony/lib/controller/sfController.class.php index 9b56c7dace..600a2f5001 100644 --- a/vendor/symfony/lib/controller/sfController.class.php +++ b/vendor/symfony/lib/controller/sfController.class.php @@ -294,7 +294,10 @@ protected function getController($moduleName, $controllerName, $extension) $classSuffix = ucfirst(strtolower($extension)); if (!isset($this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix])) { - $this->controllerExists($moduleName, $controllerName, $extension, true); + if (!$this->controllerExists($moduleName, $controllerName, $extension, true)) + { + return null; + } } $class = $this->controllerClasses[$moduleName.'_'.$controllerName.'_'.$classSuffix]; diff --git a/vendor/symfony/lib/escaper/sfOutputEscaperArrayDecorator.class.php b/vendor/symfony/lib/escaper/sfOutputEscaperArrayDecorator.class.php index 67d410a84e..7b30ee3b88 100644 --- a/vendor/symfony/lib/escaper/sfOutputEscaperArrayDecorator.class.php +++ b/vendor/symfony/lib/escaper/sfOutputEscaperArrayDecorator.class.php @@ -116,7 +116,8 @@ public function offsetExists($offset) */ public function offsetGet($offset) { - return sfOutputEscaper::escape($this->escapingMethod, $this->value[$offset]); + $value = isset($this->value[$offset]) ? $this->value[$offset] : null; + return sfOutputEscaper::escape($this->escapingMethod, $value); } /** diff --git a/vendor/symfony/lib/escaper/sfOutputEscaperObjectDecorator.class.php b/vendor/symfony/lib/escaper/sfOutputEscaperObjectDecorator.class.php index e47a5327a4..bb0108f7dd 100644 --- a/vendor/symfony/lib/escaper/sfOutputEscaperObjectDecorator.class.php +++ b/vendor/symfony/lib/escaper/sfOutputEscaperObjectDecorator.class.php @@ -111,13 +111,16 @@ public function __isset($key) /** * Returns the size of the object if it implements Countable (is required by the Countable interface). * - * It returns 1 if other cases (which is the default PHP behavior in such a case). + * It returns 1 if other cases (which was the default PHP behavior in such a case before php 7.3). * * @return int The size of the object */ public function count() { - return count($this->value); + if(is_array($this->value) || $this->value instanceof Countable || $this->value instanceof ResourceBundle || $this->value instanceof SimpleXmlElement) { + return count($this->value); + } + return 1; } public function getClass() diff --git a/vendor/symfony/lib/helper/DateHelper.php b/vendor/symfony/lib/helper/DateHelper.php index d46f317e6f..e523359207 100644 --- a/vendor/symfony/lib/helper/DateHelper.php +++ b/vendor/symfony/lib/helper/DateHelper.php @@ -17,7 +17,7 @@ * @version SVN: $Id: DateHelper.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $ */ -function format_daterange($start_date, $end_date, $format = 'd', $full_text, $start_text, $end_text, $culture = null, $charset = null) +function format_daterange($start_date, $end_date, $format = 'd', $full_text = '', $start_text = '', $end_text = '', $culture = null, $charset = null) { if ($start_date != '' && $end_date != '') { diff --git a/vendor/symfony/lib/helper/I18NHelper.php b/vendor/symfony/lib/helper/I18NHelper.php index 0c7545fe67..51ec52e9c9 100644 --- a/vendor/symfony/lib/helper/I18NHelper.php +++ b/vendor/symfony/lib/helper/I18NHelper.php @@ -60,7 +60,7 @@ function __($text, $args = array(), $catalogue = 'messages') * * @return string Result of the translation */ -function format_number_choice($text, $args = array(), $number, $catalogue = 'messages') +function format_number_choice($text, $args = array(), $number = null, $catalogue = 'messages') { $translated = __($text, $args, $catalogue); diff --git a/vendor/symfony/lib/i18n/sfCultureInfo.class.php b/vendor/symfony/lib/i18n/sfCultureInfo.class.php index ef0f2c772e..d63725b7af 100644 --- a/vendor/symfony/lib/i18n/sfCultureInfo.class.php +++ b/vendor/symfony/lib/i18n/sfCultureInfo.class.php @@ -516,7 +516,7 @@ public function getEnglishName() $culture = $this->getInvariantCulture(); $language = $culture->findInfo("Languages/{$lang}"); - if (count($language) == 0) + if (is_array($language) && count($language) == 0) { return $this->culture; } diff --git a/vendor/symfony/lib/i18n/sfDateFormat.class.php b/vendor/symfony/lib/i18n/sfDateFormat.class.php index 56292122b9..b0ad468c5c 100644 --- a/vendor/symfony/lib/i18n/sfDateFormat.class.php +++ b/vendor/symfony/lib/i18n/sfDateFormat.class.php @@ -239,9 +239,10 @@ public function format($time, $pattern = 'F', $inputPattern = null, $charset = ' } else { - $function = ucfirst($this->getFunctionName($pattern)); + $function = $this->getFunctionName($pattern); if ($function != null) { + $function = ucfirst($function); $fName = 'get'.$function; if (in_array($fName, $this->methods)) { diff --git a/vendor/symfony/lib/i18n/sfI18N.class.php b/vendor/symfony/lib/i18n/sfI18N.class.php index b5c8b6b141..e35943954a 100644 --- a/vendor/symfony/lib/i18n/sfI18N.class.php +++ b/vendor/symfony/lib/i18n/sfI18N.class.php @@ -271,6 +271,16 @@ public function getTimestampForCulture($dateTime, $culture = null) list($day, $month, $year) = $this->getDateForCulture($dateTime, null === $culture ? $this->culture : $culture); list($hour, $minute) = $this->getTimeForCulture($dateTime, null === $culture ? $this->culture : $culture); + // mktime behavior change with php8 + // $hour become not nullable + if (!$hour) { + $hour = 0; + } + // Before 8.0, $minutes value to null, was casted as (int)0 + if (!$minute) { + $minute = 0; + } + return null === $day ? null : mktime($hour, $minute, 0, $month, $day, $year); } diff --git a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionProfiler.class.php b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionProfiler.class.php index a79ce70f72..3743d8e8bf 100644 --- a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionProfiler.class.php +++ b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionProfiler.class.php @@ -195,7 +195,7 @@ static public function fixParams($params) { foreach ($params as $key => $param) { - if (strlen($param) >= 255) + if ($param && strlen($param) >= 255) { $params[$key] = '['.number_format(strlen($param) / 1024, 2).'Kb]'; } diff --git a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/debug/sfWebDebugPanelDoctrine.class.php b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/debug/sfWebDebugPanelDoctrine.class.php index 29e064314a..8faedd303d 100644 --- a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/debug/sfWebDebugPanelDoctrine.class.php +++ b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/debug/sfWebDebugPanelDoctrine.class.php @@ -68,7 +68,7 @@ static public function listenToAddPanelEvent(sfEvent $event) /** * Returns an array of Doctrine query events. - * + * * @return array */ protected function getDoctrineEvents() @@ -116,7 +116,7 @@ protected function getSqlLogs() // interpolate parameters foreach ($params as $param) { - $param = htmlspecialchars($param, ENT_QUOTES, sfConfig::get('sf_charset')); + $param = htmlspecialchars((string) $param, ENT_QUOTES, sfConfig::get('sf_charset')); $query = join(var_export(is_scalar($param) ? $param : (string) $param, true), explode('?', $query, 2)); } diff --git a/vendor/symfony/lib/response/sfWebResponse.class.php b/vendor/symfony/lib/response/sfWebResponse.class.php index 71ddb1147c..67dd876858 100644 --- a/vendor/symfony/lib/response/sfWebResponse.class.php +++ b/vendor/symfony/lib/response/sfWebResponse.class.php @@ -365,7 +365,8 @@ public function sendHttpHeaders() // cookies foreach ($this->cookies as $cookie) { - setrawcookie($cookie['name'], $cookie['value'], $cookie['expire'], $cookie['path'], $cookie['domain'], $cookie['secure'], $cookie['httpOnly']); + $expire = isset($cookie['expire']) ? $cookie['expire'] : 0; + setrawcookie($cookie['name'], $cookie['value'], $expire, $cookie['path'], $cookie['domain'], $cookie['secure'], $cookie['httpOnly']); if ($this->options['logging']) { diff --git a/vendor/symfony/lib/routing/sfRoute.class.php b/vendor/symfony/lib/routing/sfRoute.class.php index d2385beb36..34e85ba586 100644 --- a/vendor/symfony/lib/routing/sfRoute.class.php +++ b/vendor/symfony/lib/routing/sfRoute.class.php @@ -281,7 +281,7 @@ protected function generateWithTokens($parameters) switch ($token[0]) { case 'variable': - if (!$optional || !isset($this->defaults[$token[3]]) || $parameters[$token[3]] != $this->defaults[$token[3]]) + if (!$optional || !isset($this->defaults[$token[3]]) || (isset($parameters[$token[3]]) && $parameters[$token[3]] != $this->defaults[$token[3]])) { $url[] = urlencode($parameters[$token[3]]); $optional = false; @@ -796,7 +796,7 @@ protected function fixDefaults() } else { - $this->defaults[$key] = $this->params[$key] = urldecode($value); + $this->defaults[$key] = $this->params[$key] = urldecode((string) $value); } } } diff --git a/vendor/symfony/lib/task/project/sfProjectPermissionsTask.class.php b/vendor/symfony/lib/task/project/sfProjectPermissionsTask.class.php index 6820f7c66f..ddf26017b5 100644 --- a/vendor/symfony/lib/task/project/sfProjectPermissionsTask.class.php +++ b/vendor/symfony/lib/task/project/sfProjectPermissionsTask.class.php @@ -112,7 +112,7 @@ protected function chmod($file, $mode, $umask = 0000) * * @see http://www.php.net/set_error_handler */ - public function handleError($no, $string, $file, $line, $context) + public function handleError($no, $string, $file, $line, $context = null) { $this->failed[] = $this->current; } diff --git a/vendor/symfony/lib/util/sfBrowserBase.class.php b/vendor/symfony/lib/util/sfBrowserBase.class.php index 9420b65907..bdff1cc00a 100644 --- a/vendor/symfony/lib/util/sfBrowserBase.class.php +++ b/vendor/symfony/lib/util/sfBrowserBase.class.php @@ -906,7 +906,7 @@ public function doClickElement(DOMElement $item, $arguments = array(), $options } else { - $queryString = http_build_query($arguments, null, '&'); + $queryString = (is_array($arguments)) ? http_build_query($arguments, null, '&') : ''; $sep = false === strpos($url, '?') ? '?' : '&'; return array($url.($queryString ? $sep.$queryString : ''), 'get', array()); diff --git a/vendor/symfony/lib/util/sfInflector.class.php b/vendor/symfony/lib/util/sfInflector.class.php index 1d5bccc4d3..c792cce7aa 100644 --- a/vendor/symfony/lib/util/sfInflector.class.php +++ b/vendor/symfony/lib/util/sfInflector.class.php @@ -27,7 +27,7 @@ class sfInflector */ public static function camelize($lower_case_and_underscored_word) { - return strtr(ucwords(strtr($lower_case_and_underscored_word, array('/' => '::', '_' => ' ', '-' => ' ', '.' => '_ '))), array(' ' => '')); + return strtr(ucwords(strtr((string) $lower_case_and_underscored_word, array('/' => '::', '_' => ' ', '-' => ' ', '.' => '_ '))), array(' ' => '')); } /** @@ -39,7 +39,7 @@ public static function camelize($lower_case_and_underscored_word) */ public static function underscore($camel_cased_word) { - $tmp = $camel_cased_word; + $tmp = (string) $camel_cased_word; $tmp = str_replace('::', '/', $tmp); $tmp = sfToolkit::pregtr($tmp, array('/([A-Z]+)([A-Z][a-z])/' => '\\1_\\2', '/([a-z\d])([A-Z])/' => '\\1_\\2')); diff --git a/vendor/symfony/lib/util/sfToolkit.class.php b/vendor/symfony/lib/util/sfToolkit.class.php index bc34df41a7..55f42e18d8 100644 --- a/vendor/symfony/lib/util/sfToolkit.class.php +++ b/vendor/symfony/lib/util/sfToolkit.class.php @@ -361,7 +361,7 @@ public static function replaceConstants($value) */ public static function pregtr($search, $replacePairs) { - return preg_replace(array_keys($replacePairs), array_values($replacePairs), $search); + return preg_replace(array_keys($replacePairs), array_values($replacePairs), (string) $search); } /** diff --git a/vendor/symfony/lib/vendor/lime/lime.php b/vendor/symfony/lib/vendor/lime/lime.php index 6c6ac81ccb..adf3df8c47 100644 --- a/vendor/symfony/lib/vendor/lime/lime.php +++ b/vendor/symfony/lib/vendor/lime/lime.php @@ -508,11 +508,11 @@ public function error($message, $file = null, $line = null, array $traces = arra { $this->output->error($message, $file, $line, $traces); - $this->results['stats']['errors'][] = array( - 'message' => $message, - 'file' => $file, - 'line' => $line, - ); + $this->results['stats']['errors'][] = array( + 'message' => $message, + 'file' => $file, + 'line' => $line, + ); } protected function update_stats() @@ -547,7 +547,7 @@ protected function find_caller($traces) return array($traces[$last]['file'], $traces[$last]['line']); } - public function handle_error($code, $message, $file, $line, $context) + public function handle_error($code, $message, $file, $line, $context = null) { if (!$this->options['error_reporting'] || ($code & error_reporting()) == 0) { diff --git a/vendor/symfony/lib/widget/sfWidgetFormTime.class.php b/vendor/symfony/lib/widget/sfWidgetFormTime.class.php index 38fbd0b598..de593802cf 100644 --- a/vendor/symfony/lib/widget/sfWidgetFormTime.class.php +++ b/vendor/symfony/lib/widget/sfWidgetFormTime.class.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -72,7 +72,7 @@ public function render($name, $value = null, $attributes = array(), $errors = ar } else { - $value = ctype_digit($value) ? (integer) $value : strtotime($value); + $value = ctype_digit((string) $value) ? (integer) $value : strtotime((string) $value); if (false === $value) { $value = $default; diff --git a/vendor/symfony/lib/yaml/sfYamlInline.php b/vendor/symfony/lib/yaml/sfYamlInline.php index 405a853808..a6c7b9a035 100644 --- a/vendor/symfony/lib/yaml/sfYamlInline.php +++ b/vendor/symfony/lib/yaml/sfYamlInline.php @@ -98,9 +98,9 @@ static public function dump($value) return 'true'; case false === $value: return 'false'; - case ctype_digit($value): + case ctype_digit((string) $value): return is_string($value) ? "'$value'" : (int) $value; - case is_numeric($value): + case is_numeric($value) && false === strpbrk($value, "\f\n\r\t\v"): return is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : (is_string($value) ? "'$value'" : $value); case false !== strpos($value, "\n") || false !== strpos($value, "\r"): return sprintf('"%s"', str_replace(array('"', "\n", "\r"), array('\\"', '\n', '\r'), $value)); @@ -273,7 +273,7 @@ static protected function parseSequence($sequence, &$i = 0) $isQuoted = in_array($sequence[$i], array('"', "'")); $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i); - if (!$isQuoted && false !== strpos($value, ': ')) + if (!$isQuoted && false !== strpos((string) $value, ': ')) { // embedded mapping? try diff --git a/vendor/symfony/lib/yaml/sfYamlParser.php b/vendor/symfony/lib/yaml/sfYamlParser.php index 03bd0b8ae0..c3175cc3fc 100644 --- a/vendor/symfony/lib/yaml/sfYamlParser.php +++ b/vendor/symfony/lib/yaml/sfYamlParser.php @@ -396,7 +396,7 @@ protected function parseValue($value) { $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; - return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs($modifiers))); + return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs((int) $modifiers))); } else { @@ -449,7 +449,7 @@ protected function parseFoldedScalar($separator, $indicator = '', $indentation = if (preg_match('#^(?P {'.strlen($textIndent).',})(?P.+)$#u', $this->currentLine, $matches)) { - if (' ' == $separator && $previousIndent != $matches['indent']) + if (' ' == $separator && ($previousIndent && $previousIndent != $matches['indent'])) { $text = substr($text, 0, -1)."\n"; } diff --git a/vendor/symfony/test/functional/fixtures/apps/frontend/config/frontendConfiguration.class.php b/vendor/symfony/test/functional/fixtures/apps/frontend/config/frontendConfiguration.class.php index 58e5205326..9b0b90c902 100644 --- a/vendor/symfony/test/functional/fixtures/apps/frontend/config/frontendConfiguration.class.php +++ b/vendor/symfony/test/functional/fixtures/apps/frontend/config/frontendConfiguration.class.php @@ -11,7 +11,7 @@ public function configure() public function filter_parameters(sfEvent $event, $parameters) { - if (false !== stripos($event->getSubject()->getHttpHeader('user-agent'), 'iPhone')) + if (false !== stripos((string) $event->getSubject()->getHttpHeader('user-agent'), 'iPhone')) { $event->getSubject()->setRequestFormat('iphone'); } From 0007a9ae10d0953b814fdb4abe9c8b7ea653aec5 Mon Sep 17 00:00:00 2001 From: Anvit Srivastav Date: Thu, 28 Dec 2023 15:32:37 -0800 Subject: [PATCH 02/15] Update Symfony to PHP 8.1 Updating Symfony to PHP 8.1. This commit pulls changes from from FriendsOfSymfony's repo (https://github.com/FriendsOfSymfony1/symfony1) for the following fixes: - Move serialize/unserialize function implementation to __serialize/__unserialize methods since PHP 8.1 made the old method serializable implementation deprecated (FriendsOfSymfony1/symfony1@6401fcc) - Updated unit tests (FriendsOfSymfony1/symfony1@8450b13) (FriendsOfSymfony1/symfony1@b0cb92e) - Fix lime error message (FriendsOfSymfony1/symfony1@9cb7fb4) - Fix comparison function getVarsByStrlen in sfRoute since returning bool from comparison function is deprecated (FriendsOfSymfony1/symfony1@25a5e71) - Fix value error DOMDocument::loadHTML (FriendsOfSymfony1/symfony1@09fc710) - Update sfWebResponse getContentType function returns a string instead of an array (FriendsOfSymfony1/symfony1@12f7b4c) - Update sfPearRest declaration (FriendsOfSymfony1/symfony1@42112ab) - Fix sfTesterDoctrine string cannot be accessed as array (FriendsOfSymfony1/symfony1@cae793e) - Fix use of null on string parameter (FriendsOfSymfony1/symfony1@7798328) (FriendsOfSymfony1/symfony1@8b81a56) --- .../lib/config/sfViewConfigHandler.class.php | 2 +- .../lib/exception/sfException.class.php | 7 +++- .../lib/generator/sfModelGenerator.class.php | 4 +-- vendor/symfony/lib/i18n/sfI18N.class.php | 9 ++--- .../symfony/lib/plugin/sfPearRest.class.php | 4 +-- .../lib/pager/sfDoctrinePager.class.php | 33 +++++++++++++++---- .../lib/test/sfTesterDoctrine.class.php | 4 +-- .../test/functional/AdminGenBrowser.class.php | 4 +-- .../lib/request/sfWebRequest.class.php | 2 +- .../symfony/lib/response/sfResponse.class.php | 23 +++++++++++-- .../lib/response/sfWebResponse.class.php | 24 ++++++++++++-- vendor/symfony/lib/routing/sfRoute.class.php | 30 ++++++++++++++--- .../lib/storage/sfSessionStorage.class.php | 1 + .../lib/test/sfTestFunctionalBase.class.php | 2 +- .../lib/test/sfTesterResponse.class.php | 12 ++++--- vendor/symfony/lib/util/sfBrowser.class.php | 5 +-- .../symfony/lib/util/sfBrowserBase.class.php | 6 ++-- .../sfNamespacedParameterHolder.class.php | 28 +++++++++++++--- .../lib/util/sfParameterHolder.class.php | 26 +++++++++++++-- .../lib/validator/sfValidatorError.class.php | 28 ++++++++++++++-- vendor/symfony/lib/vendor/lime/lime.php | 14 ++++++-- .../lib/view/sfViewCacheManager.class.php | 4 +-- .../lib/view/sfViewParameterHolder.class.php | 27 ++++++++++++--- .../test/unit/plugin/sfPearRestTest.class.php | 4 +-- .../test/unit/response/sfResponseTest.php | 4 ++- .../test/unit/response/sfWebResponseTest.php | 4 +-- .../symfony/test/unit/sfNoRouting.class.php | 4 +-- .../unit/storage/sfSessionStorageTest.php | 1 + .../validator/sfValidatorErrorSchemaTest.php | 10 ++++++ .../unit/validator/sfValidatorErrorTest.php | 10 ++++++ .../unit/validator/sfValidatorFileTest.php | 2 +- 31 files changed, 267 insertions(+), 71 deletions(-) diff --git a/vendor/symfony/lib/config/sfViewConfigHandler.class.php b/vendor/symfony/lib/config/sfViewConfigHandler.class.php index 600035165b..36a49959b0 100644 --- a/vendor/symfony/lib/config/sfViewConfigHandler.class.php +++ b/vendor/symfony/lib/config/sfViewConfigHandler.class.php @@ -223,7 +223,7 @@ protected function addHtmlHead($viewName = '') foreach ($this->mergeConfigValue('metas', $viewName) as $name => $content) { - $data[] = sprintf(" \$response->addMeta('%s', '%s', false, false);", $name, str_replace('\'', '\\\'', preg_replace('/&(?=\w+;)/', '&', htmlspecialchars($content, ENT_QUOTES, sfConfig::get('sf_charset'))))); + $data[] = sprintf(" \$response->addMeta('%s', '%s', false, false);", $name, str_replace('\'', '\\\'', preg_replace('/&(?=\w+;)/', '&', htmlspecialchars((string) $content, ENT_QUOTES, sfConfig::get('sf_charset'))))); } return implode("\n", $data)."\n"; diff --git a/vendor/symfony/lib/exception/sfException.class.php b/vendor/symfony/lib/exception/sfException.class.php index c792fc83c2..d05dd78482 100644 --- a/vendor/symfony/lib/exception/sfException.class.php +++ b/vendor/symfony/lib/exception/sfException.class.php @@ -107,7 +107,7 @@ public function printStackTrace() header('HTTP/1.0 500 Internal Server Error'); } - if (version_compare(PHP_VERSION, '7.0.0') >= 0) + if (version_compare(PHP_VERSION, '7.0.0') >= 0) { try { @@ -367,6 +367,11 @@ static protected function formatArrayAsHtml($values) */ static protected function fileExcerpt($file, $line) { + // $file can be null for RuntimeException + if($file === null) { + return ''; + } + if (is_readable($file)) { $content = preg_split('#
#', preg_replace('/^(.*)<\/code>$/s', '$1', highlight_file($file, true))); diff --git a/vendor/symfony/lib/generator/sfModelGenerator.class.php b/vendor/symfony/lib/generator/sfModelGenerator.class.php index 10d32e1397..672f584787 100644 --- a/vendor/symfony/lib/generator/sfModelGenerator.class.php +++ b/vendor/symfony/lib/generator/sfModelGenerator.class.php @@ -177,7 +177,7 @@ public function getPrimaryKeyUrlParams($prefix = '', $full = false) return implode(".'&", $params); } - /** + /** * Configures this generator. */ abstract protected function configure(); @@ -271,7 +271,7 @@ public function renderField($field) } else if ('Date' == $field->getType()) { - $html = sprintf("false !== strtotime($html) ? format_date(%s, \"%s\") : ' '", $html, $field->getConfig('date_format', 'f')); + $html = sprintf("is_string($html) && false !== strtotime($html) ? format_date(%s, \"%s\") : ' '", $html, $field->getConfig('date_format', 'f')); } else if ('Boolean' == $field->getType()) { diff --git a/vendor/symfony/lib/i18n/sfI18N.class.php b/vendor/symfony/lib/i18n/sfI18N.class.php index e35943954a..fd6c26d7ae 100644 --- a/vendor/symfony/lib/i18n/sfI18N.class.php +++ b/vendor/symfony/lib/i18n/sfI18N.class.php @@ -273,13 +273,8 @@ public function getTimestampForCulture($dateTime, $culture = null) // mktime behavior change with php8 // $hour become not nullable - if (!$hour) { - $hour = 0; - } - // Before 8.0, $minutes value to null, was casted as (int)0 - if (!$minute) { - $minute = 0; - } + $hour = null !== $hour ? $hour : 0; + $minute = null !== $minute ? $minute : 0; return null === $day ? null : mktime($hour, $minute, 0, $month, $day, $year); } diff --git a/vendor/symfony/lib/plugin/sfPearRest.class.php b/vendor/symfony/lib/plugin/sfPearRest.class.php index 0cdca659ed..d1b63aca12 100644 --- a/vendor/symfony/lib/plugin/sfPearRest.class.php +++ b/vendor/symfony/lib/plugin/sfPearRest.class.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -23,7 +23,7 @@ class sfPearRest extends PEAR_REST /** * @see PEAR_REST::downloadHttp() */ - public function downloadHttp($url, $lastmodified = null, $accept = false) + public function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false) { return parent::downloadHttp($url, $lastmodified, array_merge(false !== $accept ? $accept : array(), array("\r\nX-SYMFONY-VERSION: ".SYMFONY_VERSION))); } diff --git a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/pager/sfDoctrinePager.class.php b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/pager/sfDoctrinePager.class.php index 27b2553959..03478db89d 100644 --- a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/pager/sfDoctrinePager.class.php +++ b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/pager/sfDoctrinePager.class.php @@ -52,9 +52,7 @@ public function setTableMethod($tableMethodName) */ public function serialize() { - $vars = get_object_vars($this); - unset($vars['query']); - return serialize($vars); + return serialize($this->__serialize()); } /** @@ -66,12 +64,35 @@ public function unserialize($serialized) { $array = unserialize($serialized); - foreach ($array as $name => $values) + return $this->__unserialize($array); + } + + /** + * Serializes the current instance for php 7.4+ + * + * @return array + */ + public function __serialize() + { + $vars = get_object_vars($this); + unset($vars['query']); + return $vars; + } + + /** + * Unserializes a sfDoctrinePager instance for php 7.4+ + * + * @param array $data + */ + public function __unserialize($data) + { + + foreach ($data as $name => $values) { - $this->$name = $values; + $this->$name = $values; } - $this->tableMethodCalled = false; + $this->tableMethodCalled = false; } /** diff --git a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/test/sfTesterDoctrine.class.php b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/test/sfTesterDoctrine.class.php index 2e6678a2a1..5d98975ef4 100644 --- a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/test/sfTesterDoctrine.class.php +++ b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/test/sfTesterDoctrine.class.php @@ -65,7 +65,7 @@ public function check($model, $query, $value = true) } $operator = '='; - if ('!' == $condition[0]) + if (strlen($condition) && '!' == substr($condition, 0, 1)) { $operator = false !== strpos($condition, '%') ? 'NOT LIKE' : '!='; $condition = substr($condition, 1); @@ -103,7 +103,7 @@ public function check($model, $query, $value = true) /** * Outputs some debug information about queries run during the current request. - * + * * @param integer|string $limit Either an integer to return the last many queries, a regular expression or a substring to search for */ public function debug($limit = null) diff --git a/vendor/symfony/lib/plugins/sfDoctrinePlugin/test/functional/AdminGenBrowser.class.php b/vendor/symfony/lib/plugins/sfDoctrinePlugin/test/functional/AdminGenBrowser.class.php index a5efd75f70..cb29fe83e3 100644 --- a/vendor/symfony/lib/plugins/sfDoctrinePlugin/test/functional/AdminGenBrowser.class.php +++ b/vendor/symfony/lib/plugins/sfDoctrinePlugin/test/functional/AdminGenBrowser.class.php @@ -152,7 +152,7 @@ protected function _testEnumDropdown() $this-> get('/subscriptions/new')-> with('response')->begin()-> - checkElement('select', 'NewActivePendingExpired')-> + checkElement('select', '/^New\R?Active\R?Pending\R?Expired\R?$/m')-> end() ; } @@ -237,7 +237,7 @@ protected function _runAdminGenModuleSanityCheck($model, $module) } protected function _generateAdminGenModule($model, $module) - { + { $this->info('Generating admin gen module "' . $module . '"'); $task = new sfDoctrineGenerateAdminTask($this->getContext()->getEventDispatcher(), new sfFormatter()); $task->run(array('application' => 'backend', 'route_or_model' => $model)); diff --git a/vendor/symfony/lib/request/sfWebRequest.class.php b/vendor/symfony/lib/request/sfWebRequest.class.php index b4a50917d2..dc62911d28 100644 --- a/vendor/symfony/lib/request/sfWebRequest.class.php +++ b/vendor/symfony/lib/request/sfWebRequest.class.php @@ -164,7 +164,7 @@ public function getContentType($trim = true) { $contentType = $this->getHttpHeader('Content-Type', null); - if ($trim && false !== $pos = strpos($contentType, ';')) + if ($trim && false !== $pos = strpos((string) $contentType, ';')) { $contentType = substr($contentType, 0, $pos); } diff --git a/vendor/symfony/lib/response/sfResponse.class.php b/vendor/symfony/lib/response/sfResponse.class.php index 44e73b4e8f..bc85a548c8 100644 --- a/vendor/symfony/lib/response/sfResponse.class.php +++ b/vendor/symfony/lib/response/sfResponse.class.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) 2004-2006 Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -147,7 +147,7 @@ public function __call($method, $arguments) /** * Serializes the current instance. * - * @return array Objects instance + * @return string Objects instance */ public function serialize() { @@ -166,4 +166,23 @@ public function unserialize($serialized) { $this->content = unserialize($serialized); } + + /** + * Serializes the current instance for php 7.4+ + * + * @return array + */ + public function __serialize() { + return array('content' => $this->content); + } + + /** + * Unserializes a sfResponse instance for php 7.4+ + * + * @param array $data + */ + public function __unserialize($data) + { + $this->content = $data['content']; + } } diff --git a/vendor/symfony/lib/response/sfWebResponse.class.php b/vendor/symfony/lib/response/sfWebResponse.class.php index 67dd876858..4b769bf288 100644 --- a/vendor/symfony/lib/response/sfWebResponse.class.php +++ b/vendor/symfony/lib/response/sfWebResponse.class.php @@ -312,7 +312,7 @@ public function getCharset() /** * Gets response content type. * - * @return array + * @return string */ public function getContentType() { @@ -823,7 +823,7 @@ public function merge(sfWebResponse $response) */ public function serialize() { - return serialize(array($this->content, $this->statusCode, $this->statusText, $this->options, $this->headerOnly, $this->headers, $this->metas, $this->httpMetas, $this->stylesheets, $this->javascripts, $this->slots)); + return serialize($this->__serialize()); } /** @@ -831,7 +831,25 @@ public function serialize() */ public function unserialize($serialized) { - list($this->content, $this->statusCode, $this->statusText, $this->options, $this->headerOnly, $this->headers, $this->metas, $this->httpMetas, $this->stylesheets, $this->javascripts, $this->slots) = unserialize($serialized); + $this->__unserialize(unserialize($serialized)); + } + + /** + * @see sfResponse + * @return array + */ + public function __serialize() + { + return array($this->content, $this->statusCode, $this->statusText, $this->options, $this->headerOnly, $this->headers, $this->metas, $this->httpMetas, $this->stylesheets, $this->javascripts, $this->slots); + } + + /** + * @see sfResponse + * @param array $data + */ + public function __unserialize($data) + { + list($this->content, $this->statusCode, $this->statusText, $this->options, $this->headerOnly, $this->headers, $this->metas, $this->httpMetas, $this->stylesheets, $this->javascripts, $this->slots) = $data; } /** diff --git a/vendor/symfony/lib/routing/sfRoute.class.php b/vendor/symfony/lib/routing/sfRoute.class.php index 34e85ba586..91a488b854 100644 --- a/vendor/symfony/lib/routing/sfRoute.class.php +++ b/vendor/symfony/lib/routing/sfRoute.class.php @@ -262,7 +262,7 @@ public function generate($params, $context = array(), $absolute = false) static private function generateCompareVarsByStrlen($a, $b) { - return strlen($a) < strlen($b); + return (strlen($a) < strlen($b)) ? 1 : -1; } /** @@ -855,15 +855,37 @@ protected function fixSuffix() public function serialize() { + return serialize($this->__serialize()); + } + + public function unserialize($data) + { + $array = unserialize($serialized); + + $this->__unserialize($array); + } + + /** + * Serializes the current instance for php 7.4+ + * + * @return array + */ + public function __serialize() { // always serialize compiled routes $this->compile(); // sfPatternRouting will always re-set defaultParameters, so no need to serialize them - return serialize(array($this->tokens, $this->defaultOptions, $this->options, $this->pattern, $this->staticPrefix, $this->regex, $this->variables, $this->defaults, $this->requirements, $this->suffix, $this->params)); + return array($this->tokens, $this->defaultOptions, $this->options, $this->pattern, $this->staticPrefix, $this->regex, $this->variables, $this->defaults, $this->requirements, $this->suffix, $this->customToken); } - public function unserialize($data) + /** + * Unserializes a sfRoute instance for php 7.4+ + * + * @param array $data + */ + public function __unserialize($data) { - list($this->tokens, $this->defaultOptions, $this->options, $this->pattern, $this->staticPrefix, $this->regex, $this->variables, $this->defaults, $this->requirements, $this->suffix, $this->params) = unserialize($data); + list($this->tokens, $this->defaultOptions, $this->options, $this->pattern, $this->staticPrefix, $this->regex, $this->variables, $this->defaults, $this->requirements, $this->suffix, $this->customToken) = $data; + $this->compiled = true; } } diff --git a/vendor/symfony/lib/storage/sfSessionStorage.class.php b/vendor/symfony/lib/storage/sfSessionStorage.class.php index aa66c427a1..4790fa6582 100644 --- a/vendor/symfony/lib/storage/sfSessionStorage.class.php +++ b/vendor/symfony/lib/storage/sfSessionStorage.class.php @@ -181,5 +181,6 @@ public function shutdown() { // don't need a shutdown procedure because read/write do it in real-time session_write_close(); + self::$sessionStarted = false; } } diff --git a/vendor/symfony/lib/test/sfTestFunctionalBase.class.php b/vendor/symfony/lib/test/sfTestFunctionalBase.class.php index 335f7af82c..fd564992da 100644 --- a/vendor/symfony/lib/test/sfTestFunctionalBase.class.php +++ b/vendor/symfony/lib/test/sfTestFunctionalBase.class.php @@ -478,7 +478,7 @@ static public function handlePhpError($errno, $errstr, $errfile, $errline) /** * Exception handler for the current test browser instance. * - * @param Exception $exception The exception + * @param Throwable $exception The exception */ function handleException(Exception $exception) { diff --git a/vendor/symfony/lib/test/sfTesterResponse.class.php b/vendor/symfony/lib/test/sfTesterResponse.class.php index c621cd41ec..cc3ece1aba 100644 --- a/vendor/symfony/lib/test/sfTesterResponse.class.php +++ b/vendor/symfony/lib/test/sfTesterResponse.class.php @@ -49,7 +49,9 @@ public function initialize() } else { - @$this->dom->loadHTML($this->response->getContent()); + if($this->response->getContent()) { + @$this->dom->loadHTML($this->response->getContent()); + } } $this->domCssSelector = new sfDomCssSelector($this->dom); } @@ -120,10 +122,10 @@ public function checkElement($selector, $value = true, $options = array()) /** * Checks that a form is rendered correctly. - * + * * @param sfForm|string $form A form object or the name of a form class * @param string $selector CSS selector for the root form element for this form - * + * * @return sfTestFunctionalBase|sfTester */ public function checkForm($form, $selector = 'form') @@ -333,11 +335,11 @@ public function isHeader($key, $value) /** * Tests if a cookie was set. - * + * * @param string $name * @param string $value * @param array $attributes Other cookie attributes to check (expires, path, domain, etc) - * + * * @return sfTestFunctionalBase|sfTester */ public function setsCookie($name, $value = null, $attributes = array()) diff --git a/vendor/symfony/lib/util/sfBrowser.class.php b/vendor/symfony/lib/util/sfBrowser.class.php index dcb4d1157c..2cd5ddf9e8 100644 --- a/vendor/symfony/lib/util/sfBrowser.class.php +++ b/vendor/symfony/lib/util/sfBrowser.class.php @@ -28,11 +28,12 @@ class sfBrowser extends sfBrowserBase */ protected function doCall() { + // Before getContext, it can trigger some + sfConfig::set('sf_test', true); + // recycle our context object $this->context = $this->getContext(true); - sfConfig::set('sf_test', true); - // we register a fake rendering filter sfConfig::set('sf_rendering_filter', array('sfFakeRenderingFilter', null)); diff --git a/vendor/symfony/lib/util/sfBrowserBase.class.php b/vendor/symfony/lib/util/sfBrowserBase.class.php index bdff1cc00a..f1f72a2431 100644 --- a/vendor/symfony/lib/util/sfBrowserBase.class.php +++ b/vendor/symfony/lib/util/sfBrowserBase.class.php @@ -364,7 +364,9 @@ public function call($uri, $method = 'get', $parameters = array(), $changeStack } else { - @$this->dom->loadHTML($response->getContent()); + if($response->getContent()) { + @$this->dom->loadHTML($response->getContent()); + } } $this->domCssSelector = new sfDomCssSelector($this->dom); } @@ -906,7 +908,7 @@ public function doClickElement(DOMElement $item, $arguments = array(), $options } else { - $queryString = (is_array($arguments)) ? http_build_query($arguments, null, '&') : ''; + $queryString = is_array($arguments) ? http_build_query($arguments, '', '&') : ''; $sep = false === strpos($url, '?') ? '?' : '&'; return array($url.($queryString ? $sep.$queryString : ''), 'get', array()); diff --git a/vendor/symfony/lib/util/sfNamespacedParameterHolder.class.php b/vendor/symfony/lib/util/sfNamespacedParameterHolder.class.php index 1d551c0c13..ba40b2bb1f 100644 --- a/vendor/symfony/lib/util/sfNamespacedParameterHolder.class.php +++ b/vendor/symfony/lib/util/sfNamespacedParameterHolder.class.php @@ -362,11 +362,11 @@ public function addByRef(& $parameters, $ns = null) /** * Serializes the current instance. * - * @return array Objects instance + * @return string Objects instance */ public function serialize() { - return serialize(array($this->default_namespace, $this->parameters)); + return serialize($this->__serialize()); } /** @@ -376,9 +376,27 @@ public function serialize() */ public function unserialize($serialized) { - $data = unserialize($serialized); + $this->__unserialize(unserialize($serialized)); + } - $this->default_namespace = $data[0]; - $this->parameters = $data[1]; + /** + * Serializes the current instance for PHP 7.4+ + * + * @return array + */ + public function __serialize() + { + return array($this->default_namespace, $this->parameters); + } + + /** + * Unserializes a sfParameterHolder instance. for PHP 7.4 + * + * @param array $data + */ + public function __unserialize($data) + { + $this->default_namespace = $data[0]; + $this->parameters = $data[1]; } } diff --git a/vendor/symfony/lib/util/sfParameterHolder.class.php b/vendor/symfony/lib/util/sfParameterHolder.class.php index f57dbfd634..ed4702fac4 100644 --- a/vendor/symfony/lib/util/sfParameterHolder.class.php +++ b/vendor/symfony/lib/util/sfParameterHolder.class.php @@ -181,11 +181,11 @@ public function addByRef(& $parameters) /** * Serializes the current instance. * - * @return array Objects instance + * @return string Objects instance */ public function serialize() { - return serialize($this->parameters); + return serialize($this->__serialize()); } /** @@ -195,6 +195,26 @@ public function serialize() */ public function unserialize($serialized) { - $this->parameters = unserialize($serialized); + $this->__unserialize(unserialize($serialized)); + } + + /** + * Serializes the current instance for PHP 7.4+ + * + * @return Array + */ + public function __serialize() { + + return $this->parameters; + } + + /** + * Unserializes a sfParameterHolder instance. for PHP 7.4 + * + * @param array $data + */ + public function __unserialize($data) + { + $this->parameters = $data; } } diff --git a/vendor/symfony/lib/validator/sfValidatorError.class.php b/vendor/symfony/lib/validator/sfValidatorError.class.php index 24326b2da1..36292c99db 100644 --- a/vendor/symfony/lib/validator/sfValidatorError.class.php +++ b/vendor/symfony/lib/validator/sfValidatorError.class.php @@ -109,7 +109,7 @@ public function getArguments($raw = false) * error messages: * * $i18n->__($error->getMessageFormat(), $error->getArguments()); - * + * * If no message format has been set in the validator, the exception standard * message is returned. * @@ -140,7 +140,7 @@ public function getMessageFormat() */ public function serialize() { - return serialize(array($this->validator, $this->arguments, $this->code, $this->message)); + return serialize($this->__serialize()); } /** @@ -151,6 +151,28 @@ public function serialize() */ public function unserialize($serialized) { - list($this->validator, $this->arguments, $this->code, $this->message) = unserialize($serialized); + $array = unserialize($serialized); + + $this->__unserialize($array); + } + + /** + * Serializes the current instance for php 7.4+ + * + * @return array + */ + public function __serialize() + { + return array($this->validator, $this->arguments, $this->code, $this->message); + } + + /** + * Unserializes a sfValidatorError instance for php 7.4+ + * + * @param string $serialized A serialized sfValidatorError instance + */ + public function __unserialize($data) + { + list($this->validator, $this->arguments, $this->code, $this->message) = $data; } } diff --git a/vendor/symfony/lib/vendor/lime/lime.php b/vendor/symfony/lib/vendor/lime/lime.php index adf3df8c47..91d3befc60 100644 --- a/vendor/symfony/lib/vendor/lime/lime.php +++ b/vendor/symfony/lib/vendor/lime/lime.php @@ -536,7 +536,9 @@ protected function find_caller($traces) $t = array_reverse($traces); foreach ($t as $trace) { - if (isset($trace['object']) && $trace['object'] instanceof lime_test) + // In internal calls, like error_handle, 'file' will be missing + if (isset($trace['object']) && $trace['object'] instanceof lime_test + && $this->is_test_object($trace['object']) && isset($trace['file'])) { return array($trace['file'], $trace['line']); } @@ -570,7 +572,11 @@ public function handle_error($code, $message, $file, $line, $context = null) $this->error($type.': '.$message, $file, $line, $trace); } - public function handle_exception(Exception $exception) + /** + * @param Throwable $exception only available on php7 + * @return bool + */ + public function handle_exception($exception) { $this->error(get_class($exception).': '.$exception->getMessage(), $exception->getFile(), $exception->getLine(), $exception->getTrace()); @@ -1070,7 +1076,9 @@ function lime_shutdown() $this->output->comment(sprintf(' at %s line %s', $this->get_relative_file($testsuite['tests'][$testcase]['file']).$this->extension, $testsuite['tests'][$testcase]['line'])); $this->output->info(' '.$testsuite['tests'][$testcase]['message']); - $this->output->echoln($testsuite['tests'][$testcase]['error'], null, false); + if(isset($testsuite['tests'][$testcase]['error'])) { + $this->output->echoln($testsuite['tests'][$testcase]['error'], null, false); + } } } } diff --git a/vendor/symfony/lib/view/sfViewCacheManager.class.php b/vendor/symfony/lib/view/sfViewCacheManager.class.php index f43ee63ed1..45cb96567b 100644 --- a/vendor/symfony/lib/view/sfViewCacheManager.class.php +++ b/vendor/symfony/lib/view/sfViewCacheManager.class.php @@ -1005,8 +1005,8 @@ public function getCurrentCacheKey() if ($getParameters = $this->request->getGetParameters()) { - $cacheKey .= false === strpos($cacheKey, '?') ? '?' : '&'; - $cacheKey .= http_build_query($getParameters, null, '&'); + $cacheKey .= false === strpos((string) $cacheKey, '?') ? '?' : '&'; + $cacheKey .= http_build_query($getParameters, '', '&'); } return $cacheKey; diff --git a/vendor/symfony/lib/view/sfViewParameterHolder.class.php b/vendor/symfony/lib/view/sfViewParameterHolder.class.php index 31096e1a4b..a91d1c3b03 100644 --- a/vendor/symfony/lib/view/sfViewParameterHolder.class.php +++ b/vendor/symfony/lib/view/sfViewParameterHolder.class.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -165,11 +165,11 @@ public function setEscapingMethod($method) /** * Serializes the current instance. * - * @return array Objects instance + * @return string Objects instance */ public function serialize() { - return serialize(array($this->getAll(), $this->escapingMethod, $this->escaping)); + return serialize($this->__serialize()); } /** @@ -179,8 +179,27 @@ public function serialize() */ public function unserialize($serialized) { - list($this->parameters, $escapingMethod, $escaping) = unserialize($serialized); + $this->__unserialize(unserialize($serialized)); + } + + /** + * Serializes the current instance for PHP 7.4+ + * + * @return array + */ + public function __serialize() + { + return array($this->getAll(), $this->escapingMethod, $this->escaping); + } + /** + * Unserializes a sfParameterHolder instance. for PHP 7.4 + * + * @param array $data + */ + public function __unserialize($data) + { + list($this->parameters, $escapingMethod, $escaping) = $data; $this->initialize(sfContext::hasInstance() ? sfContext::getInstance()->getEventDispatcher() : new sfEventDispatcher()); $this->setEscapingMethod($escapingMethod); diff --git a/vendor/symfony/test/unit/plugin/sfPearRestTest.class.php b/vendor/symfony/test/unit/plugin/sfPearRestTest.class.php index 82d7c8b228..e2872daf1e 100644 --- a/vendor/symfony/test/unit/plugin/sfPearRestTest.class.php +++ b/vendor/symfony/test/unit/plugin/sfPearRestTest.class.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -21,7 +21,7 @@ class sfPearRestTest extends sfPearRest /** * @see PEAR_REST::downloadHttp() */ - public function downloadHttp($url, $lastmodified = null, $accept = false) + public function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false) { try { diff --git a/vendor/symfony/test/unit/response/sfResponseTest.php b/vendor/symfony/test/unit/response/sfResponseTest.php index 61a9c6cd51..8e3e30614f 100644 --- a/vendor/symfony/test/unit/response/sfResponseTest.php +++ b/vendor/symfony/test/unit/response/sfResponseTest.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) 2004-2006 Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -14,6 +14,8 @@ class myResponse extends sfResponse { function serialize() {} function unserialize($serialized) {} + function __serialize() {} + function __unserialize($data) {} } class fakeResponse diff --git a/vendor/symfony/test/unit/response/sfWebResponseTest.php b/vendor/symfony/test/unit/response/sfWebResponseTest.php index f3a581fe51..2875b2a609 100644 --- a/vendor/symfony/test/unit/response/sfWebResponseTest.php +++ b/vendor/symfony/test/unit/response/sfWebResponseTest.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) 2004-2006 Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -132,7 +132,7 @@ public function normalizeHeaderName($name) $response->setContentType('text/xml'); $response->setContentType('text/html'); -$t->is(count($response->getHttpHeader('content-type')), 1, '->setContentType() overrides previous content type if replace is true'); +$t->is($response->getHttpHeader('content-type'), 'text/html; charset=ISO-8859-1', '->setContentType() overrides previous content type if replace is true'); // ->getTitle() ->setTitle() $t->diag('->getTitle() ->setTitle()'); diff --git a/vendor/symfony/test/unit/sfNoRouting.class.php b/vendor/symfony/test/unit/sfNoRouting.class.php index 625adb5e93..4b1f8ff332 100644 --- a/vendor/symfony/test/unit/sfNoRouting.class.php +++ b/vendor/symfony/test/unit/sfNoRouting.class.php @@ -29,7 +29,7 @@ public function getCurrentInternalUri($with_route_name = false) // other parameters unset($parameters['module'], $parameters['action']); ksort($parameters); - $parameters = count($parameters) ? '?'.http_build_query($parameters, null, '&') : ''; + $parameters = count($parameters) ? '?'.http_build_query($parameters, '', '&') : ''; return sprintf('%s%s', $action, $parameters); } @@ -49,7 +49,7 @@ public function generate($name, $params = array(), $absolute = false) unset($parameters['action']); } - $parameters = http_build_query($parameters, null, '&'); + $parameters = http_build_query($parameters, '', '&'); return $this->fixGeneratedUrl('/'.($parameters ? '?'.$parameters : ''), $absolute); } diff --git a/vendor/symfony/test/unit/storage/sfSessionStorageTest.php b/vendor/symfony/test/unit/storage/sfSessionStorageTest.php index 1b9f7f6da0..d7be8a9ba7 100644 --- a/vendor/symfony/test/unit/storage/sfSessionStorageTest.php +++ b/vendor/symfony/test/unit/storage/sfSessionStorageTest.php @@ -26,6 +26,7 @@ { $storage = new sfSessionStorage(); $t->pass('->__construct() does not throw an exception when not provided with options'); + $storage->shutdown(); } catch (InvalidArgumentException $e) { diff --git a/vendor/symfony/test/unit/validator/sfValidatorErrorSchemaTest.php b/vendor/symfony/test/unit/validator/sfValidatorErrorSchemaTest.php index d2bc24cbdc..23a9a5bb93 100644 --- a/vendor/symfony/test/unit/validator/sfValidatorErrorSchemaTest.php +++ b/vendor/symfony/test/unit/validator/sfValidatorErrorSchemaTest.php @@ -143,6 +143,16 @@ public function unserialize($serialized) { throw new Exception('Not serializable'); } + + public function __serialize() + { + throw new Exception('Not serializable'); + } + + public function __unserialize($data) + { + throw new Exception('Not serializable'); + } } function will_crash($a) diff --git a/vendor/symfony/test/unit/validator/sfValidatorErrorTest.php b/vendor/symfony/test/unit/validator/sfValidatorErrorTest.php index 35f8e3b9d7..301e5e8073 100644 --- a/vendor/symfony/test/unit/validator/sfValidatorErrorTest.php +++ b/vendor/symfony/test/unit/validator/sfValidatorErrorTest.php @@ -65,6 +65,16 @@ public function unserialize($serialized) { throw new Exception('Not serializable'); } + + public function __serialize() + { + throw new Exception('Not serializable'); + } + + public function __unserialize($data) + { + throw new Exception('Not serializable'); + } } function will_crash($a) diff --git a/vendor/symfony/test/unit/validator/sfValidatorFileTest.php b/vendor/symfony/test/unit/validator/sfValidatorFileTest.php index fb4ad41347..bd8141b86c 100644 --- a/vendor/symfony/test/unit/validator/sfValidatorFileTest.php +++ b/vendor/symfony/test/unit/validator/sfValidatorFileTest.php @@ -97,7 +97,7 @@ public function getMimeTypesFromCategory($category) $v = new testValidatorFile(); $t->is($v->guessFromFileBinary($tmpDir.'/test.txt'), 'text/plain', '->guessFromFileBinary() guesses the type of a given file'); $t->is($v->guessFromFileBinary($tmpDir.'/foo.txt'), null, '->guessFromFileBinary() returns null if the file type is not guessable'); -$t->is($v->guessFromFileBinary('/bin/ls'), (PHP_OS != 'Darwin') ? 'application/x-executable' : 'application/octet-stream', '->guessFromFileBinary() returns correct type if file is guessable'); +$t->like($v->guessFromFileBinary('/bin/ls'), (PHP_OS != 'Darwin') ? '/^application\/x-(pie-executable|executable|sharedlib)$/' : '/^application/octet-stream$/', '->guessFromFileBinary() returns correct type if file is guessable'); // ->getMimeType() $t->diag('->getMimeType()'); From 25a8664c23cf0f9998a7c49cec82d42019b27332 Mon Sep 17 00:00:00 2001 From: Anvit Srivastav Date: Thu, 28 Dec 2023 15:44:59 -0800 Subject: [PATCH 03/15] Update strftime and mysql error reporting PHP 8.1 This commit pulls changes from from FriendsOfSymfony's repo (https://github.com/FriendsOfSymfony1/symfony1) for the following fixes: - Add workarounds for strftime deprecation (FriendsOfSymfony1/symfony1@dcb1ce3) - Set mysql error reporting to off since this is on by default in PHP8.1 (FriendsOfSymfony1/symfony1@bb22141) (FriendsOfSymfony1/symfony1@01fadb9) - Remove full path from uploads added to PHP8.1 (FriendsOfSymfony1/symfony1@3bb8339) --- .../lib/database/sfMySQLiDatabase.class.php | 12 ++++ vendor/symfony/lib/log/sfFileLogger.class.php | 60 ++++++++++++++++++- .../lib/request/sfWebRequest.class.php | 3 + 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/vendor/symfony/lib/database/sfMySQLiDatabase.class.php b/vendor/symfony/lib/database/sfMySQLiDatabase.class.php index 9330cd6736..2e0d607c21 100644 --- a/vendor/symfony/lib/database/sfMySQLiDatabase.class.php +++ b/vendor/symfony/lib/database/sfMySQLiDatabase.class.php @@ -16,6 +16,18 @@ class sfMySQLiDatabase extends sfMySQLDatabase { + /** + * @return void + * @throws sfDatabaseException + */ + public function connect() + { + // PHP 8.1 Activate Exception per default, revert behavior to "return false" + mysqli_report(MYSQLI_REPORT_OFF); + + parent::connect(); + } + /** * Returns the appropriate connect method. * diff --git a/vendor/symfony/lib/log/sfFileLogger.class.php b/vendor/symfony/lib/log/sfFileLogger.class.php index bc94a48094..b62964ab98 100644 --- a/vendor/symfony/lib/log/sfFileLogger.class.php +++ b/vendor/symfony/lib/log/sfFileLogger.class.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) 2004-2006 Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -96,7 +96,7 @@ protected function doLog($message, $priority) fwrite($this->fp, strtr($this->format, array( '%type%' => $this->type, '%message%' => $message, - '%time%' => strftime($this->timeFormat), + '%time%' => self::strftime($this->timeFormat), '%priority%' => $this->getPriority($priority), '%EOL%' => PHP_EOL, ))); @@ -125,4 +125,60 @@ public function shutdown() fclose($this->fp); } } + + /** + * @param $format + * @return false|string + */ + public static function strftime($format) + { + if (version_compare(PHP_VERSION, '8.1.0') < 0) { + return strftime($format); + } + return date(self::_strftimeFormatToDateFormat($format)); + } + + /** + * Try to Convert a strftime to date format + * + * Unable to find a perfect implementation, based on those one (Each contains some errors) + * https://github.com/Fabrik/fabrik/blob/master/plugins/fabrik_element/date/date.php + * https://gist.github.com/mcaskill/02636e5970be1bb22270 + * https://stackoverflow.com/questions/22665959/using-php-strftime-using-date-format-string + * + * Limitation: + * - Do not apply translation + * - Some few strftime format could be broken (low probability to be used on logs) + * + * Private: because it should not be used outside of this scope + * + * A better solution is to use : IntlDateFormatter, but it will require to load a new php extension, which could break some setup. + * + * @return array|string|string[] + */ + private static function _strftimeFormatToDateFormat($strftimeFormat) { + + // Missing %V %C %g %G + $search = array( + '%a', '%A', '%d', '%e', '%u', + '%w', '%W', '%b', '%h', '%B', + '%m', '%y', '%Y', '%D', '%F', + '%x', '%n', '%t', '%H', '%k', + '%I', '%l', '%M', '%p', '%P', + '%r' /* %I:%M:%S %p */, '%R' /* %H:%M */, '%S', '%T' /* %H:%M:%S */, '%X', '%z', '%Z', + '%c', '%s', '%j', + '%%'); + + $replace = array( + 'D', 'l', 'd', 'j', 'N', + 'w', 'W', 'M', 'M', 'F', + 'm', 'y', 'Y', 'm/d/y', 'Y-m-d', + 'm/d/y', "\n", "\t", 'H', 'G', + 'h', 'g', 'i', 'A', 'a', + 'h:i:s A', 'H:i', 's', 'H:i:s', 'H:i:s', 'O', 'T', + 'D M j H:i:s Y' /*Tue Feb 5 00:45:10 2009*/, 'U', 'z', + '%'); + + return str_replace($search, $replace, $strftimeFormat); + } } diff --git a/vendor/symfony/lib/request/sfWebRequest.class.php b/vendor/symfony/lib/request/sfWebRequest.class.php index dc62911d28..2278446258 100644 --- a/vendor/symfony/lib/request/sfWebRequest.class.php +++ b/vendor/symfony/lib/request/sfWebRequest.class.php @@ -802,6 +802,9 @@ static public function convertFileInformation(array $taintedFiles) static protected function fixPhpFilesArray($data) { + // remove full_path added on php8.1 + unset($data['full_path']); + $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type'); $keys = array_keys($data); sort($keys); From 26fbedade736b9e45c7775f0fe2f1f394e15a798 Mon Sep 17 00:00:00 2001 From: Anvit Srivastav Date: Fri, 29 Dec 2023 14:38:48 -0800 Subject: [PATCH 04/15] Update symfony to PHP 8.2 Updating Symfony to PHP 8.2. This commit pulls changes from from FriendsOfSymfony's repo (https://github.com/FriendsOfSymfony1/symfony1) for the following fixes: - Update symfony classes which attempt to create dynamic class property as this is deprecated in PHP 8.2 (FriendsOfSymfony1/symfony1@d89618f) - Update string interpolation format to follow {$var} since ${var} is deprecated in PHP 8.2 (FriendsOfSymfony1/symfony1@f6d779c) --- .../lib/database/sfDoctrineConnectionListener.class.php | 6 +++++- vendor/symfony/lib/routing/sfRoute.class.php | 2 ++ vendor/symfony/lib/task/help/sfHelpTask.class.php | 4 ++-- vendor/symfony/lib/task/help/sfListTask.class.php | 4 ++-- vendor/symfony/lib/task/sfBaseTask.class.php | 4 +++- vendor/symfony/lib/util/sfBrowser.class.php | 3 ++- 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionListener.class.php b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionListener.class.php index 007c391bf7..358577aa00 100644 --- a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionListener.class.php +++ b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/database/sfDoctrineConnectionListener.class.php @@ -20,6 +20,10 @@ */ class sfDoctrineConnectionListener extends Doctrine_EventListener { + protected + $connection, + $encoding; + public function __construct($connection, $encoding) { $this->connection = $connection; @@ -31,4 +35,4 @@ public function postConnect(Doctrine_Event $event) $this->connection->setCharset($this->encoding); $this->connection->setDateFormat(); } -} \ No newline at end of file +} diff --git a/vendor/symfony/lib/routing/sfRoute.class.php b/vendor/symfony/lib/routing/sfRoute.class.php index 91a488b854..567bacaeb5 100644 --- a/vendor/symfony/lib/routing/sfRoute.class.php +++ b/vendor/symfony/lib/routing/sfRoute.class.php @@ -35,6 +35,8 @@ class sfRoute implements Serializable $requirements = array(), $tokens = array(), $customToken = false, + $firstOptional = null, + $segments = array(), $params = array(); /** diff --git a/vendor/symfony/lib/task/help/sfHelpTask.class.php b/vendor/symfony/lib/task/help/sfHelpTask.class.php index da9c4c0ddc..adb9a57918 100644 --- a/vendor/symfony/lib/task/help/sfHelpTask.class.php +++ b/vendor/symfony/lib/task/help/sfHelpTask.class.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) 2004-2006 Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -96,7 +96,7 @@ protected function outputAsText(sfTask $task) foreach ($task->getArguments() as $argument) { $default = null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault())) ? $this->formatter->format(sprintf(' (default: %s)', is_array($argument->getDefault()) ? str_replace("\n", '', print_r($argument->getDefault(), true)): $argument->getDefault()), 'COMMENT') : ''; - $messages[] = sprintf(" %-${max}s %s%s", $this->formatter->format($argument->getName(), 'INFO'), $argument->getHelp(), $default); + $messages[] = sprintf(" %-{$max}s %s%s", $this->formatter->format($argument->getName(), 'INFO'), $argument->getHelp(), $default); } $messages[] = ''; diff --git a/vendor/symfony/lib/task/help/sfListTask.class.php b/vendor/symfony/lib/task/help/sfListTask.class.php index 7d6852bfef..dcd7f37120 100644 --- a/vendor/symfony/lib/task/help/sfListTask.class.php +++ b/vendor/symfony/lib/task/help/sfListTask.class.php @@ -3,7 +3,7 @@ /* * This file is part of the symfony package. * (c) 2004-2006 Fabien Potencier - * + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -120,7 +120,7 @@ protected function outputAsText($namespace, $tasks) $aliases = $task->getAliases() ? $this->formatter->format(' ('.implode(', ', $task->getAliases()).')', 'COMMENT') : ''; - $messages[] = sprintf(" %-${width}s %s%s", $this->formatter->format(':'.$task->getName(), 'INFO'), $task->getBriefDescription(), $aliases); + $messages[] = sprintf(" %-{$width}s %s%s", $this->formatter->format(':'.$task->getName(), 'INFO'), $task->getBriefDescription(), $aliases); } $this->log($messages); diff --git a/vendor/symfony/lib/task/sfBaseTask.class.php b/vendor/symfony/lib/task/sfBaseTask.class.php index 774ed24979..cdcba670c3 100644 --- a/vendor/symfony/lib/task/sfBaseTask.class.php +++ b/vendor/symfony/lib/task/sfBaseTask.class.php @@ -20,7 +20,9 @@ abstract class sfBaseTask extends sfCommandApplicationTask { protected $configuration = null, - $pluginManager = null; + $pluginManager = null, + $filesystem = null, + $tokens = array(); /** * @see sfTask diff --git a/vendor/symfony/lib/util/sfBrowser.class.php b/vendor/symfony/lib/util/sfBrowser.class.php index 2cd5ddf9e8..0daa822741 100644 --- a/vendor/symfony/lib/util/sfBrowser.class.php +++ b/vendor/symfony/lib/util/sfBrowser.class.php @@ -21,7 +21,8 @@ class sfBrowser extends sfBrowserBase protected $listeners = array(), $context = null, - $currentException = null; + $currentException = null, + $rawConfiguration = array(); /** * Calls a request to a uri. From 0d5c78ee3229a4212b36ec9f66dfcf4426e72e7b Mon Sep 17 00:00:00 2001 From: melaniekung <71947221+melaniekung@users.noreply.github.com> Date: Fri, 5 Jan 2024 19:45:39 +0000 Subject: [PATCH 05/15] Fix internal_method_return_types for PHP 8.0 Updating Symfony to PHP 8.0. This commit pulls changes from from FriendsOfSymfony's repo (https://github.com/FriendsOfSymfony1/symfony1) for the following fixes: - Add temporary ReturnTypesWillChange attribute to return types changing for Iterator, ArrayAccess, Countable, IteratorAggregate (FriendsOfSymfony1/symfony@245c7cc) --- vendor/symfony/lib/addon/sfPager.class.php | 6 ++++++ .../escaper/sfOutputEscaperArrayDecorator.class.php | 10 ++++++++++ .../escaper/sfOutputEscaperIteratorDecorator.class.php | 9 +++++++++ .../escaper/sfOutputEscaperObjectDecorator.class.php | 1 + vendor/symfony/lib/event_dispatcher/sfEvent.php | 4 ++++ vendor/symfony/lib/form/sfForm.class.php | 10 ++++++++++ vendor/symfony/lib/form/sfFormFieldSchema.class.php | 10 ++++++++++ .../lib/generator/sfDoctrineColumn.class.php | 6 +++++- vendor/symfony/lib/request/sfRequest.class.php | 4 ++++ vendor/symfony/lib/routing/sfRouteCollection.class.php | 5 +++++ vendor/symfony/lib/user/sfUser.class.php | 4 ++++ vendor/symfony/lib/util/sfContext.class.php | 4 ++++ vendor/symfony/lib/util/sfDomCssSelector.class.php | 6 ++++++ .../lib/validator/sfValidatorErrorSchema.class.php | 10 ++++++++++ .../symfony/lib/validator/sfValidatorSchema.class.php | 4 ++++ vendor/symfony/lib/widget/sfWidgetFormSchema.class.php | 4 ++++ .../lib/widget/sfWidgetFormSchemaDecorator.class.php | 4 ++++ .../escaper/sfOutputEscaperObjectDecoratorTest.php | 1 + 18 files changed, 101 insertions(+), 1 deletion(-) diff --git a/vendor/symfony/lib/addon/sfPager.class.php b/vendor/symfony/lib/addon/sfPager.class.php index 1853b05f72..60ff769faf 100644 --- a/vendor/symfony/lib/addon/sfPager.class.php +++ b/vendor/symfony/lib/addon/sfPager.class.php @@ -532,6 +532,7 @@ protected function resetIterator() * * @see Iterator */ + #[\ReturnTypeWillChange] public function current() { if (!$this->isIteratorInitialized()) @@ -547,6 +548,7 @@ public function current() * * @see Iterator */ + #[\ReturnTypeWillChange] public function key() { if (!$this->isIteratorInitialized()) @@ -562,6 +564,7 @@ public function key() * * @see Iterator */ + #[\ReturnTypeWillChange] public function next() { if (!$this->isIteratorInitialized()) @@ -579,6 +582,7 @@ public function next() * * @see Iterator */ + #[\ReturnTypeWillChange] public function rewind() { if (!$this->isIteratorInitialized()) @@ -596,6 +600,7 @@ public function rewind() * * @see Iterator */ + #[\ReturnTypeWillChange] public function valid() { if (!$this->isIteratorInitialized()) @@ -611,6 +616,7 @@ public function valid() * * @see Countable */ + #[\ReturnTypeWillChange] public function count() { return $this->getNbResults(); diff --git a/vendor/symfony/lib/escaper/sfOutputEscaperArrayDecorator.class.php b/vendor/symfony/lib/escaper/sfOutputEscaperArrayDecorator.class.php index 7b30ee3b88..feaac9bd8f 100644 --- a/vendor/symfony/lib/escaper/sfOutputEscaperArrayDecorator.class.php +++ b/vendor/symfony/lib/escaper/sfOutputEscaperArrayDecorator.class.php @@ -41,6 +41,7 @@ public function __construct($escapingMethod, $value) /** * Reset the array to the beginning (as required for the Iterator interface). */ + #[\ReturnTypeWillChange] public function rewind() { reset($this->value); @@ -53,6 +54,7 @@ public function rewind() * * @return string The key */ + #[\ReturnTypeWillChange] public function key() { return key($this->value); @@ -66,6 +68,7 @@ public function key() * * @return mixed The escaped value */ + #[\ReturnTypeWillChange] public function current() { return sfOutputEscaper::escape($this->escapingMethod, current($this->value)); @@ -74,6 +77,7 @@ public function current() /** * Moves to the next element (as required by the Iterator interface). */ + #[\ReturnTypeWillChange] public function next() { next($this->value); @@ -90,6 +94,7 @@ public function next() * * @return bool The validity of the current element; true if it is valid */ + #[\ReturnTypeWillChange] public function valid() { return $this->count > 0; @@ -102,6 +107,7 @@ public function valid() * * @return bool true if the offset isset; false otherwise */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->value[$offset]); @@ -114,6 +120,7 @@ public function offsetExists($offset) * * @return mixed The escaped value */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { $value = isset($this->value[$offset]) ? $this->value[$offset] : null; @@ -132,6 +139,7 @@ public function offsetGet($offset) * * @throws sfException */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { throw new sfException('Cannot set values.'); @@ -148,6 +156,7 @@ public function offsetSet($offset, $value) * * @throws sfException */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { throw new sfException('Cannot unset values.'); @@ -158,6 +167,7 @@ public function offsetUnset($offset) * * @return int The size of the array */ + #[\ReturnTypeWillChange] public function count() { return count($this->value); diff --git a/vendor/symfony/lib/escaper/sfOutputEscaperIteratorDecorator.class.php b/vendor/symfony/lib/escaper/sfOutputEscaperIteratorDecorator.class.php index 99bc43b8d8..9419b8d54b 100644 --- a/vendor/symfony/lib/escaper/sfOutputEscaperIteratorDecorator.class.php +++ b/vendor/symfony/lib/escaper/sfOutputEscaperIteratorDecorator.class.php @@ -56,6 +56,7 @@ public function __construct($escapingMethod, Traversable $value) * * @return bool true, if the iterator rewinds successfully otherwise false */ + #[\ReturnTypeWillChange] public function rewind() { return $this->iterator->rewind(); @@ -66,6 +67,7 @@ public function rewind() * * @return mixed The escaped value */ + #[\ReturnTypeWillChange] public function current() { return sfOutputEscaper::escape($this->escapingMethod, $this->iterator->current()); @@ -76,6 +78,7 @@ public function current() * * @return string Iterator key */ + #[\ReturnTypeWillChange] public function key() { return $this->iterator->key(); @@ -84,6 +87,7 @@ public function key() /** * Moves to the next element in the iterator (as required by the Iterator interface). */ + #[\ReturnTypeWillChange] public function next() { return $this->iterator->next(); @@ -95,6 +99,7 @@ public function next() * * @return bool true if the current element is valid; false otherwise */ + #[\ReturnTypeWillChange] public function valid() { return $this->iterator->valid(); @@ -107,6 +112,7 @@ public function valid() * * @return bool true if the offset isset; false otherwise */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->value[$offset]); @@ -119,6 +125,7 @@ public function offsetExists($offset) * * @return mixed The escaped value */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return sfOutputEscaper::escape($this->escapingMethod, $this->value[$offset]); @@ -136,6 +143,7 @@ public function offsetGet($offset) * * @throws sfException */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { throw new sfException('Cannot set values.'); @@ -152,6 +160,7 @@ public function offsetSet($offset, $value) * * @throws sfException */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { throw new sfException('Cannot unset values.'); diff --git a/vendor/symfony/lib/escaper/sfOutputEscaperObjectDecorator.class.php b/vendor/symfony/lib/escaper/sfOutputEscaperObjectDecorator.class.php index bb0108f7dd..869b341fc3 100644 --- a/vendor/symfony/lib/escaper/sfOutputEscaperObjectDecorator.class.php +++ b/vendor/symfony/lib/escaper/sfOutputEscaperObjectDecorator.class.php @@ -115,6 +115,7 @@ public function __isset($key) * * @return int The size of the object */ + #[\ReturnTypeWillChange] public function count() { if(is_array($this->value) || $this->value instanceof Countable || $this->value instanceof ResourceBundle || $this->value instanceof SimpleXmlElement) { diff --git a/vendor/symfony/lib/event_dispatcher/sfEvent.php b/vendor/symfony/lib/event_dispatcher/sfEvent.php index 73cfdf8dcc..6fc318c7a4 100644 --- a/vendor/symfony/lib/event_dispatcher/sfEvent.php +++ b/vendor/symfony/lib/event_dispatcher/sfEvent.php @@ -117,6 +117,7 @@ public function getParameters() * * @return Boolean true if the parameter exists, false otherwise */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return array_key_exists($name, $this->parameters); @@ -139,6 +140,7 @@ public function __get($name) return $this->parameters[$name]; } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -152,6 +154,7 @@ public function offsetGet($offset) * @param string $name The parameter name * @param mixed $value The parameter value */ + #[\ReturnTypeWillChange] public function offsetSet($name, $value) { $this->parameters[$name] = $value; @@ -162,6 +165,7 @@ public function offsetSet($name, $value) * * @param string $name The parameter name */ + #[\ReturnTypeWillChange] public function offsetUnset($name) { unset($this->parameters[$name]); diff --git a/vendor/symfony/lib/form/sfForm.class.php b/vendor/symfony/lib/form/sfForm.class.php index f602950c52..e4d2b20036 100644 --- a/vendor/symfony/lib/form/sfForm.class.php +++ b/vendor/symfony/lib/form/sfForm.class.php @@ -1051,6 +1051,7 @@ public function __isset($name) return isset($this->widgetSchema[$name]); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -1095,6 +1096,7 @@ public function __get($name) return $this->formFields[$name]; } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -1110,6 +1112,7 @@ public function offsetGet($offset) * * @throws LogicException */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { throw new LogicException('Cannot update form fields.'); @@ -1136,6 +1139,7 @@ public function __unset($name) $this->resetFormFields(); } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); @@ -1193,6 +1197,7 @@ public function getFormFieldSchema() /** * Resets the field names array to the beginning (implements the Iterator interface). */ + #[\ReturnTypeWillChange] public function rewind() { $this->fieldNames = $this->widgetSchema->getPositions(); @@ -1206,6 +1211,7 @@ public function rewind() * * @return string The key */ + #[\ReturnTypeWillChange] public function key() { return current($this->fieldNames); @@ -1216,6 +1222,7 @@ public function key() * * @return mixed The escaped value */ + #[\ReturnTypeWillChange] public function current() { return $this[current($this->fieldNames)]; @@ -1224,6 +1231,7 @@ public function current() /** * Moves to the next form field (implements the Iterator interface). */ + #[\ReturnTypeWillChange] public function next() { next($this->fieldNames); @@ -1235,6 +1243,7 @@ public function next() * * @return boolean The validity of the current element; true if it is valid */ + #[\ReturnTypeWillChange] public function valid() { return $this->count > 0; @@ -1245,6 +1254,7 @@ public function valid() * * @return integer The number of embedded form fields */ + #[\ReturnTypeWillChange] public function count() { return count($this->getFormFieldSchema()); diff --git a/vendor/symfony/lib/form/sfFormFieldSchema.class.php b/vendor/symfony/lib/form/sfFormFieldSchema.class.php index a30483a38a..0f4dd180c6 100644 --- a/vendor/symfony/lib/form/sfFormFieldSchema.class.php +++ b/vendor/symfony/lib/form/sfFormFieldSchema.class.php @@ -91,6 +91,7 @@ public function getHiddenFields($recursive = true) * * @return Boolean true if the widget exists, false otherwise */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return isset($this->widget[$name]); @@ -103,6 +104,7 @@ public function offsetExists($name) * * @return sfFormField A form field instance */ + #[\ReturnTypeWillChange] public function offsetGet($name) { if (!isset($this->fields[$name])) @@ -142,6 +144,7 @@ public function offsetGet($name) * * @throws LogicException */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { throw new LogicException('Cannot update form fields (read-only).'); @@ -154,6 +157,7 @@ public function offsetSet($offset, $value) * * @throws LogicException */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { throw new LogicException('Cannot remove form fields (read-only).'); @@ -162,6 +166,7 @@ public function offsetUnset($offset) /** * Resets the field names array to the beginning (implements the Iterator interface). */ + #[\ReturnTypeWillChange] public function rewind() { reset($this->fieldNames); @@ -173,6 +178,7 @@ public function rewind() * * @return string The key */ + #[\ReturnTypeWillChange] public function key() { return current($this->fieldNames); @@ -183,6 +189,7 @@ public function key() * * @return mixed The escaped value */ + #[\ReturnTypeWillChange] public function current() { return $this[current($this->fieldNames)]; @@ -191,6 +198,7 @@ public function current() /** * Moves to the next form field (implements the Iterator interface). */ + #[\ReturnTypeWillChange] public function next() { next($this->fieldNames); @@ -202,6 +210,7 @@ public function next() * * @return boolean The validity of the current element; true if it is valid */ + #[\ReturnTypeWillChange] public function valid() { return $this->count > 0; @@ -212,6 +221,7 @@ public function valid() * * @return integer The number of embedded form fields */ + #[\ReturnTypeWillChange] public function count() { return count($this->fieldNames); diff --git a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/generator/sfDoctrineColumn.class.php b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/generator/sfDoctrineColumn.class.php index 6f77fa1064..7810c9bb67 100644 --- a/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/generator/sfDoctrineColumn.class.php +++ b/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/generator/sfDoctrineColumn.class.php @@ -309,23 +309,27 @@ public function getTable() return $this->table; } + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->definition[$offset]); } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->definition[$offset] = $value; } + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->definition[$offset]; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->definition[$offset]); } -} \ No newline at end of file +} diff --git a/vendor/symfony/lib/request/sfRequest.class.php b/vendor/symfony/lib/request/sfRequest.class.php index 562d0e7fd1..6771d7558e 100644 --- a/vendor/symfony/lib/request/sfRequest.class.php +++ b/vendor/symfony/lib/request/sfRequest.class.php @@ -155,6 +155,7 @@ public function __isset($name) return $this->parameterHolder->has($name); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -174,6 +175,7 @@ public function __get($name) return $this->parameterHolder->get($name); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -192,6 +194,7 @@ public function __set($name, $value) return $this->parameterHolder->set($name, $value); } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -209,6 +212,7 @@ public function __unset($name) return $this->parameterHolder->remove($name); } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/vendor/symfony/lib/routing/sfRouteCollection.class.php b/vendor/symfony/lib/routing/sfRouteCollection.class.php index e332f0f48f..08000ee13e 100644 --- a/vendor/symfony/lib/routing/sfRouteCollection.class.php +++ b/vendor/symfony/lib/routing/sfRouteCollection.class.php @@ -61,6 +61,7 @@ public function getOptions() /** * Reset the error array to the beginning (implements the Iterator interface). */ + #[\ReturnTypeWillChange] public function rewind() { reset($this->routes); @@ -73,6 +74,7 @@ public function rewind() * * @return string The key */ + #[\ReturnTypeWillChange] public function key() { return key($this->routes); @@ -83,6 +85,7 @@ public function key() * * @return mixed The escaped value */ + #[\ReturnTypeWillChange] public function current() { return current($this->routes); @@ -91,6 +94,7 @@ public function current() /** * Moves to the next route (implements the Iterator interface). */ + #[\ReturnTypeWillChange] public function next() { next($this->routes); @@ -103,6 +107,7 @@ public function next() * * @return boolean The validity of the current route; true if it is valid */ + #[\ReturnTypeWillChange] public function valid() { return $this->count > 0; diff --git a/vendor/symfony/lib/user/sfUser.class.php b/vendor/symfony/lib/user/sfUser.class.php index 4dcc477533..e9eb8b934c 100644 --- a/vendor/symfony/lib/user/sfUser.class.php +++ b/vendor/symfony/lib/user/sfUser.class.php @@ -221,6 +221,7 @@ public function getCulture() * * @return Boolean true if the user attribute exists, false otherwise */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return $this->hasAttribute($name); @@ -233,6 +234,7 @@ public function offsetExists($name) * * @return mixed The user attribute if exists, null otherwise */ + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->getAttribute($name, false); @@ -244,6 +246,7 @@ public function offsetGet($name) * @param string $offset The parameter name * @param string $value The parameter value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->setAttribute($offset, $value); @@ -254,6 +257,7 @@ public function offsetSet($offset, $value) * * @param string $offset The parameter name */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $this->getAttributeHolder()->remove($offset); diff --git a/vendor/symfony/lib/util/sfContext.class.php b/vendor/symfony/lib/util/sfContext.class.php index 05315bed05..76085f5055 100644 --- a/vendor/symfony/lib/util/sfContext.class.php +++ b/vendor/symfony/lib/util/sfContext.class.php @@ -448,6 +448,7 @@ public function getConfigCache() * * @return Boolean true if the context object exists, false otherwise */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return $this->has($name); @@ -460,6 +461,7 @@ public function offsetExists($name) * * @return mixed The context object if exists, null otherwise */ + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->get($name); @@ -471,6 +473,7 @@ public function offsetGet($name) * @param string $offset The parameter name * @param string $value The parameter value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->set($offset, $value); @@ -481,6 +484,7 @@ public function offsetSet($offset, $value) * * @param string $offset The parameter name */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->factories[$offset]); diff --git a/vendor/symfony/lib/util/sfDomCssSelector.class.php b/vendor/symfony/lib/util/sfDomCssSelector.class.php index 1a401d3d05..bbd5df53df 100644 --- a/vendor/symfony/lib/util/sfDomCssSelector.class.php +++ b/vendor/symfony/lib/util/sfDomCssSelector.class.php @@ -563,6 +563,7 @@ protected function nth($cur, $result = 1, $dir = 'nextSibling') /** * Reset the array to the beginning (as required for the Iterator interface). */ + #[\ReturnTypeWillChange] public function rewind() { reset($this->nodes); @@ -575,6 +576,7 @@ public function rewind() * * @return string The key */ + #[\ReturnTypeWillChange] public function key() { return key($this->nodes); @@ -585,6 +587,7 @@ public function key() * * @return mixed The escaped value */ + #[\ReturnTypeWillChange] public function current() { return current($this->nodes); @@ -593,6 +596,7 @@ public function current() /** * Moves to the next element (as required by the Iterator interface). */ + #[\ReturnTypeWillChange] public function next() { next($this->nodes); @@ -609,6 +613,7 @@ public function next() * * @return bool The validity of the current element; true if it is valid */ + #[\ReturnTypeWillChange] public function valid() { return $this->count > 0; @@ -619,6 +624,7 @@ public function valid() * * @param integer The number of matching nodes */ + #[\ReturnTypeWillChange] public function count() { return count($this->nodes); diff --git a/vendor/symfony/lib/validator/sfValidatorErrorSchema.class.php b/vendor/symfony/lib/validator/sfValidatorErrorSchema.class.php index 751b66ef21..2c7f063aa2 100644 --- a/vendor/symfony/lib/validator/sfValidatorErrorSchema.class.php +++ b/vendor/symfony/lib/validator/sfValidatorErrorSchema.class.php @@ -194,6 +194,7 @@ public function getMessageFormat() * * @return int The number of array */ + #[\ReturnTypeWillChange] public function count() { return count($this->errors); @@ -202,6 +203,7 @@ public function count() /** * Reset the error array to the beginning (implements the Iterator interface). */ + #[\ReturnTypeWillChange] public function rewind() { reset($this->errors); @@ -214,6 +216,7 @@ public function rewind() * * @return string The key */ + #[\ReturnTypeWillChange] public function key() { return key($this->errors); @@ -224,6 +227,7 @@ public function key() * * @return mixed The escaped value */ + #[\ReturnTypeWillChange] public function current() { return current($this->errors); @@ -232,6 +236,7 @@ public function current() /** * Moves to the next error (implements the Iterator interface). */ + #[\ReturnTypeWillChange] public function next() { next($this->errors); @@ -244,6 +249,7 @@ public function next() * * @return boolean The validity of the current element; true if it is valid */ + #[\ReturnTypeWillChange] public function valid() { return $this->count > 0; @@ -256,6 +262,7 @@ public function valid() * * @return bool true if the error exists, false otherwise */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return isset($this->errors[$name]); @@ -268,6 +275,7 @@ public function offsetExists($name) * * @return sfValidatorError A sfValidatorError instance */ + #[\ReturnTypeWillChange] public function offsetGet($name) { return isset($this->errors[$name]) ? $this->errors[$name] : null; @@ -281,6 +289,7 @@ public function offsetGet($name) * * @throws LogicException */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { throw new LogicException('Unable update an error.'); @@ -291,6 +300,7 @@ public function offsetSet($offset, $value) * * @param string $offset (ignored) */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { } diff --git a/vendor/symfony/lib/validator/sfValidatorSchema.class.php b/vendor/symfony/lib/validator/sfValidatorSchema.class.php index 6943e8ad75..b3be586459 100644 --- a/vendor/symfony/lib/validator/sfValidatorSchema.class.php +++ b/vendor/symfony/lib/validator/sfValidatorSchema.class.php @@ -306,6 +306,7 @@ public function __isset($name) return isset($this->fields[$name]); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -325,6 +326,7 @@ public function __get($name) return isset($this->fields[$name]) ? $this->fields[$name] : null; } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -348,6 +350,7 @@ public function __set($name, $validator) $this->fields[$name] = clone $validator; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -365,6 +368,7 @@ public function __unset($name) unset($this->fields[$name]); } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/vendor/symfony/lib/widget/sfWidgetFormSchema.class.php b/vendor/symfony/lib/widget/sfWidgetFormSchema.class.php index d7cbd28b48..48f3bff5d4 100644 --- a/vendor/symfony/lib/widget/sfWidgetFormSchema.class.php +++ b/vendor/symfony/lib/widget/sfWidgetFormSchema.class.php @@ -703,6 +703,7 @@ public function __isset($name) return isset($this->fields[$name]); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -722,6 +723,7 @@ public function __get($name) return isset($this->fields[$name]) ? $this->fields[$name] : null; } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -758,6 +760,7 @@ public function __set($name, $widget) } } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -781,6 +784,7 @@ public function __unset($name) } } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/vendor/symfony/lib/widget/sfWidgetFormSchemaDecorator.class.php b/vendor/symfony/lib/widget/sfWidgetFormSchemaDecorator.class.php index 28bfeeb333..c7a034bfaa 100644 --- a/vendor/symfony/lib/widget/sfWidgetFormSchemaDecorator.class.php +++ b/vendor/symfony/lib/widget/sfWidgetFormSchemaDecorator.class.php @@ -319,6 +319,7 @@ public function moveField($field, $action, $pivot = null) /** * @see sfWidgetFormSchema */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return isset($this->widget[$name]); @@ -327,6 +328,7 @@ public function offsetExists($name) /** * @see sfWidgetFormSchema */ + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->widget[$name]; @@ -335,6 +337,7 @@ public function offsetGet($name) /** * @see sfWidgetFormSchema */ + #[\ReturnTypeWillChange] public function offsetSet($name, $widget) { $this->widget[$name] = $widget; @@ -343,6 +346,7 @@ public function offsetSet($name, $widget) /** * @see sfWidgetFormSchema */ + #[\ReturnTypeWillChange] public function offsetUnset($name) { unset($this->widget[$name]); diff --git a/vendor/symfony/test/unit/escaper/sfOutputEscaperObjectDecoratorTest.php b/vendor/symfony/test/unit/escaper/sfOutputEscaperObjectDecoratorTest.php index c876505208..99e0a114cb 100644 --- a/vendor/symfony/test/unit/escaper/sfOutputEscaperObjectDecoratorTest.php +++ b/vendor/symfony/test/unit/escaper/sfOutputEscaperObjectDecoratorTest.php @@ -74,6 +74,7 @@ class Foo class FooCountable implements Countable { + #[\ReturnTypeWillChange] public function count() { return 2; From 85dac5a4d6f9354e471cd8c4250f858a125a9d2a Mon Sep 17 00:00:00 2001 From: Anvit Srivastav Date: Mon, 16 Dec 2024 16:53:25 -0800 Subject: [PATCH 06/15] Fix broken routing issue Fix the broken routing by addressing the missing param in sfRoute --- vendor/symfony/lib/routing/sfRoute.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/symfony/lib/routing/sfRoute.class.php b/vendor/symfony/lib/routing/sfRoute.class.php index 567bacaeb5..2597d83a0f 100644 --- a/vendor/symfony/lib/routing/sfRoute.class.php +++ b/vendor/symfony/lib/routing/sfRoute.class.php @@ -876,7 +876,7 @@ public function __serialize() { // always serialize compiled routes $this->compile(); // sfPatternRouting will always re-set defaultParameters, so no need to serialize them - return array($this->tokens, $this->defaultOptions, $this->options, $this->pattern, $this->staticPrefix, $this->regex, $this->variables, $this->defaults, $this->requirements, $this->suffix, $this->customToken); + return array($this->tokens, $this->defaultOptions, $this->options, $this->pattern, $this->staticPrefix, $this->regex, $this->variables, $this->defaults, $this->requirements, $this->suffix, $this->params); } /** @@ -886,7 +886,7 @@ public function __serialize() { */ public function __unserialize($data) { - list($this->tokens, $this->defaultOptions, $this->options, $this->pattern, $this->staticPrefix, $this->regex, $this->variables, $this->defaults, $this->requirements, $this->suffix, $this->customToken) = $data; + list($this->tokens, $this->defaultOptions, $this->options, $this->pattern, $this->staticPrefix, $this->regex, $this->variables, $this->defaults, $this->requirements, $this->suffix, $this->params) = $data; $this->compiled = true; } From 7589f41f379ec5e2dbac6ca625b7962d3cba0840 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 19 Dec 2024 21:42:51 +0000 Subject: [PATCH 07/15] Update net_gearman to latest version Update net_gearman vendor package to latest version and add AtoM specific customizations to Job.php --- vendor/net_gearman/.gitignore | 2 +- vendor/net_gearman/Net/Gearman/Client.php | 301 +++--- vendor/net_gearman/Net/Gearman/Connection.php | 383 +++++-- vendor/net_gearman/Net/Gearman/Exception.php | 11 +- vendor/net_gearman/Net/Gearman/Job.php | 54 +- vendor/net_gearman/Net/Gearman/Job/Common.php | 17 +- vendor/net_gearman/Net/Gearman/Manager.php | 77 +- vendor/net_gearman/Net/Gearman/Set.php | 10 +- vendor/net_gearman/Net/Gearman/Task.php | 23 +- vendor/net_gearman/Net/Gearman/Worker.php | 637 ++++++++++-- vendor/net_gearman/README | 59 -- vendor/net_gearman/README.md | 50 + vendor/net_gearman/build.xml | 100 -- vendor/net_gearman/composer.json | 34 + vendor/net_gearman/package.xml | 979 ------------------ vendor/net_gearman/phpunit.xml.dist | 18 + .../net_gearman/phpunit.xml.functional-dist | 21 + vendor/net_gearman/tests/ManagerTest.php | 61 ++ .../tests/Net/Gearman/ConnectionTest.php | 107 +- .../tests/Net/Gearman/TaskTest.php | 80 +- vendor/net_gearman/tests/README.md | 14 + vendor/net_gearman/tests/bootstrap.php | 25 + 22 files changed, 1449 insertions(+), 1614 deletions(-) delete mode 100644 vendor/net_gearman/README create mode 100644 vendor/net_gearman/README.md delete mode 100644 vendor/net_gearman/build.xml create mode 100644 vendor/net_gearman/composer.json delete mode 100644 vendor/net_gearman/package.xml create mode 100644 vendor/net_gearman/phpunit.xml.dist create mode 100644 vendor/net_gearman/phpunit.xml.functional-dist create mode 100644 vendor/net_gearman/tests/ManagerTest.php create mode 100644 vendor/net_gearman/tests/README.md create mode 100644 vendor/net_gearman/tests/bootstrap.php diff --git a/vendor/net_gearman/.gitignore b/vendor/net_gearman/.gitignore index 45d40e3310..a5be80f2f0 100644 --- a/vendor/net_gearman/.gitignore +++ b/vendor/net_gearman/.gitignore @@ -1,3 +1,3 @@ tests/tests-config.php tests/report* -tests/run-tests.log \ No newline at end of file +tests/run-tests.log diff --git a/vendor/net_gearman/Net/Gearman/Client.php b/vendor/net_gearman/Net/Gearman/Client.php index 7522b93db0..3288325e8e 100644 --- a/vendor/net_gearman/Net/Gearman/Client.php +++ b/vendor/net_gearman/Net/Gearman/Client.php @@ -14,11 +14,11 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ - * @link http://pear.php.net/package/Net_Gearman - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman */ /** @@ -30,9 +30,9 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman */ class Net_Gearman_Client { @@ -46,14 +46,9 @@ class Net_Gearman_Client /** * A list of Gearman servers * - * @var array $serverToSocket A list of Gearman servers and their corresponding Sockets + * @var array $servers A list of potential Gearman servers */ - protected $serverToSocket = array(); - - /** - * @var array $socketIdToServer A list of socket IDs and their corresponding server URLs - */ - protected $socketIdToServer = array(); + protected $servers = array(); /** * The timeout for Gearman connections @@ -62,11 +57,20 @@ class Net_Gearman_Client */ protected $timeout = 1000; + /** + * Callbacks array for receiving connection status + * + * @var array $callback + */ + protected $callback = array(); + /** * Constructor * * @param array $servers An array of servers or a single server - * @param integer $timeout Timeout in microseconds + * @param integer $timeout Timeout in miliseconds for the server connect time + * If multiple servers have to be tried, the total + * timeout for getConnection will be $timeout * {servers tried} * * @return void * @throws Net_Gearman_Exception @@ -74,29 +78,13 @@ class Net_Gearman_Client */ public function __construct($servers, $timeout = 1000) { - if (!is_array($servers) && strlen($servers)) { + if (!is_array($servers) && strlen($servers) > 0) { $servers = array($servers); } elseif (is_array($servers) && !count($servers)) { throw new Net_Gearman_Exception('Invalid servers specified'); } - $this->serverToSocket = array_flip($servers); - foreach ($this->serverToSocket as $server => $dummy) { - $conn = null; - try{ - $conn = Net_Gearman_Connection::connect($server, $timeout); - } catch(Net_Gearman_Exception $e) { - trigger_error($e->getMessage(). " server: $server", E_USER_WARNING); - } - if (!Net_Gearman_Connection::isConnected($conn)) { - unset($this->serverToSocket[$server]); - continue; - } - - $this->serverToSocket[$server] = $conn; - $this->socketIdToServer[(int) $conn] = $server; - $this->conn[] = $conn; - } + $this->servers = array_values($servers); $this->timeout = $timeout; } @@ -104,114 +92,114 @@ public function __construct($servers, $timeout = 1000) /** * Get a connection to a Gearman server * - * @param string $uniq The unique id of the job + * @param string $uniq The unique id of the job + * @param array $servers Optional list of servers to limit use * * @return resource A connection to a Gearman server */ - protected function getConnection($uniq = null) + protected function getConnection($uniq=null, $servers=null) { $conn = null; - if(count($this->conn) > 0){ + $start = microtime(true); + $elapsed = 0; - if(count($this->conn) === 1){ - $conn = current($this->conn); - } elseif($uniq === null){ - $conn = $this->conn[array_rand($this->conn)]; - } else { - $server = ord(substr(md5($uniq), -1)) % count($this->conn); - $conn = $this->conn[$server]; + if (is_null($servers)) { + $servers = $this->servers; } - } + $try_servers = $servers; - return $conn; - } + /** + * Keep a list of the servers actually tried for the error message + */ + $tried_servers = array(); - /** - * Gets the current status of a Task - * - * @param string $handle The handle returned when the task was created - * @return mixed An associative array containing information about - * the provided task handle. Returns false if the request failed. - */ - public function getTaskStatusByHandle($handle, $server = null) - { - return $this->getStatus($handle, $server); - } - - /** - * Gets the current status of a Task - * - * @param Net_Gearman_Task $task - * @return mixed An associative array containing information about - * the provided task handle. Returns false if the request failed. - */ - public function getTaskStatus(Net_Gearman_Task $task) - { - return $this->getStatus($task->handle, $task->server); - } + while ($conn === null && count($servers) > 0) { + if (count($servers) === 1) { + $key = key($servers); + } elseif ($uniq === null) { + $key = array_rand($servers); + } else { + $key = ord(substr(md5($uniq), -1)) % count($servers); + } - /** - * Private function to handle the status communication - * - * @param string $handle The handle returned when the task was created - * @param string $server The server name(:port) this task was assigned to. - * If not set, all servers in the server list will be checked - * @return mixed An associative array containing information about - * the provided task handle. Returns false if the request failed. - */ - private function getStatus($handle, $server = null) - { + $server = $servers[$key]; - $params = array( - 'handle' => $handle, - ); + $tried_servers[] = $server; - if(!is_null($server)){ - $server_list = array($this->serverToSocket[$server]); + if (empty($this->conn[$server]) || !$this->conn[$server]->isConnected()) { - if (!$this->serverToSocket[$server]) - throw new Net_Gearman_Exception('Invalid server specified'); + $conn = null; + $start = microtime(true); + $e = null; - } else { - $server_list = $this->serverToSocket; - } + try { + $conn = new Net_Gearman_Connection($server, $this->timeout); + } catch (Net_Gearman_Exception $e) { + $conn = null; + } + + if (!$conn || !$conn->isConnected()) { + $conn = null; + unset($servers[$key]); + // we need to rekey the array + $servers = array_values($servers); + } else { + $this->conn[$server] = $conn; + break; + } - foreach($server_list as $s) { - Net_Gearman_Connection::send($s, 'get_status', $params); + foreach ($this->callback as $callback) { + call_user_func( + $callback, + $server, + $conn !== null, + $this->timeout, + microtime(true) - $start, + $e + ); + } - $read = array($s); - $write = null; - $except = null; + } else { + $conn = $this->conn[$server]; + } - socket_select($read, $write, $except, 10); + $elapsed = microtime(true) - $start; - foreach ($read as $socket) { - $resp = Net_Gearman_Connection::read($socket); + } - if (isset($resp['function'], $resp['data']) - && ($resp['function'] == 'status_res') - ) { - if($resp["data"]["denominator"] > 0){ - $resp["data"]["percent_complete"] = round(($resp["data"]["numerator"] / $resp["data"]["denominator"]) * 100, 0); - } elseif($resp["data"]["running"]) { - $resp["data"]["percent_complete"] = 0; - } else { - $resp["data"]["percent_complete"] = null; - } - return $resp['data']; - } + if (empty($conn)) { + $message = "Failed to connect to a Gearman server. Attempted to connect to ".implode(",", $tried_servers)."."; + if (count($tried_servers) != count($try_servers)) { + $message.= " Not all servers were tried. Full server list is ".implode(",", $try_servers)."."; } + throw new Net_Gearman_Exception($message); } - return false; + return $conn; + } + + /** + * Attach a callback for connection status + * + * @param callback $callback A valid PHP callback + * + * @return void + * @throws Net_Gearman_Exception When an invalid callback is specified. + */ + public function attachCallback($callback) + { + if (!is_callable($callback)) { + throw new Net_Gearman_Exception('Invalid callback specified'); + } + $this->callback[] = $callback; } /** * Fire off a background task with the given arguments * - * @param string $func Name of job to run + * @param string $func Name of job to run * @param array $args First key should be args to send * * @return void @@ -266,8 +254,8 @@ protected function submitTask(Net_Gearman_Task $task) // if we don't have a scalar // json encode the data - if(!is_scalar($task->arg)){ - $arg = json_encode($task->arg); + if (!is_scalar($task->arg)) { + $arg = @json_encode($task->arg); } else { $arg = $task->arg; } @@ -278,22 +266,22 @@ protected function submitTask(Net_Gearman_Task $task) 'arg' => $arg ); - $s = $this->getConnection($task->uniq); - Net_Gearman_Connection::send($s, $type, $params); - - $s_key = (int)$s; - - if (!is_array(Net_Gearman_Connection::$waiting[$s_key])) { - Net_Gearman_Connection::$waiting[$s_key] = array(); + if (!empty($task->servers)) { + $servers = $task->servers; + } else { + $servers = null; } - array_push(Net_Gearman_Connection::$waiting[$s_key], $task); + $conn = $this->getConnection($task->uniq, $servers); + $conn->send($type, $params); + + $conn->addWaitingTask($task); } /** * Run a set of tasks * - * @param object $set A set of tasks to run + * @param object $set A set of tasks to run * @param int $timeout Time in seconds for the socket timeout. Max is 10 seconds * * @return void @@ -305,7 +293,7 @@ public function runSet(Net_Gearman_Set $set, $timeout = null) $taskKeys = array_keys($set->tasks); $t = 0; - if ($timeout !== null){ + if ($timeout !== null) { $socket_timeout = min(10, (int)$timeout); } else { $socket_timeout = 10; @@ -330,6 +318,7 @@ public function runSet(Net_Gearman_Set $set, $timeout = null) } + if ($t < $totalTasks) { $k = $taskKeys[$t]; $this->submitTask($set->tasks[$k]); @@ -344,16 +333,38 @@ public function runSet(Net_Gearman_Set $set, $timeout = null) $t++; } - $write = null; - $except = null; - $read = $this->conn; - socket_select($read, $write, $except, $socket_timeout); - foreach ($read as $socket) { - $resp = Net_Gearman_Connection::read($socket); + $write = null; + $except = null; + $read_cons = array(); + + foreach ($this->conn as $conn) { + $read_conns[] = $conn->socket; + } + + @socket_select($read_conns, $write, $except, $socket_timeout); + + $error_messages = []; + + foreach ($this->conn as $server => $conn) { + $err = socket_last_error($conn->socket); + // Error 11 is EAGAIN and is normal in non-blocking mode + // Error 35 happens on macOS often enough to be annoying + if ($err && $err != 11 && $err != 35) { + $msg = socket_strerror($err); + list($remote_address, $remote_port) = explode(":", $server); + $error_messages[] = "socket_select failed: ($err) $msg; server: $remote_address:$remote_port"; + } + socket_clear_error($conn->socket); + $resp = $conn->read(); if (count($resp)) { - $this->handleResponse($resp, $socket, $set); + $this->handleResponse($resp, $conn, $set); } } + + // if all connections threw errors, throw an exception + if (count($error_messages) == count($this->conn)) { + throw new Net_Gearman_Exception(implode("; ", $error_messages)); + } } } @@ -367,7 +378,7 @@ public function runSet(Net_Gearman_Set $set, $timeout = null) * @return void * @throws Net_Gearman_Exception */ - protected function handleResponse($resp, $s, Net_Gearman_Set $tasks) + protected function handleResponse($resp, $conn, Net_Gearman_Set $tasks) { if (isset($resp['data']['handle']) && $resp['function'] != 'job_created') { @@ -389,9 +400,8 @@ protected function handleResponse($resp, $s, Net_Gearman_Set $tasks) $task->fail(); break; case 'job_created': - $task = array_shift(Net_Gearman_Connection::$waiting[(int)$s]); + $task = $conn->getWaitingTask(); $task->handle = $resp['data']['handle']; - $task->server = $this->socketIdToServer[(int) $s]; if ($task->type == Net_Gearman_Task::JOB_BACKGROUND) { $task->finished = true; } @@ -418,8 +428,12 @@ public function disconnect() } foreach ($this->conn as $conn) { - Net_Gearman_Connection::close($conn); + if (is_callable(array($conn, "close"))) { + $conn->close(); + } } + + $this->conn = []; } /** @@ -432,6 +446,25 @@ public function __destruct() $this->disconnect(); } -} + /** + * Creates a singleton instance of this class for reuse + * + * @param array $servers An array of servers or a single server + * @param integer $timeout Timeout in microseconds + * + * @return object + * + */ + public static function getInstance($servers, $timeout = 1000) { + + static $instances; + + $key = md5(json_encode($servers)); -?> + if (!isset($instances[$key])) { + $instances[$key] = new Net_Gearman_Client($servers, $timeout); + } + + return $instances[$key]; + } +} diff --git a/vendor/net_gearman/Net/Gearman/Connection.php b/vendor/net_gearman/Net/Gearman/Connection.php index 1e54a2e9c2..fd1a1c5c5d 100644 --- a/vendor/net_gearman/Net/Gearman/Connection.php +++ b/vendor/net_gearman/Net/Gearman/Connection.php @@ -18,8 +18,6 @@ * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ - * @link http://pear.php.net/package/Net_Gearman - * @link http://www.danga.com/gearman/ * @link https://github.com/brianlmoon/net_gearman */ @@ -29,9 +27,8 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @link http://www.danga.com/gearman/ * @link https://github.com/brianlmoon/net_gearman */ class Net_Gearman_Connection @@ -47,7 +44,7 @@ class Net_Gearman_Connection * @see Net_Gearman_Connection::$magic * @see Net_Gearman_Connection::connect() */ - static protected $commands = array( + protected $commands = array( 'can_do' => array(1, array('func')), 'can_do_timeout' => array(23, array('func', 'timeout')), 'cant_do' => array(2, array('func')), @@ -86,7 +83,7 @@ class Net_Gearman_Connection * @see Net_Gearman_Connection::$commands * @see Net_Gearman_Connection::connect() */ - static protected $magic = array(); + protected $magic = array(); /** * Tasks waiting for a handle @@ -99,7 +96,7 @@ class Net_Gearman_Connection * @var array $waiting * @static */ - static public $waiting = array(); + protected $waiting = array(); /** * Is PHP's multibyte overload turned on? @@ -108,14 +105,23 @@ class Net_Gearman_Connection */ static protected $multiByteSupport = null; + public $socket; + /** - * Constructor + * Gearmand Server Version * - * @return void + * @var string */ - final private function __construct() - { - // Don't allow this class to be instantiated + protected $serverVersion; + + public function __construct($host=null, $timeout=250) { + if ($host) { + $this->connect($host, $timeout); + } + } + + public function __destruct() { + $this->close(); } /** @@ -124,8 +130,8 @@ final private function __construct() * Opens the socket to the Gearman Job server. It throws an exception if * a socket error occurs. Also populates Net_Gearman_Connection::$magic. * - * @param string $host e.g. 127.0.0.1 or 127.0.0.1:7003 - * @param int $timeout Timeout in milliseconds + * @param string $host e.g. 127.0.0.1 or 127.0.0.1:7003 + * @param int $timeout Timeout in milliseconds * * @return resource A connection to a Gearman server * @throws Net_Gearman_Exception when it can't connect to server @@ -133,43 +139,105 @@ final private function __construct() * @see Net_Gearman_Connection::$magic * @see Net_Gearman_Connection::$commands */ - static public function connect($host, $timeout = 2000) + public function connect($host, $timeout = 250) { - if (!count(self::$magic)) { - foreach (self::$commands as $cmd => $i) { - self::$magic[$i[0]] = array($cmd, $i[1]); + + $this->close(); + + if (!count($this->magic)) { + foreach ($this->commands as $cmd => $i) { + $this->magic[$i[0]] = array($cmd, $i[1]); } } - $err = ''; - $errno = 0; - $port = 4730; - if (strpos($host, ':')) { list($host, $port) = explode(':', $host); + } else { + $port = 4730; } - $start = microtime(true); + $this->socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + + /** + * Set the send and receive timeouts super low so that socket_connect + * will return to us quickly. We then loop and check the real timeout + * and check the socket error to decide if its connected yet or not. + */ + socket_set_option($this->socket, SOL_SOCKET, SO_SNDTIMEO, array("sec"=>0, "usec" => 100)); + socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>0, "usec" => 100)); + + /** + * Explicitly set this to blocking which should be the default + */ + socket_set_block($this->socket); + + $now = microtime(true); + $waitUntil = $now + $timeout / 1000; + + /** + * Loop calling socket_connect. As long as the error is 115 (in progress) + * or 114 (already called) and our timeout has not been reached, keep + * trying. + */ + $socket_connected = false; do { - $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); - $socket_connected = @socket_connect($socket, $host, $port); - $elapsed = ((microtime(true) - $start) * 1000); - if ($socket_connected) { - socket_set_nonblock($socket); - socket_set_option($socket, SOL_TCP, 1, 1); - } - } while (!$socket_connected && $elapsed < $timeout); + socket_clear_error($this->socket); + $socket_connected = @socket_connect($this->socket, $host, $port); + $err = @socket_last_error($this->socket); + } + while (($err === 115 || $err === 114) && (microtime(true) < $waitUntil)); + + $elapsed = microtime(true) - $now; + + /** + * For some reason, socket_connect can return true even when it is + * not connected. Make sure it returned true the last error is zero + */ + $socket_connected = $socket_connected && $err === 0; + + + if ($socket_connected) { + socket_set_nonblock($this->socket); + + socket_set_option($this->socket, SOL_SOCKET, SO_KEEPALIVE, 1); + + /** + * set the real send/receive timeouts here now that we are connected + */ + $timeout = self::calculateTimeout($timeout); + socket_set_option($this->socket, SOL_SOCKET, SO_SNDTIMEO, array("sec"=>$timeout[0], "usec" => $timeout[1])); + socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$timeout[0], "usec" => $timeout[1])); + + // socket_set_option($this->socket, SOL_TCP, SO_DEBUG, 1); // Debug + + $this->setServerVersion($host); + + } else { + + $errno = @socket_last_error($this->socket); + $errstr = @socket_strerror($errno); + + /** + * close the socket just in case it + * is somehow alive to some degree + */ + $this->close(); - if (!$socket_connected) { - $errno = socket_last_error($socket); - $errstr = socket_strerror($errno); throw new Net_Gearman_Exception( "Can't connect to server ($errno: $errstr)" ); } - self::$waiting[(int)$socket] = array(); - return $socket; + $this->waiting = array(); + + } + + public function addWaitingTask($task) { + $this->waiting[] = $task; + } + + public function getWaitingTask() { + return array_shift($this->waiting); } /** @@ -180,22 +248,25 @@ static public function connect($host, $timeout = 2000) * parameters (in key value pairings) and packs it all up to send across * the socket. * - * @param resource $socket The socket to send the command to * @param string $command Command to send (e.g. 'can_do') * @param array $params Params to send * - * @see Net_Gearman_Connection::$commands, Net_Gearman_Connection::$socket + * @see Net_Gearman_Connection::$commands, Net_Gearman_Connection::$this->socket * @return boolean * @throws Net_Gearman_Exception on invalid command or unable to write */ - static public function send($socket, $command, array $params = array()) + public function send($command, array $params = array()) { - if (!isset(self::$commands[$command])) { + if (!isset($this->commands[$command])) { throw new Net_Gearman_Exception('Invalid command: ' . $command); } + if ($command === 'can_do_timeout') { + $params = $this->fixTimeout($params); + } + $data = array(); - foreach (self::$commands[$command][1] as $field) { + foreach ($this->commands[$command][1] as $field) { if (isset($params[$field])) { $data[] = $params[$field]; } @@ -204,23 +275,23 @@ static public function send($socket, $command, array $params = array()) $d = implode("\x00", $data); $cmd = "\0REQ" . pack("NN", - self::$commands[$command][0], - self::stringLength($d)) . $d; + $this->commands[$command][0], + $this->stringLength($d)) . $d; - $cmdLength = self::stringLength($cmd); + $cmdLength = $this->stringLength($cmd); $written = 0; $error = false; do { - $check = @socket_write($socket, - self::subString($cmd, $written, $cmdLength), + $check = @socket_write($this->socket, + $this->subString($cmd, $written, $cmdLength), $cmdLength); if ($check === false) { - if (socket_last_error($socket) == SOCKET_EAGAIN or - socket_last_error($socket) == SOCKET_EWOULDBLOCK or - socket_last_error($socket) == SOCKET_EINPROGRESS) + if (socket_last_error($this->socket) == SOCKET_EAGAIN or + socket_last_error($this->socket) == SOCKET_EWOULDBLOCK or + socket_last_error($this->socket) == SOCKET_EINPROGRESS) { - // skip this is okay + // skip this is okay } else { @@ -233,8 +304,8 @@ static public function send($socket, $command, array $params = array()) } while ($written < $cmdLength); if ($error === true) { - $errno = socket_last_error($socket); - $errstr = socket_strerror($errno); + $errno = @socket_last_error($this->socket); + $errstr = @socket_strerror($errno); throw new Net_Gearman_Exception( "Could not write command to socket ($errno: $errstr)" ); @@ -244,26 +315,24 @@ static public function send($socket, $command, array $params = array()) /** * Read command from Gearman * - * @param resource $socket The socket to read from - * * @see Net_Gearman_Connection::$magic * @return array Result read back from Gearman * @throws Net_Gearman_Exception connection issues or invalid responses */ - static public function read($socket) + public function read() { $header = ''; do { - $buf = @socket_read($socket, 12 - self::stringLength($header)); + $buf = @socket_read($this->socket, 12 - $this->stringLength($header)); $header .= $buf; } while ($buf !== false && - $buf !== '' && self::stringLength($header) < 12); + $buf !== '' && $this->stringLength($header) < 12); if ($buf === '') { throw new Net_Gearman_Exception("Connection was reset"); } - if (self::stringLength($header) == 0) { + if ($this->stringLength($header) == 0) { return array(); } $resp = @unpack('a4magic/Ntype/Nlen', $header); @@ -272,7 +341,7 @@ static public function read($socket) throw new Net_Gearman_Exception('Received an invalid response'); } - if (!isset(self::$magic[$resp['type']])) { + if (!isset($this->magic[$resp['type']])) { throw new Net_Gearman_Exception( 'Invalid response magic returned: ' . $resp['type'] ); @@ -281,28 +350,26 @@ static public function read($socket) $return = array(); if ($resp['len'] > 0) { $data = ''; - while (self::stringLength($data) < $resp['len']) { - $data .= @socket_read($socket, $resp['len'] - self::stringLength($data)); + while ($this->stringLength($data) < $resp['len']) { + $data .= @socket_read($this->socket, $resp['len'] - $this->stringLength($data)); } $d = explode("\x00", $data); - foreach (self::$magic[$resp['type']][1] as $i => $a) { + foreach ($this->magic[$resp['type']][1] as $i => $a) { $return[$a] = $d[$i]; } } - $function = self::$magic[$resp['type']][0]; + $function = $this->magic[$resp['type']][0]; if ($function == 'error') { - if (!self::stringLength($return['err_text'])) { + if (!$this->stringLength($return['err_text'])) { $return['err_text'] = 'Unknown error; see error code.'; } - throw new Net_Gearman_Exception( - $return['err_text'], $return['err_code'] - ); + throw new Net_Gearman_Exception("({$return['err_code']}): {$return['err_text']}"); } - return array('function' => self::$magic[$resp['type']][0], + return array('function' => $this->magic[$resp['type']][0], 'type' => $resp['type'], 'data' => $return); } @@ -310,49 +377,106 @@ static public function read($socket) /** * Blocking socket read * - * @param resource $socket The socket to read from * @param float $timeout The timeout for the read * * @throws Net_Gearman_Exception on timeouts * @return array */ - static public function blockingRead($socket, $timeout = 500) + public function blockingRead($timeout = 250) { - static $cmds = array(); - - $tv_sec = floor(($timeout % 1000)); - $tv_usec = ($timeout * 1000); - - $start = microtime(true); - while (count($cmds) == 0) { - if (((microtime(true) - $start) * 1000) > $timeout) { - throw new Net_Gearman_Exception('Blocking read timed out'); + $write = null; + $except = null; + $read = array($this->socket); + + $timeout = self::calculateTimeout($timeout); + + socket_clear_error($this->socket); + $success = @socket_select($read, $write, $except, $timeout[0], $timeout[1]); + if ($success === false) { + $errno = @socket_last_error($this->socket); + if ($errno != 0) { + throw new Net_Gearman_Exception("Socket error: ($errno) ".socket_strerror($errno)); } + } - $write = null; - $except = null; - $read = array($socket); - - @socket_select($read, $write, $except, $tv_sec, $tv_usec); - foreach ($read as $s) { - $cmds[] = Net_Gearman_Connection::read($s); - } + if ($success === 0) { + $errno = @socket_last_error($this->socket); + throw new Net_Gearman_Exception( + sprintf("Socket timeout (%.4fs, %.4fμs): (%s)", $timeout[0], $timeout[1], socket_strerror($errno)) + ); } - return array_shift($cmds); + $cmd = $this->read(); + + return $cmd; } /** * Close the connection * - * @param resource $socket The connection/socket to close - * * @return void */ - static public function close($socket) + public function close() { - if (is_resource($socket)) { - socket_close($socket); + if (isset($this->socket) && is_resource($this->socket)) { + + socket_clear_error($this->socket); + + socket_set_block($this->socket); + + socket_set_option($this->socket, SOL_SOCKET, SO_SNDTIMEO, array("sec"=>0, "usec" => 500)); + socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>0, "usec" => 500)); + + @socket_shutdown($this->socket); + + $err = socket_last_error($this->socket); + if ($err != 0) { + if ($err == 107) { + // 107 means Transport endpoint is not connected + unset($this->socket); + return; + } + throw new Net_Gearman_Exception("Socket error: ($err) ".socket_strerror($err)); + } + + /** + * Read anything left on the buffer that we didn't get + * due to a timeout or something + */ + do { + $err = 0; + $buf = ""; + socket_clear_error($this->socket); + socket_close($this->socket); + if (isset($this->socket) && is_resource($this->socket)) { + $err = socket_last_error($this->socket); + // Check for EAGAIN error + // 11 on Linux + // 35 on BSD + if ($err == 11 || $err == 35) { + $buf = @socket_read($this->socket, 8192); + $err = socket_last_error($this->socket); + } else { + // Some other error was returned. We need to + // terminate the socket and get out. To do this, + // we set SO_LINGER to {on, 0} which causes + // the connection to be aborted. + socket_set_option( + $this->socket, + SOL_SOCKET, + SO_LINGER, + array( + 'l_onoff' => 1, + 'l_linger' => 0 + ) + ); + socket_close($this->socket); + $err = 0; + } + } + } while ($err != 0 && strlen($buf) > 0); + + unset($this->socket); } } @@ -363,11 +487,40 @@ static public function close($socket) * * @return boolean False if we aren't connected */ - static public function isConnected($conn) + public function isConnected() + { + // PHP 8+ returns Socket object instead of resource + if ($this->socket instanceof \Socket) { + return true; + } + + // PHP 5.x-7.x returns socket + if (is_resource($this->socket) === true) { + $type = strtolower(get_resource_type($this->socket)); + return $type === 'socket'; + } + + return false; + } + + /** + * Calculates the timeout values for socket_select + * + * @param int $milliseconds Timeout in milliseconds + * @return array The first value is the seconds and the second value + * is microseconds + */ + public static function calculateTimeout($milliseconds) { - return (is_null($conn) !== true && - is_resource($conn) === true && - strtolower(get_resource_type($conn)) == 'socket'); + if ($milliseconds >= 1000) { + $ts_seconds = $milliseconds / 1000; + $tv_sec = floor($ts_seconds); + $tv_usec = ($ts_seconds - $tv_sec) * 1000000; + } else { + $tv_sec = 0; + $tv_usec = $milliseconds * 1000; + } + return [$tv_sec, $tv_usec]; } /** @@ -378,7 +531,7 @@ static public function isConnected($conn) * @return integer Size of string * @see Net_Gearman_Connection::$multiByteSupport */ - static public function stringLength($value) + public static function stringLength($value) { if (is_null(self::$multiByteSupport)) { self::$multiByteSupport = intval(ini_get('mbstring.func_overload')); @@ -387,8 +540,8 @@ static public function stringLength($value) if (self::$multiByteSupport & 2) { return mb_strlen($value, '8bit'); } else { - return strlen($value); - } + return strlen($value); + } } /** @@ -403,7 +556,7 @@ static public function stringLength($value) * @link http://us3.php.net/mb_substr * @link http://us3.php.net/substr */ - static public function subString($str, $start, $length) + public static function subString($str, $start, $length) { if (is_null(self::$multiByteSupport)) { self::$multiByteSupport = intval(ini_get('mbstring.func_overload')); @@ -415,6 +568,30 @@ static public function subString($str, $start, $length) return substr($str, $start, $length); } } -} -?> + /** + * Sets the server version. + * + * @param string $host The host + * @param Net_Gearman_Manager $manager Optional manager object + */ + protected function setServerVersion($host, $manager = null) + { + if (empty($manager)) { + $manager = new \Net_Gearman_Manager($host); + } + $this->serverVersion = $manager->version(); + unset($manager); + } + + protected function fixTimeout($params) { + // In gearmand version 1.1.19 and greater, the timeout is + // expected to be in milliseconds. Before that version, it + // is expected to be in seconds. + // https://github.com/gearman/gearmand/issues/196 + if (version_compare('1.1.18', $this->serverVersion)) { + $params['timeout'] *= 1000; + } + return $params; + } +} diff --git a/vendor/net_gearman/Net/Gearman/Exception.php b/vendor/net_gearman/Net/Gearman/Exception.php index 93d921e415..e607a96c6c 100644 --- a/vendor/net_gearman/Net/Gearman/Exception.php +++ b/vendor/net_gearman/Net/Gearman/Exception.php @@ -14,11 +14,11 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ - * @link http://pear.php.net/package/Net_Gearman - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman */ /** @@ -27,12 +27,11 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @link http://www.danga.com/gearman/ - * @version Release: @package_version@ - * @see PEAR_Exception + * @link https://github.com/brianlmoon/net_gearman */ class Net_Gearman_Exception extends Exception { + } diff --git a/vendor/net_gearman/Net/Gearman/Job.php b/vendor/net_gearman/Net/Gearman/Job.php index 48da99b165..db0ee2086c 100644 --- a/vendor/net_gearman/Net/Gearman/Job.php +++ b/vendor/net_gearman/Net/Gearman/Job.php @@ -14,11 +14,11 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ - * @link http://pear.php.net/package/Net_Gearman - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman */ // Define this if you want your Jobs to be stored in a different @@ -38,11 +38,9 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @link http://www.danga.com/gearman/ - * @version Release: @package_version@ - * @see Net_Gearman_Job_Common, Net_Gearman_Worker + * @link https://github.com/brianlmoon/net_gearman */ abstract class Net_Gearman_Job { @@ -65,29 +63,49 @@ abstract class Net_Gearman_Job */ static public function factory($job, $conn, $handle, $initParams=array()) { - $file = NET_GEARMAN_JOB_PATH . '/' . $job . '.php'; + if (empty($initParams['path'])) { + $paths = explode(',', NET_GEARMAN_JOB_PATH); + $file = null; + + foreach ($paths as $path) { + $tmpFile = $path . '/' . $job . '.php'; + + if (file_exists(realpath($tmpFile))) { + $file = $tmpFile; + break; + } + } + } + else { + $file = $initParams['path']; + } + include_once $file; - $class = NET_GEARMAN_JOB_CLASS_PREFIX . $job; - // Strip out any potential prefixes used in uniquely identifying AtoM installs. - // e.g. "fdd4764376d2f763-arFindingAidJob" -> "arFindingAidJob" - // See issue #7423. - $prefix = QubitJob::getJobPrefix(); - if (substr($class, 0, strlen($prefix)) === $prefix) { - $class = substr($class, strlen($prefix)); + if (empty($initParams['class_name'])) { + $class = NET_GEARMAN_JOB_CLASS_PREFIX . $job; + } + else { + $class = $initParams['class_name']; } + // Strip out any potential prefixes used in uniquely identifying AtoM installs. + // // e.g. "fdd4764376d2f763-arFindingAidJob" -> "arFindingAidJob" + // // See issue #7423. + $prefix = QubitJob::getJobPrefix(); + if (substr($class, 0, strlen($prefix)) === $prefix) { + $class = substr($class, strlen($prefix)); + } + if (!class_exists($class)) { - throw new Net_Gearman_Job_Exception('Invalid Job class'); + throw new Net_Gearman_Job_Exception('Invalid Job class: ' . (empty($class) ? '' : $class) . ' in ' . (empty($file) ? '' : $file) ); } $instance = new $class($conn, $handle, $initParams); if (!$instance instanceof Net_Gearman_Job_Common) { - throw new Net_Gearman_Job_Exception('Job is of invalid type'); + throw new Net_Gearman_Job_Exception('Job is of invalid type: ' . get_class($instance)); } return $instance; } } - -?> diff --git a/vendor/net_gearman/Net/Gearman/Job/Common.php b/vendor/net_gearman/Net/Gearman/Job/Common.php index bcfe01ce3a..d11a176465 100644 --- a/vendor/net_gearman/Net/Gearman/Job/Common.php +++ b/vendor/net_gearman/Net/Gearman/Job/Common.php @@ -21,6 +21,7 @@ * @link http://www.danga.com/gearman/ */ + /** * Base job class for all Gearman jobs * @@ -54,6 +55,7 @@ abstract class Net_Gearman_Job_Common * Parameters for Job instantiation * @var array $initParams */ + protected $initParams; /** * Constructor @@ -64,7 +66,7 @@ abstract class Net_Gearman_Job_Common * * @return void */ - public function __construct($conn, $handle, array $initParams=array()) + public function __construct(Net_Gearman_Connection $conn, $handle, array $initParams=array()) { $this->conn = $conn; $this->handle = $handle; @@ -92,7 +94,7 @@ abstract public function run($arg); */ public function status($numerator, $denominator) { - Net_Gearman_Connection::send($this->conn, 'work_status', array( + $this->conn->send('work_status', array( 'handle' => $this->handle, 'numerator' => $numerator, 'denominator' => $denominator @@ -100,13 +102,15 @@ public function status($numerator, $denominator) } /** - * Mark your job as complete with its status + * Mark your job as complete with its status. * * Net_Gearman communicates between the client and jobs in JSON. The main * benefit of this is that we can send fairly complex data types between * different languages. You should always pass an array as the result to * this function. * + * NOTE: Your actual worker code should not call this if you are using the GearmanManager + * * @param array $result Result of your job * * @return void @@ -115,7 +119,7 @@ public function status($numerator, $denominator) public function complete(array $result) { - Net_Gearman_Connection::send($this->conn, 'work_complete', array( + $this->conn->send('work_complete', array( 'handle' => $this->handle, 'result' => json_encode($result) )); @@ -128,12 +132,15 @@ public function complete(array $result) * this function and exit from your run() method. This will tell Gearman * (and the client by proxy) that the job has failed. * + * NOTE: Your actual worker code should not call this if you are using the GearmanManager, you should + * throw a Net_Gearman_Job_Exception instead. + * * @return void * @see Net_Gearman_Connection::send() */ public function fail() { - Net_Gearman_Connection::send($this->conn, 'work_fail', array( + $this->conn->send('work_fail', array( 'handle' => $this->handle )); } diff --git a/vendor/net_gearman/Net/Gearman/Manager.php b/vendor/net_gearman/Net/Gearman/Manager.php index 45544d9110..c6d796d952 100644 --- a/vendor/net_gearman/Net/Gearman/Manager.php +++ b/vendor/net_gearman/Net/Gearman/Manager.php @@ -14,11 +14,10 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/Net_Gearman - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman */ /** @@ -31,10 +30,10 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: @package_version@ - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman */ class Net_Gearman_Manager { @@ -61,28 +60,30 @@ class Net_Gearman_Manager /** * Constructor * - * @param string $server Host and port (e.g. 'localhost:7003') + * @param string $server Host and port (e.g. 'localhost:4730') * @param integer $timeout Connection timeout * * @throws Net_Gearman_Exception * @see Net_Gearman_Manager::$conn */ - public function __construct($server, $timeout = 5) + public function __construct($server = null, $timeout = 5) { - if (strpos($server, ':')) { - list($host, $port) = explode(':', $server); - } else { - $host = $server; - $port = 4730; - } + if (func_num_args() > 0) { + if (strpos($server, ':')) { + list($host, $port) = explode(':', $server); + } else { + $host = $server; + $port = 4730; + } - $errCode = 0; - $errMsg = ''; - $this->conn = @fsockopen($host, $port, $errCode, $errMsg, $timeout); - if ($this->conn === false) { - throw new Net_Gearman_Exception( - 'Could not connect to ' . $host . ':' . $port - ); + $errCode = 0; + $errMsg = ''; + $this->conn = @fsockopen($host, $port, $errCode, $errMsg, $timeout); + if ($this->conn === false) { + throw new Net_Gearman_Exception( + 'Could not connect to ' . $host . ':' . $port + ); + } } } @@ -134,7 +135,17 @@ public function shutdown($graceful = false) public function workers() { $this->sendCommand('workers'); - $res = $this->recvCommand(); + $res = $this->recvCommand(); + return $this->parseWorkersResponse($res); + } + + /** + * Parses a 'workers' response payload + * @param string $res Response payload from a `workers` command + * @return array + */ + public function parseWorkersResponse($res) + { $workers = array(); $tmp = explode("\n", $res); foreach ($tmp as $t) { @@ -142,17 +153,17 @@ public function workers() continue; } - list($info, $abilities) = explode(" : ", $t); - list($fd, $ip, $id) = explode(' ', $info); - - $abilities = trim($abilities); + $t = trim($t); - $workers[] = array( - 'fd' => $fd, - 'ip' => $ip, - 'id' => $id, - 'abilities' => empty($abilities) ? array() : explode(' ', $abilities) - ); + if (preg_match("/^(.+?) (.+?) (.+?) :(.*)$/", $t, $matches)) { + $abilities = trim($matches[4]); + $workers[] = array( + 'fd' => $matches[1], + 'ip' => $matches[2], + 'id' => $matches[3], + 'abilities' => empty($abilities) ? [] : explode(' ', $abilities) + ); + } } return $workers; @@ -288,7 +299,7 @@ protected function checkForError($data) $data = trim($data); if (preg_match('/^ERR/', $data)) { list(, $code, $msg) = explode(' ', $data); - throw new Net_Gearman_Exception($msg, urldecode($code)); + throw new Net_Gearman_Exception($msg . ' [error code: ' . urldecode($code) . ']'); } } @@ -315,5 +326,3 @@ public function __destruct() $this->disconnect(); } } - -?> diff --git a/vendor/net_gearman/Net/Gearman/Set.php b/vendor/net_gearman/Net/Gearman/Set.php index 6e480ae795..63551848a8 100644 --- a/vendor/net_gearman/Net/Gearman/Set.php +++ b/vendor/net_gearman/Net/Gearman/Set.php @@ -14,11 +14,11 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ - * @link http://pear.php.net/package/Net_Gearman - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman */ /** @@ -58,10 +58,10 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: @package_version@ - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman * @see Net_Gearman_Job_Common, Net_Gearman_Worker */ class Net_Gearman_Set implements IteratorAggregate, Countable @@ -194,6 +194,7 @@ public function attachCallback($callback) * * @return ArrayIterator Tasks */ + #[\ReturnTypeWillChange] public function getIterator() { return new ArrayIterator($this->tasks); @@ -205,6 +206,7 @@ public function getIterator() * @return int Number of tasks in the set * @see {@link Countable::count()} */ + #[\ReturnTypeWillChange] public function count() { return $this->tasksCount; diff --git a/vendor/net_gearman/Net/Gearman/Task.php b/vendor/net_gearman/Net/Gearman/Task.php index 15cdcf206e..48b003dceb 100644 --- a/vendor/net_gearman/Net/Gearman/Task.php +++ b/vendor/net_gearman/Net/Gearman/Task.php @@ -14,11 +14,11 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ - * @link http://pear.php.net/package/Net_Gearman - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman */ /** @@ -27,10 +27,10 @@ * @category Net * @package Net_Gearman * @author Joe Stump + * @author Brian Moon * @copyright 2007-2008 Digg.com, Inc. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version Release: @package_version@ - * @link http://www.danga.com/gearman/ + * @link https://github.com/brianlmoon/net_gearman * @see Net_Gearman_Set, Net_Gearman_Client */ class Net_Gearman_Task @@ -74,6 +74,15 @@ class Net_Gearman_Task */ public $handle = ''; + /** + * List of servers this task can run on. If not set, the servers the client + * has will be used. This is for cases where different tasks all in one + * set may only be available on certain servers. + * + * @var array + */ + public $servers = array(); + /** * Server used for the task * @@ -225,7 +234,7 @@ class Net_Gearman_Task * @throws Net_Gearman_Exception */ public function __construct($func, $arg, $uniq = null, - $type = self::JOB_NORMAL) + $type = self::JOB_NORMAL, array $servers = array()) { $this->func = $func; $this->arg = $arg; @@ -236,6 +245,10 @@ public function __construct($func, $arg, $uniq = null, $this->uniq = $uniq; } + if(!empty($servers)){ + $this->servers = $servers; + } + $this->type = $type; if (!in_array( diff --git a/vendor/net_gearman/Net/Gearman/Worker.php b/vendor/net_gearman/Net/Gearman/Worker.php index 2d321dcc68..a4c9f964f5 100644 --- a/vendor/net_gearman/Net/Gearman/Worker.php +++ b/vendor/net_gearman/Net/Gearman/Worker.php @@ -20,6 +20,7 @@ * @link http://www.danga.com/gearman/ */ + /** * Gearman worker class * @@ -47,7 +48,7 @@ * exit; * } * - * ?> + * * * * @category Net @@ -75,6 +76,20 @@ class Net_Gearman_Worker */ protected $retryConn = array(); + /** + * List of servers that have failed a connection + * + * @var array $conn + */ + protected $failedConn = array(); + + /** + * Holds a count of jobs done for each server + * + * @var array $stats + */ + protected $stats = array(); + /** * Pool of worker abilities * @@ -89,6 +104,42 @@ class Net_Gearman_Worker */ protected $initParams = array(); + /** + * Number of seconds to wait to retry a connection after it has failed. + * If a server is already in the retry list when a new connection is + * attempted, the retry time for that server will be increased using + * this value as the base + a multiple. + * + * @var float + */ + protected $retryTime = 3; + + /** + * The maximum of amount of time in seconds to wait before trying to + * reconnect to a server. + * + * @var integer + */ + protected $maxRetryTime = 60; + + /** + * Stores the minimum current retry time of the servers in the retry list. + * We use this when putting workers into pre_sleep so we can wake up + * after this time and retry connections. + * + * @var integer + */ + protected $minCurrentRetryTime = null; + + /** + * The time in seconds to to read on the sockets when we have had no work + * to do. This prevents the worker from constantly requesting jobs + * from the server. + * + * @var integer + */ + protected $sleepTime = 30; + /** * Callbacks registered for this worker * @@ -96,11 +147,13 @@ class Net_Gearman_Worker * @see Net_Gearman_Worker::JOB_START * @see Net_Gearman_Worker::JOB_COMPLETE * @see Net_Gearman_Worker::JOB_FAIL + * @see Net_Gearman_Worker::WORKER_STATUS */ protected $callback = array( self::JOB_START => array(), self::JOB_COMPLETE => array(), - self::JOB_FAIL => array() + self::JOB_FAIL => array(), + self::WORKER_STATUS => array(), ); /** @@ -111,22 +164,39 @@ class Net_Gearman_Worker protected $id = ""; /** - * Socket return timeout + * Socket timeout in milliseconds * * @var int $socket_timeout */ - protected $socket_timeout = 1; + protected $socket_timeout = 250; /** - * Callback types + * Callback type * - * @const integer JOB_START Ran when a job is started - * @const integer JOB_COMPLETE Ran when a job is finished - * @const integer JOB_FAIL Ran when a job fails + * @const integer JOB_START Runs when a job is started */ - const JOB_START = 1; - const JOB_COMPLETE = 2; - const JOB_FAIL = 3; + const JOB_START = 1; + + /** + * Callback type + * + * @const integer JOB_COMPLETE Runs when a job is finished + */ + const JOB_COMPLETE = 2; + + /** + * Callback type + * + * @const integer JOB_COMPLETE Runs when a job is finished + */ + const JOB_FAIL = 3; + + /** + * Callback type + * + * @const integer WORKER_STATUS Runs to send status info for servers + */ + const WORKER_STATUS = 4; /** * Constructor @@ -147,52 +217,158 @@ public function __construct($servers, $id = "", $socket_timeout=null) throw new Net_Gearman_Exception('Invalid servers specified'); } - if(empty($id)){ + if (empty($id)) { $id = "pid_".getmypid()."_".uniqid(); } $this->id = $id; - if(!is_null($socket_timeout)){ - if(is_numeric($socket_timeout)){ + if (!is_null($socket_timeout)) { + if (is_numeric($socket_timeout)) { $this->socket_timeout = (int)$socket_timeout; } else { - throw Net_Gearman_Exception("Invalid valid for socket timeout"); + throw new Net_Gearman_Exception("Invalid valid for socket timeout"); } } + /** + * Randomize the server list so all the workers don't try and connect + * to the same server first causing a connection stampede + */ + shuffle($servers); + foreach ($servers as $s) { - try { - $conn = Net_Gearman_Connection::connect($s); - Net_Gearman_Connection::send($conn, "set_client_id", array("client_id" => $this->id)); + $this->connect($s); - $this->conn[$s] = $conn; + } + + } - } catch (Net_Gearman_Exception $e) { - $this->retryConn[$s] = time(); + /** + * Connects to a gearman server and puts failed connections into the retry + * list. + * + * @param string $server Server name/ip and optional port to connect + * + * @return bool + */ + private function connect($server) { + $success = false; + + try { + + /** + * If this is a reconnect, be sure we close the old connection + * before making a new one. + */ + if (isset($this->conn[$server]) && is_resource($this->conn[$server])) { + $this->close($server); } - } - if (empty($this->conn)) { - throw new Net_Gearman_Exception( - "Couldn't connect to any available servers" + $this->conn[$server] = new Net_Gearman_Connection($server, $this->socket_timeout); + + $this->conn[$server]->send("set_client_id", array("client_id" => $this->id)); + + $this->addAbilities($this->conn[$server]); + + if (isset($this->retryConn[$server])) { + unset($this->retryConn[$server]); + $this->status("Removing server from the retry list.", $server); + } + + $this->status("Connected to $server", $server); + + $success = true; + + } catch (Net_Gearman_Exception $e) { + + $this->sleepConnection($server); + + $this->status( + "Connection failed", + $server ); } + + return $success; + + } + + /** + * Removes a server from the connection list and adds it to a + * reconnect list. + * + * @param string $server Server and port + * @return void + */ + private function sleepConnection($server) { + + if (isset($this->conn[$server])) { + $this->close($server); + } + + if (empty($this->failedConn[$server])) { + $this->failedConn[$server] = 1; + } else { + $this->failedConn[$server]++; + } + + $waitTime = $this->retryTime($this->failedConn[$server]); + $this->retryConn[$server] = time() + $waitTime; + + if (is_null($this->minCurrentRetryTime)) { + $this->minCurrentRetryTime = $waitTime; + } else { + $this->minCurrentRetryTime = min(array_values($this->retryConn)) - time(); + } + + $this->status( + "Putting $server connection to sleep for ".$waitTime." seconds", + $server + ); } + /** + * Returns the status of the gearmand connections for this object + * + * @return array An array containing a connected count, disconnected count + * and array that lists each server and true/false for connected + */ + public function connection_status() + { + $servers = array(); + + foreach ($this->conn as $server=>$socket) { + $servers[$server] = true; + } + foreach ($this->retryConn as $server=>$status) { + $servers[$server] = false; + } + + return array( + "connected" => count($this->conn), + "disconnected" => count($this->retryConn), + "servers" => $servers, + "stats" => $this->stats + ); + } + + /** * Announce an ability to the job server * - * @param string $ability Name of functcion/ability - * @param integer $timeout How long to give this job - * @param array $initParams Parameters for job constructor + * @param string $ability Name of functcion/ability + * @param integer $timeout How long to give this job + * @param array $initParams Parameters for job constructor + * @param int $conn Optional connection to add ability to. if not set, all + * connections are used * * @return void - * @see Net_Gearman_Connection::send() + * @see $conn->send() */ - public function addAbility($ability, $timeout = null, $initParams=array()) + public function addAbility($ability, $timeout = null, $initParams=array(), $conn=null) { $call = 'can_do'; $params = array('func' => $ability); @@ -205,11 +381,32 @@ public function addAbility($ability, $timeout = null, $initParams=array()) $this->abilities[$ability] = $timeout; - foreach ($this->conn as $conn) { - Net_Gearman_Connection::send($conn, $call, $params); + if ($conn) { + $conn->send($call, $params); + } else { + foreach ($this->conn as $conn) { + $conn->send($call, $params); + } } } + /** + * Announce all abilities to all servers or one server + * + * @param int $conn Optional connection to add ability to. if not set, all + * connections are used + * @return void + */ + protected function addAbilities($conn=null) + { + foreach ($this->abilities as $ability => $timeout) { + $this->addAbility( + $ability, $timeout, $this->initParams[$ability], $conn + ); + } + } + + /** * Begin working * @@ -217,12 +414,14 @@ public function addAbility($ability, $timeout = null, $initParams=array()) * argument is a PHP callback to a function that can be used to monitor * the worker. If no callback is provided then the worker works until it * is killed. The monitor is passed two arguments; whether or not the - * worker is idle and when the last job was ran. + * worker is idle and when the last job was ran. If the monitor returns + * true, then the worker will stop working. * - * @param callback $monitor Function to monitor work + * @param callback $monitor Function to monitor work * * @return void - * @see Net_Gearman_Connection::send(), Net_Gearman_Connection::connect() + * + * @see $conn->send(), $conn->connect() * @see Net_Gearman_Worker::doWork(), Net_Gearman_Worker::addAbility() */ public function beginWork($monitor = null) @@ -231,74 +430,249 @@ public function beginWork($monitor = null) $monitor = array($this, 'stopWork'); } - $write = null; - $except = null; - $working = true; - $lastJob = time(); - $retryTime = 5; + $keep_working = true; + $lastJobTime = time(); - while ($working) { - $sleep = true; - $currentTime = time(); + while ($keep_working) { + + $worked = false; + + $this->retryConnections(); + + if (!empty($this->conn)) { + $worked = $this->askForWork(); - foreach ($this->conn as $server => $socket) { - $worked = false; - try { - $worked = $this->doWork($socket); - } catch (Net_Gearman_Exception $e) { - unset($this->conn[$server]); - $this->retryConn[$server] = $currentTime; - } if ($worked) { - $lastJob = time(); - $sleep = false; + $lastJobTime = time(); } } - $idle = false; - if ($sleep && count($this->conn)) { - foreach ($this->conn as $socket) { - Net_Gearman_Connection::send($socket, 'pre_sleep'); + if ($this->retryConnections()) { + $sleep = false; + } else { + $sleep = !$worked; + } + + if ($sleep && !empty($this->conn)) { + $this->waitQuietly($monitor, $lastJobTime); + } + + if (empty($this->conn)) { + $this->deepSleep($monitor, $lastJobTime); + } + + $keep_working = !call_user_func($monitor, !$worked, $lastJobTime); + } + } + + /** + * Monitors the sockets for incoming data which should cause an + * immediate wake to perform work + * + * @return bool True if there was data on any socket; false if not + */ + protected function waitQuietly($monitor, $lastJobTime) + { + // This is sent to notify the server that the worker is about to + // sleep, and that it should be woken up with a NOOP packet if a + // job comes in for a function the worker is able to perform. + foreach ($this->conn as $server => $conn) { + try { + $conn->send('pre_sleep'); + } catch (Net_Gearman_Exception $e) { + $this->sleepConnection($server); + } + } + + $this->status( + "Worker going quiet for ".$this->sleepTime." seconds" + ); + + $idle = true; + $write = null; + $except = null; + + $wakeTime = time() + $this->sleepTime; + + $socket_timeout = Net_Gearman_Connection::calculateTimeout($this->socket_timeout); + + while ($idle && $wakeTime > time()) { + + if (!empty($this->conn)) { + + foreach ($this->conn as $conn) { + $read_conns[] = $conn->socket; + socket_clear_error($conn->socket); } - $read = $this->conn; - @socket_select($read, $write, $except, $this->socket_timeout); - $idle = (count($read) == 0); + $success = @socket_select($read_conns, $write, $except, $socket_timeout[0], $socket_timeout[1]); + + if (call_user_func($monitor, true, $lastJobTime)) { + break; + } + + // check for errors on any sockets + if ($success === false) { + foreach ($this->conn as $server => $conn) { + $errno = socket_last_error($conn->socket); + if ($errno > 0) { + $this->status( + "Error while listening for wake up; Socket error ($errno): ".socket_strerror($errno), + $server + ); + $this->sleepConnection($server); + } + } + } + + // if we have any read connections left + // after the socket_select call, then there + // is work to do and we need to break + $idle = empty($read_conns); } + } + + return !$idle; + } + + /** + * If we have no open connections, sleep for the retry time. We don't + * actually want to call sleep() for the whole time as the process will + * not respond to signals. So, we will loop and sleep for 1s until the + * retry time has passed. + * + * @return void + */ + protected function deepSleep($monitor, $lastJobTime) + { + $retryTime = !empty($this->minCurrentRetryTime) ? $this->minCurrentRetryTime : $this->retryTime; - $retryChange = false; - foreach ($this->retryConn as $s => $lastTry) { - if (($lastTry + $retryTime) < $currentTime) { - try { - $conn = Net_Gearman_Connection::connect($s); - $this->conn[$s] = $conn; - $retryChange = true; - unset($this->retryConn[$s]); - Net_Gearman_Connection::send($conn, "set_client_id", array("client_id" => $this->id)); - } catch (Net_Gearman_Exception $e) { - $this->retryConn[$s] = $currentTime; + $this->status( + "No open connections. Sleeping for ".$retryTime." seconds" + ); + + $now = time(); + do { + sleep(1); + if (call_user_func($monitor, true, $lastJobTime)) { + break; + } + } + while (microtime(true) - $now < $retryTime); + } + + /** + * Asks each server for work and performs any work that is sent + * + * @return bool True if any work was done, false if not + */ + protected function askForWork($monitor = null, $lastJobTime = null) + { + + $workDone = false; + + /** + * Shuffle the list so we are not always starting with the same + * server on every loop through the while loop. + * + * shuffle() destroys keys, so we have to loop a shuffle of the + * keys. + */ + + $servers = array_keys($this->conn); + shuffle($servers); + + foreach ($servers as $server) { + + $conn = $this->conn[$server]; + + $worked = false; + + try { + $this->status( + "Asking $server for work", + $server + ); + + $worked = $this->doWork($conn); + + if ($worked) { + $workDone = true; + if (empty($this->stats[$server])) { + $this->stats[$server] = 0; } + $this->stats[$server]++; } + + } catch (Net_Gearman_Exception $e) { + + $this->status( + "Exception caught while doing work: ".$e->getMessage(), + $server + ); + + $this->sleepConnection($server); } - if (count($this->conn) == 0) { - // sleep to avoid wasted cpu cycles if no connections to block on using socket_select - sleep(1); + if ($monitor && call_user_func($monitor, true, $lastJobTime)) { + break; } + } - if ($retryChange === true) { - // broadcast all abilities to all servers - foreach ($this->abilities as $ability => $timeout) { - $this->addAbility( - $ability, $timeout, $this->initParams[$ability] + return $workDone; + } + + /** + * Attempts to reconnect to servers which are in a failed state + * + * @return bool True if new connections were created, false if not + */ + protected function retryConnections() + { + $newConnections = false; + + if (count($this->retryConn)) { + + $now = time(); + + foreach ($this->retryConn as $server => $retryTime) { + + if ($retryTime <= $now) { + + $this->status( + "Attempting to reconnect to $server", + $server ); + + /** + * If we reconnect to a server, don't sleep + */ + if ($this->connect($server)) { + $newConnections = true; + } } } - if (call_user_func($monitor, $idle, $lastJob) == true) { - $working = false; + // reset the min retry time as needed + if (empty($this->retryConn)) { + $this->minCurrentRetryTime = null; + } else { + $this->minCurrentRetryTime = min(array_values($this->retryConn)) - time(); } } + + return $newConnections; + } + + /** + * Calculates the connection retry timeout + * + * @param int $retry_count The number of times the connection has been retried + * @return int The number of seconds to wait before retrying + */ + protected function retryTime($retry_count) + { + return min($this->maxRetryTime, $this->retryTime << ($retry_count - 1)); } /** @@ -312,15 +686,37 @@ public function beginWork($monitor = null) * * @return boolean Returns true if work was done, false if not * @throws Net_Gearman_Exception - * @see Net_Gearman_Connection::send() + * @see $conn->send() */ - protected function doWork($socket) + protected function doWork($conn) { - Net_Gearman_Connection::send($socket, 'grab_job'); + $conn->send('grab_job'); $resp = array('function' => 'noop'); while (count($resp) && $resp['function'] == 'noop') { - $resp = Net_Gearman_Connection::blockingRead($socket); + $resp = $conn->blockingRead(); + } + + /** + * The response can be empty during shut down. We don't need to proceed + * in those cases. But, most of the time, it should not be. + */ + if (!is_array($resp) || empty($resp)) { + foreach ($this->conn as $s => $this_conn) { + if ($conn == $this_conn) { + $server = $s; + break; + } + } + + $this->sleepConnection($server); + + $this->status( + "No job was returned from the server", + $server + ); + + return false; } if (in_array($resp['function'], array('noop', 'no_job'))) { @@ -338,15 +734,21 @@ protected function doWork($socket) if (isset($resp['data']['arg']) && Net_Gearman_Connection::stringLength($resp['data']['arg'])) { $arg = json_decode($resp['data']['arg'], true); - if($arg === null){ + if ($arg === null) { $arg = $resp['data']['arg']; } } - $job = Net_Gearman_Job::factory( - $name, $socket, $handle, $this->initParams[$name] - ); try { + + if (empty($this->initParams[$name])) { + $this->initParams[$name] = []; + } + + $job = Net_Gearman_Job::factory( + $name, $conn, $handle, $this->initParams[$name] + ); + $this->start($handle, $name, $arg); $res = $job->run($arg); @@ -357,7 +759,11 @@ protected function doWork($socket) $job->complete($res); $this->complete($handle, $name, $res); } catch (Net_Gearman_Job_Exception $e) { - $job->fail(); + // If the factory method call fails, we won't have a job. + if (isset($job) && $job instanceof Net_Gearman_Job_Common) { + $job->fail(); + } + $this->fail($handle, $name, $e); } @@ -448,6 +854,39 @@ protected function fail($handle, $job, Exception $error) } } + /** + * Run the worker status callbacks + * + * @param string $message A message about the worker's status. + * @param string $server The server name related to the status + * + * @return void + */ + protected function status($message, $server = null) + { + if (count($this->callback[self::WORKER_STATUS]) == 0) { + return; // No callbacks to run + } + + if (!empty($server)) { + $failed_conns = isset($this->failedConn[$server]) ? $this->failedConn[$server] : 0; + $connected = isset($this->conn[$server]) && $this->conn[$server]->isConnected(); + } else { + $failed_conns = null; + $connected = null; + } + + foreach ($this->callback[self::WORKER_STATUS] as $callback) { + call_user_func( + $callback, + $message, + $server, + $connected, + $failed_conns + ); + } + } + /** * Stop working * @@ -455,8 +894,22 @@ protected function fail($handle, $job, Exception $error) */ public function endWork() { - foreach ($this->conn as $conn) { - Net_Gearman_Connection::close($conn); + foreach ($this->conn as $server => $conn) { + $this->close($server); + } + } + + protected function close($server) { + if (isset($this->conn[$server])) { + $conn = $this->conn[$server]; + + try { + $conn->send("reset_abilities"); + } catch (Net_Gearman_Exception $e) { + + } + $conn->close(); + unset($this->conn[$server]); } } diff --git a/vendor/net_gearman/README b/vendor/net_gearman/README deleted file mode 100644 index 6bd52304dc..0000000000 --- a/vendor/net_gearman/README +++ /dev/null @@ -1,59 +0,0 @@ - -Net_Gearman -About - -Net_Gearman is a PEAR package for interfacing with Danga's Gearman. Gearman is a system to farm out work to other machines, dispatching function calls to machines that are better suited to do work, to do work in parallel, to load balance lots of function calls, or to call functions between languages. - -Net_Gearman is currently in production at Yahoo! and Digg doing all sorts of offloaded near time processing. -Installation - - 1. Install PEAR if it is not already installed on your system. - 2. Run pear install http://netgearman.googlecode.com/files/Net_Gearman-x.y.z.tgz (Replace x.y.z with the latest version from the featured download to the right). - -Examples -Client - -someBackgroundJob(array( - 'userid' => 5555, - 'action' => 'new-comment' -)); - -?> - -Job - - - -Worker - -addAbility('someBackgroundJob'); -$worker->beginWork(); - -?> diff --git a/vendor/net_gearman/README.md b/vendor/net_gearman/README.md new file mode 100644 index 0000000000..dbb241e538 --- /dev/null +++ b/vendor/net_gearman/README.md @@ -0,0 +1,50 @@ +# Net Gearman + +## About + +Net_Gearman is a package for interfacing with Gearman. Gearman is a system to farm out work to other machines, dispatching function calls to machines that are better suited to do work, to do work in parallel, to load balance lots of function calls, or to call functions between languages. + +## Installation + +``` +$ composer require brianlmoon/net_gearman +``` + +## Examples + +### Client + +``` +$client = new Net_Gearman_Client("localhost"); +$set = new Net_Gearman_Set(); +$task = new Net_Gearman_Task("Reverse_String", "foobar"); +$task->attachCallback( + function($func, $handle, $result){ + print_r($result) + } +); +$set->addTask($task); +$client->runSet($set, $timeout); +``` + +### Job + +``` +class Reverse_String extends Net_Gearman_Job_Common { + + public function run($workload) { + $result = strrev($workload); + return $result; + } +} +``` + +### Worker + +For easiest use, use GearmanManager for running workers. See: https://github.com/brianlmoon/GearmanManager + +``` +$worker = new Net_Gearman_Worker('localhost'); +$worker->addAbility('Reverse_String'); +$worker->beginWork(); +``` \ No newline at end of file diff --git a/vendor/net_gearman/build.xml b/vendor/net_gearman/build.xml deleted file mode 100644 index cdfd3a84a5..0000000000 --- a/vendor/net_gearman/build.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/net_gearman/composer.json b/vendor/net_gearman/composer.json new file mode 100644 index 0000000000..ee6066ea4c --- /dev/null +++ b/vendor/net_gearman/composer.json @@ -0,0 +1,34 @@ +{ + "name": "brianlmoon/net_gearman", + "homepage": "http://brian.moonspot.net/GearmanManager", + "description": "PHP daemon for managing gearman workers", + "keywords": ["gearman","net_gearman","gearman-manager"], + "type": "library", + "license": "BSD-2-Clause", + "authors": [ + { + "name": "Brian Moon", + "homepage": "http://brian.moonspot.net" + } + ], + "support": { + "issues": "https://github.com/brianlmoon/net_gearman/issues" + }, + "require": { + "php": "^7.0.0|^8.0.0" + }, + "autoload": { + "classmap": [ "Net/Gearman" ] + }, + "autoload-dev": { + "psr-4": { + "Net\\Gearman\\Tests\\": "tests/" + } + }, + "include-path": [ + "." + ], + "require-dev": { + "phpunit/phpunit": "^9.6" + } +} diff --git a/vendor/net_gearman/package.xml b/vendor/net_gearman/package.xml deleted file mode 100644 index 2cec145bbe..0000000000 --- a/vendor/net_gearman/package.xml +++ /dev/null @@ -1,979 +0,0 @@ - - - Net_Gearman - pear.php.net - A PHP interface to Danga's Gearman - Gearman (http://www.danga.com/gearman) is a system to farm out work to other machines. It can load balance function calls to lots of machines and allows you to call functions between languages. It can also run all function calls in parallel. - - Brian Moon - brianlmoon - brian@moonspot.net - yes - - - Till Klampaeckel - till - till@php.net - yes - - - Joe Stump - jstump - joe@joestump.net - no - - - Chris Goffinet - lenn0x - cg@chrisgoffinet.com - no - - 2009-04-22 - - 0.2.3 - 0.2.2 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5.1.0 - - - 1.4.0b1 - - - json - - - - - - - 2009-03-12 - - 0.2.2 - 0.2.2 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2008-01-28 - - 0.2.1 - 0.2.1 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2008-11-16 - - 0.2.0 - 0.2.0 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2008-05-14 - - 0.1.1 - 0.1.0 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2008-04-25 - - 0.1.0 - 0.1.0 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2008-04-05 - - 0.0.9 - 0.0.9 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2008-04-05 - - 0.0.9 - 0.0.9 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2008-03-04 - - 0.0.7 - 0.0.7 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2007-12-11 - - 0.0.6 - 0.0.6 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2007-11-12 - - 0.0.4 - 0.0.4 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2007-10-31 - - 0.0.3 - 0.0.3 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2007-10-25 - - 0.0.2 - 0.0.2 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2007-10-19 - - 0.0.1 - 0.0.1 - - - alpha - alpha - - New BSD License - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/net_gearman/phpunit.xml.dist b/vendor/net_gearman/phpunit.xml.dist new file mode 100644 index 0000000000..a0a6826233 --- /dev/null +++ b/vendor/net_gearman/phpunit.xml.dist @@ -0,0 +1,18 @@ + + + + + ./Net + + + + + ./tests + + + + + functional + + + diff --git a/vendor/net_gearman/phpunit.xml.functional-dist b/vendor/net_gearman/phpunit.xml.functional-dist new file mode 100644 index 0000000000..be69e72918 --- /dev/null +++ b/vendor/net_gearman/phpunit.xml.functional-dist @@ -0,0 +1,21 @@ + + + + + ./Net + + + + + + + + ./tests + + + + + functional + + + diff --git a/vendor/net_gearman/tests/ManagerTest.php b/vendor/net_gearman/tests/ManagerTest.php new file mode 100644 index 0000000000..7246250317 --- /dev/null +++ b/vendor/net_gearman/tests/ManagerTest.php @@ -0,0 +1,61 @@ +parseWorkersResponse($input); + $this->assertEquals( + $expected, + $workers + ); + } + + public function workerResponseData() { + return [ + [ + "41 172.17.0.7 pid_3493_5b7aca9571e4a : Job1 Job2 Job3\n". + "37 172.17.0.7 pid_3489_5b7aca9083c2e : Job4 Job5 Job6", + [ + [ + "fd" => "41", + "ip" => "172.17.0.7", + "id" => "pid_3493_5b7aca9571e4a", + "abilities" => [ + "Job1", + "Job2", + "Job3" + ] + ], + [ + "fd" => "37", + "ip" => "172.17.0.7", + "id" => "pid_3489_5b7aca9083c2e", + "abilities" => [ + "Job4", + "Job5", + "Job6" + ] + ] + ] + ], + [ + // Invalid IPv6 data see bug https://bugs.launchpad.net/gearmand/+bug/1319250 + "34 ::3530:3539:3500:0%2134665296 - :", + [ + [ + "fd" => "34", + "ip" => "::3530:3539:3500:0%2134665296", + "id" => "-", + "abilities" => [] + ], + ] + ] + ]; + } +} diff --git a/vendor/net_gearman/tests/Net/Gearman/ConnectionTest.php b/vendor/net_gearman/tests/Net/Gearman/ConnectionTest.php index 4dfdc65389..793664f155 100644 --- a/vendor/net_gearman/tests/Net/Gearman/ConnectionTest.php +++ b/vendor/net_gearman/tests/Net/Gearman/ConnectionTest.php @@ -1,57 +1,110 @@ - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/Net_Gearman - * @since 0.2.4 + * @group functional */ -class Net_Gearman_ConnectionTest extends PHPUnit_Framework_TestCase +class Net_Gearman_ConnectionTest extends \PHPUnit\Framework\TestCase { + /** + * @group unit + */ + public function testSetServerVersion() { + $mock_manager = new class extends \Net_Gearman_Manager { + public $mock_version; + public function __construct() { + // noop + } + public function version() { + return $this->mock_version; + } + }; + + $connection = new class extends Net_Gearman_Connection { + public function setServerVersion($host, $manager = null) { + parent::setServerVersion($host, $manager); + return $this->serverVersion; + } + }; + + $mock_manager->mock_version = '1.1.18'; + + $result = $connection->setServerVersion('localhost:4730', $mock_manager); + $this->assertEquals('1.1.18', $result); + + $mock_manager->mock_version = '1.1.19'; + + $result = $connection->setServerVersion('localhost:4730', $mock_manager); + $this->assertEquals('1.1.19', $result); + } + + /** + * @group unit + */ + public function testFixTimeout() { + $connection = new class extends Net_Gearman_Connection { + public $serverVersion; + public function fixTimeout($params) { + return parent::fixTimeout($params); + } + }; + + $connection->serverVersion = '1.1.18'; + $result = $connection->fixTimeout(['timeout' => 10]); + $this->assertEquals(['timeout' => 10], $result); + + $connection->serverVersion = '1.1.19'; + $result = $connection->fixTimeout(['timeout' => 10]); + $this->assertEquals(['timeout' => 10000], $result); + + $connection->serverVersion = '1.1.19.1'; + $result = $connection->fixTimeout(['timeout' => 10]); + $this->assertEquals(['timeout' => 10000], $result); + } + /** * When no server is supplied, it should connect to localhost:4730. - * + * @group functional * @return void */ public function testDefaultConnect() { - $connection = Net_Gearman_Connection::connect(); - $this->assertType('resource', $connection); - $this->assertEquals('socket', strtolower(get_resource_type($connection))); + $connection = new Net_Gearman_Connection(NET_GEARMAN_TEST_SERVER); + if (version_compare(PHP_VERSION, '8.0.0') >= 0) { + // PHP 8+ returns a Socket class instead of a resource now + $this->assertInstanceOf('Socket', $connection->socket); + } else { + $this->assertEquals('socket', strtolower(get_resource_type($connection->socket))); + } - $this->assertTrue(Net_Gearman_Connection::isConnected($connection)); + $this->assertTrue($connection->isConnected()); - Net_Gearman_Connection::close($connection); + $connection->close(); } /** * 001-echo_req.phpt - * + * @group functional * @return void */ public function testSend() { - $connection = Net_Gearman_Connection::connect(); - Net_Gearman_Connection::send($connection, 'echo_req', array('text' => 'foobar')); + $connection = new Net_Gearman_Connection(NET_GEARMAN_TEST_SERVER); + $this->assertTrue($connection->isConnected()); + $connection->send('echo_req', ['text' => 'foobar']); do { - $ret = Net_Gearman_Connection::read($connection); - } while (is_array($ret) && !count($ret)); + $ret = $connection->read(); + } while (is_array($ret) && ! count($ret)); - Net_Gearman_Connection::close($connection); + $connection->close(); - $this->assertType('array', $ret); + $this->assertIsArray($ret); $this->assertEquals('echo_res', $ret['function']); $this->assertEquals(17, $ret['type']); + $this->assertIsArray($ret['data']); - $this->assertType('array', $ret['data']); $this->assertEquals('foobar', $ret['data']['text']); } -} \ No newline at end of file +} diff --git a/vendor/net_gearman/tests/Net/Gearman/TaskTest.php b/vendor/net_gearman/tests/Net/Gearman/TaskTest.php index 4970793bc7..b447a5f2a8 100644 --- a/vendor/net_gearman/tests/Net/Gearman/TaskTest.php +++ b/vendor/net_gearman/tests/Net/Gearman/TaskTest.php @@ -1,29 +1,18 @@ - * @license http://www.opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id$ - * @link http://pear.php.net/package/Net_Gearman - * @since 0.2.4 + * Net_Gearman_TaskTest. */ -class Net_Gearman_TaskTest extends PHPUnit_Framework_TestCase +class Net_Gearman_TaskTest extends \PHPUnit\Framework\TestCase { /** * Unknown job type. * * @return void - * @expectedException Net_Gearman_Exception */ public function testExceptionFromConstruct() { - new Net_Gearman_Task('foo', array(), null, 8); + $this->expectException(\Net_Gearman_Exception::class); + new Net_Gearman_Task('foo', [], null, 8); } /** @@ -34,38 +23,34 @@ public function testExceptionFromConstruct() public function testParameters() { $uniq = uniqid(); - $task = new Net_Gearman_Task('foo', array('bar'), $uniq, 1); + $task = new Net_Gearman_Task('foo', ['bar'], $uniq, 1); $this->assertEquals('foo', $task->func); - $this->assertEquals(array('bar'), $task->arg); - $this->assertEquals($uniq, $task->uniq); + $this->assertEquals(['bar'], $task->arg); + $this->assertEquals($uniq, $task->uniq); } - /** - * @expectedException Net_Gearman_Exception - */ public function testAttachInvalidCallback() { - $task = new Net_Gearman_Task('foo', array()); + $this->expectException(\Net_Gearman_Exception::class); + $task = new Net_Gearman_Task('foo', []); $task->attachCallback('func_bar'); } - /** - * @expectedException Net_Gearman_Exception - */ public function testAttachInvalidCallbackType() { - $task = new Net_Gearman_Task('foo', array()); - $this->assertType('Net_Gearman_Task', $task->attachCallback('strlen', 666)); + $this->expectException(\Net_Gearman_Exception::class); + $task = new Net_Gearman_Task('foo', []); + $this->assertInstanceOf('Net_Gearman_Task', $task->attachCallback('strlen', 666)); } public static function callbackProvider() { - return array( - array('strlen', Net_Gearman_Task::TASK_FAIL), - array('intval', Net_Gearman_Task::TASK_COMPLETE), - array('explode', Net_Gearman_Task::TASK_STATUS), - ); + return [ + ['strlen', Net_Gearman_Task::TASK_FAIL], + ['intval', Net_Gearman_Task::TASK_COMPLETE], + ['explode', Net_Gearman_Task::TASK_STATUS], + ]; } /** @@ -73,7 +58,7 @@ public static function callbackProvider() */ public function testAttachCallback($func, $type) { - $task = new Net_Gearman_Task('foo', array()); + $task = new Net_Gearman_Task('foo', []); $task->attachCallback($func, $type); $callbacks = $task->getCallbacks(); @@ -88,7 +73,7 @@ public function testAttachCallback($func, $type) */ public function testCompleteCallback() { - $task = new Net_Gearman_Task('foo', array('foo' => 'bar')); + $task = new Net_Gearman_Task('foo', ['foo' => 'bar']); $this->assertEquals(null, $task->complete('foo')); @@ -102,7 +87,7 @@ public function testCompleteCallback() $this->assertEquals($json, $task->result); $this->assertEquals( - array('func' => 'foo', 'handle' => '', 'result' => $json), + ['func' => 'foo', 'handle' => '', 'result' => $json], $GLOBALS['Net_Gearman_TaskTest'] ); @@ -112,22 +97,23 @@ public function testCompleteCallback() /** * See that task has handle and server assigned. * + * @group functional + * * @return void */ public function testTaskStatus() { - $client = new Net_Gearman_Client(); - - $task = new Net_Gearman_Task('Reverse', range(1,5)); + $client = new Net_Gearman_Client([NET_GEARMAN_TEST_SERVER]); + + $task = new Net_Gearman_Task('Reverse', range(1, 5)); $task->type = Net_Gearman_Task::JOB_BACKGROUND; - + $set = new Net_Gearman_Set(); $set->addTask($task); - + $client->runSet($set); - + $this->assertNotEquals('', $task->handle); - $this->assertNotEquals('', $task->server); } } @@ -142,9 +128,9 @@ public function testTaskStatus() */ function Net_Gearman_TaskTest_testCallBack($func, $handle, $result) { - $GLOBALS['Net_Gearman_TaskTest'] = array( - 'func' => $func, + $GLOBALS['Net_Gearman_TaskTest'] = [ + 'func' => $func, 'handle' => $handle, - 'result' => $result - ); -} \ No newline at end of file + 'result' => $result, + ]; +} diff --git a/vendor/net_gearman/tests/README.md b/vendor/net_gearman/tests/README.md new file mode 100644 index 0000000000..c29362b88e --- /dev/null +++ b/vendor/net_gearman/tests/README.md @@ -0,0 +1,14 @@ +# Runnings tests +From the project root: + +## Install +1. composer install + +## Run the unit tests +1. vendor/bin/phpunit -c phpunit.xml.dist + +## Run the functional tests +1. Start up your gearman job server + 1. For local testing, this docker command can be used: ` docker run --name gearmand --rm -d -p 4730:4730 artefactual/gearmand:latest` +1. Update the `NET_GEARMAN_TEST_SERVER` constant in `phpunit.xml.functional-dist` (if not on localhost and/or port 4730) +1. vendor/bin/phpunit -c phpunit.xml.functional-dist diff --git a/vendor/net_gearman/tests/bootstrap.php b/vendor/net_gearman/tests/bootstrap.php new file mode 100644 index 0000000000..723dd69b34 --- /dev/null +++ b/vendor/net_gearman/tests/bootstrap.php @@ -0,0 +1,25 @@ + $t) { + if (!isset($t["file"])) { + break; + } + fwrite(STDERR, "#$pos {$t["file"]} on line {$t["line"]}\n"); + } + fwrite(STDERR, "###########\n"); + $args = func_get_args(); + foreach ($args as $arg) { + fwrite(STDERR, trim(var_export($arg, true))."\n"); + } + fwrite(STDERR, "###########\n"); + fwrite(STDERR, "END DEBUG\n\n"); +} From 4b1cb097f730beb0150e66c8881d0be5b88ee24e Mon Sep 17 00:00:00 2001 From: melaniekung Date: Mon, 13 Jan 2025 11:04:58 -0800 Subject: [PATCH 08/15] Update Dockerfile for PHP 8.2 --- Dockerfile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 43dab7e633..1380f03508 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM php:7.4-fpm-alpine +FROM php:8.2-fpm-alpine ENV FOP_HOME=/usr/share/fop-2.1 \ COMPOSER_ALLOW_SUPERUSER=1 \ @@ -15,6 +15,7 @@ RUN set -xe \ autoconf \ build-base \ openldap-dev \ + linux-headers \ && docker-php-ext-install \ calendar \ gettext \ @@ -28,10 +29,10 @@ RUN set -xe \ zip \ ldap \ && pecl install apcu pcov \ - && curl -Ls https://github.com/websupport-sk/pecl-memcache/archive/NON_BLOCKING_IO_php7.tar.gz | tar xz -C / \ - && cd /pecl-memcache-NON_BLOCKING_IO_php7 \ + && curl -Ls https://github.com/websupport-sk/pecl-memcache/archive/refs/tags/8.2.tar.gz | tar xz -C / \ + && cd /pecl-memcache-8.2 \ && phpize && ./configure && make && make install \ - && cd / && rm -rf /pecl-memcache-NON_BLOCKING_IO_php7 \ + && cd / && rm -rf /pecl-memcache-8.2 \ && docker-php-ext-enable apcu memcache pcov \ && apk add --no-cache --virtual .phpext-rundeps \ gettext \ From 60ca104f335dbfa6394083e2f8ca3117c21bbbb0 Mon Sep 17 00:00:00 2001 From: melaniekung Date: Mon, 16 Dec 2024 16:09:57 -0800 Subject: [PATCH 09/15] Fix QubitAcl checks. --- .../repository/actions/browseAction.class.php | 2 +- lib/job/arGearman.class.php | 2 +- lib/task/migrate/QubitMigrate.class.php | 12 ++++++++++-- .../sfIsdiahPlugin/templates/indexSuccess.php | 2 +- .../lib/model/arElasticSearchAip.class.php | 2 +- plugins/qbAclPlugin/lib/QubitAcl.class.php | 6 +++--- plugins/qbAclPlugin/lib/QubitActorAcl.class.php | 4 ++-- plugins/sfIsadPlugin/lib/sfIsadPlugin.class.php | 4 ++-- .../sfIsdiahPlugin/templates/indexSuccess.php | 2 +- .../sfPropelPlugin/lib/addon/sfPropelData.class.php | 4 +++- .../propel/engine/database/model/XMLElement.php | 2 -- 11 files changed, 25 insertions(+), 17 deletions(-) diff --git a/apps/qubit/modules/repository/actions/browseAction.class.php b/apps/qubit/modules/repository/actions/browseAction.class.php index 6be51aaf5b..a4f274d2f2 100644 --- a/apps/qubit/modules/repository/actions/browseAction.class.php +++ b/apps/qubit/modules/repository/actions/browseAction.class.php @@ -211,7 +211,7 @@ private function getAdvancedFilterTerms() private function setI18nFieldCultures() { foreach (self::$AGGS as $key => &$value) { - if (false !== array_search('i18n.%s', $value['field'])) { + if (is_array($value['field']) && false !== array_search('i18n.%s', $value['field'])) { $value['field'] = sprintf($value['field'], $this->context->user->getCulture()); } } diff --git a/lib/job/arGearman.class.php b/lib/job/arGearman.class.php index 36292f2858..4840ce52b6 100644 --- a/lib/job/arGearman.class.php +++ b/lib/job/arGearman.class.php @@ -98,7 +98,7 @@ public static function getAbilities($options = []) $abilities = array_merge($abilities, $config['worker_types'][$type]); } } else { - $abilities = call_user_func_array('array_merge', $config['worker_types']); + $abilities = call_user_func_array('array_merge', array_values($config['worker_types'])); } return $abilities; diff --git a/lib/task/migrate/QubitMigrate.class.php b/lib/task/migrate/QubitMigrate.class.php index 5b49ed9d02..ff434c39f3 100644 --- a/lib/task/migrate/QubitMigrate.class.php +++ b/lib/task/migrate/QubitMigrate.class.php @@ -245,6 +245,10 @@ public static function findForeignKeys(array $tables, $configuration) continue; } + if (!is_array($column)) { + continue; + } + if ('integer' != $column['type']) { continue; } @@ -481,12 +485,16 @@ public static function addColumn($table, $column, array $options = []) $connection->exec($query); } } catch (Exception $e) { - $connection->rollback(); + if ($connection->inTransaction()) { + $connection->rollback(); + } throw $e; } - $connection->commit(); + if ($connection->inTransaction()) { + $connection->commit(); + } } public static function dropColumn($table, $column) diff --git a/plugins/arDominionB5Plugin/modules/sfIsdiahPlugin/templates/indexSuccess.php b/plugins/arDominionB5Plugin/modules/sfIsdiahPlugin/templates/indexSuccess.php index 61af4dd234..9b28d86978 100644 --- a/plugins/arDominionB5Plugin/modules/sfIsdiahPlugin/templates/indexSuccess.php +++ b/plugins/arDominionB5Plugin/modules/sfIsdiahPlugin/templates/indexSuccess.php @@ -278,7 +278,7 @@
  • 'repository', 'action' => 'add'], ['class' => 'btn atom-btn-outline-light']); ?>
  • - +
  • 'informationobject', 'action' => 'add', 'repository' => $resource->id], ['class' => 'btn atom-btn-outline-light']); ?>
  • diff --git a/plugins/arElasticSearchPlugin/lib/model/arElasticSearchAip.class.php b/plugins/arElasticSearchPlugin/lib/model/arElasticSearchAip.class.php index 9d8a17f334..87938a8c27 100644 --- a/plugins/arElasticSearchPlugin/lib/model/arElasticSearchAip.class.php +++ b/plugins/arElasticSearchPlugin/lib/model/arElasticSearchAip.class.php @@ -24,7 +24,7 @@ public function load() $sql = 'SELECT id'; $sql .= ' FROM '.QubitAip::TABLE_NAME; - $aips = QubitPdo::fetchAll($sql, ['QubitAip']); + $aips = QubitPdo::fetchAll($sql); $this->count = count($aips); diff --git a/plugins/qbAclPlugin/lib/QubitAcl.class.php b/plugins/qbAclPlugin/lib/QubitAcl.class.php index 82115a177e..702d492014 100644 --- a/plugins/qbAclPlugin/lib/QubitAcl.class.php +++ b/plugins/qbAclPlugin/lib/QubitAcl.class.php @@ -580,7 +580,7 @@ protected function addRole($role) if (!in_array($role->id, $this->_roles)) { foreach ($role->getAncestorsAndSelfForAcl() as $ancestor) { if (!in_array($ancestor->id, $this->_roles)) { - $this->acl->addRole($ancestor, $ancestor->parentId); + $this->acl->addRole((string) $ancestor, $ancestor->parentId); } } } @@ -618,7 +618,7 @@ protected function buildUserRoleList($user) } // Add user role - $this->acl->addRole($user->getUserID(), $parents); + $this->acl->addRole((string) $user->getUserID(), $parents); $this->_roles[] = $user->getUserID(); } else { // Add anonymous role @@ -642,7 +642,7 @@ protected function buildResourceList($resource, $options = []) if (is_object($resource)) { foreach ($resource->getAncestorsAndSelfForAcl() as $r) { if (!in_array($r->id, $this->_resources)) { - $this->acl->addResource($r->id, $r->parentId); + $this->acl->addResource((string) $r->id, $r->parentId); $this->_resources[] = $r->id; } } diff --git a/plugins/qbAclPlugin/lib/QubitActorAcl.class.php b/plugins/qbAclPlugin/lib/QubitActorAcl.class.php index 8c17e9e037..9218109472 100644 --- a/plugins/qbAclPlugin/lib/QubitActorAcl.class.php +++ b/plugins/qbAclPlugin/lib/QubitActorAcl.class.php @@ -54,7 +54,7 @@ public static function isAllowed($user, $resource, $action, $options = []) { // Do custom ACL checks for digital object actions if (in_array($action, self::$_digitalObjectActions)) { - return self::isDigitalObjectActionAllowed( + return QubitActorAcl::isDigitalObjectActionAllowed( $user, $resource, $action, @@ -77,7 +77,7 @@ public static function isAllowed($user, $resource, $action, $options = []) * * @return bool true if $user is authorized to perform $action */ - private function isDigitalObjectActionAllowed( + private static function isDigitalObjectActionAllowed( $user, $resource, $action, diff --git a/plugins/sfIsadPlugin/lib/sfIsadPlugin.class.php b/plugins/sfIsadPlugin/lib/sfIsadPlugin.class.php index b5fc616a2a..37a993a028 100644 --- a/plugins/sfIsadPlugin/lib/sfIsadPlugin.class.php +++ b/plugins/sfIsadPlugin/lib/sfIsadPlugin.class.php @@ -72,11 +72,11 @@ public function __set($name, $value) case 'languageNotes': $note = $this->resource->getMemoryNotesByType(['noteTypeId' => QubitTerm::LANGUAGE_NOTE_ID])->offsetGet(0); - $missingNote = 0 === count($note); + $missingNote = (is_countable($note) && 0 === count($note)); if (0 == strlen($value)) { // Delete note if it's available - if (!$missingNote) { + if (!$missingNote && is_countable($note)) { $note->delete(); } diff --git a/plugins/sfIsdiahPlugin/modules/sfIsdiahPlugin/templates/indexSuccess.php b/plugins/sfIsdiahPlugin/modules/sfIsdiahPlugin/templates/indexSuccess.php index ea2f8c75fe..0353958ef6 100644 --- a/plugins/sfIsdiahPlugin/modules/sfIsdiahPlugin/templates/indexSuccess.php +++ b/plugins/sfIsdiahPlugin/modules/sfIsdiahPlugin/templates/indexSuccess.php @@ -256,7 +256,7 @@
  • 'repository', 'action' => 'add'], ['class' => 'c-btn', 'title' => __('Add new')]); ?>
  • - +
  • 'informationobject', 'action' => 'add', 'repository' => $resource->id], ['class' => 'c-btn', 'title' => __('Add description')]); ?>
  • diff --git a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/addon/sfPropelData.class.php b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/addon/sfPropelData.class.php index f45a972f01..986559b818 100644 --- a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/addon/sfPropelData.class.php +++ b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/addon/sfPropelData.class.php @@ -114,7 +114,9 @@ public function loadDataFromArray($data) } // foreign key? - if (isset($column) && $column->isForeignKey() && isset($this->object_references[$value])) + $columnCheck = !empty($column) && (isset($column) ? true : false); +- $objectCheck = !empty($value) && is_string($value) && (isset($this->object_references[$value]) ? true : false); + if ($columnCheck && $column->isForeignKey() && $objectCheck) { $value = $this->object_references[$value]->getPrimaryKey(); } diff --git a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/database/model/XMLElement.php b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/database/model/XMLElement.php index 7e57128dc1..e9b827f67f 100644 --- a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/database/model/XMLElement.php +++ b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/engine/database/model/XMLElement.php @@ -19,8 +19,6 @@ * . */ -include_once 'propel/engine/database/model/VendorInfo.php'; - /** * An abstract class for elements represented by XML tags (e.g. Column, Table). * From e919d5c58dcf14ed7d13001e48901e3199d7fe2f Mon Sep 17 00:00:00 2001 From: root Date: Thu, 9 Jan 2025 19:15:49 +0000 Subject: [PATCH 10/15] Fix render_field, skos import, validation errors --- lib/helper/QubitHelper.php | 4 ++-- plugins/sfSkosPlugin/lib/sfSkosPlugin.class.php | 2 +- vendor/easyrdf/EasyRdf/ParsedUri.php | 2 +- vendor/symfony/lib/form/sfFormField.class.php | 9 ++++++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/helper/QubitHelper.php b/lib/helper/QubitHelper.php index 8d1c26e640..64bbe83864 100644 --- a/lib/helper/QubitHelper.php +++ b/lib/helper/QubitHelper.php @@ -102,7 +102,7 @@ function render_b5_field($field, $translation = null, $options = []) $widget = $field->getWidget(); if ( - in_array($field->type, ['checkbox', 'radio']) + in_array($widget->getOption('type'), ['checkbox', 'radio']) || $widget instanceof sfWidgetFormSelectRadio || ( $widget instanceof sfWidgetFormChoice @@ -113,7 +113,7 @@ function render_b5_field($field, $translation = null, $options = []) $isFormCheck = true; $inputClass = 'form-check-input'; $labelClass = 'form-check-label'; - } elseif ('color' == $field->type) { + } else if ('color' == $widget->getOption('type')) { $inputClass .= ' form-control-color'; } diff --git a/plugins/sfSkosPlugin/lib/sfSkosPlugin.class.php b/plugins/sfSkosPlugin/lib/sfSkosPlugin.class.php index c9c10325c9..5bc52ef015 100644 --- a/plugins/sfSkosPlugin/lib/sfSkosPlugin.class.php +++ b/plugins/sfSkosPlugin/lib/sfSkosPlugin.class.php @@ -74,7 +74,7 @@ public function load($resource) $this->logger->info($this->i18n->__('Type of scheme: %1%', ['%1%' => $scheme])); $this->logger->info($this->i18n->__('Taxonomy: %1%', ['%1%' => $this->taxonomy->getName(['cultureFallback' => true])])); - $this->logger->info($this->i18n->__('Term ID: %1%', ['%1%' => $this->parent - id])); + $this->logger->info($this->i18n->__('Term ID: %1%', ['%1%' => $this->parent->id])); if ('file' === $scheme) { $this->graph->parseFile($resource); diff --git a/vendor/easyrdf/EasyRdf/ParsedUri.php b/vendor/easyrdf/EasyRdf/ParsedUri.php index 0b8dd47691..0c60338303 100644 --- a/vendor/easyrdf/EasyRdf/ParsedUri.php +++ b/vendor/easyrdf/EasyRdf/ParsedUri.php @@ -242,7 +242,7 @@ public function normalise() } // Construct the new normalised path - $this->path = implode($newSegments, '/'); + $this->path = implode('/', $newSegments); // Allow easy chaining of methods return $this; diff --git a/vendor/symfony/lib/form/sfFormField.class.php b/vendor/symfony/lib/form/sfFormField.class.php index ff496c9e16..0c7b4c5bbb 100644 --- a/vendor/symfony/lib/form/sfFormField.class.php +++ b/vendor/symfony/lib/form/sfFormField.class.php @@ -316,11 +316,11 @@ public function getError() /** * Returns true is the field has an error. * - * @return Boolean true if the field has some errors, false otherwise + * @return bool true if the field has some errors, false otherwise */ public function hasError() { - return null !== $this->error && count($this->error); + return !empty($this->error); } public function __call($name, $args) @@ -329,7 +329,10 @@ public function __call($name, $args) array_unshift($args, $name); - call_user_func_array(array($clone->parent->getWidget()->__get($clone->name), 'setOption'), $args); + if ($clone->parent && $clone->parent->getWidget()->__get($clone->name)) + { + call_user_func_array(array($clone->parent->getWidget()->__get($clone->name), 'setOption'), $args); + } return $clone; } From d9846bf2f57de01ab42662a9301b65b886fbd54b Mon Sep 17 00:00:00 2001 From: melaniekung Date: Mon, 13 Jan 2025 11:04:29 -0800 Subject: [PATCH 11/15] Fix PHP 8.x deprecation warnings - Add #[\ReturnTypeWillChange] attribute for functions extending PDO in PropelPDO and PropelConfiguration - Using empty string instead of null in preg_replace call in sfAutoloadConfigHandler - Optional params are required to be at the end in function declarations in PHP 8, so updating function deprecation and call in unlinkCreatorTask - Dynamic property creation is deprecated in PHP 8, so adding declarations for properties created dynamically in sfCommandApplication and digitalObjectRegenDerivativesTask --- .../digitalObjectRegenDerivativesTask.class.php | 2 ++ lib/task/tools/unlinkCreatorTask.class.php | 4 ++-- vendor/symfony/lib/action/sfComponent.class.php | 4 ++++ vendor/symfony/lib/command/sfCommandApplication.class.php | 3 ++- vendor/symfony/lib/config/sfAutoloadConfigHandler.class.php | 2 +- .../lib/vendor/propel/util/PropelConfiguration.php | 4 ++++ .../sfPropelPlugin/lib/vendor/propel/util/PropelPDO.php | 6 ++++++ 7 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/task/digitalobject/digitalObjectRegenDerivativesTask.class.php b/lib/task/digitalobject/digitalObjectRegenDerivativesTask.class.php index 98775a2d13..ccc96644f2 100644 --- a/lib/task/digitalobject/digitalObjectRegenDerivativesTask.class.php +++ b/lib/task/digitalobject/digitalObjectRegenDerivativesTask.class.php @@ -19,6 +19,8 @@ class digitalObjectRegenDerivativesTask extends arBaseTask { + private $validTypes = []; + public static function regenerateDerivatives(&$digitalObject, $options = []) { // Determine usage ID from type flag diff --git a/lib/task/tools/unlinkCreatorTask.class.php b/lib/task/tools/unlinkCreatorTask.class.php index 6a57b8bc8b..4ef2828332 100644 --- a/lib/task/tools/unlinkCreatorTask.class.php +++ b/lib/task/tools/unlinkCreatorTask.class.php @@ -190,7 +190,7 @@ private function unlinkCreators($criteria) } if ($deleteCreators) { - self::removeCreator($io, $creatorIds); + self::removeCreator($creatorIds, $io); } } } @@ -201,7 +201,7 @@ private function unlinkCreators($criteria) * @param null|mixed $infoObj * @param mixed $creatorIds */ - private function removeCreator($infoObj = null, $creatorIds) + private function removeCreator($creatorIds, $infoObj = null) { // This will unlink this Actor from all creation events on this IO. foreach ($infoObj->getActorEvents(['eventTypeId' => QubitTerm::CREATION_ID]) as $event) { diff --git a/vendor/symfony/lib/action/sfComponent.class.php b/vendor/symfony/lib/action/sfComponent.class.php index 974577fbc2..169a99e017 100644 --- a/vendor/symfony/lib/action/sfComponent.class.php +++ b/vendor/symfony/lib/action/sfComponent.class.php @@ -307,6 +307,7 @@ public function __set($key, $value) return $this->varHolder->setByRef($key, $value); } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -332,6 +333,7 @@ public function & __get($key) return $this->varHolder->get($key); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -357,6 +359,7 @@ public function __isset($name) return isset($value); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -378,6 +381,7 @@ public function __unset($name) $this->varHolder->remove($name); } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/vendor/symfony/lib/command/sfCommandApplication.class.php b/vendor/symfony/lib/command/sfCommandApplication.class.php index c4dab620fc..9d4a2c425c 100644 --- a/vendor/symfony/lib/command/sfCommandApplication.class.php +++ b/vendor/symfony/lib/command/sfCommandApplication.class.php @@ -29,7 +29,8 @@ abstract class sfCommandApplication $currentTask = null, $dispatcher = null, $options = array(), - $formatter = null; + $formatter = null, + $commandOptions = null; /** * Constructor. diff --git a/vendor/symfony/lib/config/sfAutoloadConfigHandler.class.php b/vendor/symfony/lib/config/sfAutoloadConfigHandler.class.php index c32e47f1b1..578fb1cb00 100644 --- a/vendor/symfony/lib/config/sfAutoloadConfigHandler.class.php +++ b/vendor/symfony/lib/config/sfAutoloadConfigHandler.class.php @@ -167,7 +167,7 @@ static public function getConfiguration(array $configFiles) // move plugin files to front foreach ($configFiles as $i => $configFile) { - $path = preg_replace('/(?:\/[^\/]+){2}$/', null, $configFile); + $path = preg_replace('/(?:\/[^\/]+){2}$/', '', $configFile); if (in_array($path, $pluginPaths)) { $pluginConfigFiles[] = $configFile; diff --git a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/PropelConfiguration.php b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/PropelConfiguration.php index d802fc9243..a9c3606eaf 100644 --- a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/PropelConfiguration.php +++ b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/PropelConfiguration.php @@ -57,6 +57,7 @@ public function __construct(array $parameters = array()) /** * @see http://www.php.net/ArrayAccess */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->parameter[$offset]) || array_key_exists($offset, $this->parameters); @@ -65,6 +66,7 @@ public function offsetExists($offset) /** * @see http://www.php.net/ArrayAccess */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->parameter[$offset] = $value; @@ -73,6 +75,7 @@ public function offsetSet($offset, $value) /** * @see http://www.php.net/ArrayAccess */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->parameters[$offset]; @@ -81,6 +84,7 @@ public function offsetGet($offset) /** * @see http://www.php.net/ArrayAccess */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->parameters[$offset]); diff --git a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/PropelPDO.php b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/PropelPDO.php index b51fa10703..46a42f1786 100644 --- a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/PropelPDO.php +++ b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/PropelPDO.php @@ -120,6 +120,7 @@ public function isInTransaction() /** * Overrides PDO::beginTransaction() to prevent errors due to already-in-progress transaction. */ + #[\ReturnTypeWillChange] public function beginTransaction() { $return = true; @@ -136,6 +137,7 @@ public function beginTransaction() * Overrides PDO::commit() to only commit the transaction if we are in the outermost * transaction nesting level. */ + #[\ReturnTypeWillChange] public function commit() { $return = true; @@ -158,6 +160,7 @@ public function commit() * transaction nesting level * @return boolean Whether operation was successful. */ + #[\ReturnTypeWillChange] public function rollBack() { $return = true; @@ -203,6 +206,7 @@ public function forceRollBack() * @param int $attribute The attribute to set (e.g. PropelPDO::PROPEL_ATTR_CACHE_PREPARES). * @param mixed $value The attribute value. */ + #[\ReturnTypeWillChange] public function setAttribute($attribute, $value) { switch($attribute) { @@ -222,6 +226,7 @@ public function setAttribute($attribute, $value) * * @param int $attribute The attribute to get (e.g. PropelPDO::PROPEL_ATTR_CACHE_PREPARES). */ + #[\ReturnTypeWillChange] public function getAttribute($attribute) { switch($attribute) { @@ -241,6 +246,7 @@ public function getAttribute($attribute) * @param array * @return PDOStatement */ + #[\ReturnTypeWillChange] public function prepare($sql, $driver_options = array()) { if ($this->cachePreparedStatements) { From 3407e4f9e730ec353c58a32ac8b847d6e4b91c59 Mon Sep 17 00:00:00 2001 From: melaniekung Date: Wed, 15 Jan 2025 11:49:58 -0800 Subject: [PATCH 12/15] Fix PHP 8.x deprecation warnings from purge - Add #[\ReturnTypeWillChange] attribute for functions - Add declarations for dynamically created properties - Fix deprecation wanrings in BaseSettingI18n on a first time run of purge. --- lib/model/QubitSlug.php | 2 +- lib/model/om/BaseActor.php | 2 +- lib/model/om/BaseActorI18n.php | 4 ++++ lib/model/om/BaseContactInformation.php | 4 ++++ lib/model/om/BaseInformationObject.php | 2 +- lib/model/om/BaseInformationObjectI18n.php | 4 ++++ lib/model/om/BaseNote.php | 4 ++++ lib/model/om/BaseOtherName.php | 4 ++++ lib/model/om/BaseProperty.php | 4 ++++ lib/model/om/BaseRepositoryI18n.php | 4 ++++ lib/model/om/BaseSettingI18n.php | 4 ++++ lib/model/om/BaseStatus.php | 4 ++++ lib/search/QubitSearchEngine.class.php | 3 +++ .../lib/arElasticSearchPlugin.class.php | 5 +++++ .../sfPropelPlugin/lib/vendor/propel/util/Criteria.php | 2 +- 15 files changed, 48 insertions(+), 4 deletions(-) diff --git a/lib/model/QubitSlug.php b/lib/model/QubitSlug.php index ed4f1444d1..2d933a790d 100644 --- a/lib/model/QubitSlug.php +++ b/lib/model/QubitSlug.php @@ -78,7 +78,7 @@ public static function slugify($slug, $creationType = null) $slugCreation = (null === $creationType) ? sfConfig::get('app_permissive_slug_creation', QubitSlug::SLUG_RESTRICTIVE) : $creationType; // Remove apostrophes from slug - $slug = preg_replace('/\'/', '', $slug); + $slug = preg_replace('/\'/', '', (string) $slug); switch ($slugCreation) { case QubitSlug::SLUG_PERMISSIVE: diff --git a/lib/model/om/BaseActor.php b/lib/model/om/BaseActor.php index 63a969725e..2b84158aa7 100644 --- a/lib/model/om/BaseActor.php +++ b/lib/model/om/BaseActor.php @@ -242,7 +242,7 @@ public function __get($name) try { - if (1 > strlen($value = call_user_func_array(array($this->getCurrentactorI18n($options), '__get'), $args)) && !empty($options['cultureFallback'])) + if (1 > strlen((string) $value = call_user_func_array(array($this->getCurrentactorI18n($options), '__get'), $args)) && !empty($options['cultureFallback'])) { return call_user_func_array(array($this->getCurrentactorI18n(array('sourceCulture' => true) + $options), '__get'), $args); } diff --git a/lib/model/om/BaseActorI18n.php b/lib/model/om/BaseActorI18n.php index 1490a70b67..264fed2297 100644 --- a/lib/model/om/BaseActorI18n.php +++ b/lib/model/om/BaseActorI18n.php @@ -209,6 +209,7 @@ public function __isset($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -250,6 +251,7 @@ public function __get($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -304,6 +306,7 @@ public function __set($name, $value) return $this; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -335,6 +338,7 @@ public function __unset($name) return $this; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/lib/model/om/BaseContactInformation.php b/lib/model/om/BaseContactInformation.php index 1435914ed7..ff6423788d 100644 --- a/lib/model/om/BaseContactInformation.php +++ b/lib/model/om/BaseContactInformation.php @@ -228,6 +228,7 @@ public function __isset($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -299,6 +300,7 @@ public function __get($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -355,6 +357,7 @@ public function __set($name, $value) return $this; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -396,6 +399,7 @@ public function __unset($name) return $this; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/lib/model/om/BaseInformationObject.php b/lib/model/om/BaseInformationObject.php index 6196665d8b..ee1a95349a 100644 --- a/lib/model/om/BaseInformationObject.php +++ b/lib/model/om/BaseInformationObject.php @@ -237,7 +237,7 @@ public function __get($name) try { - if (1 > strlen($value = call_user_func_array(array($this->getCurrentinformationObjectI18n($options), '__get'), $args)) && !empty($options['cultureFallback'])) + if (1 > strlen((string) $value = call_user_func_array(array($this->getCurrentinformationObjectI18n($options), '__get'), $args)) && !empty($options['cultureFallback'])) { return call_user_func_array(array($this->getCurrentinformationObjectI18n(array('sourceCulture' => true) + $options), '__get'), $args); } diff --git a/lib/model/om/BaseInformationObjectI18n.php b/lib/model/om/BaseInformationObjectI18n.php index f979610bd1..dfa52ca05e 100644 --- a/lib/model/om/BaseInformationObjectI18n.php +++ b/lib/model/om/BaseInformationObjectI18n.php @@ -225,6 +225,7 @@ public function __isset($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -266,6 +267,7 @@ public function __get($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -320,6 +322,7 @@ public function __set($name, $value) return $this; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -351,6 +354,7 @@ public function __unset($name) return $this; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/lib/model/om/BaseNote.php b/lib/model/om/BaseNote.php index 740a8bbb31..68337e19f3 100644 --- a/lib/model/om/BaseNote.php +++ b/lib/model/om/BaseNote.php @@ -208,6 +208,7 @@ public function __isset($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -279,6 +280,7 @@ public function __get($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -335,6 +337,7 @@ public function __set($name, $value) return $this; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -376,6 +379,7 @@ public function __unset($name) return $this; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/lib/model/om/BaseOtherName.php b/lib/model/om/BaseOtherName.php index 0475c7e114..c7a399688f 100644 --- a/lib/model/om/BaseOtherName.php +++ b/lib/model/om/BaseOtherName.php @@ -208,6 +208,7 @@ public function __isset($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -279,6 +280,7 @@ public function __get($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -335,6 +337,7 @@ public function __set($name, $value) return $this; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -376,6 +379,7 @@ public function __unset($name) return $this; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/lib/model/om/BaseProperty.php b/lib/model/om/BaseProperty.php index b11f8bd9d7..c64d7d860d 100644 --- a/lib/model/om/BaseProperty.php +++ b/lib/model/om/BaseProperty.php @@ -206,6 +206,7 @@ public function __isset($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -277,6 +278,7 @@ public function __get($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -333,6 +335,7 @@ public function __set($name, $value) return $this; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -374,6 +377,7 @@ public function __unset($name) return $this; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/lib/model/om/BaseRepositoryI18n.php b/lib/model/om/BaseRepositoryI18n.php index 33534905ec..c332cda8ea 100644 --- a/lib/model/om/BaseRepositoryI18n.php +++ b/lib/model/om/BaseRepositoryI18n.php @@ -213,6 +213,7 @@ public function __isset($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -254,6 +255,7 @@ public function __get($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -308,6 +310,7 @@ public function __set($name, $value) return $this; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -339,6 +342,7 @@ public function __unset($name) return $this; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/lib/model/om/BaseSettingI18n.php b/lib/model/om/BaseSettingI18n.php index 5abc44701d..f5ad7238b8 100644 --- a/lib/model/om/BaseSettingI18n.php +++ b/lib/model/om/BaseSettingI18n.php @@ -185,6 +185,7 @@ public function __isset($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -226,6 +227,7 @@ public function __get($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -280,6 +282,7 @@ public function __set($name, $value) return $this; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -311,6 +314,7 @@ public function __unset($name) return $this; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/lib/model/om/BaseStatus.php b/lib/model/om/BaseStatus.php index 402aa14e85..179a7d4b7f 100644 --- a/lib/model/om/BaseStatus.php +++ b/lib/model/om/BaseStatus.php @@ -186,6 +186,7 @@ public function __isset($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetExists($offset) { $args = func_get_args(); @@ -227,6 +228,7 @@ public function __get($name) throw new sfException("Unknown record property \"$name\" on \"".get_class($this).'"'); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { $args = func_get_args(); @@ -281,6 +283,7 @@ public function __set($name, $value) return $this; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $args = func_get_args(); @@ -312,6 +315,7 @@ public function __unset($name) return $this; } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $args = func_get_args(); diff --git a/lib/search/QubitSearchEngine.class.php b/lib/search/QubitSearchEngine.class.php index d6ab172996..446c499d7a 100644 --- a/lib/search/QubitSearchEngine.class.php +++ b/lib/search/QubitSearchEngine.class.php @@ -22,6 +22,9 @@ */ abstract class QubitSearchEngine { + private $dispatcher; + private $event; + /** * Constructor. */ diff --git a/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php b/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php index 0170ba146e..642c77c3a6 100644 --- a/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php +++ b/plugins/arElasticSearchPlugin/lib/arElasticSearchPlugin.class.php @@ -90,6 +90,11 @@ class arElasticSearchPlugin extends QubitSearchEngine */ private $batchDeleteDocs = []; + private $batchSize; + private $batchMode; + private $cache; + private $config; + /** * Constructor. */ diff --git a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/Criteria.php b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/Criteria.php index 42f11be63e..984f2d12ea 100644 --- a/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/Criteria.php +++ b/vendor/symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel/util/Criteria.php @@ -1349,7 +1349,7 @@ public function init(Criteria $criteria) //init $this->realtable $realtable = $criteria->getTableForAlias($this->table); - if (! strlen ( $realtable ) ) { + if (! strlen ( (string) $realtable ) ) { $realtable = $this->table; } $this->realtable = $realtable; From f10917dce255799234891fe250af9e3346fe5f8e Mon Sep 17 00:00:00 2001 From: Anvit Srivastav Date: Wed, 15 Jan 2025 11:59:08 -0800 Subject: [PATCH 13/15] Fix deprecation warnings for call_user_func_array Fix deprecation warnings for call_user_func_array calls that use $this in the callable which isn't required and has been deprecated in PHP 8.2 --- lib/model/QubitActor.php | 4 ++-- lib/model/QubitInformationObject.php | 6 +++--- lib/model/QubitObject.php | 6 +++--- lib/model/QubitRepository.php | 4 ++-- lib/model/om/BaseActor.php | 8 ++++---- lib/model/om/BaseInformationObject.php | 8 ++++---- lib/model/om/BaseRepository.php | 8 ++++---- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/model/QubitActor.php b/lib/model/QubitActor.php index 632d977e41..cf4141d0bd 100644 --- a/lib/model/QubitActor.php +++ b/lib/model/QubitActor.php @@ -70,7 +70,7 @@ public function __get($name) return []; } - return call_user_func_array([$this, 'BaseActor::__get'], $args); + return call_user_func_array('BaseActor::__get', $args); } public function __set($name, $value) @@ -104,7 +104,7 @@ public function __set($name, $value) return $this; } - return call_user_func_array([$this, 'BaseActor::__set'], $args); + return call_user_func_array('BaseActor::__set', $args); } public function save($connection = null) diff --git a/lib/model/QubitInformationObject.php b/lib/model/QubitInformationObject.php index 72d980dbf3..0c3acb752e 100644 --- a/lib/model/QubitInformationObject.php +++ b/lib/model/QubitInformationObject.php @@ -123,7 +123,7 @@ public function __get($name) case 'sourceStandard': foreach ($this->ancestors->andSelf()->orderBy('rgt') as $item) { if (isset($item->sourceStandard)) { - return call_user_func_array([$item, 'QubitObject::__get'], $args); + return call_user_func_array('QubitObject::__get', $args); } // Stop iteration before the root object is reached @@ -135,7 +135,7 @@ public function __get($name) break; default: - return call_user_func_array([$this, 'BaseInformationObject::__get'], $args); + return call_user_func_array('BaseInformationObject::__get', $args); } } @@ -172,7 +172,7 @@ public function __set($name, $value) return $this; default: - return call_user_func_array([$this, 'BaseInformationObject::__set'], $args); + return call_user_func_array('BaseInformationObject::__set', $args); } } diff --git a/lib/model/QubitObject.php b/lib/model/QubitObject.php index c7dad3e80e..68eff619cf 100644 --- a/lib/model/QubitObject.php +++ b/lib/model/QubitObject.php @@ -43,7 +43,7 @@ public function __isset($name) return isset($this->values['slug']); default: - return call_user_func_array([$this, 'BaseObject::__isset'], $args); + return call_user_func_array('BaseObject::__isset', $args); } } @@ -69,7 +69,7 @@ public function __get($name) return $this->values['slug']; default: - return call_user_func_array([$this, 'BaseObject::__get'], $args); + return call_user_func_array('BaseObject::__get', $args); } } @@ -84,7 +84,7 @@ public function __set($name, $value) return $this; default: - return call_user_func_array([$this, 'BaseObject::__set'], $args); + return call_user_func_array('BaseObject::__set', $args); } } diff --git a/lib/model/QubitRepository.php b/lib/model/QubitRepository.php index b0fd5cdb3c..ea06fac1c2 100644 --- a/lib/model/QubitRepository.php +++ b/lib/model/QubitRepository.php @@ -53,7 +53,7 @@ public function __get($name) break; default: - return call_user_func_array([$this, 'BaseRepository::__get'], $args); + return call_user_func_array('BaseRepository::__get', $args); } } @@ -88,7 +88,7 @@ public function __set($name, $value) return $this; default: - return call_user_func_array([$this, 'BaseRepository::__set'], $args); + return call_user_func_array('BaseRepository::__set', $args); } } diff --git a/lib/model/om/BaseActor.php b/lib/model/om/BaseActor.php index 2b84158aa7..a7389eca71 100644 --- a/lib/model/om/BaseActor.php +++ b/lib/model/om/BaseActor.php @@ -90,7 +90,7 @@ public function __isset($name) try { - return call_user_func_array(array($this, 'QubitObject::__isset'), $args); + return call_user_func_array('QubitObject::__isset', $args); } catch (sfException $e) { @@ -149,7 +149,7 @@ public function __get($name) try { - return call_user_func_array(array($this, 'QubitObject::__get'), $args); + return call_user_func_array('QubitObject::__get', $args); } catch (sfException $e) { @@ -266,7 +266,7 @@ public function __set($name, $value) $options = $args[2]; } - call_user_func_array(array($this, 'QubitObject::__set'), $args); + call_user_func_array('QubitObject::__set', $args); call_user_func_array(array($this->getCurrentactorI18n($options), '__set'), $args); @@ -283,7 +283,7 @@ public function __unset($name) $options = $args[1]; } - call_user_func_array(array($this, 'QubitObject::__unset'), $args); + call_user_func_array('QubitObject::__unset', $args); call_user_func_array(array($this->getCurrentactorI18n($options), '__unset'), $args); diff --git a/lib/model/om/BaseInformationObject.php b/lib/model/om/BaseInformationObject.php index ee1a95349a..1920c5352e 100644 --- a/lib/model/om/BaseInformationObject.php +++ b/lib/model/om/BaseInformationObject.php @@ -119,7 +119,7 @@ public function __isset($name) try { - return call_user_func_array(array($this, 'QubitObject::__isset'), $args); + return call_user_func_array('QubitObject::__isset', $args); } catch (sfException $e) { @@ -178,7 +178,7 @@ public function __get($name) try { - return call_user_func_array(array($this, 'QubitObject::__get'), $args); + return call_user_func_array('QubitObject::__get', $args); } catch (sfException $e) { @@ -301,7 +301,7 @@ public function __set($name, $value) $options = $args[2]; } - call_user_func_array(array($this, 'QubitObject::__set'), $args); + call_user_func_array('QubitObject::__set', $args); call_user_func_array(array($this->getCurrentinformationObjectI18n($options), '__set'), $args); @@ -318,7 +318,7 @@ public function __unset($name) $options = $args[1]; } - call_user_func_array(array($this, 'QubitObject::__unset'), $args); + call_user_func_array('QubitObject::__unset', $args); call_user_func_array(array($this->getCurrentinformationObjectI18n($options), '__unset'), $args); diff --git a/lib/model/om/BaseRepository.php b/lib/model/om/BaseRepository.php index 594418dba8..99866d1e7a 100644 --- a/lib/model/om/BaseRepository.php +++ b/lib/model/om/BaseRepository.php @@ -86,7 +86,7 @@ public function __isset($name) try { - return call_user_func_array(array($this, 'QubitActor::__isset'), $args); + return call_user_func_array('QubitActor::__isset', $args); } catch (sfException $e) { @@ -130,7 +130,7 @@ public function __get($name) try { - return call_user_func_array(array($this, 'QubitActor::__get'), $args); + return call_user_func_array('QubitActor::__get', $args); } catch (sfException $e) { @@ -196,7 +196,7 @@ public function __set($name, $value) $options = $args[2]; } - call_user_func_array(array($this, 'QubitActor::__set'), $args); + call_user_func_array('QubitActor::__set', $args); call_user_func_array(array($this->getCurrentrepositoryI18n($options), '__set'), $args); @@ -213,7 +213,7 @@ public function __unset($name) $options = $args[1]; } - call_user_func_array(array($this, 'QubitActor::__unset'), $args); + call_user_func_array('QubitActor::__unset', $args); call_user_func_array(array($this->getCurrentrepositoryI18n($options), '__unset'), $args); From 9e7238e7b6c1ab86734af2fc55e5193a42bacfe7 Mon Sep 17 00:00:00 2001 From: melaniekung Date: Tue, 21 Jan 2025 13:00:00 -0800 Subject: [PATCH 14/15] Fix Descriptions dropdown list --- lib/helper/QubitHelper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/helper/QubitHelper.php b/lib/helper/QubitHelper.php index 64bbe83864..9861abe5aa 100644 --- a/lib/helper/QubitHelper.php +++ b/lib/helper/QubitHelper.php @@ -113,7 +113,7 @@ function render_b5_field($field, $translation = null, $options = []) $isFormCheck = true; $inputClass = 'form-check-input'; $labelClass = 'form-check-label'; - } else if ('color' == $widget->getOption('type')) { + } elseif ('color' == $widget->getOption('type')) { $inputClass .= ' form-control-color'; } @@ -773,7 +773,7 @@ function render_autocomplete_string($hit) } if (0 < count($levelOfDescriptionAndIdentifier)) { - $string[] = implode($levelOfDescriptionAndIdentifier, ' '); + $string[] = implode(' ', $levelOfDescriptionAndIdentifier); } $titleAndPublicationStatus = []; @@ -787,7 +787,7 @@ function render_autocomplete_string($hit) } if (0 < count($titleAndPublicationStatus)) { - $string[] = implode($titleAndPublicationStatus, ' '); + $string[] = implode(' ', $titleAndPublicationStatus); } return implode(' - ', $string); From a68ed52a21f9a90deed06ef43b466e94822a3dad Mon Sep 17 00:00:00 2001 From: melaniekung Date: Wed, 22 Jan 2025 12:48:20 -0800 Subject: [PATCH 15/15] Fix edit DO styling --- .../modules/digitalobject/templates/editSuccess.php | 6 +++--- plugins/qbAclPlugin/lib/QubitAcl.class.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/arDominionB5Plugin/modules/digitalobject/templates/editSuccess.php b/plugins/arDominionB5Plugin/modules/digitalobject/templates/editSuccess.php index 7c8b07f828..035dabe63f 100644 --- a/plugins/arDominionB5Plugin/modules/digitalobject/templates/editSuccess.php +++ b/plugins/arDominionB5Plugin/modules/digitalobject/templates/editSuccess.php @@ -106,11 +106,11 @@ mediaTypeId || QubitTerm::AUDIO_ID == $resource->mediaTypeId) { ?> - + $videoTrack) { ?> mediaTypeId && QubitTerm::SUBTITLES_ID == $usageId) { ?> - + $resource, 'subtitles' => $videoTrack, 'form' => $form, 'usageId' => $usageId]); ?> @@ -132,7 +132,7 @@ - + diff --git a/plugins/qbAclPlugin/lib/QubitAcl.class.php b/plugins/qbAclPlugin/lib/QubitAcl.class.php index 702d492014..5b3f6f3d2e 100644 --- a/plugins/qbAclPlugin/lib/QubitAcl.class.php +++ b/plugins/qbAclPlugin/lib/QubitAcl.class.php @@ -129,7 +129,7 @@ public static function check($resource, $actions, $options = []) } // OR condition, first "true" result returns - if ($hasAccess = self::checkAccessByClass($resource, $user, $action, $options)) { + if (null !== $resource && $hasAccess = self::checkAccessByClass($resource, $user, $action, $options)) { return $hasAccess; } }