Skip to content

Releases: salient-labs/toolkit

v0.99.75

22 Feb 06:44
v0.99.75
7526e85
Compare
Choose a tag to compare

Achieved with the changes detailed below:

  • Completion of Core API review
  • Cleaner access to constants via classes that implement their interfaces
  • Progress towards decoupling the Core component from Container
  • Progress towards rewritten "sli generate" commands

Added

Core

  • Add Serializable interface
  • Add, implement and adopt InvalidDataException
  • Add, implement and adopt EventDispatcherInterface and EventListenerProviderInterface
  • 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() and File::select()
  • Add File::getIndentation()
  • Add Inflect::list(), with optional Oxford comma support
  • Add Reflect::getDeclaring(), Reflect::getFileName() and getNamespaceName()

Changed

  • Rename exception interfaces to reduce verbosity
  • Move Indentation to Salient\Utility\Support
  • Move MimeType to Salient\Contract\Http
  • Move SqlQuery to Salient\Db

Cache

  • Treat DateInterval TTLs like integers, i.e. delete the item if TTL is <= 0 seconds

Console

  • Rename:
    • ConsoleWriterInterface -> ConsoleInterface
    • ConsoleWriter -> Console
    • ConsoleMessageType -> HasMessageType
    • ConsoleMessageTypeGroup -> HasMessageTypes
  • Implement HasMessageLevel, HasMessageLevels, HasMessageType and HasMessageTypes from the Console facade

Core

  • Rename:
    • AbstractBuilder -> Builder
    • AbstractFacade -> Facade and move to Salient\Core\Facade
    • AbstractStore -> Store
    • AbstractStreamWrapper -> StreamWrapper
    • AbstractException -> Exception and move to Salient\Core\Exception
    • AbstractMultipleErrorException -> MultipleErrorException and move to Salient\Core\Exception
    • HasBuilder -> BuildableTrait
    • HasChainableMethods -> ChainableTrait
    • HasFacade -> FacadeAwareInstanceTrait
    • HasMutator -> ImmutableTrait
    • HasNormaliser -> NormalisableTrait
    • HasReadableProperties -> ReadableTrait
    • HasWritableProperties -> WritableTrait
    • JsonSchemaInterface -> HasJsonSchema
    • Process methods:
      • getText() -> getOutputAsText()
      • getNewText() -> getNewOutputAsText()
    • ProvidableEntityInterface -> ProviderEntityInterface and move to Salient\Core\Entity
    • ReadsProtectedProperties -> ReadableProtectedPropertiesTrait
    • SerializeRulesInterface methods:
      • getIncludeMeta() -> getDynamicProperties()
      • withIncludeMeta() -> withDynamicProperties()
    • UnloadsFacades -> FacadeAwareTrait
  • Rename, move to Salient\Contract and update constants:
    • EscapeSequence -> HasEscapeSequence
    • FileDescriptor -> HasFileDescriptor
    • ListConformity -> HasConformity
    • MessageLevel -> HasMessageLevel
    • MessageLevelGroup -> HasMessageLevels
    • TextComparisonAlgorithm -> HasTextComparisonFlag
    • TextComparisonFlag -> HasTextComparisonFlag
  • Move:
    • StoppableEventInterface -> Salient\Contract\Core\Event
    • EventDispatcher -> Salient\Core\Event
    • StoppableEventTrait -> Salient\Core\Event
    • FacadeInterface -> Salient\Contract\Core\Facade
    • FacadeAwareInterface -> Salient\Contract\Core\Facade
    • ArrayMapperInterface -> Salient\Contract\Core\Pipeline
    • DateFormatter -> Salient\Core\Date
    • DateFormatParser -> Salient\Core\Date
    • DateParser -> Salient\Core\Date
    • DotNetDateParser -> Salient\Core\Date
    • Providable -> Salient\Core\Entity
    • SerializeRulesInterface -> Salient\Core\Entity
    • ExceptionTrait -> Salient\Core\Exception
    • MultipleErrorExceptionTrait -> Salient\Core\Exception
    • AbstractEntity -> Salient\Core\Provider
    • AbstractProvider -> Salient\Core\Provider
    • ProviderContext -> 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 use Container if it is defined
  • Detect date properties and parameters via native type hints even if Temporal is not implemented
  • Refactor Facade::getService() for simplicity
  • Narrow Hierarchical return types to $this as needed
  • Refactor Normalisable::normaliseProperty() for clarity
  • Make $context a required parameter of Providable methods provide() and provideMultiple() and remove $provider accordingly
  • Refactor Providable::provideMultiple() for consistency with Constructible
  • Improve uninitialised property handling in TreeableTrait
  • Replace ConfigurationManager::getMany() with getMultiple()
  • Extend DateParserInterface from DateFormatterInterface
  • In DateParserInterface::parse(), specify that $timezone is ignored if $value has a timezone and update implementations accordingly
  • Deregister ErrorHandler when the facade it's running behind is unloaded
  • In MultipleErrorException:
    • Rename getMessageWithoutErrors() to getMessageOnly()
    • Add $console parameter to reportErrors()
  • In Process:
    • Improve robustness of stream handling
    • Always throw ProcessTerminatedBySignalException when a process is killed, not just when wait() is called
    • Add and throw ProcessDidNotTerminateException
    • Do not throw ProcessException for stream-related errors
  • Add ClassReflection and adopt instead of Introspector and IntrospectionClass where 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 Treeable classes to return invalid parent/children properties

