Releases: salient-labs/toolkit
Releases · salient-labs/toolkit
v0.99.80
- Review referenced RFCs for compliance, clarity and currency
- Rename
Regex::UUIDtoUUID_V4 - Add
Regex::UUIDto match all UUIDs and adopt inAbstractSyncProvider::isValidIdentifier()
- Rename
- Normalise exception variable names as
$ex
Added
Cli
- Add
CliUtilwithgetJson()and consolidate similar methods
Collection
- Add dictionary interface, class and trait
Http
- Add
getHeaderLines()alongside existinggetHeaderLine()methods - Add
HeadersInterfacemethodshasBadWhitespace()andhasObsoleteLineFolding() - Add
MultipartStreamInterface::getParts()for completeness
Changed
Collection
- Allow
Arrayable::toArray()return type variations by adding an optionalTArrayValuetemplate toDictionaryInterfaceandCollectionInterface - Move
toArray()fromReadOnlyCollectionTraittoRecursiveArrayableCollectionTrait - Add non-recursive implementation of
toArray()toArrayableCollectionTrait
Curler
- Pass the number of entities returned from the endpoint via previous pages to
CurlerPagerInterface::getPage() - Rename
METHOD_HAS_BODYtoREQUEST_METHOD_HAS_BODY(to prevent conflict with otherMETHOD_*constants) - Rename methods for consistency with
Httpchanges:getPublicHttpHeaders()->getPublicHeaders()hasAccessToken()->hasCredential()withAccessToken()->withCredential()
Http
Move and rename various interfaces, classes, traits and members
- Rename:
AccessTokenInterface->CredentialInterfacegetTokenType()->getAuthenticationScheme()getToken()->getCredential()
HttpHeadersInterface->HeadersInterfacehasLastLine()->hasEmptyLine()append()->addValue()canonicalize()->normalise()
HasHttpHeaders(interface) ->HasInnerHeadersgetHttpHeaders()->getInnerHeaders()
HttpHeaders->HeadersHasHttpHeaders(trait) ->HasInnerHeadersTraitHttpServer->Serverand move to separate namespaceStream::copyToString()->getStreamContents()and move toHttpUtilStream::copyToStream()->copyStream()and move toHttpUtilUriInterface::toParts()->getComponents()UriInterface::isReference()->isRelativeReference()Uri::EXPAND_EMPTY_PATH->NORMALISE_EMPTY_PATHUri::COLLAPSE_MULTIPLE_SLASHES->NORMALISE_MULTIPLE_SLASHESHttpUtil::escapeQuotedString()->quoteString()HttpUtil::getNameValueGenerator()->getNameValuePairs()HttpServerException->ServerExceptionStreamDetachedException->StreamClosedExceptionStreamInvalidRequestException->InvalidStreamRequestExceptionUploadedFileException->UploadFailedException
- Move:
Headers::getContentLength()toHttpUtilHeaders::getMultipartBoundary()toHttpUtilHeaders::getPreferences()toHttpUtilHeaders::mergePreferences()toHttpUtilHeaders::getRetryAfter()toHttpUtilUri::isAuthorityForm()toHttpUtil
- Move message-related interfaces to their own namespace and rename:
HttpMessageInterface->MessageInterfaceHttpMultipartStreamInterface->MultipartStreamInterfaceHttpRequestInterface->RequestInterfaceHttpResponseInterface->ResponseInterfaceHttpServerRequestInterface->ServerRequestInterfaceHttpStreamInterface->StreamInterfaceHttpMultipartStreamPartInterface->StreamPartInterfacegetFallbackFilename()->getAsciiFilename()getContent()->getBody()
- Move message-related classes to their own namespace and rename:
AbstractHttpMessage->AbstractMessageAbstractHttpRequest->AbstractRequestHttpFactory->MessageFactoryHttpMultipartStream->MultipartStreamHttpRequest->RequestHttpResponse->ResponseHttpServerRequest->ServerRequestHttpServerRequestUpload->ServerRequestUploadHttpStream->StreamHttpMultipartStreamPart->StreamPart
- Rename
FormDataFlagtoHasFormDataFlag, addDATA_prefix to the names of its constants and access them via implementations - Rename
MimeTypetoHasMediaType, addTYPE_prefix to the names of its constants and access them via implementations - Rename
HttpRequestMethodtoHasRequestMethod, addMETHOD_prefix to the names of its constants and access them via implementations - Rename
HttpHeadertoHasHttpHeader, addHEADER_prefix to the names of its constants and access them via implementations - Rename
HttpHeaderGrouptoHasHttpHeaders, addHEADERS_prefix to the names of its constants and access them via implementations
- In
HeadersInterface, extendDictionaryInterface(new) instead ofCollectionInterface - In
Headers::addLine():- Throw an exception on invalid header field syntax or line folding even if
$strictisfalse - Throw
LogicExceptionif called after headers are applied via another method - Throw
InvalidHeaderExceptioninstead ofInvalidArgumentException
- Throw an exception on invalid header field syntax or line folding even if
- In
Headers::map(), return the same instance if mapped values are equivalent - In
HttpUtil::quoteString(), add double quotes - In
UriInterface, remove nullability fromparse()parameter$component - In
Uri::parse(), replicateparse_url()behaviour when URI and component are both invalid (i.e. returnfalse) - In
AbstractMessage/AbstractRequest:- Don't apply an implicit media type to messages with multipart bodies
- Normalise headers when casting messages to strings
- In
MultipartStream, do not remain operational afterclose()ordetach()are called - Refactor
Serverfor compliance and consistency- Rename:
getProxyTls()->proxyHasTls()getProxyBasePath()->getProxyPath()getBaseUri()->getUri()and returnUri, notstring
- Add:
getLocalIpAddress()getLocalPort()to improve support for dynamic port allocation
- Allow
stop()to be called when the server is not running - In
listen():- Replace
$callbackwith$listener, which returns aServerResponseinstead of receiving control variables by reference - Keep listening for requests until a response has a return value unless a non-negative
$limitis given - Add request target validity checks
- Respond to invalid requests with "400 Bad Request" or "501 Not Implemented" and don't throw the underlying exception by default
- Replace
- Throw
LogicExceptionwhen:getProxy*()is called on an instance with no proxy, or- an assertion fails (instead of
ServerException)
- Rename:
- Adopt terminology and behaviour of [RFC9112], [RFC9110] and [RFC8187], which supercede [RFC7230], [RFC7231] and [RFC5987]
- Replace "header line" with "field line" where appropriate
- In
Headers::addLine(), don't throwInvalidHeaderExceptionwhen bad whitespace is received and$strict = true - Use
getLastHeaderValue()when retrievingContent-Typeheaders - Use
getOnlyHeaderValue()when retrievingLocationheaders
Removed
Http
- Remove superfluous
MessageInterface::getHttpPayload() - Remove
$strictparameter fromHeadersInterface::addLine()(implementation detail) - Remove unused
Urimethods:fromParts()unparse()resolveReference()removeDotSegments()
- Remove superfluous
Server::getScheme() - Remove unused
HttpRequestHandlerInterface
Fixed
Http
- Fix issue where message objects cast to strings may have too many empty lines between headers and body
- Fix
AbstractRequestissue where request target typeorigin-formmay be incorrectly detected when the given URI has an empty path - Fix
Headers::addLine()issue where invalid line folding in the first trailer may not be detected - Fix
Headers::getHeaderLine()issue where headers with unquoted commas may be inadvertently modified - Fix
HttpUtil::getRetryAfter()issue where negative delay seconds are parsed as a timestamp - Fix
Serverissue where large responses might not be written in full
v0.99.79
v0.99.78
Added
Console
- Add and implement
ConsoleInterfacemethods:getTtyTarget()removeEscapes()removeTags()
- Add and implement
StreamTargetInterfacemethodgetUri() - In
ConsoleInterface:- Add optional
$debugparameters toregisterStderrTarget()andregisterStdioTargets() - Add optional
$escapeNewlinesparameter toescape() - Add optional
$countparameter toexception()
- Add optional
Container
- Allow closures to be bound to the container
- Add
$containerparameter toHasBindingsmethods and allow them to return closures - Add
$containerparameter togetContextualBindings()and allow it to return parameter and unmapped services, closures and instances - Add and implement
ApplicationInterfacemethods:getVersion()getVersionString()reportVersion()
PHPStan
- Add
ContainerRuleto report when calls toContainerInterface::getAs()have an$idthat isn't a subtype of$service
Changed
Console
- Change default
Console::info()prefix from➤to>to address inconsistent output width on some platforms - In
ConsoleLogger, pass debug messages toConsole::debug()so the caller is output - In
StreamTarget::reopen(), don't throw an exception if the stream can't be reopened - Don't close targets when they are deregistered
- Rename
ConsoleInterfacemethods:getLogger()->logger()setTargetPrefix()->setPrefix()printOut()->printStdio()getErrorCount()->errors()getWarningCount()->warnings()
- Remove
$typeparameters fromprint()methods inConsoleInterface - Rename
StreamTargetmethodfromPath()to more accuratefromFile() - Rename:
ConsoleFormatInterface->FormatInterfaceConsoleFormatterInterface->FormatterInterfaceConsoleMessageAttributesInterface->MessageAttributesInterfaceConsoleMessageFormatInterface->MessageFormatInterfaceConsoleTagAttributesInterface->TagAttributesInterfaceConsoleTargetInterface->TargetInterfaceConsoleTargetPrefixInterface->HasPrefixConsoleTargetStreamInterface->StreamTargetInterfaceConsoleFormat->TtyFormatConsoleFormatter->FormatterConsoleLoopbackFormat->LoopbackFormatConsoleManPageFormat->ManPageFormatConsoleMarkdownFormat->MarkdownFormatConsoleMessageAttributes->MessageAttributesConsoleMessageFormat->MessageFormatConsoleMessageFormats->MessageFormatsConsolePrefixTarget->AbstractTargetWithPrefixConsoleStreamTarget->AbstractStreamTargetConsoleTag->HasTagand addTAG_prefix to the names of its constantsConsoleTagAttributes->TagAttributesConsoleTagFormats->TagFormatsConsoleTarget->AbstractTargetConsoleTargetTypeFlag->HasTargetFlagand addTARGET_prefix to the names of its constants
- Rename methods:
withUnescape()->withRemoveEscapes()getUnescape()->removesEscapes()withWrapAfterApply()->withWrapAfterFormatting()getWrapAfterApply()->wrapsAfterFormatting()
- Replace "dim" with "faint" in method names and documentation
Container
- Remove
$argsparameters frombind(),bindIf(),singleton()andsingletonIf() - Rename
getName()->getClass() - In
getAs(), throw an exception if$iddoesn't extend or implement$service - In
providers(), map unmapped providers to themselves - Rename event and exception interfaces for consistency
- Rename
ArgumentsNotUsedException->UnusedArgumentsException - Rename
ServiceLifetime->HasServiceLifetimeand addLIFETIME_prefix to the names of its constants - Rename
ApplicationInterfacemethods:getAppName()->getName()isProduction()->isRunningInProduction()registerSyncNamespace()->sync()and start the entity store implicitly when calledgetWorkingDirectory()->getInitialWorkingDirectory()setWorkingDirectory()->setInitialWorkingDirectory()and remove nullability from parameter
- In
Application:- Always load
.envfiles (previously, they were only loaded when running from source) - Write console messages to
STDERRwhen running on the command line (previously, warnings and errors were written toSTDERRand everything else was written toSTDOUTby default) - Retrieve application name from configuration value
"app.name"before falling back to script basename - Only stop cache and sync store instances started by the container
- Always load
Removed
Cli
- Remove redundant
CliApplicationInterfacemethodsreportVersion()andgetVersionString()
Console
- Remove
ConsoleInterfacemethods:getFormatter()(retrieve viagetTtyTarget())getWidth()(retrieve viagetTtyTarget())printStderr()(unused)
- Remove
FormatterInterface::withSpinnerState() - Remove
StreamTargetInterface::getEol() - Remove
StreamTarget::fromStream()in favour of a public constructor - Remove unused
StreamTargetmethodgetPath()
Container
- Remove unused
unbind()method - Remove implementation-specific
resumeCache()method fromApplicationInterface - Remove implementation-specific arguments from
startSync()method inApplicationInterface
Fixed
Console
- Fix issue where
$msg2is not indented when prefix width is 2 - Fix issue where trailing carriage returns may not be preserved in
LoopbackFormat,ManPageFormatandMarkdownFormat
Container
- Fix issue where calling
bind()with$class = nulldoes not replace an existing binding to a different class - Fix issue where parameter bindings only work for untyped and scalar constructor parameters
- Fix issue where objects cannot be bound to constructor parameters via contextual bindings
- Fix
addContextualBinding()issue where$classcannot benull - Fix
inContextOf()issue where contextual callbacks are not used - Fix issue where
Application::logOutput()can be called repeatedly
Core
- Fix issue where methods that return
$thisfrom behind a facade return a facade-bound instance
Security
Console
- Fix issue where
StreamTarget::reopen()may not apply file permissions correctly in some log rotation scenarios
v0.99.77
Added
Utility
- Add
Reflect::getAllTraits(), with optional recursion into parents - Add
Reflect::isMethodInClass()
Changed
PHPStan
- Ignore static properties and properties
ImmutableTraitmethods cannot access inImmutableTraitReadWritePropertiesExtension - Improve array argument unpacking in
ArrExtendReturnTypeExtension,GetCoalesceReturnTypeExtensionandStrCoalesceReturnTypeExtension
Utility
- Optionally recurse into traits in
Reflect::getTraitMethod()
Fixed
PHPStan
- In
ImmutableTraitRule:- Fix issue where inaccessible properties may not be reported
- Fix issue where calls to
ImmutableTraitmethods are not detected when they override inherited methods or whenImmutableTraitis inserted by another trait
- Fix
ArrWhereNotNullReturnTypeExtensionandArrWhereNotEmptyReturnTypeExtensionissues where:iterabletypes may be returned- invalid key types may be returned
- variadic arguments are not unpacked
- Fix
GetCoalesceRuleissue where calls toGet::coalesce()are matched case-sensitively
Testing
- Fix issue where
MockTarget::write()may fail to write long messages to the (optional) underlying stream
v0.99.76
Added
Http
- Add and implement exception interfaces:
HttpExceptionInvalidHeaderExceptionStreamExceptionStreamEncapsulationException
Sli
- Add
--constructoroption to "generate builder" command
Changed
- Rename methods across all
HttpandCurlerclasses:getFirstHeaderLine()->getFirstHeaderValue()getLastHeaderLine()->getLastHeaderValue()getOneHeaderLine()->getOnlyHeaderValue()
Collection
- Extend
Traversableinstead ofIteratorAggregatefromCollectionInterfaceso inheritors can implementIterator - Allow
CollectionInterface::map()to return a collection of items of a different type - Return
static<TKey|int,TValue>fromCollectionInterfacemethods that add items without explicit keys
Core
- Add
$preserveKeysparameter toArrayable::toArray()
Curler
- In
Curler(andCurlerInterface, if applicable):- Simplify
__construct()and include it in the API - Don't replace user agent headers by default
- Add
hasUserAgent()method - In
getPublicHttpHeaders(), always treat access token headers as sensitive - Only call
Console::debug()if the global console service is loaded - Rename methods:
getCacheStore()->getCache()withCacheStore()->withCache()
- Simplify
- Rename event-related abstractions for consistency with exceptions:
CurlEventInterface->CurlEventCurlRequestEventInterface->CurlRequestEventCurlResponseEventInterface->CurlResponseEventCurlerEventInterface->CurlerEventResponseCacheHitEventInterface->ResponseCacheHitEventAbstractCurlerEvent->CurlerEventAbstractCurlEvent->CurlEvent
Iterator
- Rename
FluentIteratorInterface::nextWithValue()togetFirstWith() - In
FluentIteratorTrait::getFirstWith():- Check properties exist before accessing them
- Do not move to the next element after finding a match
- Rename
RecursiveFilesystemIteratortoFileIteratorand refactor- Return files and directories by default (previous behaviour was to return files, not directories)
- Remove optional parameters and adopt one callback signature
- Rename methods:
noDirs()->files()(the previousfiles()method has been removed)noFiles()->directories()matchRelative()->relative()doNotMatchRelative()->notRelative()
Utility
- In
Get::array()andGet::list(), preferiterator_to_array()when value is bothTraversableandArrayable - In
Get::list()andGet::count(), use$preserveKeys = falsewithArrayablevalues instead ofarray_values()
Removed
Iterator
- Remove
FileIteratormethodsdirs()andfiles() - Remove redundant
FluentIteratorInterface::forEach()method - Remove unused
MutableIteratorinterface - Remove unused
MutableGraphIteratorclass - Remove unused
RecursiveMutableGraphIteratorclass - Remove unnecessary
RecursiveGraphIteratorTrait
v0.99.75
Achieved with the changes detailed below:
- Completion of
CoreAPI review - Cleaner access to constants via classes that implement their interfaces
- Progress towards decoupling the
Corecomponent fromContainer - Progress towards rewritten "sli generate" commands
Added
Core
- Add
Serializableinterface - Add, implement and adopt
InvalidDataException - Add, implement and adopt
EventDispatcherInterfaceandEventListenerProviderInterface - Add
Builder::getStaticConstructor()to allow use of a static method for instantiation instead of the constructor - Add
MetricCollector::getMaxTimers()to provide maximum number of timers running simultaneously per group
Utility
- Add
File::eof()andFile::select() - Add
File::getIndentation() - Add
Inflect::list(), with optional Oxford comma support - Add
Reflect::getDeclaring(),Reflect::getFileName()andgetNamespaceName()
Changed
- Rename exception interfaces to reduce verbosity
- Move
IndentationtoSalient\Utility\Support - Move
MimeTypetoSalient\Contract\Http - Move
SqlQuerytoSalient\Db
Cache
- Treat
DateIntervalTTLs like integers, i.e. delete the item if TTL is <= 0 seconds
Console
- Rename:
ConsoleWriterInterface->ConsoleInterfaceConsoleWriter->ConsoleConsoleMessageType->HasMessageTypeConsoleMessageTypeGroup->HasMessageTypes
- Implement
HasMessageLevel,HasMessageLevels,HasMessageTypeandHasMessageTypesfrom theConsolefacade
Core
- Rename:
AbstractBuilder->BuilderAbstractFacade->Facadeand move toSalient\Core\FacadeAbstractStore->StoreAbstractStreamWrapper->StreamWrapperAbstractException->Exceptionand move toSalient\Core\ExceptionAbstractMultipleErrorException->MultipleErrorExceptionand move toSalient\Core\ExceptionHasBuilder->BuildableTraitHasChainableMethods->ChainableTraitHasFacade->FacadeAwareInstanceTraitHasMutator->ImmutableTraitHasNormaliser->NormalisableTraitHasReadableProperties->ReadableTraitHasWritableProperties->WritableTraitJsonSchemaInterface->HasJsonSchemaProcessmethods:getText()->getOutputAsText()getNewText()->getNewOutputAsText()
ProvidableEntityInterface->ProviderEntityInterfaceand move toSalient\Core\EntityReadsProtectedProperties->ReadableProtectedPropertiesTraitSerializeRulesInterfacemethods:getIncludeMeta()->getDynamicProperties()withIncludeMeta()->withDynamicProperties()
UnloadsFacades->FacadeAwareTrait
- Rename, move to
Salient\Contractand update constants:EscapeSequence->HasEscapeSequenceFileDescriptor->HasFileDescriptorListConformity->HasConformityMessageLevel->HasMessageLevelMessageLevelGroup->HasMessageLevelsTextComparisonAlgorithm->HasTextComparisonFlagTextComparisonFlag->HasTextComparisonFlag
- Move:
StoppableEventInterface->Salient\Contract\Core\EventEventDispatcher->Salient\Core\EventStoppableEventTrait->Salient\Core\EventFacadeInterface->Salient\Contract\Core\FacadeFacadeAwareInterface->Salient\Contract\Core\FacadeArrayMapperInterface->Salient\Contract\Core\PipelineDateFormatter->Salient\Core\DateDateFormatParser->Salient\Core\DateDateParser->Salient\Core\DateDotNetDateParser->Salient\Core\DateProvidable->Salient\Core\EntitySerializeRulesInterface->Salient\Core\EntityExceptionTrait->Salient\Core\ExceptionMultipleErrorExceptionTrait->Salient\Core\ExceptionAbstractEntity->Salient\Core\ProviderAbstractProvider->Salient\Core\ProviderProviderContext->Salient\Core\Provider
- Don't accept a container when creating a builder (builders are tightly coupled with constructors, so no container is needed)
- In
Facade, only useContainerif it is defined - Detect date properties and parameters via native type hints even if
Temporalis not implemented - Refactor
Facade::getService()for simplicity - Narrow
Hierarchicalreturn types to$thisas needed - Refactor
Normalisable::normaliseProperty()for clarity - Make
$contexta required parameter ofProvidablemethodsprovide()andprovideMultiple()and remove$provideraccordingly - Refactor
Providable::provideMultiple()for consistency withConstructible - Improve uninitialised property handling in
TreeableTrait - Replace
ConfigurationManager::getMany()withgetMultiple() - Extend
DateParserInterfacefromDateFormatterInterface - In
DateParserInterface::parse(), specify that$timezoneis ignored if$valuehas a timezone and update implementations accordingly - Deregister
ErrorHandlerwhen the facade it's running behind is unloaded - In
MultipleErrorException:- Rename
getMessageWithoutErrors()togetMessageOnly() - Add
$consoleparameter toreportErrors()
- Rename
- In
Process:- Improve robustness of stream handling
- Always throw
ProcessTerminatedBySignalExceptionwhen a process is killed, not just whenwait()is called - Add and throw
ProcessDidNotTerminateException - Do not throw
ProcessExceptionfor stream-related errors
- Add
ClassReflectionand adopt instead ofIntrospectorandIntrospectionClasswhere possible- Fix issue where reserved properties are ignored when getting "magic" properties
- Fix issue where properties with asymmetric handling are not serialized, e.g. when a protected property is read via
__get()and written via_setMyProperty() - Do not allow multiple properties or "magic" property methods to resolve to the same name after normalisation
- Do not allow dynamic property properties to be serviced by "magic" property methods
- Do not allow
Treeableclasses to return invalid parent/children properties
PHPDoc
- Collect and propagate context data to allow expansion of relative class types like
static,$thisandself
PHPStan
- Preserve key types when
$preserveKeys = trueis passed toArr::flatten() - Handle optional keys in arrays passed to
Arr::flatten()
Sli
- Refactor "generate facade" command
- Add new options:
--implement <interface>--skip-deprecated(previous behaviour was to skip deprecated methods unconditionally)
- Exclude
@internalmethods from facades
- Add new options:
- Build out PHPDoc tag handling and other abstractions in
AbstractGenerateCommand
Sync
- Extend
ClassReflectionfromReflectionclasses - Rename
Reflectionclasses for consistency - Refactor
SyncSerializeRulesInterfacefor consistency withSerializeRulesInterface - Rename
SyncSerializeRulesInterfacemethods:getIncludeCanonicalId()->getCanonicalId()withIncludeCanonicalId()->withCanonicalId()
- Rename
SyncSerializeRulesBuildermethods:includeMeta()->dynamicProperties()includeCanonicalId()->canonicalId()
- Do not extend
AbstractEntityfromAbstractSyncEntity - Remove
TemporalfromSyncEntityInterfaceand implement it inAbstractSyncEntity - Refactor
SyncEntityProviderInterface::getResolver()and downstream implementations- Accept closures for
$namePropertyand$weightProperty - Require
$namePropertyclosures to returnstring - Handle uninitialised properties and invalid values gracefully
- Accept closures for
Utility
- Optionally preserve keys in
Arr::pluck(),Arr::flatten()andReflect::getNames() - In
Test::isBuiltinType(), optionally exclude relative class types and/or theresourcetype, and remove soft-reserved typesenumandnumericentirely
Removed
Core
- Remove
getB(),issetB(),unsetB()fromBuilderInterface(implementation details are not needed in the contract) - Remove unused
Exception::withExitStatus()method - Remove
MultipleErrorExceptionTrait::getMetadata()to prevent errors being reported twice - Remove
GraphInterfacefrom API - Remove
NormaliserFlag - Remove unused
PipeInterfaceand related code - Remove unused
Process::isTerminatedBySignal() - Remove unused
WritesProtectedPropertiestrait - Remove date formatter caching from
AbstractProvider- Remove
finalfromAbstractProvider::getDateFormatter()and replace with a default implementation - Deprecate
AbstractProvider::createDateFormatter()and make itfinalto force downstream implementation updates
- Remove
PHPDoc
- Remove
$trackInheritanceparameter fromPHPDoc::forClass()
Sli
- Remove support for setting properties via generated builders
Utility
- Remove
Indentation::from()(replaced withFile::getIndentation())
Fixed
Core
- Fix issue where a deregistered
ErrorHandlercannot be re-registered and may still report errors on shutdown - Fix issue where multiple calls to
ErrorHandler::deregister()may remove other error/exception handlers - Fix issue where timeout behaviour may be incorrect after calling
Process::setTimeout()
PHPDoc
- Do not inherit DocBlocks from private members of inherited classes
- Fix issue where empty template maps are needlessly inherited
Utility
- Fix
Date::maybeSetTimezone()issue where+00:00, the timezone applied when timestamps are parsed, is not handled correctly - Add missing
int<1,max>type to tab size inIndentation
v0.99.74
v0.99.73
Changed
Utility
- Rename
Arr::isIndexed()tohasNumericKeys() - Make
Date::immutable()argument optional - In
Str::expandTabs()andexpandLeadingTabs(), add support for strings with two or more different end-of-line sequences - In
Str::expandLeadingTabs(), add support for an arbitrary combination of tabs and spaces at the start of each line
v0.99.72
Added
Cli
- Add overridable
CliCommand::canRunAsRoot()method and fail with an exception if it returnsfalsewhen running as root
Utility
- Add
Package::isInstalled()to public API - Add
Sys::isRunningAsRoot()
Changed
Utility
- Rename
Json::stringify()toencode() - Rename
Json::parseObjectAsArraytoobjectAsArray() - Rename
Regex::quoteCharacterClass()toquoteCharacters()
Fixed
Cli
- Fix issue where
CliApplication::getVersionString()returns values likeapp dev-ef08c76d7c0e5563080e1276bccd2ca666ed85d8 (ef08c76d) PHP 8.3.6
Utility
- Fix
Get::copy()issue where private property values are not copied correctly if an extending class has a property with the same name - Fix
Reflect::getAllProperties()issue where private properties in parent classes are not returned if an inheriting class has a property with the same name - Fix issue where
Package::getPackagePath()doesn't useFile::realpath()to return the canonical path - Fix issue where package versions like
dev-ef08c76d7c0e...@ef08c76dmay be returned
Security
Cli
- Allow applications to run as root
- Don't allow commands to run as root by default (see above)
v0.99.71
Added
Utility
- Add
Filemethodsrename()andsymlink() - Add
Regex::quote()for completeness
Changed
Utility
- Improve
Regexpattern consistency and readability - Add non-capturing groups to
Regexpatterns as needed for atomicity and to limit the scope of case sensitivity changes - Don't match leading and trailing whitespace in
RegexpatternsBOOLEAN_STRINGandINTEGER_STRING
Removed
Utility
- Remove unused
RegexpatternsPHP_UNION_TYPE,PHP_INTERSECTION_TYPE,PHP_DNF_SEGMENT,PHP_DNF_TYPEandPHP_FULL_TYPE
Security
Utility
- Apply umask by default in
File::create()andcreateDir()