PHPDoc

  • Collect and propagate context data to allow expansion of relative class types like static, $this and self

PHPStan

  • Preserve key types when $preserveKeys = true is passed to Arr::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 @internal methods from facades
  • Build out PHPDoc tag handling and other abstractions in AbstractGenerateCommand

Sync

  • Extend ClassReflection from Reflection classes
  • Rename Reflection classes for consistency
  • Refactor SyncSerializeRulesInterface for consistency with SerializeRulesInterface
  • Rename SyncSerializeRulesInterface methods:
    • getIncludeCanonicalId() -> getCanonicalId()
    • withIncludeCanonicalId() -> withCanonicalId()
  • Rename SyncSerializeRulesBuilder methods:
    • includeMeta() -> dynamicProperties()
    • includeCanonicalId() -> canonicalId()
  • Do not extend AbstractEntity from AbstractSyncEntity
  • Remove Temporal from SyncEntityInterface and implement it in AbstractSyncEntity
  • Refactor SyncEntityProviderInterface::getResolver() and downstream implementations
    • Accept closures for $nameProperty and $weightProperty
    • Require $nameProperty closures to return string
    • Handle uninitialised properties and invalid values gracefully

Utility

  • Optionally preserve keys in Arr::pluck(), Arr::flatten() and Reflect::getNames()
  • In Test::isBuiltinType(), optionally exclude relative class types and/or the resource type, and remove soft-reserved types enum and numeric entirely

Removed

Core

  • Remove getB(), issetB(), unsetB() from BuilderInterface (implementation details are not needed in the contract)
  • Remove unused Exception::withExitStatus() method
  • Remove MultipleErrorExceptionTrait::getMetadata() to prevent errors being reported twice
  • Remove GraphInterface from API
  • Remove NormaliserFlag
  • Remove unused PipeInterface and related code
  • Remove unused Process::isTerminatedBySignal()
  • Remove unused WritesProtectedProperties trait
  • Remove date formatter caching from AbstractProvider
    • Remove final from AbstractProvider::getDateFormatter() and replace with a default implementation
    • Deprecate AbstractProvider::createDateFormatter() and make it final to force downstream implementation updates

PHPDoc

  • Remove $trackInheritance parameter from PHPDoc::forClass()

Sli

  • Remove support for setting properties via generated builders

Utility

  • Remove Indentation::from() (replaced with File::getIndentation())

Fixed

Core

  • Fix issue where a deregistered ErrorHandler cannot 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 in Indentation

v0.99.74

29 Jan 00:28
v0.99.74
78f33f4
Compare
Choose a tag to compare

Fixed

Utility

  • Fix regression in Str::expandLeadingTabs() where the indentation of the second line may be incorrect when $preserveLine1 is true

v0.99.73

28 Jan 12:22
v0.99.73
e409aa4
Compare
Choose a tag to compare

Changed

Utility

  • Rename Arr::isIndexed() to hasNumericKeys()
  • Make Date::immutable() argument optional
  • In Str::expandTabs() and expandLeadingTabs(), 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

27 Jan 06:15
v0.99.72
6ec6bc9
Compare
Choose a tag to compare

Added

Cli

  • Add overridable CliCommand::canRunAsRoot() method and fail with an exception if it returns false when running as root

Utility

  • Add Package::isInstalled() to public API
  • Add Sys::isRunningAsRoot()

Changed

Utility

  • Rename Json::stringify() to encode()
  • Rename Json::parseObjectAsArray to objectAsArray()
  • Rename Regex::quoteCharacterClass() to quoteCharacters()

Fixed

Cli

  • Fix issue where CliApplication::getVersionString() returns values like app 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 use File::realpath() to return the canonical path
  • Fix issue where package versions like dev-ef08c76d7c0e...@ef08c76d may 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

24 Jan 05:06
v0.99.71
9242909
Compare
Choose a tag to compare

Added

Utility

  • Add File methods rename() and symlink()
  • Add Regex::quote() for completeness

Changed

Utility

  • Improve Regex pattern consistency and readability
  • Add non-capturing groups to Regex patterns as needed for atomicity and to limit the scope of case sensitivity changes
  • Don't match leading and trailing whitespace in Regex patterns BOOLEAN_STRING and INTEGER_STRING

Removed

Utility

  • Remove unused Regex patterns PHP_UNION_TYPE, PHP_INTERSECTION_TYPE, PHP_DNF_SEGMENT, PHP_DNF_TYPE and PHP_FULL_TYPE

Security

Utility

  • Apply umask by default in File::create() and createDir()

v0.99.70

23 Jan 12:47
v0.99.70
e3a89c1
Compare
Choose a tag to compare

Changed

  • Adopt ReflectionClass<*> instead of ReflectionClass<object> to work around T not being covariant on PHPStan 2.1.2 + PHP 8.4

Polyfill

  • Remove dependency on salient/utils

Fixed

Polyfill

  • Fix issue where PhpToken doesn't tokenize binary strings like b"$foo" correctly
  • Fix issue where PhpToken fails if salient/sli is not installed

Security

Utility

  • Optionally honour umask in File::create() and createDir()

v0.99.69

22 Jan 12:19
v0.99.69
0c4bf67
Compare
Choose a tag to compare

Added

Utility

  • Add File::createTemp() for completeness

Changed

Utility

  • Rename File::getCleanDir() to sanitiseDir()
  • In File, remove resource type checks in favour of upstream exceptions

Fixed

Utility

  • Fix issue where File::createTempDir() consumes full CPU indefinitely if given a directory that is not writable (or not a directory)

Security

Utility

  • In File::create() and createDir():
    • Change default permissions from 0777 to 0755
    • Use umask 0077 to prevent access by an attacker before permissions are applied
    • In create(), open files with mode 'x' instead of using touch() to create them

v0.99.68

14 Jan 05:58
v0.99.68
0c211b1
Compare
Choose a tag to compare

Added

PHPStan

  • Add HasMutatorReadWritePropertiesExtension to resolve errors like property.unused and property.unusedType in classes that insert HasMutator

Sync

  • Add SyncUtil::getServicedEntityType()

Changed

Sync

  • In SyncEntityProvider, resolve custom entity types to base entities serviced by the provider if necessary

    This change means sync operations performed on a $provider via $provider->with(<entity>::class) are resolved against a parent of <entity> if:

    • $provider doesn't service <entity> but does service one of its non-abstract parents, and
    • the service container resolves that parent to <entity>

v0.99.67

13 Jan 12:02
v0.99.67
886e4fb
Compare
Choose a tag to compare

Changed

Sli

  • Generate sync entity providers that return iterable<array-key,TEntity> instead of iterable<TEntity>, as per Sync change in v0.99.63

v0.99.66

13 Jan 06:44
v0.99.66
f44ff66
Compare
Choose a tag to compare

Changed

Cli

  • Don't let applications run as root by default

Core

  • Rename Chainable methods for clarity:
    • if() -> applyIf()
    • withEach() -> applyForEach()

Sli

  • Update default builder description to "A builder for <class>"