upgrade to laravel 7 and set branch to v2
This commit is contained in:
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
//use Exception;
|
||||
use Throwable;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
@@ -32,7 +33,7 @@ class Handler extends ExceptionHandler
|
||||
* @param \Exception $exception
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $exception)
|
||||
public function report(Throwable $exception)
|
||||
{
|
||||
parent::report($exception);
|
||||
}
|
||||
@@ -44,7 +45,7 @@ class Handler extends ExceptionHandler
|
||||
* @param \Exception $exception
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $exception)
|
||||
public function render($request, Throwable $exception)
|
||||
{
|
||||
return parent::render($request, $exception);
|
||||
}
|
||||
|
||||
@@ -6,26 +6,24 @@
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"consoletvs/charts": "6.*",
|
||||
"eveseat/eseye": "^1.1",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"khill/lavacharts": "^3.1.14",
|
||||
"laravel/framework": "^5.8",
|
||||
"laravel/horizon": "^3.1",
|
||||
"laravel/socialite": "^3.1",
|
||||
"laravel/tinker": "^1.0",
|
||||
"laravelcollective/html": "^5.8.0",
|
||||
"predis/predis": "^1.1",
|
||||
"twbs/bootstrap": "^4.1"
|
||||
"laravel/framework": "^7.0",
|
||||
"twbs/bootstrap": "^4.5",
|
||||
"laravelcollective/html": "^6.0",
|
||||
"laravel/helpers": "^1.4",
|
||||
"laravel/socialite": "^5.1",
|
||||
"laravel/horizon": "^4.0",
|
||||
"laravel/ui": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"beyondcode/laravel-dump-server": "^1.0",
|
||||
"filp/whoops": "^2.0",
|
||||
"fzaninotto/faker": "^1.4",
|
||||
"mockery/mockery": "^1.0",
|
||||
"nunomaduro/collision": "^2.0",
|
||||
"phpunit/phpunit": "^7.0"
|
||||
"phpunit/phpunit": "^8.5",
|
||||
"nunomaduro/collision": "^4.1"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
|
||||
3100
composer.lock
generated
3100
composer.lock
generated
File diff suppressed because it is too large
Load Diff
674
vendor/balping/json-raw-encoder/LICENSE
vendored
674
vendor/balping/json-raw-encoder/LICENSE
vendored
@@ -1,674 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
106
vendor/balping/json-raw-encoder/README.md
vendored
106
vendor/balping/json-raw-encoder/README.md
vendored
@@ -1,106 +0,0 @@
|
||||
# Json Raw Encoder
|
||||
|
||||
Use this package to encode arrays to JSON with raw JS objects (eg. callbacks) in them.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
composer require balping/json-raw-encoder
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Suppose you need to pass a callback to a JSON object.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$array = [
|
||||
'type' => 'cat',
|
||||
'count' => 42,
|
||||
'callback' => 'function(a){alert(a);}'
|
||||
];
|
||||
?>
|
||||
|
||||
<script>
|
||||
let bar = <?php echo json_encode($array); ?>;
|
||||
bar.callback('hello'); //error
|
||||
</script>
|
||||
```
|
||||
|
||||
However, the above array will be encoded as
|
||||
|
||||
```json
|
||||
{"type":"cat","count":42,"callback":"function(a){alert(a);}"}
|
||||
```
|
||||
|
||||
On this object, you cannot call `callback()`, as `callback` is a string and not a function.
|
||||
|
||||
To get around this problem, use `Raw` objects provided by this package:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Balping\JsonRaw\Raw;
|
||||
use Balping\JsonRaw\Encoder;
|
||||
|
||||
$array = [
|
||||
'type' => 'cat',
|
||||
'count' => 42,
|
||||
'callback' => new Raw('function(a){alert(a);}')
|
||||
];
|
||||
?>
|
||||
|
||||
<script>
|
||||
let bar = <?php echo Encoder::encode($array); ?>;
|
||||
bar.callback('hello'); //prints hello
|
||||
</script>
|
||||
```
|
||||
|
||||
Now, the encoded JSON looks like this. Notice, that there are no parentheses around the function.
|
||||
|
||||
```js
|
||||
{"type":"cat","count":42,"callback":function(a){alert(a);}}
|
||||
```
|
||||
|
||||
Calling `bar.callback()` now works, as `callback` is a function and not a string.
|
||||
|
||||
## Using with third party libraries
|
||||
|
||||
It is possible that the serialisation is done by a library (eg. Fractal), and not by your code, i.e. you cannot replace `json_encode` with `Encoder::encode()`.
|
||||
|
||||
In this case, you can still pass callbacks to JSON, by passing the encoded json and an array of all raw objects to `Replacer::replace()`:
|
||||
|
||||
```php
|
||||
|
||||
use Balping\JsonRaw\Raw;
|
||||
use Balping\JsonRaw\Replacer;
|
||||
|
||||
$rawObjects = [];
|
||||
|
||||
$array = [
|
||||
'type' => 'cat',
|
||||
'count' => 42,
|
||||
'callback' => $rawObjects[] = new Raw('function(a){alert(a);}')
|
||||
];
|
||||
|
||||
// you cannot alter the behaviour of a third party encoder
|
||||
$encoded = $thirdParty->jsonEncode($array);
|
||||
|
||||
echo Replacer::replace($encoded, $rawObjects);
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```js
|
||||
{"type":"cat","count":42,"callback":function(a){alert(a);}}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This package is licensed under GPLv3.
|
||||
|
||||
## Download statistics
|
||||
|
||||
[](https://packagist-statistics.dura.hu/balping/json-raw-encoder/10days.svg)
|
||||
30
vendor/balping/json-raw-encoder/composer.json
vendored
30
vendor/balping/json-raw-encoder/composer.json
vendored
@@ -1,30 +0,0 @@
|
||||
{
|
||||
"name": "balping/json-raw-encoder",
|
||||
"description": "Encode arrays to json with raw JS objects (eg. callbacks) in them",
|
||||
"keywords": ["json", "encode", "callback"],
|
||||
"type": "library",
|
||||
"require": {
|
||||
"php": ">=7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.1"
|
||||
},
|
||||
"license": "GPL-3.0-only",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Balázs Dura-Kovács"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Balping\\JsonRaw\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Balping\\JsonRaw\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
51
vendor/balping/json-raw-encoder/src/Encoder.php
vendored
51
vendor/balping/json-raw-encoder/src/Encoder.php
vendored
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
Json Raw Encoder
|
||||
Encode arrays to json with raw JS objects (eg. callbacks) in them
|
||||
Copyright (C) 2018 Balázs Dura-Kovács
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
namespace Balping\JsonRaw;
|
||||
|
||||
class Encoder {
|
||||
/**
|
||||
* Encode array containing Raw objects to JSON
|
||||
*
|
||||
* @see json_encode
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param int $options
|
||||
* @param int $depth [optional]
|
||||
* @return string|false
|
||||
*/
|
||||
static function encode($value, ...$args){
|
||||
$rawObjects = [];
|
||||
|
||||
// find raw object items in the input array
|
||||
array_walk_recursive($value, function($item) use (&$rawObjects){
|
||||
if(is_object($item) && is_a($item, Raw::class)){
|
||||
$rawObjects[] = &$item;
|
||||
}
|
||||
});
|
||||
|
||||
$encoded = json_encode($value, ...$args);
|
||||
|
||||
return Replacer::replace($encoded, $rawObjects);
|
||||
}
|
||||
}
|
||||
57
vendor/balping/json-raw-encoder/src/Raw.php
vendored
57
vendor/balping/json-raw-encoder/src/Raw.php
vendored
@@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
Json Raw Encoder
|
||||
Encode arrays to json with raw JS objects (eg. callbacks) in them
|
||||
Copyright (C) 2018 Balázs Dura-Kovács
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
namespace Balping\JsonRaw;
|
||||
|
||||
class Raw implements \JsonSerializable {
|
||||
/**
|
||||
* Unique identifier. Gets replaced with raw value
|
||||
* after using built-in json_encode
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Raw value. This is passed to json without any modification
|
||||
* (i.e. without escaping, etc.)
|
||||
* @var string
|
||||
*/
|
||||
protected $value;
|
||||
|
||||
public function __construct(string $value){
|
||||
$this->value = $value;
|
||||
$this->id = bin2hex(random_bytes(20));
|
||||
}
|
||||
|
||||
public function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getValue(){
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function jsonSerialize(){
|
||||
return $this->getId();
|
||||
}
|
||||
}
|
||||
48
vendor/balping/json-raw-encoder/src/Replacer.php
vendored
48
vendor/balping/json-raw-encoder/src/Replacer.php
vendored
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
Json Raw Encoder
|
||||
Encode arrays to json with raw JS objects (eg. callbacks) in them
|
||||
Copyright (C) 2018 Balázs Dura-Kovács
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
namespace Balping\JsonRaw;
|
||||
|
||||
class Replacer {
|
||||
/**
|
||||
* Replace unique ids with raw values in an encoded json
|
||||
*
|
||||
* @param string $json encoded json
|
||||
* @param array $rawObjects
|
||||
* @return string
|
||||
*/
|
||||
static function replace(string $json, array $rawObjects){
|
||||
$encoded = &$json;
|
||||
|
||||
// replace unique strings with raw values
|
||||
foreach ($rawObjects as $rawObject) {
|
||||
$encoded = str_replace(
|
||||
'"'. $rawObject->getId() . '"',
|
||||
$rawObject->getValue(),
|
||||
$encoded
|
||||
);
|
||||
}
|
||||
|
||||
return $encoded;
|
||||
}
|
||||
}
|
||||
34
vendor/beyondcode/laravel-dump-server/README.md
vendored
34
vendor/beyondcode/laravel-dump-server/README.md
vendored
@@ -8,8 +8,6 @@ Bringing the [Symfony Var-Dump Server](https://symfony.com/doc/current/component
|
||||
|
||||
This package will give you a dump server, that collects all your `dump` call outputs, so that it does not interfere with HTTP / API responses.
|
||||
|
||||
> If you want to learn how to create reusable PHP packages yourself, take a look at my upcoming [PHP Package Development](https://phppackagedevelopment.com) video course.
|
||||
|
||||
## Installation
|
||||
|
||||
You can install the package via composer:
|
||||
@@ -18,37 +16,9 @@ You can install the package via composer:
|
||||
composer require --dev beyondcode/laravel-dump-server
|
||||
```
|
||||
|
||||
The package will register itself automatically.
|
||||
## Documentation
|
||||
|
||||
Optionally you can publish the package configuration using:
|
||||
|
||||
```bash
|
||||
php artisan vendor:publish --provider=BeyondCode\\DumpServer\\DumpServerServiceProvider
|
||||
```
|
||||
|
||||
This will publish a file called `debug-server.php` in your `config` folder.
|
||||
In the config file, you can specify the dump server host that you want to listen on, in case you want to change the default value.
|
||||
|
||||
## Usage
|
||||
|
||||
Start the dump server by calling the artisan command:
|
||||
|
||||
```bash
|
||||
php artisan dump-server
|
||||
```
|
||||
|
||||
You can set the output format to HTML using the `--format` option:
|
||||
|
||||
```bash
|
||||
php artisan dump-server --format=html > dump.html
|
||||
```
|
||||
|
||||
And then you can, as you are used to, put `dump` calls in your methods. But instead of dumping the output in your current HTTP request, they will be dumped in the artisan command.
|
||||
This is very useful, when you want to dump data from API requests, without having to deal with HTTP errors.
|
||||
|
||||
You can see it in action here:
|
||||
|
||||

|
||||
You can find the documentation on the [Beyond Code website](https://beyondco.de/docs/laravel-dump-server/installation).
|
||||
|
||||
### Changelog
|
||||
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1",
|
||||
"illuminate/console": "5.6.*|5.7.*|5.8.*|^6.0",
|
||||
"illuminate/http": "5.6.*|5.7.*|5.8.*|^6.0",
|
||||
"illuminate/support": "5.6.*|5.7.*|5.8.*|^6.0",
|
||||
"symfony/var-dumper": "^4.1.1"
|
||||
"php": ">=7.2.5",
|
||||
"illuminate/console": "5.6.*|5.7.*|5.8.*|^6.0|^7.0|^8.0",
|
||||
"illuminate/http": "5.6.*|5.7.*|5.8.*|^6.0|^7.0|^8.0",
|
||||
"illuminate/support": "5.6.*|5.7.*|5.8.*|^6.0|^7.0|^8.0",
|
||||
"symfony/var-dumper": "^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"larapack/dd": "^1.0",
|
||||
"phpunit/phpunit": "^7.0"
|
||||
"phpunit/phpunit": "^7.0|^9.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
@@ -4,5 +4,5 @@ return [
|
||||
/*
|
||||
* The host to use when listening for debug server connections.
|
||||
*/
|
||||
'host' => 'tcp://127.0.0.1:9912',
|
||||
'host' => env('DUMP_SERVER_HOST', 'tcp://127.0.0.1:9912'),
|
||||
];
|
||||
|
||||
4
vendor/beyondcode/laravel-dump-server/docs/_index.md
vendored
Normal file
4
vendor/beyondcode/laravel-dump-server/docs/_index.md
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
packageName: Laravel Dump Server
|
||||
githubUrl: https://github.com/beyondcode/laravel-dump-server
|
||||
---
|
||||
30
vendor/beyondcode/laravel-dump-server/docs/installation.md
vendored
Normal file
30
vendor/beyondcode/laravel-dump-server/docs/installation.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Installation
|
||||
order: 1
|
||||
---
|
||||
# Laravel Dump Server
|
||||
|
||||
Bringing the Symfony Var-Dump Server to Laravel.
|
||||
|
||||
This package will give you a dump server, that collects all your dump call outputs, so that it does not interfere with HTTP / API responses.
|
||||
|
||||

|
||||
|
||||
# Installation
|
||||
|
||||
You can install the package via composer:
|
||||
|
||||
```bash
|
||||
composer require --dev beyondcode/laravel-dump-server
|
||||
```
|
||||
|
||||
The package will register itself automatically.
|
||||
|
||||
Optionally you can publish the package configuration using:
|
||||
|
||||
```bash
|
||||
php artisan vendor:publish --provider="BeyondCode\DumpServer\DumpServerServiceProvider"
|
||||
```
|
||||
|
||||
This will publish a file called `debug-server.php` in your `config` folder.
|
||||
In the config file, you can specify the dump server host that you want to listen on, in case you want to change the default value.
|
||||
22
vendor/beyondcode/laravel-dump-server/docs/usage.md
vendored
Normal file
22
vendor/beyondcode/laravel-dump-server/docs/usage.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: Usage
|
||||
order: 2
|
||||
---
|
||||
|
||||
# Usage
|
||||
|
||||
Start the dump server by calling the artisan command:
|
||||
|
||||
```bash
|
||||
php artisan dump-server
|
||||
```
|
||||
|
||||
You can set the output format to HTML using the `--format` option:
|
||||
|
||||
```bash
|
||||
php artisan dump-server --format=html > dump.html
|
||||
```
|
||||
|
||||
Now you can put regular `dump` statements in your code. Instead of dumping the output directly in the HTTP response, the dumped data will be shown inside of your terminal / the running artisan command.
|
||||
|
||||
This is very useful, when you want to dump data from API requests, without having to deal with HTTP errors.
|
||||
@@ -50,7 +50,7 @@ class DumpServerServiceProvider extends ServiceProvider
|
||||
]);
|
||||
|
||||
VarDumper::setHandler(function ($var) use ($connection) {
|
||||
(new Dumper($connection))->dump($var);
|
||||
$this->app->makeWith(Dumper::class, ['connection' => $connection])->dump($var);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class Dumper
|
||||
public function dump($value)
|
||||
{
|
||||
if (class_exists(CliDumper::class)) {
|
||||
$data = (new VarCloner)->cloneVar($value);
|
||||
$data = $this->createVarCloner()->cloneVar($value);
|
||||
|
||||
if ($this->connection === null || $this->connection->write($data) === false) {
|
||||
$dumper = in_array(PHP_SAPI, ['cli', 'phpdbg']) ? new CliDumper : new HtmlDumper;
|
||||
@@ -46,4 +46,12 @@ class Dumper
|
||||
var_dump($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return VarCloner
|
||||
*/
|
||||
protected function createVarCloner(): VarCloner
|
||||
{
|
||||
return new VarCloner();
|
||||
}
|
||||
}
|
||||
|
||||
1
vendor/bin/commonmark
vendored
Symbolic link
1
vendor/bin/commonmark
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../league/commonmark/bin/commonmark
|
||||
1
vendor/bin/php-parse
vendored
1
vendor/bin/php-parse
vendored
@@ -1 +0,0 @@
|
||||
../nikic/php-parser/bin/php-parse
|
||||
1
vendor/bin/psysh
vendored
1
vendor/bin/psysh
vendored
@@ -1 +0,0 @@
|
||||
../psy/psysh/bin/psysh
|
||||
1
vendor/bin/tokengenerator
vendored
1
vendor/bin/tokengenerator
vendored
@@ -1 +0,0 @@
|
||||
../eveseat/eseye/bin/tokengenerator
|
||||
20
vendor/brick/math/LICENSE
vendored
Normal file
20
vendor/brick/math/LICENSE
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-present Benjamin Morel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
16
vendor/brick/math/SECURITY.md
vendored
Normal file
16
vendor/brick/math/SECURITY.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Only the latest release stream is supported.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 0.8.x | :white_check_mark: |
|
||||
| < 0.8 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report a security vulnerability, please use the
|
||||
[Tidelift security contact](https://tidelift.com/security).
|
||||
Tidelift will coordinate the fix and disclosure.
|
||||
35
vendor/brick/math/composer.json
vendored
Normal file
35
vendor/brick/math/composer.json
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "brick/math",
|
||||
"description": "Arbitrary-precision arithmetic library",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"Brick",
|
||||
"Math",
|
||||
"Arbitrary-precision",
|
||||
"Arithmetic",
|
||||
"BigInteger",
|
||||
"BigDecimal",
|
||||
"BigRational",
|
||||
"Bignum"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.1|^8.0",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5.15|^8.5",
|
||||
"php-coveralls/php-coveralls": "^2.2",
|
||||
"vimeo/psalm": "^3.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Brick\\Math\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Brick\\Math\\Tests\\": "tests/"
|
||||
}
|
||||
}
|
||||
}
|
||||
40
vendor/brick/math/psalm-baseline.xml
vendored
Normal file
40
vendor/brick/math/psalm-baseline.xml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="3.8.5@e6ec5fa22a7b9e61670a24d07b3119aff80dcd89">
|
||||
<file src="src/Internal/Calculator/BcMathCalculator.php">
|
||||
<InvalidNullableReturnType occurrences="3">
|
||||
<code>string</code>
|
||||
<code>string</code>
|
||||
<code>string</code>
|
||||
</InvalidNullableReturnType>
|
||||
<InvalidReturnStatement occurrences="1">
|
||||
<code>[$q, $r]</code>
|
||||
</InvalidReturnStatement>
|
||||
<InvalidReturnType occurrences="1">
|
||||
<code>array</code>
|
||||
</InvalidReturnType>
|
||||
<NullableReturnStatement occurrences="3">
|
||||
<code>\bcdiv($a, $b, 0)</code>
|
||||
<code>\bcmod($a, $b)</code>
|
||||
<code>\bcpowmod($base, $exp, $mod, 0)</code>
|
||||
</NullableReturnStatement>
|
||||
</file>
|
||||
<file src="src/Internal/Calculator/NativeCalculator.php">
|
||||
<InvalidOperand occurrences="6">
|
||||
<code>$a</code>
|
||||
<code>$a</code>
|
||||
<code>$a</code>
|
||||
<code>$b</code>
|
||||
<code>$blockA</code>
|
||||
<code>$blockA</code>
|
||||
</InvalidOperand>
|
||||
<LoopInvalidation occurrences="4">
|
||||
<code>$i</code>
|
||||
<code>$i</code>
|
||||
<code>$i</code>
|
||||
<code>$j</code>
|
||||
</LoopInvalidation>
|
||||
<PossiblyInvalidArgument occurrences="1">
|
||||
<code>$e / 2</code>
|
||||
</PossiblyInvalidArgument>
|
||||
</file>
|
||||
</files>
|
||||
56
vendor/brick/math/psalm.xml
vendored
Normal file
56
vendor/brick/math/psalm.xml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
totallyTyped="false"
|
||||
resolveFromConfigFile="true"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
errorBaseline="psalm-baseline.xml"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
|
||||
<issueHandlers>
|
||||
<LessSpecificReturnType errorLevel="info" />
|
||||
|
||||
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||
|
||||
<DeprecatedMethod errorLevel="info" />
|
||||
<DeprecatedProperty errorLevel="info" />
|
||||
<DeprecatedClass errorLevel="info" />
|
||||
<DeprecatedConstant errorLevel="info" />
|
||||
<DeprecatedFunction errorLevel="info" />
|
||||
<DeprecatedInterface errorLevel="info" />
|
||||
<DeprecatedTrait errorLevel="info" />
|
||||
|
||||
<InternalMethod errorLevel="info" />
|
||||
<InternalProperty errorLevel="info" />
|
||||
<InternalClass errorLevel="info" />
|
||||
|
||||
<MissingClosureReturnType errorLevel="info" />
|
||||
<MissingReturnType errorLevel="info" />
|
||||
<MissingPropertyType errorLevel="info" />
|
||||
<InvalidDocblock errorLevel="info" />
|
||||
<MisplacedRequiredParam errorLevel="info" />
|
||||
|
||||
<PropertyNotSetInConstructor errorLevel="info" />
|
||||
<MissingConstructor errorLevel="info" />
|
||||
<MissingClosureParamType errorLevel="info" />
|
||||
<MissingParamType errorLevel="info" />
|
||||
|
||||
<RedundantCondition errorLevel="info" />
|
||||
|
||||
<DocblockTypeContradiction errorLevel="info" />
|
||||
<RedundantConditionGivenDocblockType errorLevel="info" />
|
||||
|
||||
<UnresolvableInclude errorLevel="info" />
|
||||
|
||||
<RawObjectIteration errorLevel="info" />
|
||||
|
||||
<InvalidStringClass errorLevel="info" />
|
||||
</issueHandlers>
|
||||
</psalm>
|
||||
184
vendor/brick/math/random-tests.php
vendored
Normal file
184
vendor/brick/math/random-tests.php
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This script stress tests calculators with random large numbers and ensures that all implementations return the same
|
||||
* results. It is designed to run in an infinite loop unless a bug is found.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
|
||||
(new class(30) { // max digits
|
||||
private $gmp;
|
||||
private $bcmath;
|
||||
private $native;
|
||||
|
||||
private $maxDigits;
|
||||
|
||||
public function __construct(int $maxDigits)
|
||||
{
|
||||
$this->gmp = new Calculator\GmpCalculator();
|
||||
$this->bcmath = new Calculator\BcMathCalculator();
|
||||
$this->native = new Calculator\NativeCalculator();
|
||||
|
||||
$this->maxDigits = $maxDigits;
|
||||
}
|
||||
|
||||
public function __invoke() : void
|
||||
{
|
||||
for (;;) {
|
||||
$a = $this->generateRandomNumber();
|
||||
$b = $this->generateRandomNumber();
|
||||
$c = $this->generateRandomNumber();
|
||||
|
||||
$this->runTests($a, $b);
|
||||
$this->runTests($b, $a);
|
||||
|
||||
if ($a !== '0') {
|
||||
$this->runTests("-$a", $b);
|
||||
$this->runTests($b, "-$a");
|
||||
}
|
||||
|
||||
if ($b !== '0') {
|
||||
$this->runTests($a, "-$b");
|
||||
$this->runTests("-$b", $a);
|
||||
}
|
||||
|
||||
if ($a !== '0' && $b !== '0') {
|
||||
$this->runTests("-$a", "-$b");
|
||||
$this->runTests("-$b", "-$a");
|
||||
}
|
||||
|
||||
if ($c !== '0') {
|
||||
$this->test("$a POW $b MOD $c", function(Calculator $calc) use($a, $b, $c) {
|
||||
return $calc->modPow($a, $b, $c);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $a The left operand.
|
||||
* @param string $b The right operand.
|
||||
*/
|
||||
function runTests(string $a, string $b) : void
|
||||
{
|
||||
$this->test("$a + $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->add($a, $b);
|
||||
});
|
||||
|
||||
$this->test("$a - $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->sub($a, $b);
|
||||
});
|
||||
|
||||
$this->test("$a * $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->mul($a, $b);
|
||||
});
|
||||
|
||||
if ($b !== '0') {
|
||||
$this->test("$a / $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->divQR($a, $b);
|
||||
});
|
||||
|
||||
$this->test("$a MOD $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->mod($a, $b);
|
||||
});
|
||||
}
|
||||
|
||||
if ($b !== '0' && $b[0] !== '-') {
|
||||
$this->test("INV $a MOD $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->modInverse($a, $b);
|
||||
});
|
||||
}
|
||||
|
||||
$this->test("GCD $a, $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->gcd($a, $b);
|
||||
});
|
||||
|
||||
if ($a[0] !== '-') {
|
||||
$this->test("SQRT $a", function(Calculator $c) use($a, $b) {
|
||||
return $c->sqrt($a);
|
||||
});
|
||||
}
|
||||
|
||||
$this->test("$a AND $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->and($a, $b);
|
||||
});
|
||||
|
||||
$this->test("$a OR $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->or($a, $b);
|
||||
});
|
||||
|
||||
$this->test("$a XOR $b", function(Calculator $c) use($a, $b) {
|
||||
return $c->xor($a, $b);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $test A string representing the test being executed.
|
||||
* @param Closure $callback A callback function accepting a Calculator instance and returning a calculation result.
|
||||
*/
|
||||
private function test(string $test, Closure $callback) : void
|
||||
{
|
||||
static $counter = 0;
|
||||
static $lastOutputTime = null;
|
||||
|
||||
$gmpResult = $callback($this->gmp);
|
||||
$bcmathResult = $callback($this->bcmath);
|
||||
$nativeResult = $callback($this->native);
|
||||
|
||||
if ($gmpResult !== $bcmathResult) {
|
||||
self::failure('GMP', 'BCMath', $test);
|
||||
}
|
||||
|
||||
if ($gmpResult !== $nativeResult) {
|
||||
self::failure('GMP', 'Native', $test);
|
||||
}
|
||||
|
||||
$counter++;
|
||||
$time = microtime(true);
|
||||
|
||||
if ($lastOutputTime === null) {
|
||||
$lastOutputTime = $time;
|
||||
} elseif ($time - $lastOutputTime >= 0.1) {
|
||||
echo "\r", number_format($counter);
|
||||
$lastOutputTime = $time;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $c1 The name of the first calculator.
|
||||
* @param string $c2 The name of the second calculator.
|
||||
* @param string $test A string representing the test being executed.
|
||||
*/
|
||||
private static function failure(string $c1, string $c2, string $test) : void
|
||||
{
|
||||
echo PHP_EOL;
|
||||
echo 'FAILURE!', PHP_EOL;
|
||||
echo $c1, ' vs ', $c2, PHP_EOL;
|
||||
echo $test, PHP_EOL;
|
||||
die;
|
||||
}
|
||||
|
||||
private function generateRandomNumber() : string
|
||||
{
|
||||
$length = random_int(1, $this->maxDigits);
|
||||
|
||||
$number = '';
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$number .= random_int(0, 9);
|
||||
}
|
||||
|
||||
$number = ltrim($number, '0');
|
||||
|
||||
if ($number === '') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
})();
|
||||
855
vendor/brick/math/src/BigDecimal.php
vendored
Normal file
855
vendor/brick/math/src/BigDecimal.php
vendored
Normal file
@@ -0,0 +1,855 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
use Brick\Math\Exception\DivisionByZeroException;
|
||||
use Brick\Math\Exception\MathException;
|
||||
use Brick\Math\Exception\NegativeNumberException;
|
||||
use Brick\Math\Internal\Calculator;
|
||||
|
||||
/**
|
||||
* Immutable, arbitrary-precision signed decimal numbers.
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class BigDecimal extends BigNumber
|
||||
{
|
||||
/**
|
||||
* The unscaled value of this decimal number.
|
||||
*
|
||||
* This is a string of digits with an optional leading minus sign.
|
||||
* No leading zero must be present.
|
||||
* No leading minus sign must be present if the value is 0.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* The scale (number of digits after the decimal point) of this decimal number.
|
||||
*
|
||||
* This must be zero or more.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $scale;
|
||||
|
||||
/**
|
||||
* Protected constructor. Use a factory method to obtain an instance.
|
||||
*
|
||||
* @param string $value The unscaled value, validated.
|
||||
* @param int $scale The scale, validated.
|
||||
*/
|
||||
protected function __construct(string $value, int $scale = 0)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->scale = $scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigDecimal of the given value.
|
||||
*
|
||||
* @param BigNumber|int|float|string $value
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws MathException If the value cannot be converted to a BigDecimal.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function of($value) : BigNumber
|
||||
{
|
||||
return parent::of($value)->toBigDecimal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigDecimal from an unscaled value and a scale.
|
||||
*
|
||||
* Example: `(12345, 3)` will result in the BigDecimal `12.345`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $value The unscaled value. Must be convertible to a BigInteger.
|
||||
* @param int $scale The scale of the number, positive or zero.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws \InvalidArgumentException If the scale is negative.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function ofUnscaledValue($value, int $scale = 0) : BigDecimal
|
||||
{
|
||||
if ($scale < 0) {
|
||||
throw new \InvalidArgumentException('The scale cannot be negative.');
|
||||
}
|
||||
|
||||
return new BigDecimal((string) BigInteger::of($value), $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigDecimal representing zero, with a scale of zero.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function zero() : BigDecimal
|
||||
{
|
||||
/** @psalm-suppress ImpureStaticVariable */
|
||||
static $zero;
|
||||
|
||||
if ($zero === null) {
|
||||
$zero = new BigDecimal('0');
|
||||
}
|
||||
|
||||
return $zero;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigDecimal representing one, with a scale of zero.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function one() : BigDecimal
|
||||
{
|
||||
/** @psalm-suppress ImpureStaticVariable */
|
||||
static $one;
|
||||
|
||||
if ($one === null) {
|
||||
$one = new BigDecimal('1');
|
||||
}
|
||||
|
||||
return $one;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigDecimal representing ten, with a scale of zero.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function ten() : BigDecimal
|
||||
{
|
||||
/** @psalm-suppress ImpureStaticVariable */
|
||||
static $ten;
|
||||
|
||||
if ($ten === null) {
|
||||
$ten = new BigDecimal('10');
|
||||
}
|
||||
|
||||
return $ten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of this number and the given one.
|
||||
*
|
||||
* The result has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws MathException If the number is not valid, or is not convertible to a BigDecimal.
|
||||
*/
|
||||
public function plus($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '0' && $that->scale <= $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->value === '0' && $this->scale <= $that->scale) {
|
||||
return $that;
|
||||
}
|
||||
|
||||
[$a, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
$value = Calculator::get()->add($a, $b);
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference of this number and the given one.
|
||||
*
|
||||
* The result has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws MathException If the number is not valid, or is not convertible to a BigDecimal.
|
||||
*/
|
||||
public function minus($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '0' && $that->scale <= $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
[$a, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
$value = Calculator::get()->sub($a, $b);
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of this number and the given one.
|
||||
*
|
||||
* The result has a scale of `$this->scale + $that->scale`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws MathException If the multiplier is not a valid number, or is not convertible to a BigDecimal.
|
||||
*/
|
||||
public function multipliedBy($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '1' && $that->scale === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->value === '1' && $this->scale === 0) {
|
||||
return $that;
|
||||
}
|
||||
|
||||
$value = Calculator::get()->mul($this->value, $that->value);
|
||||
$scale = $this->scale + $that->scale;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of the division of this number by the given one, at the given scale.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor.
|
||||
* @param int|null $scale The desired scale, or null to use the scale of this number.
|
||||
* @param int $roundingMode An optional rounding mode.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws \InvalidArgumentException If the scale or rounding mode is invalid.
|
||||
* @throws MathException If the number is invalid, is zero, or rounding was necessary.
|
||||
*/
|
||||
public function dividedBy($that, ?int $scale = null, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
if ($scale === null) {
|
||||
$scale = $this->scale;
|
||||
} elseif ($scale < 0) {
|
||||
throw new \InvalidArgumentException('Scale cannot be negative.');
|
||||
}
|
||||
|
||||
if ($that->value === '1' && $that->scale === 0 && $scale === $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale + $scale);
|
||||
$q = $that->valueWithMinScale($this->scale - $scale);
|
||||
|
||||
$result = Calculator::get()->divRound($p, $q, $roundingMode);
|
||||
|
||||
return new BigDecimal($result, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exact result of the division of this number by the given one.
|
||||
*
|
||||
* The scale of the result is automatically calculated to fit all the fraction digits.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid number, is not convertible to a BigDecimal, is zero,
|
||||
* or the result yields an infinite number of digits.
|
||||
*/
|
||||
public function exactlyDividedBy($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->value === '0') {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
[, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
$d = \rtrim($b, '0');
|
||||
$scale = \strlen($b) - \strlen($d);
|
||||
|
||||
$calculator = Calculator::get();
|
||||
|
||||
foreach ([5, 2] as $prime) {
|
||||
for (;;) {
|
||||
$lastDigit = (int) $d[-1];
|
||||
|
||||
if ($lastDigit % $prime !== 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
$d = $calculator->divQ($d, (string) $prime);
|
||||
$scale++;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->dividedBy($that, $scale)->stripTrailingZeros();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this number exponentiated to the given value.
|
||||
*
|
||||
* The result has a scale of `$this->scale * $exponent`.
|
||||
*
|
||||
* @param int $exponent The exponent.
|
||||
*
|
||||
* @return BigDecimal The result.
|
||||
*
|
||||
* @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000.
|
||||
*/
|
||||
public function power(int $exponent) : BigDecimal
|
||||
{
|
||||
if ($exponent === 0) {
|
||||
return BigDecimal::one();
|
||||
}
|
||||
|
||||
if ($exponent === 1) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($exponent < 0 || $exponent > Calculator::MAX_POWER) {
|
||||
throw new \InvalidArgumentException(\sprintf(
|
||||
'The exponent %d is not in the range 0 to %d.',
|
||||
$exponent,
|
||||
Calculator::MAX_POWER
|
||||
));
|
||||
}
|
||||
|
||||
return new BigDecimal(Calculator::get()->pow($this->value, $exponent), $this->scale * $exponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the division of this number by this given one.
|
||||
*
|
||||
* The quotient has a scale of `0`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The quotient.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
||||
*/
|
||||
public function quotient($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale);
|
||||
$q = $that->valueWithMinScale($this->scale);
|
||||
|
||||
$quotient = Calculator::get()->divQ($p, $q);
|
||||
|
||||
return new BigDecimal($quotient, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remainder of the division of this number by this given one.
|
||||
*
|
||||
* The remainder has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The remainder.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
||||
*/
|
||||
public function remainder($that) : BigDecimal
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale);
|
||||
$q = $that->valueWithMinScale($this->scale);
|
||||
|
||||
$remainder = Calculator::get()->divR($p, $q);
|
||||
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
return new BigDecimal($remainder, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient and remainder of the division of this number by the given one.
|
||||
*
|
||||
* The quotient has a scale of `0`, and the remainder has a scale of `max($this->scale, $that->scale)`.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal[] An array containing the quotient and the remainder.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid decimal number, or is zero.
|
||||
*/
|
||||
public function quotientAndRemainder($that) : array
|
||||
{
|
||||
$that = BigDecimal::of($that);
|
||||
|
||||
if ($that->isZero()) {
|
||||
throw DivisionByZeroException::divisionByZero();
|
||||
}
|
||||
|
||||
$p = $this->valueWithMinScale($that->scale);
|
||||
$q = $that->valueWithMinScale($this->scale);
|
||||
|
||||
[$quotient, $remainder] = Calculator::get()->divQR($p, $q);
|
||||
|
||||
$scale = $this->scale > $that->scale ? $this->scale : $that->scale;
|
||||
|
||||
$quotient = new BigDecimal($quotient, 0);
|
||||
$remainder = new BigDecimal($remainder, $scale);
|
||||
|
||||
return [$quotient, $remainder];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square root of this number, rounded down to the given number of decimals.
|
||||
*
|
||||
* @param int $scale
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws \InvalidArgumentException If the scale is negative.
|
||||
* @throws NegativeNumberException If this number is negative.
|
||||
*/
|
||||
public function sqrt(int $scale) : BigDecimal
|
||||
{
|
||||
if ($scale < 0) {
|
||||
throw new \InvalidArgumentException('Scale cannot be negative.');
|
||||
}
|
||||
|
||||
if ($this->value === '0') {
|
||||
return new BigDecimal('0', $scale);
|
||||
}
|
||||
|
||||
if ($this->value[0] === '-') {
|
||||
throw new NegativeNumberException('Cannot calculate the square root of a negative number.');
|
||||
}
|
||||
|
||||
$value = $this->value;
|
||||
$addDigits = 2 * $scale - $this->scale;
|
||||
|
||||
if ($addDigits > 0) {
|
||||
// add zeros
|
||||
$value .= \str_repeat('0', $addDigits);
|
||||
} elseif ($addDigits < 0) {
|
||||
// trim digits
|
||||
if (-$addDigits >= \strlen($this->value)) {
|
||||
// requesting a scale too low, will always yield a zero result
|
||||
return new BigDecimal('0', $scale);
|
||||
}
|
||||
|
||||
$value = \substr($value, 0, $addDigits);
|
||||
}
|
||||
|
||||
$value = Calculator::get()->sqrt($value);
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this BigDecimal with the decimal point moved $n places to the left.
|
||||
*
|
||||
* @param int $n
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function withPointMovedLeft(int $n) : BigDecimal
|
||||
{
|
||||
if ($n === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($n < 0) {
|
||||
return $this->withPointMovedRight(-$n);
|
||||
}
|
||||
|
||||
return new BigDecimal($this->value, $this->scale + $n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this BigDecimal with the decimal point moved $n places to the right.
|
||||
*
|
||||
* @param int $n
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function withPointMovedRight(int $n) : BigDecimal
|
||||
{
|
||||
if ($n === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($n < 0) {
|
||||
return $this->withPointMovedLeft(-$n);
|
||||
}
|
||||
|
||||
$value = $this->value;
|
||||
$scale = $this->scale - $n;
|
||||
|
||||
if ($scale < 0) {
|
||||
if ($value !== '0') {
|
||||
$value .= \str_repeat('0', -$scale);
|
||||
}
|
||||
$scale = 0;
|
||||
}
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of this BigDecimal with any trailing zeros removed from the fractional part.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function stripTrailingZeros() : BigDecimal
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$trimmedValue = \rtrim($this->value, '0');
|
||||
|
||||
if ($trimmedValue === '') {
|
||||
return BigDecimal::zero();
|
||||
}
|
||||
|
||||
$trimmableZeros = \strlen($this->value) - \strlen($trimmedValue);
|
||||
|
||||
if ($trimmableZeros === 0) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($trimmableZeros > $this->scale) {
|
||||
$trimmableZeros = $this->scale;
|
||||
}
|
||||
|
||||
$value = \substr($this->value, 0, -$trimmableZeros);
|
||||
$scale = $this->scale - $trimmableZeros;
|
||||
|
||||
return new BigDecimal($value, $scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this number.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function abs() : BigDecimal
|
||||
{
|
||||
return $this->isNegative() ? $this->negated() : $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the negated value of this number.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
public function negated() : BigDecimal
|
||||
{
|
||||
return new BigDecimal(Calculator::get()->neg($this->value), $this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compareTo($that) : int
|
||||
{
|
||||
$that = BigNumber::of($that);
|
||||
|
||||
if ($that instanceof BigInteger) {
|
||||
$that = $that->toBigDecimal();
|
||||
}
|
||||
|
||||
if ($that instanceof BigDecimal) {
|
||||
[$a, $b] = $this->scaleValues($this, $that);
|
||||
|
||||
return Calculator::get()->cmp($a, $b);
|
||||
}
|
||||
|
||||
return - $that->compareTo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSign() : int
|
||||
{
|
||||
return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function getUnscaledValue() : BigInteger
|
||||
{
|
||||
return BigInteger::create($this->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getScale() : int
|
||||
{
|
||||
return $this->scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing the integral part of this decimal number.
|
||||
*
|
||||
* Example: `-123.456` => `-123`.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIntegralPart() : string
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
||||
|
||||
return \substr($value, 0, -$this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing the fractional part of this decimal number.
|
||||
*
|
||||
* If the scale is zero, an empty string is returned.
|
||||
*
|
||||
* Examples: `-123.456` => '456', `123` => ''.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFractionalPart() : string
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
||||
|
||||
return \substr($value, -$this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this decimal number has a non-zero fractional part.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNonZeroFractionalPart() : bool
|
||||
{
|
||||
return $this->getFractionalPart() !== \str_repeat('0', $this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigInteger() : BigInteger
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
$zeroScaleDecimal = $this;
|
||||
} else {
|
||||
$zeroScaleDecimal = $this->dividedBy(1, 0);
|
||||
}
|
||||
|
||||
return BigInteger::create($zeroScaleDecimal->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigDecimal() : BigDecimal
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigRational() : BigRational
|
||||
{
|
||||
$numerator = BigInteger::create($this->value);
|
||||
$denominator = BigInteger::create('1' . \str_repeat('0', $this->scale));
|
||||
|
||||
return BigRational::create($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
|
||||
{
|
||||
if ($scale === $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->dividedBy(BigDecimal::one(), $scale, $roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toInt() : int
|
||||
{
|
||||
return $this->toBigInteger()->toInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toFloat() : float
|
||||
{
|
||||
return (float) (string) $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString() : string
|
||||
{
|
||||
if ($this->scale === 0) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
$value = $this->getUnscaledValueWithLeadingZeros();
|
||||
|
||||
return \substr($value, 0, -$this->scale) . '.' . \substr($value, -$this->scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by interface Serializable and SHOULD NOT be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize() : string
|
||||
{
|
||||
return $this->value . ':' . $this->scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only here to implement interface Serializable and cannot be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function unserialize($value) : void
|
||||
{
|
||||
if (isset($this->value)) {
|
||||
throw new \LogicException('unserialize() is an internal function, it must not be called directly.');
|
||||
}
|
||||
|
||||
[$value, $scale] = \explode(':', $value);
|
||||
|
||||
$this->value = $value;
|
||||
$this->scale = (int) $scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the internal values of the given decimal numbers on the same scale.
|
||||
*
|
||||
* @param BigDecimal $x The first decimal number.
|
||||
* @param BigDecimal $y The second decimal number.
|
||||
*
|
||||
* @return array{0: string, 1: string} The scaled integer values of $x and $y.
|
||||
*/
|
||||
private function scaleValues(BigDecimal $x, BigDecimal $y) : array
|
||||
{
|
||||
$a = $x->value;
|
||||
$b = $y->value;
|
||||
|
||||
if ($b !== '0' && $x->scale > $y->scale) {
|
||||
$b .= \str_repeat('0', $x->scale - $y->scale);
|
||||
} elseif ($a !== '0' && $x->scale < $y->scale) {
|
||||
$a .= \str_repeat('0', $y->scale - $x->scale);
|
||||
}
|
||||
|
||||
return [$a, $b];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $scale
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function valueWithMinScale(int $scale) : string
|
||||
{
|
||||
$value = $this->value;
|
||||
|
||||
if ($this->value !== '0' && $scale > $this->scale) {
|
||||
$value .= \str_repeat('0', $scale - $this->scale);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds leading zeros if necessary to the unscaled value to represent the full decimal number.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getUnscaledValueWithLeadingZeros() : string
|
||||
{
|
||||
$value = $this->value;
|
||||
$targetLength = $this->scale + 1;
|
||||
$negative = ($value[0] === '-');
|
||||
$length = \strlen($value);
|
||||
|
||||
if ($negative) {
|
||||
$length--;
|
||||
}
|
||||
|
||||
if ($length >= $targetLength) {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
if ($negative) {
|
||||
$value = \substr($value, 1);
|
||||
}
|
||||
|
||||
$value = \str_pad($value, $targetLength, '0', STR_PAD_LEFT);
|
||||
|
||||
if ($negative) {
|
||||
$value = '-' . $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
1134
vendor/brick/math/src/BigInteger.php
vendored
Normal file
1134
vendor/brick/math/src/BigInteger.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
566
vendor/brick/math/src/BigNumber.php
vendored
Normal file
566
vendor/brick/math/src/BigNumber.php
vendored
Normal file
@@ -0,0 +1,566 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
use Brick\Math\Exception\DivisionByZeroException;
|
||||
use Brick\Math\Exception\MathException;
|
||||
use Brick\Math\Exception\NumberFormatException;
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
|
||||
/**
|
||||
* Common interface for arbitrary-precision rational numbers.
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
abstract class BigNumber implements \Serializable, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* The regular expression used to parse integer, decimal and rational numbers.
|
||||
*/
|
||||
private const PARSE_REGEXP =
|
||||
'/^' .
|
||||
'(?<sign>[\-\+])?' .
|
||||
'(?:' .
|
||||
'(?:' .
|
||||
'(?<integral>[0-9]+)?' .
|
||||
'(?<point>\.)?' .
|
||||
'(?<fractional>[0-9]+)?' .
|
||||
'(?:[eE](?<exponent>[\-\+]?[0-9]+))?' .
|
||||
')|(?:' .
|
||||
'(?<numerator>[0-9]+)' .
|
||||
'\/?' .
|
||||
'(?<denominator>[0-9]+)' .
|
||||
')' .
|
||||
')' .
|
||||
'$/';
|
||||
|
||||
/**
|
||||
* Creates a BigNumber of the given value.
|
||||
*
|
||||
* The concrete return type is dependent on the given value, with the following rules:
|
||||
*
|
||||
* - BigNumber instances are returned as is
|
||||
* - integer numbers are returned as BigInteger
|
||||
* - floating point numbers are converted to a string then parsed as such
|
||||
* - strings containing a `/` character are returned as BigRational
|
||||
* - strings containing a `.` character or using an exponential notation are returned as BigDecimal
|
||||
* - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger
|
||||
*
|
||||
* @param BigNumber|int|float|string $value
|
||||
*
|
||||
* @return BigNumber
|
||||
*
|
||||
* @throws NumberFormatException If the format of the number is not valid.
|
||||
* @throws DivisionByZeroException If the value represents a rational number with a denominator of zero.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function of($value) : BigNumber
|
||||
{
|
||||
if ($value instanceof BigNumber) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (\is_int($value)) {
|
||||
return new BigInteger((string) $value);
|
||||
}
|
||||
|
||||
if (\is_float($value)) {
|
||||
$value = self::floatToString($value);
|
||||
} else {
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
$throw = function() use ($value) : void {
|
||||
throw new NumberFormatException(\sprintf(
|
||||
'The given value "%s" does not represent a valid number.',
|
||||
$value
|
||||
));
|
||||
};
|
||||
|
||||
if (\preg_match(self::PARSE_REGEXP, $value, $matches) !== 1) {
|
||||
$throw();
|
||||
}
|
||||
|
||||
$getMatch = function(string $value) use ($matches) : ?string {
|
||||
return isset($matches[$value]) && $matches[$value] !== '' ? $matches[$value] : null;
|
||||
};
|
||||
|
||||
$sign = $getMatch('sign');
|
||||
$numerator = $getMatch('numerator');
|
||||
$denominator = $getMatch('denominator');
|
||||
|
||||
if ($numerator !== null) {
|
||||
$numerator = self::cleanUp($sign . $numerator);
|
||||
$denominator = self::cleanUp($denominator);
|
||||
|
||||
if ($denominator === '0') {
|
||||
throw DivisionByZeroException::denominatorMustNotBeZero();
|
||||
}
|
||||
|
||||
return new BigRational(
|
||||
new BigInteger($numerator),
|
||||
new BigInteger($denominator),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
$point = $getMatch('point');
|
||||
$integral = $getMatch('integral');
|
||||
$fractional = $getMatch('fractional');
|
||||
$exponent = $getMatch('exponent');
|
||||
|
||||
if ($integral === null && $fractional === null) {
|
||||
$throw();
|
||||
}
|
||||
|
||||
if ($integral === null) {
|
||||
$integral = '0';
|
||||
}
|
||||
|
||||
if ($point !== null || $exponent !== null) {
|
||||
$fractional = $fractional ?? '';
|
||||
$exponent = $exponent !== null ? (int) $exponent : 0;
|
||||
|
||||
if ($exponent === PHP_INT_MIN || $exponent === PHP_INT_MAX) {
|
||||
throw new NumberFormatException('Exponent too large.');
|
||||
}
|
||||
|
||||
$unscaledValue = self::cleanUp($sign . $integral . $fractional);
|
||||
|
||||
$scale = \strlen($fractional) - $exponent;
|
||||
|
||||
if ($scale < 0) {
|
||||
if ($unscaledValue !== '0') {
|
||||
$unscaledValue .= \str_repeat('0', - $scale);
|
||||
}
|
||||
$scale = 0;
|
||||
}
|
||||
|
||||
return new BigDecimal($unscaledValue, $scale);
|
||||
}
|
||||
|
||||
$integral = self::cleanUp($sign . $integral);
|
||||
|
||||
return new BigInteger($integral);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely converts float to string, avoiding locale-dependent issues.
|
||||
*
|
||||
* @see https://github.com/brick/math/pull/20
|
||||
*
|
||||
* @param float $float
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @psalm-pure
|
||||
* @psalm-suppress ImpureFunctionCall
|
||||
*/
|
||||
private static function floatToString(float $float) : string
|
||||
{
|
||||
$currentLocale = \setlocale(LC_NUMERIC, '0');
|
||||
\setlocale(LC_NUMERIC, 'C');
|
||||
|
||||
$result = (string) $float;
|
||||
|
||||
\setlocale(LC_NUMERIC, $currentLocale);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy method to access protected constructors from sibling classes.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param mixed ...$args The arguments to the constructor.
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
protected static function create(... $args) : BigNumber
|
||||
{
|
||||
/** @psalm-suppress TooManyArguments */
|
||||
return new static(... $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum of the given values.
|
||||
*
|
||||
* @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible
|
||||
* to an instance of the class this method is called on.
|
||||
*
|
||||
* @return static The minimum value.
|
||||
*
|
||||
* @throws \InvalidArgumentException If no values are given.
|
||||
* @throws MathException If an argument is not valid.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function min(...$values) : BigNumber
|
||||
{
|
||||
$min = null;
|
||||
|
||||
foreach ($values as $value) {
|
||||
$value = static::of($value);
|
||||
|
||||
if ($min === null || $value->isLessThan($min)) {
|
||||
$min = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($min === null) {
|
||||
throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
||||
}
|
||||
|
||||
return $min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum of the given values.
|
||||
*
|
||||
* @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible
|
||||
* to an instance of the class this method is called on.
|
||||
*
|
||||
* @return static The maximum value.
|
||||
*
|
||||
* @throws \InvalidArgumentException If no values are given.
|
||||
* @throws MathException If an argument is not valid.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function max(...$values) : BigNumber
|
||||
{
|
||||
$max = null;
|
||||
|
||||
foreach ($values as $value) {
|
||||
$value = static::of($value);
|
||||
|
||||
if ($max === null || $value->isGreaterThan($max)) {
|
||||
$max = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($max === null) {
|
||||
throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
||||
}
|
||||
|
||||
return $max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of the given values.
|
||||
*
|
||||
* @param BigNumber|int|float|string ...$values The numbers to add. All the numbers need to be convertible
|
||||
* to an instance of the class this method is called on.
|
||||
*
|
||||
* @return static The sum.
|
||||
*
|
||||
* @throws \InvalidArgumentException If no values are given.
|
||||
* @throws MathException If an argument is not valid.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function sum(...$values) : BigNumber
|
||||
{
|
||||
/** @var BigNumber|null $sum */
|
||||
$sum = null;
|
||||
|
||||
foreach ($values as $value) {
|
||||
$value = static::of($value);
|
||||
|
||||
if ($sum === null) {
|
||||
$sum = $value;
|
||||
} else {
|
||||
$sum = self::add($sum, $value);
|
||||
}
|
||||
}
|
||||
|
||||
if ($sum === null) {
|
||||
throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.');
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two BigNumber instances in the correct order to avoid a RoundingNecessaryException.
|
||||
*
|
||||
* @todo This could be better resolved by creating an abstract protected method in BigNumber, and leaving to
|
||||
* concrete classes the responsibility to perform the addition themselves or delegate it to the given number,
|
||||
* depending on their ability to perform the operation. This will also require a version bump because we're
|
||||
* potentially breaking custom BigNumber implementations (if any...)
|
||||
*
|
||||
* @param BigNumber $a
|
||||
* @param BigNumber $b
|
||||
*
|
||||
* @return BigNumber
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
private static function add(BigNumber $a, BigNumber $b) : BigNumber
|
||||
{
|
||||
if ($a instanceof BigRational) {
|
||||
return $a->plus($b);
|
||||
}
|
||||
|
||||
if ($b instanceof BigRational) {
|
||||
return $b->plus($a);
|
||||
}
|
||||
|
||||
if ($a instanceof BigDecimal) {
|
||||
return $a->plus($b);
|
||||
}
|
||||
|
||||
if ($b instanceof BigDecimal) {
|
||||
return $b->plus($a);
|
||||
}
|
||||
|
||||
/** @var BigInteger $a */
|
||||
|
||||
return $a->plus($b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes optional leading zeros and + sign from the given number.
|
||||
*
|
||||
* @param string $number The number, validated as a non-empty string of digits with optional leading sign.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
private static function cleanUp(string $number) : string
|
||||
{
|
||||
$firstChar = $number[0];
|
||||
|
||||
if ($firstChar === '+' || $firstChar === '-') {
|
||||
$number = \substr($number, 1);
|
||||
}
|
||||
|
||||
$number = \ltrim($number, '0');
|
||||
|
||||
if ($number === '') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if ($firstChar === '-') {
|
||||
return '-' . $number;
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is equal to the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEqualTo($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly lower than the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLessThan($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is lower than or equal to the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLessThanOrEqualTo($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly greater than the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreaterThan($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is greater than or equal to the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreaterThanOrEqualTo($that) : bool
|
||||
{
|
||||
return $this->compareTo($that) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number equals zero.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isZero() : bool
|
||||
{
|
||||
return $this->getSign() === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly negative.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNegative() : bool
|
||||
{
|
||||
return $this->getSign() < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is negative or zero.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNegativeOrZero() : bool
|
||||
{
|
||||
return $this->getSign() <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly positive.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPositive() : bool
|
||||
{
|
||||
return $this->getSign() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is positive or zero.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPositiveOrZero() : bool
|
||||
{
|
||||
return $this->getSign() >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sign of this number.
|
||||
*
|
||||
* @return int -1 if the number is negative, 0 if zero, 1 if positive.
|
||||
*/
|
||||
abstract public function getSign() : int;
|
||||
|
||||
/**
|
||||
* Compares this number to the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that
|
||||
*
|
||||
* @return int [-1,0,1] If `$this` is lower than, equal to, or greater than `$that`.
|
||||
*
|
||||
* @throws MathException If the number is not valid.
|
||||
*/
|
||||
abstract public function compareTo($that) : int;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigInteger.
|
||||
*
|
||||
* @return BigInteger The converted number.
|
||||
*
|
||||
* @throws RoundingNecessaryException If this number cannot be converted to a BigInteger without rounding.
|
||||
*/
|
||||
abstract public function toBigInteger() : BigInteger;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigDecimal.
|
||||
*
|
||||
* @return BigDecimal The converted number.
|
||||
*
|
||||
* @throws RoundingNecessaryException If this number cannot be converted to a BigDecimal without rounding.
|
||||
*/
|
||||
abstract public function toBigDecimal() : BigDecimal;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigRational.
|
||||
*
|
||||
* @return BigRational The converted number.
|
||||
*/
|
||||
abstract public function toBigRational() : BigRational;
|
||||
|
||||
/**
|
||||
* Converts this number to a BigDecimal with the given scale, using rounding if necessary.
|
||||
*
|
||||
* @param int $scale The scale of the resulting `BigDecimal`.
|
||||
* @param int $roundingMode A `RoundingMode` constant.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*
|
||||
* @throws RoundingNecessaryException If this number cannot be converted to the given scale without rounding.
|
||||
* This only applies when RoundingMode::UNNECESSARY is used.
|
||||
*/
|
||||
abstract public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal;
|
||||
|
||||
/**
|
||||
* Returns the exact value of this number as a native integer.
|
||||
*
|
||||
* If this number cannot be converted to a native integer without losing precision, an exception is thrown.
|
||||
* Note that the acceptable range for an integer depends on the platform and differs for 32-bit and 64-bit.
|
||||
*
|
||||
* @return int The converted value.
|
||||
*
|
||||
* @throws MathException If this number cannot be exactly converted to a native integer.
|
||||
*/
|
||||
abstract public function toInt() : int;
|
||||
|
||||
/**
|
||||
* Returns an approximation of this number as a floating-point value.
|
||||
*
|
||||
* Note that this method can discard information as the precision of a floating-point value
|
||||
* is inherently limited.
|
||||
*
|
||||
* If the number is greater than the largest representable floating point number, positive infinity is returned.
|
||||
* If the number is less than the smallest representable floating point number, negative infinity is returned.
|
||||
*
|
||||
* @return float The converted value.
|
||||
*/
|
||||
abstract public function toFloat() : float;
|
||||
|
||||
/**
|
||||
* Returns a string representation of this number.
|
||||
*
|
||||
* The output of this method can be parsed by the `of()` factory method;
|
||||
* this will yield an object equal to this one, without any information loss.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function __toString() : string;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function jsonSerialize() : string
|
||||
{
|
||||
return $this->__toString();
|
||||
}
|
||||
}
|
||||
479
vendor/brick/math/src/BigRational.php
vendored
Normal file
479
vendor/brick/math/src/BigRational.php
vendored
Normal file
@@ -0,0 +1,479 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
use Brick\Math\Exception\DivisionByZeroException;
|
||||
use Brick\Math\Exception\MathException;
|
||||
use Brick\Math\Exception\NumberFormatException;
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
|
||||
/**
|
||||
* An arbitrarily large rational number.
|
||||
*
|
||||
* This class is immutable.
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class BigRational extends BigNumber
|
||||
{
|
||||
/**
|
||||
* The numerator.
|
||||
*
|
||||
* @var BigInteger
|
||||
*/
|
||||
private $numerator;
|
||||
|
||||
/**
|
||||
* The denominator. Always strictly positive.
|
||||
*
|
||||
* @var BigInteger
|
||||
*/
|
||||
private $denominator;
|
||||
|
||||
/**
|
||||
* Protected constructor. Use a factory method to obtain an instance.
|
||||
*
|
||||
* @param BigInteger $numerator The numerator.
|
||||
* @param BigInteger $denominator The denominator.
|
||||
* @param bool $checkDenominator Whether to check the denominator for negative and zero.
|
||||
*
|
||||
* @throws DivisionByZeroException If the denominator is zero.
|
||||
*/
|
||||
protected function __construct(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator)
|
||||
{
|
||||
if ($checkDenominator) {
|
||||
if ($denominator->isZero()) {
|
||||
throw DivisionByZeroException::denominatorMustNotBeZero();
|
||||
}
|
||||
|
||||
if ($denominator->isNegative()) {
|
||||
$numerator = $numerator->negated();
|
||||
$denominator = $denominator->negated();
|
||||
}
|
||||
}
|
||||
|
||||
$this->numerator = $numerator;
|
||||
$this->denominator = $denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigRational of the given value.
|
||||
*
|
||||
* @param BigNumber|int|float|string $value
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @throws MathException If the value cannot be converted to a BigRational.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function of($value) : BigNumber
|
||||
{
|
||||
return parent::of($value)->toBigRational();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigRational out of a numerator and a denominator.
|
||||
*
|
||||
* If the denominator is negative, the signs of both the numerator and the denominator
|
||||
* will be inverted to ensure that the denominator is always positive.
|
||||
*
|
||||
* @param BigNumber|int|float|string $numerator The numerator. Must be convertible to a BigInteger.
|
||||
* @param BigNumber|int|float|string $denominator The denominator. Must be convertible to a BigInteger.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @throws NumberFormatException If an argument does not represent a valid number.
|
||||
* @throws RoundingNecessaryException If an argument represents a non-integer number.
|
||||
* @throws DivisionByZeroException If the denominator is zero.
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function nd($numerator, $denominator) : BigRational
|
||||
{
|
||||
$numerator = BigInteger::of($numerator);
|
||||
$denominator = BigInteger::of($denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigRational representing zero.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function zero() : BigRational
|
||||
{
|
||||
/** @psalm-suppress ImpureStaticVariable */
|
||||
static $zero;
|
||||
|
||||
if ($zero === null) {
|
||||
$zero = new BigRational(BigInteger::zero(), BigInteger::one(), false);
|
||||
}
|
||||
|
||||
return $zero;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigRational representing one.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function one() : BigRational
|
||||
{
|
||||
/** @psalm-suppress ImpureStaticVariable */
|
||||
static $one;
|
||||
|
||||
if ($one === null) {
|
||||
$one = new BigRational(BigInteger::one(), BigInteger::one(), false);
|
||||
}
|
||||
|
||||
return $one;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a BigRational representing ten.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function ten() : BigRational
|
||||
{
|
||||
/** @psalm-suppress ImpureStaticVariable */
|
||||
static $ten;
|
||||
|
||||
if ($ten === null) {
|
||||
$ten = new BigRational(BigInteger::ten(), BigInteger::one(), false);
|
||||
}
|
||||
|
||||
return $ten;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function getNumerator() : BigInteger
|
||||
{
|
||||
return $this->numerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function getDenominator() : BigInteger
|
||||
{
|
||||
return $this->denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the division of the numerator by the denominator.
|
||||
*
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function quotient() : BigInteger
|
||||
{
|
||||
return $this->numerator->quotient($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remainder of the division of the numerator by the denominator.
|
||||
*
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function remainder() : BigInteger
|
||||
{
|
||||
return $this->numerator->remainder($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient and remainder of the division of the numerator by the denominator.
|
||||
*
|
||||
* @return BigInteger[]
|
||||
*/
|
||||
public function quotientAndRemainder() : array
|
||||
{
|
||||
return $this->numerator->quotientAndRemainder($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of this number and the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to add.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws MathException If the number is not valid.
|
||||
*/
|
||||
public function plus($that) : BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$numerator = $numerator->plus($that->numerator->multipliedBy($this->denominator));
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference of this number and the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The number to subtract.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws MathException If the number is not valid.
|
||||
*/
|
||||
public function minus($that) : BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$numerator = $numerator->minus($that->numerator->multipliedBy($this->denominator));
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of this number and the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The multiplier.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws MathException If the multiplier is not a valid number.
|
||||
*/
|
||||
public function multipliedBy($that) : BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->numerator);
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of the division of this number by the given one.
|
||||
*
|
||||
* @param BigNumber|int|float|string $that The divisor.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws MathException If the divisor is not a valid number, or is zero.
|
||||
*/
|
||||
public function dividedBy($that) : BigRational
|
||||
{
|
||||
$that = BigRational::of($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$denominator = $this->denominator->multipliedBy($that->numerator);
|
||||
|
||||
return new BigRational($numerator, $denominator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this number exponentiated to the given value.
|
||||
*
|
||||
* @param int $exponent The exponent.
|
||||
*
|
||||
* @return BigRational The result.
|
||||
*
|
||||
* @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000.
|
||||
*/
|
||||
public function power(int $exponent) : BigRational
|
||||
{
|
||||
if ($exponent === 0) {
|
||||
$one = BigInteger::one();
|
||||
|
||||
return new BigRational($one, $one, false);
|
||||
}
|
||||
|
||||
if ($exponent === 1) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new BigRational(
|
||||
$this->numerator->power($exponent),
|
||||
$this->denominator->power($exponent),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reciprocal of this BigRational.
|
||||
*
|
||||
* The reciprocal has the numerator and denominator swapped.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @throws DivisionByZeroException If the numerator is zero.
|
||||
*/
|
||||
public function reciprocal() : BigRational
|
||||
{
|
||||
return new BigRational($this->denominator, $this->numerator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this BigRational.
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function abs() : BigRational
|
||||
{
|
||||
return new BigRational($this->numerator->abs(), $this->denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the negated value of this BigRational.
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function negated() : BigRational
|
||||
{
|
||||
return new BigRational($this->numerator->negated(), $this->denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the simplified value of this BigRational.
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function simplified() : BigRational
|
||||
{
|
||||
$gcd = $this->numerator->gcd($this->denominator);
|
||||
|
||||
$numerator = $this->numerator->quotient($gcd);
|
||||
$denominator = $this->denominator->quotient($gcd);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compareTo($that) : int
|
||||
{
|
||||
return $this->minus($that)->getSign();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSign() : int
|
||||
{
|
||||
return $this->numerator->getSign();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigInteger() : BigInteger
|
||||
{
|
||||
$simplified = $this->simplified();
|
||||
|
||||
if (! $simplified->denominator->isEqualTo(1)) {
|
||||
throw new RoundingNecessaryException('This rational number cannot be represented as an integer value without rounding.');
|
||||
}
|
||||
|
||||
return $simplified->numerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigDecimal() : BigDecimal
|
||||
{
|
||||
return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBigRational() : BigRational
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
|
||||
{
|
||||
return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toInt() : int
|
||||
{
|
||||
return $this->toBigInteger()->toInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toFloat() : float
|
||||
{
|
||||
return $this->numerator->toFloat() / $this->denominator->toFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString() : string
|
||||
{
|
||||
$numerator = (string) $this->numerator;
|
||||
$denominator = (string) $this->denominator;
|
||||
|
||||
if ($denominator === '1') {
|
||||
return $numerator;
|
||||
}
|
||||
|
||||
return $this->numerator . '/' . $this->denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by interface Serializable and SHOULD NOT be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize() : string
|
||||
{
|
||||
return $this->numerator . '/' . $this->denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is only here to implement interface Serializable and cannot be accessed directly.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function unserialize($value) : void
|
||||
{
|
||||
if (isset($this->numerator)) {
|
||||
throw new \LogicException('unserialize() is an internal function, it must not be called directly.');
|
||||
}
|
||||
|
||||
[$numerator, $denominator] = \explode('/', $value);
|
||||
|
||||
$this->numerator = BigInteger::of($numerator);
|
||||
$this->denominator = BigInteger::of($denominator);
|
||||
}
|
||||
}
|
||||
41
vendor/brick/math/src/Exception/DivisionByZeroException.php
vendored
Normal file
41
vendor/brick/math/src/Exception/DivisionByZeroException.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a division by zero occurs.
|
||||
*/
|
||||
class DivisionByZeroException extends MathException
|
||||
{
|
||||
/**
|
||||
* @return DivisionByZeroException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function divisionByZero() : DivisionByZeroException
|
||||
{
|
||||
return new self('Division by zero.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DivisionByZeroException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function modulusMustNotBeZero() : DivisionByZeroException
|
||||
{
|
||||
return new self('The modulus must not be zero.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DivisionByZeroException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function denominatorMustNotBeZero() : DivisionByZeroException
|
||||
{
|
||||
return new self('The denominator of a rational number cannot be zero.');
|
||||
}
|
||||
}
|
||||
27
vendor/brick/math/src/Exception/IntegerOverflowException.php
vendored
Normal file
27
vendor/brick/math/src/Exception/IntegerOverflowException.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
use Brick\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Exception thrown when an integer overflow occurs.
|
||||
*/
|
||||
class IntegerOverflowException extends MathException
|
||||
{
|
||||
/**
|
||||
* @param BigInteger $value
|
||||
*
|
||||
* @return IntegerOverflowException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function toIntOverflow(BigInteger $value) : IntegerOverflowException
|
||||
{
|
||||
$message = '%s is out of range %d to %d and cannot be represented as an integer.';
|
||||
|
||||
return new self(\sprintf($message, (string) $value, PHP_INT_MIN, PHP_INT_MAX));
|
||||
}
|
||||
}
|
||||
14
vendor/brick/math/src/Exception/MathException.php
vendored
Normal file
14
vendor/brick/math/src/Exception/MathException.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Base class for all math exceptions.
|
||||
*
|
||||
* This class is abstract to ensure that only fine-grained exceptions are thrown throughout the code.
|
||||
*/
|
||||
class MathException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
12
vendor/brick/math/src/Exception/NegativeNumberException.php
vendored
Normal file
12
vendor/brick/math/src/Exception/NegativeNumberException.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when attempting to perform an unsupported operation, such as a square root, on a negative number.
|
||||
*/
|
||||
class NegativeNumberException extends MathException
|
||||
{
|
||||
}
|
||||
35
vendor/brick/math/src/Exception/NumberFormatException.php
vendored
Normal file
35
vendor/brick/math/src/Exception/NumberFormatException.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when attempting to create a number from a string with an invalid format.
|
||||
*/
|
||||
class NumberFormatException extends MathException
|
||||
{
|
||||
/**
|
||||
* @param string $char The failing character.
|
||||
*
|
||||
* @return NumberFormatException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function charNotInAlphabet(string $char) : self
|
||||
{
|
||||
$ord = \ord($char);
|
||||
|
||||
if ($ord < 32 || $ord > 126) {
|
||||
$char = \strtoupper(\dechex($ord));
|
||||
|
||||
if ($ord < 10) {
|
||||
$char = '0' . $char;
|
||||
}
|
||||
} else {
|
||||
$char = '"' . $char . '"';
|
||||
}
|
||||
|
||||
return new self(sprintf('Char %s is not a valid character in the given alphabet.', $char));
|
||||
}
|
||||
}
|
||||
21
vendor/brick/math/src/Exception/RoundingNecessaryException.php
vendored
Normal file
21
vendor/brick/math/src/Exception/RoundingNecessaryException.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a number cannot be represented at the requested scale without rounding.
|
||||
*/
|
||||
class RoundingNecessaryException extends MathException
|
||||
{
|
||||
/**
|
||||
* @return RoundingNecessaryException
|
||||
*
|
||||
* @psalm-pure
|
||||
*/
|
||||
public static function roundingNecessary() : RoundingNecessaryException
|
||||
{
|
||||
return new self('Rounding is necessary to represent the result of the operation at this scale.');
|
||||
}
|
||||
}
|
||||
756
vendor/brick/math/src/Internal/Calculator.php
vendored
Normal file
756
vendor/brick/math/src/Internal/Calculator.php
vendored
Normal file
@@ -0,0 +1,756 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal;
|
||||
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
use Brick\Math\RoundingMode;
|
||||
|
||||
/**
|
||||
* Performs basic operations on arbitrary size integers.
|
||||
*
|
||||
* Unless otherwise specified, all parameters must be validated as non-empty strings of digits,
|
||||
* without leading zero, and with an optional leading minus sign if the number is not zero.
|
||||
*
|
||||
* Any other parameter format will lead to undefined behaviour.
|
||||
* All methods must return strings respecting this format, unless specified otherwise.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
abstract class Calculator
|
||||
{
|
||||
/**
|
||||
* The maximum exponent value allowed for the pow() method.
|
||||
*/
|
||||
public const MAX_POWER = 1000000;
|
||||
|
||||
/**
|
||||
* The alphabet for converting from and to base 2 to 36, lowercase.
|
||||
*/
|
||||
public const ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
/**
|
||||
* The Calculator instance in use.
|
||||
*
|
||||
* @var Calculator|null
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* Sets the Calculator instance to use.
|
||||
*
|
||||
* An instance is typically set only in unit tests: the autodetect is usually the best option.
|
||||
*
|
||||
* @param Calculator|null $calculator The calculator instance, or NULL to revert to autodetect.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
final public static function set(?Calculator $calculator) : void
|
||||
{
|
||||
self::$instance = $calculator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Calculator instance to use.
|
||||
*
|
||||
* If none has been explicitly set, the fastest available implementation will be returned.
|
||||
*
|
||||
* @return Calculator
|
||||
*
|
||||
* @psalm-pure
|
||||
* @psalm-suppress ImpureStaticProperty
|
||||
*/
|
||||
final public static function get() : Calculator
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
/** @psalm-suppress ImpureMethodCall */
|
||||
self::$instance = self::detect();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fastest available Calculator implementation.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return Calculator
|
||||
*/
|
||||
private static function detect() : Calculator
|
||||
{
|
||||
if (\extension_loaded('gmp')) {
|
||||
return new Calculator\GmpCalculator();
|
||||
}
|
||||
|
||||
if (\extension_loaded('bcmath')) {
|
||||
return new Calculator\BcMathCalculator();
|
||||
}
|
||||
|
||||
return new Calculator\NativeCalculator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the sign & digits of the operands.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return array{0: bool, 1: bool, 2: string, 3: string} Whether $a and $b are negative, followed by their digits.
|
||||
*/
|
||||
final protected function init(string $a, string $b) : array
|
||||
{
|
||||
return [
|
||||
$aNeg = ($a[0] === '-'),
|
||||
$bNeg = ($b[0] === '-'),
|
||||
|
||||
$aNeg ? \substr($a, 1) : $a,
|
||||
$bNeg ? \substr($b, 1) : $b,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of a number.
|
||||
*
|
||||
* @param string $n The number.
|
||||
*
|
||||
* @return string The absolute value.
|
||||
*/
|
||||
final public function abs(string $n) : string
|
||||
{
|
||||
return ($n[0] === '-') ? \substr($n, 1) : $n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Negates a number.
|
||||
*
|
||||
* @param string $n The number.
|
||||
*
|
||||
* @return string The negated value.
|
||||
*/
|
||||
final public function neg(string $n) : string
|
||||
{
|
||||
if ($n === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if ($n[0] === '-') {
|
||||
return \substr($n, 1);
|
||||
}
|
||||
|
||||
return '-' . $n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two numbers.
|
||||
*
|
||||
* @param string $a The first number.
|
||||
* @param string $b The second number.
|
||||
*
|
||||
* @return int [-1, 0, 1] If the first number is less than, equal to, or greater than the second number.
|
||||
*/
|
||||
final public function cmp(string $a, string $b) : int
|
||||
{
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
if ($aNeg && ! $bNeg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($bNeg && ! $aNeg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$aLen = \strlen($aDig);
|
||||
$bLen = \strlen($bDig);
|
||||
|
||||
if ($aLen < $bLen) {
|
||||
$result = -1;
|
||||
} elseif ($aLen > $bLen) {
|
||||
$result = 1;
|
||||
} else {
|
||||
$result = $aDig <=> $bDig;
|
||||
}
|
||||
|
||||
return $aNeg ? -$result : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds two numbers.
|
||||
*
|
||||
* @param string $a The augend.
|
||||
* @param string $b The addend.
|
||||
*
|
||||
* @return string The sum.
|
||||
*/
|
||||
abstract public function add(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Subtracts two numbers.
|
||||
*
|
||||
* @param string $a The minuend.
|
||||
* @param string $b The subtrahend.
|
||||
*
|
||||
* @return string The difference.
|
||||
*/
|
||||
abstract public function sub(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Multiplies two numbers.
|
||||
*
|
||||
* @param string $a The multiplicand.
|
||||
* @param string $b The multiplier.
|
||||
*
|
||||
* @return string The product.
|
||||
*/
|
||||
abstract public function mul(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Returns the quotient of the division of two numbers.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
*
|
||||
* @return string The quotient.
|
||||
*/
|
||||
abstract public function divQ(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Returns the remainder of the division of two numbers.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
*
|
||||
* @return string The remainder.
|
||||
*/
|
||||
abstract public function divR(string $a, string $b) : string;
|
||||
|
||||
/**
|
||||
* Returns the quotient and remainder of the division of two numbers.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
*
|
||||
* @return string[] An array containing the quotient and remainder.
|
||||
*/
|
||||
abstract public function divQR(string $a, string $b) : array;
|
||||
|
||||
/**
|
||||
* Exponentiates a number.
|
||||
*
|
||||
* @param string $a The base number.
|
||||
* @param int $e The exponent, validated as an integer between 0 and MAX_POWER.
|
||||
*
|
||||
* @return string The power.
|
||||
*/
|
||||
abstract public function pow(string $a, int $e) : string;
|
||||
|
||||
/**
|
||||
* @param string $a
|
||||
* @param string $b The modulus; must not be zero.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mod(string $a, string $b) : string
|
||||
{
|
||||
return $this->divR($this->add($this->divR($a, $b), $b), $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the modular multiplicative inverse of $x modulo $m.
|
||||
*
|
||||
* If $x has no multiplicative inverse mod m, this method must return null.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library has built-in support.
|
||||
*
|
||||
* @param string $x
|
||||
* @param string $m The modulus; must not be negative or zero.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function modInverse(string $x, string $m) : ?string
|
||||
{
|
||||
if ($m === '1') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
$modVal = $x;
|
||||
|
||||
if ($x[0] === '-' || ($this->cmp($this->abs($x), $m) >= 0)) {
|
||||
$modVal = $this->mod($x, $m);
|
||||
}
|
||||
|
||||
$x = '0';
|
||||
$y = '0';
|
||||
$g = $this->gcdExtended($modVal, $m, $x, $y);
|
||||
|
||||
if ($g !== '1') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->mod($this->add($this->mod($x, $m), $m), $m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Raises a number into power with modulo.
|
||||
*
|
||||
* @param string $base The base number; must be positive or zero.
|
||||
* @param string $exp The exponent; must be positive or zero.
|
||||
* @param string $mod The modulus; must be strictly positive.
|
||||
*
|
||||
* @return string The power.
|
||||
*/
|
||||
abstract public function modPow(string $base, string $exp, string $mod) : string;
|
||||
|
||||
/**
|
||||
* Returns the greatest common divisor of the two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for GCD calculations.
|
||||
*
|
||||
* @param string $a The first number.
|
||||
* @param string $b The second number.
|
||||
*
|
||||
* @return string The GCD, always positive, or zero if both arguments are zero.
|
||||
*/
|
||||
public function gcd(string $a, string $b) : string
|
||||
{
|
||||
if ($a === '0') {
|
||||
return $this->abs($b);
|
||||
}
|
||||
|
||||
if ($b === '0') {
|
||||
return $this->abs($a);
|
||||
}
|
||||
|
||||
return $this->gcd($b, $this->divR($a, $b));
|
||||
}
|
||||
|
||||
private function gcdExtended(string $a, string $b, string &$x, string &$y) : string
|
||||
{
|
||||
if ($a === '0') {
|
||||
$x = '0';
|
||||
$y = '1';
|
||||
|
||||
return $b;
|
||||
}
|
||||
|
||||
$x1 = '0';
|
||||
$y1 = '0';
|
||||
|
||||
$gcd = $this->gcdExtended($this->mod($b, $a), $a, $x1, $y1);
|
||||
|
||||
$x = $this->sub($y1, $this->mul($this->divQ($b, $a), $x1));
|
||||
$y = $x1;
|
||||
|
||||
return $gcd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the square root of the given number, rounded down.
|
||||
*
|
||||
* The result is the largest x such that x² ≤ n.
|
||||
* The input MUST NOT be negative.
|
||||
*
|
||||
* @param string $n The number.
|
||||
*
|
||||
* @return string The square root.
|
||||
*/
|
||||
abstract public function sqrt(string $n) : string;
|
||||
|
||||
/**
|
||||
* Converts a number from an arbitrary base.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for base conversion.
|
||||
*
|
||||
* @param string $number The number, positive or zero, non-empty, case-insensitively validated for the given base.
|
||||
* @param int $base The base of the number, validated from 2 to 36.
|
||||
*
|
||||
* @return string The converted number, following the Calculator conventions.
|
||||
*/
|
||||
public function fromBase(string $number, int $base) : string
|
||||
{
|
||||
return $this->fromArbitraryBase(\strtolower($number), self::ALPHABET, $base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a number to an arbitrary base.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for base conversion.
|
||||
*
|
||||
* @param string $number The number to convert, following the Calculator conventions.
|
||||
* @param int $base The base to convert to, validated from 2 to 36.
|
||||
*
|
||||
* @return string The converted number, lowercase.
|
||||
*/
|
||||
public function toBase(string $number, int $base) : string
|
||||
{
|
||||
$negative = ($number[0] === '-');
|
||||
|
||||
if ($negative) {
|
||||
$number = \substr($number, 1);
|
||||
}
|
||||
|
||||
$number = $this->toArbitraryBase($number, self::ALPHABET, $base);
|
||||
|
||||
if ($negative) {
|
||||
return '-' . $number;
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a non-negative number in an arbitrary base using a custom alphabet, to base 10.
|
||||
*
|
||||
* @param string $number The number to convert, validated as a non-empty string,
|
||||
* containing only chars in the given alphabet/base.
|
||||
* @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum.
|
||||
* @param int $base The base of the number, validated from 2 to alphabet length.
|
||||
*
|
||||
* @return string The number in base 10, following the Calculator conventions.
|
||||
*/
|
||||
final public function fromArbitraryBase(string $number, string $alphabet, int $base) : string
|
||||
{
|
||||
// remove leading "zeros"
|
||||
$number = \ltrim($number, $alphabet[0]);
|
||||
|
||||
if ($number === '') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// optimize for "one"
|
||||
if ($number === $alphabet[1]) {
|
||||
return '1';
|
||||
}
|
||||
|
||||
$result = '0';
|
||||
$power = '1';
|
||||
|
||||
$base = (string) $base;
|
||||
|
||||
for ($i = \strlen($number) - 1; $i >= 0; $i--) {
|
||||
$index = \strpos($alphabet, $number[$i]);
|
||||
|
||||
if ($index !== 0) {
|
||||
$result = $this->add($result, ($index === 1)
|
||||
? $power
|
||||
: $this->mul($power, (string) $index)
|
||||
);
|
||||
}
|
||||
|
||||
if ($i !== 0) {
|
||||
$power = $this->mul($power, $base);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a non-negative number to an arbitrary base using a custom alphabet.
|
||||
*
|
||||
* @param string $number The number to convert, positive or zero, following the Calculator conventions.
|
||||
* @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum.
|
||||
* @param int $base The base to convert to, validated from 2 to alphabet length.
|
||||
*
|
||||
* @return string The converted number in the given alphabet.
|
||||
*/
|
||||
final public function toArbitraryBase(string $number, string $alphabet, int $base) : string
|
||||
{
|
||||
if ($number === '0') {
|
||||
return $alphabet[0];
|
||||
}
|
||||
|
||||
$base = (string) $base;
|
||||
$result = '';
|
||||
|
||||
while ($number !== '0') {
|
||||
[$number, $remainder] = $this->divQR($number, $base);
|
||||
$remainder = (int) $remainder;
|
||||
|
||||
$result .= $alphabet[$remainder];
|
||||
}
|
||||
|
||||
return \strrev($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a rounded division.
|
||||
*
|
||||
* Rounding is performed when the remainder of the division is not zero.
|
||||
*
|
||||
* @param string $a The dividend.
|
||||
* @param string $b The divisor, must not be zero.
|
||||
* @param int $roundingMode The rounding mode.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \InvalidArgumentException If the rounding mode is invalid.
|
||||
* @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary.
|
||||
*/
|
||||
final public function divRound(string $a, string $b, int $roundingMode) : string
|
||||
{
|
||||
[$quotient, $remainder] = $this->divQR($a, $b);
|
||||
|
||||
$hasDiscardedFraction = ($remainder !== '0');
|
||||
$isPositiveOrZero = ($a[0] === '-') === ($b[0] === '-');
|
||||
|
||||
$discardedFractionSign = function() use ($remainder, $b) : int {
|
||||
$r = $this->abs($this->mul($remainder, '2'));
|
||||
$b = $this->abs($b);
|
||||
|
||||
return $this->cmp($r, $b);
|
||||
};
|
||||
|
||||
$increment = false;
|
||||
|
||||
switch ($roundingMode) {
|
||||
case RoundingMode::UNNECESSARY:
|
||||
if ($hasDiscardedFraction) {
|
||||
throw RoundingNecessaryException::roundingNecessary();
|
||||
}
|
||||
break;
|
||||
|
||||
case RoundingMode::UP:
|
||||
$increment = $hasDiscardedFraction;
|
||||
break;
|
||||
|
||||
case RoundingMode::DOWN:
|
||||
break;
|
||||
|
||||
case RoundingMode::CEILING:
|
||||
$increment = $hasDiscardedFraction && $isPositiveOrZero;
|
||||
break;
|
||||
|
||||
case RoundingMode::FLOOR:
|
||||
$increment = $hasDiscardedFraction && ! $isPositiveOrZero;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_UP:
|
||||
$increment = $discardedFractionSign() >= 0;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_DOWN:
|
||||
$increment = $discardedFractionSign() > 0;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_CEILING:
|
||||
$increment = $isPositiveOrZero ? $discardedFractionSign() >= 0 : $discardedFractionSign() > 0;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_FLOOR:
|
||||
$increment = $isPositiveOrZero ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0;
|
||||
break;
|
||||
|
||||
case RoundingMode::HALF_EVEN:
|
||||
$lastDigit = (int) $quotient[-1];
|
||||
$lastDigitIsEven = ($lastDigit % 2 === 0);
|
||||
$increment = $lastDigitIsEven ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid rounding mode.');
|
||||
}
|
||||
|
||||
if ($increment) {
|
||||
return $this->add($quotient, $isPositiveOrZero ? '1' : '-1');
|
||||
}
|
||||
|
||||
return $quotient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates bitwise AND of two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for bitwise operations.
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function and(string $a, string $b) : string
|
||||
{
|
||||
return $this->bitwise('and', $a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates bitwise OR of two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for bitwise operations.
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function or(string $a, string $b) : string
|
||||
{
|
||||
return $this->bitwise('or', $a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates bitwise XOR of two numbers.
|
||||
*
|
||||
* This method can be overridden by the concrete implementation if the underlying library
|
||||
* has built-in support for bitwise operations.
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function xor(string $a, string $b) : string
|
||||
{
|
||||
return $this->bitwise('xor', $a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a bitwise operation on a decimal number.
|
||||
*
|
||||
* @param string $operator The operator to use, must be "and", "or" or "xor".
|
||||
* @param string $a The left operand.
|
||||
* @param string $b The right operand.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function bitwise(string $operator, string $a, string $b) : string
|
||||
{
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
$aBin = $this->toBinary($aDig);
|
||||
$bBin = $this->toBinary($bDig);
|
||||
|
||||
$aLen = \strlen($aBin);
|
||||
$bLen = \strlen($bBin);
|
||||
|
||||
if ($aLen > $bLen) {
|
||||
$bBin = \str_repeat("\x00", $aLen - $bLen) . $bBin;
|
||||
} elseif ($bLen > $aLen) {
|
||||
$aBin = \str_repeat("\x00", $bLen - $aLen) . $aBin;
|
||||
}
|
||||
|
||||
if ($aNeg) {
|
||||
$aBin = $this->twosComplement($aBin);
|
||||
}
|
||||
if ($bNeg) {
|
||||
$bBin = $this->twosComplement($bBin);
|
||||
}
|
||||
|
||||
switch ($operator) {
|
||||
case 'and':
|
||||
$value = $aBin & $bBin;
|
||||
$negative = ($aNeg and $bNeg);
|
||||
break;
|
||||
|
||||
case 'or':
|
||||
$value = $aBin | $bBin;
|
||||
$negative = ($aNeg or $bNeg);
|
||||
break;
|
||||
|
||||
case 'xor':
|
||||
$value = $aBin ^ $bBin;
|
||||
$negative = ($aNeg xor $bNeg);
|
||||
break;
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid bitwise operator.');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
if ($negative) {
|
||||
$value = $this->twosComplement($value);
|
||||
}
|
||||
|
||||
$result = $this->toDecimal($value);
|
||||
|
||||
return $negative ? $this->neg($result) : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $number A positive, binary number.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function twosComplement(string $number) : string
|
||||
{
|
||||
$xor = \str_repeat("\xff", \strlen($number));
|
||||
|
||||
$number = $number ^ $xor;
|
||||
|
||||
for ($i = \strlen($number) - 1; $i >= 0; $i--) {
|
||||
$byte = \ord($number[$i]);
|
||||
|
||||
if (++$byte !== 256) {
|
||||
$number[$i] = \chr($byte);
|
||||
break;
|
||||
}
|
||||
|
||||
$number[$i] = "\x00";
|
||||
|
||||
if ($i === 0) {
|
||||
$number = "\x01" . $number;
|
||||
}
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a decimal number to a binary string.
|
||||
*
|
||||
* @param string $number The number to convert, positive or zero, only digits.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function toBinary(string $number) : string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
while ($number !== '0') {
|
||||
[$number, $remainder] = $this->divQR($number, '256');
|
||||
$result .= \chr((int) $remainder);
|
||||
}
|
||||
|
||||
return \strrev($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the positive decimal representation of a binary number.
|
||||
*
|
||||
* @param string $bytes The bytes representing the number.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function toDecimal(string $bytes) : string
|
||||
{
|
||||
$result = '0';
|
||||
$power = '1';
|
||||
|
||||
for ($i = \strlen($bytes) - 1; $i >= 0; $i--) {
|
||||
$index = \ord($bytes[$i]);
|
||||
|
||||
if ($index !== 0) {
|
||||
$result = $this->add($result, ($index === 1)
|
||||
? $power
|
||||
: $this->mul($power, (string) $index)
|
||||
);
|
||||
}
|
||||
|
||||
if ($i !== 0) {
|
||||
$power = $this->mul($power, '256');
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
92
vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php
vendored
Normal file
92
vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal\Calculator;
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
|
||||
/**
|
||||
* Calculator implementation built around the bcmath library.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class BcMathCalculator extends Calculator
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add(string $a, string $b) : string
|
||||
{
|
||||
return \bcadd($a, $b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sub(string $a, string $b) : string
|
||||
{
|
||||
return \bcsub($a, $b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function mul(string $a, string $b) : string
|
||||
{
|
||||
return \bcmul($a, $b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQ(string $a, string $b) : string
|
||||
{
|
||||
return \bcdiv($a, $b, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divR(string $a, string $b) : string
|
||||
{
|
||||
return \bcmod($a, $b);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQR(string $a, string $b) : array
|
||||
{
|
||||
$q = \bcdiv($a, $b, 0);
|
||||
$r = \bcmod($a, $b);
|
||||
|
||||
return [$q, $r];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function pow(string $a, int $e) : string
|
||||
{
|
||||
return \bcpow($a, (string) $e, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function modPow(string $base, string $exp, string $mod) : string
|
||||
{
|
||||
return \bcpowmod($base, $exp, $mod, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function sqrt(string $n) : string
|
||||
{
|
||||
return \bcsqrt($n, 0);
|
||||
}
|
||||
}
|
||||
156
vendor/brick/math/src/Internal/Calculator/GmpCalculator.php
vendored
Normal file
156
vendor/brick/math/src/Internal/Calculator/GmpCalculator.php
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal\Calculator;
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
|
||||
/**
|
||||
* Calculator implementation built around the GMP library.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class GmpCalculator extends Calculator
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_add($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sub(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_sub($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function mul(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_mul($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQ(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_div_q($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divR(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_div_r($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQR(string $a, string $b) : array
|
||||
{
|
||||
[$q, $r] = \gmp_div_qr($a, $b);
|
||||
|
||||
return [
|
||||
\gmp_strval($q),
|
||||
\gmp_strval($r)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function pow(string $a, int $e) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_pow($a, $e));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function modInverse(string $x, string $m) : ?string
|
||||
{
|
||||
$result = \gmp_invert($x, $m);
|
||||
|
||||
if ($result === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return \gmp_strval($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function modPow(string $base, string $exp, string $mod) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_powm($base, $exp, $mod));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function gcd(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_gcd($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fromBase(string $number, int $base) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_init($number, $base));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toBase(string $number, int $base) : string
|
||||
{
|
||||
return \gmp_strval($number, $base);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function and(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_and($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function or(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_or($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function xor(string $a, string $b) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_xor($a, $b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function sqrt(string $n) : string
|
||||
{
|
||||
return \gmp_strval(\gmp_sqrt($n));
|
||||
}
|
||||
}
|
||||
616
vendor/brick/math/src/Internal/Calculator/NativeCalculator.php
vendored
Normal file
616
vendor/brick/math/src/Internal/Calculator/NativeCalculator.php
vendored
Normal file
@@ -0,0 +1,616 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math\Internal\Calculator;
|
||||
|
||||
use Brick\Math\Internal\Calculator;
|
||||
|
||||
/**
|
||||
* Calculator implementation using only native PHP code.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @psalm-immutable
|
||||
*/
|
||||
class NativeCalculator extends Calculator
|
||||
{
|
||||
/**
|
||||
* The max number of digits the platform can natively add, subtract, multiply or divide without overflow.
|
||||
* For multiplication, this represents the max sum of the lengths of both operands.
|
||||
*
|
||||
* For addition, it is assumed that an extra digit can hold a carry (1) without overflowing.
|
||||
* Example: 32-bit: max number 1,999,999,999 (9 digits + carry)
|
||||
* 64-bit: max number 1,999,999,999,999,999,999 (18 digits + carry)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $maxDigits;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
switch (PHP_INT_SIZE) {
|
||||
case 4:
|
||||
$this->maxDigits = 9;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
$this->maxDigits = 18;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \RuntimeException('The platform is not 32-bit or 64-bit as expected.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add(string $a, string $b) : string
|
||||
{
|
||||
$result = $a + $b;
|
||||
|
||||
if (is_int($result)) {
|
||||
return (string) $result;
|
||||
}
|
||||
|
||||
if ($a === '0') {
|
||||
return $b;
|
||||
}
|
||||
|
||||
if ($b === '0') {
|
||||
return $a;
|
||||
}
|
||||
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
if ($aNeg === $bNeg) {
|
||||
$result = $this->doAdd($aDig, $bDig);
|
||||
} else {
|
||||
$result = $this->doSub($aDig, $bDig);
|
||||
}
|
||||
|
||||
if ($aNeg) {
|
||||
$result = $this->neg($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function sub(string $a, string $b) : string
|
||||
{
|
||||
return $this->add($a, $this->neg($b));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function mul(string $a, string $b) : string
|
||||
{
|
||||
$result = $a * $b;
|
||||
|
||||
if (is_int($result)) {
|
||||
return (string) $result;
|
||||
}
|
||||
|
||||
if ($a === '0' || $b === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if ($a === '1') {
|
||||
return $b;
|
||||
}
|
||||
|
||||
if ($b === '1') {
|
||||
return $a;
|
||||
}
|
||||
|
||||
if ($a === '-1') {
|
||||
return $this->neg($b);
|
||||
}
|
||||
|
||||
if ($b === '-1') {
|
||||
return $this->neg($a);
|
||||
}
|
||||
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
$result = $this->doMul($aDig, $bDig);
|
||||
|
||||
if ($aNeg !== $bNeg) {
|
||||
$result = $this->neg($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQ(string $a, string $b) : string
|
||||
{
|
||||
return $this->divQR($a, $b)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divR(string $a, string $b): string
|
||||
{
|
||||
return $this->divQR($a, $b)[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function divQR(string $a, string $b) : array
|
||||
{
|
||||
if ($a === '0') {
|
||||
return ['0', '0'];
|
||||
}
|
||||
|
||||
if ($a === $b) {
|
||||
return ['1', '0'];
|
||||
}
|
||||
|
||||
if ($b === '1') {
|
||||
return [$a, '0'];
|
||||
}
|
||||
|
||||
if ($b === '-1') {
|
||||
return [$this->neg($a), '0'];
|
||||
}
|
||||
|
||||
$na = $a * 1; // cast to number
|
||||
|
||||
if (is_int($na)) {
|
||||
$nb = $b * 1;
|
||||
|
||||
if (is_int($nb)) {
|
||||
// the only division that may overflow is PHP_INT_MIN / -1,
|
||||
// which cannot happen here as we've already handled a divisor of -1 above.
|
||||
$r = $na % $nb;
|
||||
$q = ($na - $r) / $nb;
|
||||
|
||||
assert(is_int($q));
|
||||
|
||||
return [
|
||||
(string) $q,
|
||||
(string) $r
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
[$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b);
|
||||
|
||||
[$q, $r] = $this->doDiv($aDig, $bDig);
|
||||
|
||||
if ($aNeg !== $bNeg) {
|
||||
$q = $this->neg($q);
|
||||
}
|
||||
|
||||
if ($aNeg) {
|
||||
$r = $this->neg($r);
|
||||
}
|
||||
|
||||
return [$q, $r];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function pow(string $a, int $e) : string
|
||||
{
|
||||
if ($e === 0) {
|
||||
return '1';
|
||||
}
|
||||
|
||||
if ($e === 1) {
|
||||
return $a;
|
||||
}
|
||||
|
||||
$odd = $e % 2;
|
||||
$e -= $odd;
|
||||
|
||||
$aa = $this->mul($a, $a);
|
||||
$result = $this->pow($aa, $e / 2);
|
||||
|
||||
if ($odd === 1) {
|
||||
$result = $this->mul($result, $a);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Algorithm from: https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function modPow(string $base, string $exp, string $mod) : string
|
||||
{
|
||||
// special case: the algorithm below fails with 0 power 0 mod 1 (returns 1 instead of 0)
|
||||
if ($base === '0' && $exp === '0' && $mod === '1') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// special case: the algorithm below fails with power 0 mod 1 (returns 1 instead of 0)
|
||||
if ($exp === '0' && $mod === '1') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
$x = $base;
|
||||
|
||||
$res = '1';
|
||||
|
||||
// numbers are positive, so we can use remainder instead of modulo
|
||||
$x = $this->divR($x, $mod);
|
||||
|
||||
while ($exp !== '0') {
|
||||
if (in_array($exp[-1], ['1', '3', '5', '7', '9'])) { // odd
|
||||
$res = $this->divR($this->mul($res, $x), $mod);
|
||||
}
|
||||
|
||||
$exp = $this->divQ($exp, '2');
|
||||
$x = $this->divR($this->mul($x, $x), $mod);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapted from https://cp-algorithms.com/num_methods/roots_newton.html
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function sqrt(string $n) : string
|
||||
{
|
||||
if ($n === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// initial approximation
|
||||
$x = \str_repeat('9', \intdiv(\strlen($n), 2) ?: 1);
|
||||
|
||||
$decreased = false;
|
||||
|
||||
for (;;) {
|
||||
$nx = $this->divQ($this->add($x, $this->divQ($n, $x)), '2');
|
||||
|
||||
if ($x === $nx || $this->cmp($nx, $x) > 0 && $decreased) {
|
||||
break;
|
||||
}
|
||||
|
||||
$decreased = $this->cmp($nx, $x) < 0;
|
||||
$x = $nx;
|
||||
}
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the addition of two non-signed large integers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function doAdd(string $a, string $b) : string
|
||||
{
|
||||
[$a, $b, $length] = $this->pad($a, $b);
|
||||
|
||||
$carry = 0;
|
||||
$result = '';
|
||||
|
||||
for ($i = $length - $this->maxDigits;; $i -= $this->maxDigits) {
|
||||
$blockLength = $this->maxDigits;
|
||||
|
||||
if ($i < 0) {
|
||||
$blockLength += $i;
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
$blockA = \substr($a, $i, $blockLength);
|
||||
$blockB = \substr($b, $i, $blockLength);
|
||||
|
||||
$sum = (string) ($blockA + $blockB + $carry);
|
||||
$sumLength = \strlen($sum);
|
||||
|
||||
if ($sumLength > $blockLength) {
|
||||
$sum = \substr($sum, 1);
|
||||
$carry = 1;
|
||||
} else {
|
||||
if ($sumLength < $blockLength) {
|
||||
$sum = \str_repeat('0', $blockLength - $sumLength) . $sum;
|
||||
}
|
||||
$carry = 0;
|
||||
}
|
||||
|
||||
$result = $sum . $result;
|
||||
|
||||
if ($i === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($carry === 1) {
|
||||
$result = '1' . $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the subtraction of two non-signed large integers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function doSub(string $a, string $b) : string
|
||||
{
|
||||
if ($a === $b) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
// Ensure that we always subtract to a positive result: biggest minus smallest.
|
||||
$cmp = $this->doCmp($a, $b);
|
||||
|
||||
$invert = ($cmp === -1);
|
||||
|
||||
if ($invert) {
|
||||
$c = $a;
|
||||
$a = $b;
|
||||
$b = $c;
|
||||
}
|
||||
|
||||
[$a, $b, $length] = $this->pad($a, $b);
|
||||
|
||||
$carry = 0;
|
||||
$result = '';
|
||||
|
||||
$complement = 10 ** $this->maxDigits;
|
||||
|
||||
for ($i = $length - $this->maxDigits;; $i -= $this->maxDigits) {
|
||||
$blockLength = $this->maxDigits;
|
||||
|
||||
if ($i < 0) {
|
||||
$blockLength += $i;
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
$blockA = \substr($a, $i, $blockLength);
|
||||
$blockB = \substr($b, $i, $blockLength);
|
||||
|
||||
$sum = $blockA - $blockB - $carry;
|
||||
|
||||
if ($sum < 0) {
|
||||
$sum += $complement;
|
||||
$carry = 1;
|
||||
} else {
|
||||
$carry = 0;
|
||||
}
|
||||
|
||||
$sum = (string) $sum;
|
||||
$sumLength = \strlen($sum);
|
||||
|
||||
if ($sumLength < $blockLength) {
|
||||
$sum = \str_repeat('0', $blockLength - $sumLength) . $sum;
|
||||
}
|
||||
|
||||
$result = $sum . $result;
|
||||
|
||||
if ($i === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Carry cannot be 1 when the loop ends, as a > b
|
||||
assert($carry === 0);
|
||||
|
||||
$result = \ltrim($result, '0');
|
||||
|
||||
if ($invert) {
|
||||
$result = $this->neg($result);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the multiplication of two non-signed large integers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function doMul(string $a, string $b) : string
|
||||
{
|
||||
$x = \strlen($a);
|
||||
$y = \strlen($b);
|
||||
|
||||
$maxDigits = \intdiv($this->maxDigits, 2);
|
||||
$complement = 10 ** $maxDigits;
|
||||
|
||||
$result = '0';
|
||||
|
||||
for ($i = $x - $maxDigits;; $i -= $maxDigits) {
|
||||
$blockALength = $maxDigits;
|
||||
|
||||
if ($i < 0) {
|
||||
$blockALength += $i;
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
$blockA = (int) \substr($a, $i, $blockALength);
|
||||
|
||||
$line = '';
|
||||
$carry = 0;
|
||||
|
||||
for ($j = $y - $maxDigits;; $j -= $maxDigits) {
|
||||
$blockBLength = $maxDigits;
|
||||
|
||||
if ($j < 0) {
|
||||
$blockBLength += $j;
|
||||
$j = 0;
|
||||
}
|
||||
|
||||
$blockB = (int) \substr($b, $j, $blockBLength);
|
||||
|
||||
$mul = $blockA * $blockB + $carry;
|
||||
$value = $mul % $complement;
|
||||
$carry = ($mul - $value) / $complement;
|
||||
|
||||
$value = (string) $value;
|
||||
$value = \str_pad($value, $maxDigits, '0', STR_PAD_LEFT);
|
||||
|
||||
$line = $value . $line;
|
||||
|
||||
if ($j === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($carry !== 0) {
|
||||
$line = $carry . $line;
|
||||
}
|
||||
|
||||
$line = \ltrim($line, '0');
|
||||
|
||||
if ($line !== '') {
|
||||
$line .= \str_repeat('0', $x - $blockALength - $i);
|
||||
$result = $this->add($result, $line);
|
||||
}
|
||||
|
||||
if ($i === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the division of two non-signed large integers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return string[] The quotient and remainder.
|
||||
*/
|
||||
private function doDiv(string $a, string $b) : array
|
||||
{
|
||||
$cmp = $this->doCmp($a, $b);
|
||||
|
||||
if ($cmp === -1) {
|
||||
return ['0', $a];
|
||||
}
|
||||
|
||||
$x = \strlen($a);
|
||||
$y = \strlen($b);
|
||||
|
||||
// we now know that a >= b && x >= y
|
||||
|
||||
$q = '0'; // quotient
|
||||
$r = $a; // remainder
|
||||
$z = $y; // focus length, always $y or $y+1
|
||||
|
||||
for (;;) {
|
||||
$focus = \substr($a, 0, $z);
|
||||
|
||||
$cmp = $this->doCmp($focus, $b);
|
||||
|
||||
if ($cmp === -1) {
|
||||
if ($z === $x) { // remainder < dividend
|
||||
break;
|
||||
}
|
||||
|
||||
$z++;
|
||||
}
|
||||
|
||||
$zeros = \str_repeat('0', $x - $z);
|
||||
|
||||
$q = $this->add($q, '1' . $zeros);
|
||||
$a = $this->sub($a, $b . $zeros);
|
||||
|
||||
$r = $a;
|
||||
|
||||
if ($r === '0') { // remainder == 0
|
||||
break;
|
||||
}
|
||||
|
||||
$x = \strlen($a);
|
||||
|
||||
if ($x < $y) { // remainder < dividend
|
||||
break;
|
||||
}
|
||||
|
||||
$z = $y;
|
||||
}
|
||||
|
||||
return [$q, $r];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two non-signed large numbers.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return int [-1, 0, 1]
|
||||
*/
|
||||
private function doCmp(string $a, string $b) : int
|
||||
{
|
||||
$x = \strlen($a);
|
||||
$y = \strlen($b);
|
||||
|
||||
$cmp = $x <=> $y;
|
||||
|
||||
if ($cmp !== 0) {
|
||||
return $cmp;
|
||||
}
|
||||
|
||||
return \strcmp($a, $b) <=> 0; // enforce [-1, 0, 1]
|
||||
}
|
||||
|
||||
/**
|
||||
* Pads the left of one of the given numbers with zeros if necessary to make both numbers the same length.
|
||||
*
|
||||
* The numbers must only consist of digits, without leading minus sign.
|
||||
*
|
||||
* @param string $a The first operand.
|
||||
* @param string $b The second operand.
|
||||
*
|
||||
* @return array{0: string, 1: string, 2: int}
|
||||
*/
|
||||
private function pad(string $a, string $b) : array
|
||||
{
|
||||
$x = \strlen($a);
|
||||
$y = \strlen($b);
|
||||
|
||||
if ($x > $y) {
|
||||
$b = \str_repeat('0', $x - $y) . $b;
|
||||
|
||||
return [$a, $b, $x];
|
||||
}
|
||||
|
||||
if ($x < $y) {
|
||||
$a = \str_repeat('0', $y - $x) . $a;
|
||||
|
||||
return [$a, $b, $y];
|
||||
}
|
||||
|
||||
return [$a, $b, $x];
|
||||
}
|
||||
}
|
||||
107
vendor/brick/math/src/RoundingMode.php
vendored
Normal file
107
vendor/brick/math/src/RoundingMode.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
/**
|
||||
* Specifies a rounding behavior for numerical operations capable of discarding precision.
|
||||
*
|
||||
* Each rounding mode indicates how the least significant returned digit of a rounded result
|
||||
* is to be calculated. If fewer digits are returned than the digits needed to represent the
|
||||
* exact numerical result, the discarded digits will be referred to as the discarded fraction
|
||||
* regardless the digits' contribution to the value of the number. In other words, considered
|
||||
* as a numerical value, the discarded fraction could have an absolute value greater than one.
|
||||
*/
|
||||
final class RoundingMode
|
||||
{
|
||||
/**
|
||||
* Private constructor. This class is not instantiable.
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the requested operation has an exact result, hence no rounding is necessary.
|
||||
*
|
||||
* If this rounding mode is specified on an operation that yields a result that
|
||||
* cannot be represented at the requested scale, a RoundingNecessaryException is thrown.
|
||||
*/
|
||||
public const UNNECESSARY = 0;
|
||||
|
||||
/**
|
||||
* Rounds away from zero.
|
||||
*
|
||||
* Always increments the digit prior to a nonzero discarded fraction.
|
||||
* Note that this rounding mode never decreases the magnitude of the calculated value.
|
||||
*/
|
||||
public const UP = 1;
|
||||
|
||||
/**
|
||||
* Rounds towards zero.
|
||||
*
|
||||
* Never increments the digit prior to a discarded fraction (i.e., truncates).
|
||||
* Note that this rounding mode never increases the magnitude of the calculated value.
|
||||
*/
|
||||
public const DOWN = 2;
|
||||
|
||||
/**
|
||||
* Rounds towards positive infinity.
|
||||
*
|
||||
* If the result is positive, behaves as for UP; if negative, behaves as for DOWN.
|
||||
* Note that this rounding mode never decreases the calculated value.
|
||||
*/
|
||||
public const CEILING = 3;
|
||||
|
||||
/**
|
||||
* Rounds towards negative infinity.
|
||||
*
|
||||
* If the result is positive, behave as for DOWN; if negative, behave as for UP.
|
||||
* Note that this rounding mode never increases the calculated value.
|
||||
*/
|
||||
public const FLOOR = 4;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
|
||||
*
|
||||
* Behaves as for UP if the discarded fraction is >= 0.5; otherwise, behaves as for DOWN.
|
||||
* Note that this is the rounding mode commonly taught at school.
|
||||
*/
|
||||
public const HALF_UP = 5;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
|
||||
*
|
||||
* Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN.
|
||||
*/
|
||||
public const HALF_DOWN = 6;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive infinity.
|
||||
*
|
||||
* If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN.
|
||||
*/
|
||||
public const HALF_CEILING = 7;
|
||||
|
||||
/**
|
||||
* Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative infinity.
|
||||
*
|
||||
* If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP.
|
||||
*/
|
||||
public const HALF_FLOOR = 8;
|
||||
|
||||
/**
|
||||
* Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the even neighbor.
|
||||
*
|
||||
* Behaves as for HALF_UP if the digit to the left of the discarded fraction is odd;
|
||||
* behaves as for HALF_DOWN if it's even.
|
||||
*
|
||||
* Note that this is the rounding mode that statistically minimizes
|
||||
* cumulative error when applied repeatedly over a sequence of calculations.
|
||||
* It is sometimes known as "Banker's rounding", and is chiefly used in the USA.
|
||||
*/
|
||||
public const HALF_EVEN = 9;
|
||||
}
|
||||
9
vendor/cakephp/chronos/.appveyor.yml
vendored
9
vendor/cakephp/chronos/.appveyor.yml
vendored
@@ -6,6 +6,8 @@ clone_folder: c:\projects\chronos
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- 1.x
|
||||
- 2.next
|
||||
|
||||
environment:
|
||||
global:
|
||||
@@ -16,17 +18,18 @@ init:
|
||||
|
||||
install:
|
||||
- cd c:\
|
||||
- curl -fsS https://windows.php.net/downloads/releases/archives/php-5.6.40-nts-Win32-VC11-x86.zip -o php.zip
|
||||
- curl -fsS https://windows.php.net/downloads/releases/latest/php-7.2-nts-Win32-VC15-x86-latest.zip -o php.zip
|
||||
- 7z x php.zip -oc:\php
|
||||
- cd c:\php
|
||||
- copy php.ini-production php.ini
|
||||
- echo date.timezone="UTC" >> php.ini
|
||||
- echo extension_dir=ext >> php.ini
|
||||
- echo extension=php_openssl.dll >> php.ini
|
||||
- echo extension=mbstring >> php.ini
|
||||
- echo extension=intl >> php.ini
|
||||
- echo extension=fileinfo >> php.ini
|
||||
- cd C:\projects\chronos
|
||||
- appveyor DownloadFile https://getcomposer.org/composer.phar
|
||||
# phpstan requires php 7.0. While here used php 5.5 we can't install it
|
||||
- php composer.phar remove --dev phpstan/phpstan
|
||||
- php composer.phar install --prefer-dist --no-interaction --ansi --no-progress
|
||||
|
||||
test_script:
|
||||
|
||||
2
vendor/cakephp/chronos/.coveralls.yml
vendored
Normal file
2
vendor/cakephp/chronos/.coveralls.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
coverage_clover: clover.xml
|
||||
json_path: coveralls-upload.json
|
||||
28
vendor/cakephp/chronos/README.md
vendored
28
vendor/cakephp/chronos/README.md
vendored
@@ -1,9 +1,10 @@
|
||||
# CakePHP Chronos
|
||||
|
||||
[](https://travis-ci.com/cakephp/chronos)
|
||||
[](https://packagist.org/packages/cakephp/chronos)
|
||||
[](https://packagist.org/packages/cakephp/chronos/stats)
|
||||
[](https://coveralls.io/r/cakephp/chronos?branch=master)
|
||||
[](LICENSE)
|
||||
[](https://travis-ci.org/cakephp/chronos)
|
||||
[](https://coveralls.io/r/cakephp/chronos?branch=master)
|
||||
[](https://packagist.org/packages/cakephp/chronos)
|
||||
|
||||
Chronos aims to be a drop-in replacement for `nesbot/carbon`. It focuses on providing
|
||||
immutable date/datetime objects. Immutable objects help ensure that datetime objects
|
||||
@@ -37,16 +38,14 @@ since developers don't have to manually copy the instance every time they need a
|
||||
Another important feature it offers is the `Date` class, which is used for representing dates without time (calendar dates).
|
||||
Any time method called on this type of object is basically a no-op.
|
||||
|
||||
A minor but still noticeable difference is that `Chronos` has no external dependencies, it is completely standalone.
|
||||
|
||||
There are other implementation changes, but one that users might not notice is ``Chronos`` considers Monday as
|
||||
the start of the week instead of Sunday. This follows the ISO-8601 and current versions of PHP 5.6 and PHP 7.
|
||||
|
||||
A minor but still noticeable difference is that `Chronos` has no external dependencies, it is completely standalone.
|
||||
|
||||
Finally, Chronos is faster than Carbon as it has been optimized for the creation of hundreds of instances with minimal
|
||||
overhead.
|
||||
|
||||
Chronos also strives for HHVM compatibility, this library can be used safely with HHVM 3.11.
|
||||
|
||||
# Migrating from Carbon
|
||||
|
||||
|
||||
@@ -121,10 +120,11 @@ $fixed = $date->toImmutable();
|
||||
|
||||
# Calendar Dates
|
||||
|
||||
PHP only offers datetime objects as part of the native extensions. Chronos
|
||||
adds a number of conveniences to the traditional DateTime object and introduces
|
||||
a `Date` object. `Date` instances offer compatibility with the `ChronosInterface`, but
|
||||
have their time & timezone frozen to `00:00:00 UTC`. This makes them ideal when working with
|
||||
PHP only offers datetime objects as part of the native extensions. Chronos adds
|
||||
a number of conveniences to the traditional DateTime object and introduces
|
||||
a `Date` object. `Date` instances offer compatibility with the
|
||||
`ChronosInterface`, but have their time frozen to `00:00:00` and the timezone
|
||||
set to the server default timezone. This makes them ideal when working with
|
||||
calendar dates as the time components will always match.
|
||||
|
||||
```php
|
||||
@@ -138,12 +138,12 @@ echo $today->modify('+3 hours');
|
||||
// Outputs '2015-10-21'
|
||||
```
|
||||
|
||||
Like instances of `Chronos`, `Date` objects are also *immutable*. The `MutableDate` class provides
|
||||
a mutable variant of `Date`.
|
||||
Like instances of `Chronos`, `Date` objects are also *immutable*. The
|
||||
`MutableDate` class provides a mutable variant of `Date`.
|
||||
|
||||
# Documentation
|
||||
|
||||
A more descriptive documentation can be found at [book.cakephp.org/chronos/1.x/en/](https://book.cakephp.org/chronos/1.x/en/).
|
||||
A more descriptive documentation can be found at [book.cakephp.org/chronos/2/en/](https://book.cakephp.org/chronos/2/en/).
|
||||
|
||||
# API Documentation
|
||||
|
||||
|
||||
118
vendor/cakephp/chronos/composer.json
vendored
118
vendor/cakephp/chronos/composer.json
vendored
@@ -1,62 +1,62 @@
|
||||
{
|
||||
"name": "cakephp/chronos",
|
||||
"type": "library",
|
||||
"description": "A simple API extension for DateTime.",
|
||||
"keywords": [
|
||||
"date",
|
||||
"time",
|
||||
"DateTime"
|
||||
],
|
||||
"homepage": "http://cakephp.org",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brian Nesbitt",
|
||||
"email": "brian@nesbot.com",
|
||||
"homepage": "http://nesbot.com"
|
||||
},
|
||||
{
|
||||
"name": "The CakePHP Team",
|
||||
"homepage": "http://cakephp.org"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/cakephp/chronos/issues",
|
||||
"irc": "irc://irc.freenode.org/cakephp",
|
||||
"source": "https://github.com/cakephp/chronos"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "<6.0 || ^7.0",
|
||||
"athletic/athletic": "~0.1",
|
||||
"cakephp/cakephp-codesniffer": "^3.0",
|
||||
"phpbench/phpbench": "@dev"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cake\\Chronos\\": "src/"
|
||||
},
|
||||
"files": ["src/carbon_compat.php"]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Cake\\Chronos\\Test\\": "tests/"
|
||||
},
|
||||
"files": ["tests/TestCase.php"]
|
||||
},
|
||||
"scripts": {
|
||||
"check": [
|
||||
"@test",
|
||||
"@cs-check",
|
||||
"@phpstan"
|
||||
"name": "cakephp/chronos",
|
||||
"type": "library",
|
||||
"description": "A simple API extension for DateTime.",
|
||||
"keywords": [
|
||||
"date",
|
||||
"time",
|
||||
"DateTime"
|
||||
],
|
||||
"test": "phpunit",
|
||||
"cs-check": "phpcs",
|
||||
"cs-fix": "phpcbf",
|
||||
"bench": "phpbench run",
|
||||
"phpstan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan-shim:^0.11 && mv composer.backup composer.json",
|
||||
"phpstan": "phpstan analyze -c phpstan.neon -l 3 src/"
|
||||
}
|
||||
"homepage": "http://cakephp.org",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brian Nesbitt",
|
||||
"email": "brian@nesbot.com",
|
||||
"homepage": "http://nesbot.com"
|
||||
},
|
||||
{
|
||||
"name": "The CakePHP Team",
|
||||
"homepage": "http://cakephp.org"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/cakephp/chronos/issues",
|
||||
"irc": "irc://irc.freenode.org/cakephp",
|
||||
"source": "https://github.com/cakephp/chronos"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.0",
|
||||
"cakephp/cakephp-codesniffer": "^4.0",
|
||||
"phpbench/phpbench": "^1.0@dev"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Cake\\Chronos\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/carbon_compat.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Cake\\Chronos\\Test\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"check": [
|
||||
"@test",
|
||||
"@cs-check",
|
||||
"@phpstan"
|
||||
],
|
||||
"test": "phpunit",
|
||||
"cs-check": "phpcs",
|
||||
"cs-fix": "phpcbf",
|
||||
"benchmark": "phpbench run --report=chronos",
|
||||
"phpstan": "phpstan analyze -c phpstan.neon src/",
|
||||
"phpstan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:^0.12 && mv composer.backup composer.json"
|
||||
}
|
||||
}
|
||||
|
||||
11
vendor/cakephp/chronos/docs/config/all.py
vendored
11
vendor/cakephp/chronos/docs/config/all.py
vendored
@@ -10,10 +10,10 @@ from cakephpsphinx.config.all import *
|
||||
#
|
||||
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.x'
|
||||
release = '2.x'
|
||||
|
||||
# The search index version.
|
||||
search_version = 'chronos-1'
|
||||
search_version = 'chronos-2'
|
||||
|
||||
# The marketing display name for the book.
|
||||
version_name = ''
|
||||
@@ -23,7 +23,8 @@ project = 'Chronos'
|
||||
|
||||
# Other versions that display in the version picker menu.
|
||||
version_list = [
|
||||
{'name': '1.x', 'number': '/chronos/1.x', 'title': '1.x', 'current': True},
|
||||
{'name': '1.x', 'number': '/chronos/1', 'title': '1.x'},
|
||||
{'name': '2.x', 'number': '/chronos/2', 'title': '2.x', 'current': True},
|
||||
]
|
||||
|
||||
# Languages available.
|
||||
@@ -31,10 +32,10 @@ languages = ['en', 'fr', 'ja', 'pt']
|
||||
|
||||
# The GitHub branch name for this version of the docs
|
||||
# for edit links to point at.
|
||||
branch = 'master'
|
||||
branch = '2.x'
|
||||
|
||||
# Current version being built
|
||||
version = '1.x'
|
||||
version = '2.x'
|
||||
|
||||
# Language in use for this directory.
|
||||
language = 'en'
|
||||
|
||||
14
vendor/cakephp/chronos/docs/en/index.rst
vendored
14
vendor/cakephp/chronos/docs/en/index.rst
vendored
@@ -16,7 +16,7 @@ To install Chronos, you should use ``composer``. From your
|
||||
application's ROOT directory (where composer.json file is located) run the
|
||||
following::
|
||||
|
||||
php composer.phar require cakephp/chronos "@stable"
|
||||
php composer.phar require "cakephp/chronos:^2.0"
|
||||
|
||||
Overview
|
||||
--------
|
||||
@@ -111,6 +111,14 @@ methods operate at the day resolution::
|
||||
// Outputs '2015-12-20'
|
||||
echo $today;
|
||||
|
||||
Although ``Date`` uses a fixed time zone internally, you can specify which
|
||||
time zone to use for current time such as ``now()`` or ``today()``::
|
||||
|
||||
use Cake\Chronos\Date:
|
||||
|
||||
// Takes the current date from Asia/Tokyo time zone
|
||||
$today = Date::today('Asia/Tokyo');
|
||||
|
||||
Modifier Methods
|
||||
----------------
|
||||
|
||||
@@ -265,19 +273,19 @@ Extracting Date Components
|
||||
|
||||
Getting parts of a date object can be done by directly accessing properties::
|
||||
|
||||
$time = new Chronos('2015-12-31 23:59:58');
|
||||
$time = new Chronos('2015-12-31 23:59:58.123');
|
||||
$time->year; // 2015
|
||||
$time->month; // 12
|
||||
$time->day; // 31
|
||||
$time->hour // 23
|
||||
$time->minute // 59
|
||||
$time->second // 58
|
||||
$time->micro // 123
|
||||
|
||||
Other properties that can be accessed are:
|
||||
|
||||
- timezone
|
||||
- timezoneName
|
||||
- micro
|
||||
- dayOfWeek
|
||||
- dayOfMonth
|
||||
- dayOfYear
|
||||
|
||||
47
vendor/cakephp/chronos/src/Chronos.php
vendored
47
vendor/cakephp/chronos/src/Chronos.php
vendored
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -28,10 +30,11 @@ use DateTimeZone;
|
||||
* @property-read int $hour
|
||||
* @property-read int $minute
|
||||
* @property-read int $second
|
||||
* @property-read int $timestamp seconds since the Unix Epoch
|
||||
* @property-read DateTimeZone $timezone the current timezone
|
||||
* @property-read DateTimeZone $tz alias of timezone
|
||||
* @property-read int $micro
|
||||
* @property-read int $microsecond
|
||||
* @property-read int $timestamp seconds since the Unix Epoch
|
||||
* @property-read \DateTimeZone $timezone the current timezone
|
||||
* @property-read \DateTimeZone $tz alias of timezone
|
||||
* @property-read int $dayOfWeek 1 (for Monday) through 7 (for Sunday)
|
||||
* @property-read int $dayOfYear 0 through 365
|
||||
* @property-read int $weekOfMonth 1 through 5
|
||||
@@ -64,7 +67,7 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
* There is a single test now for all date/time classes provided by Chronos.
|
||||
* This aims to emulate stubbing out 'now' which is a single global fact.
|
||||
*
|
||||
* @var \Cake\Chronos\ChronosInterface
|
||||
* @var \Cake\Chronos\ChronosInterface|null
|
||||
*/
|
||||
protected static $testNow;
|
||||
|
||||
@@ -81,7 +84,7 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
* Please see the testing aids section (specifically static::setTestNow())
|
||||
* for more on the possibility of this constructor returning a test instance.
|
||||
*
|
||||
* @param string|null $time Fixed or relative time
|
||||
* @param \DateTime|\DateTimeImmutable|string|int|null $time Fixed or relative time
|
||||
* @param \DateTimeZone|string|null $tz The timezone for the instance
|
||||
*/
|
||||
public function __construct($time = 'now', $tz = null)
|
||||
@@ -90,10 +93,14 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
$tz = $tz instanceof DateTimeZone ? $tz : new DateTimeZone($tz);
|
||||
}
|
||||
|
||||
if ($time instanceof \DateTimeInterface) {
|
||||
$time = $time->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
static::$_lastErrors = [];
|
||||
$testNow = static::getTestNow();
|
||||
if ($testNow === null) {
|
||||
parent::__construct($time === null ? 'now' : $time, $tz);
|
||||
parent::__construct($time ?? 'now', $tz);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -106,13 +113,13 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
}
|
||||
|
||||
$testNow = clone $testNow;
|
||||
if ($relative) {
|
||||
$testNow = $testNow->modify($time);
|
||||
$relativetime = static::isTimeExpression($time);
|
||||
if (!$relativetime && $tz !== $testNow->getTimezone()) {
|
||||
$testNow = $testNow->setTimezone($tz ?? date_default_timezone_get());
|
||||
}
|
||||
|
||||
$relativeTime = static::isTimeExpression($time);
|
||||
if (!$relativeTime && $tz !== $testNow->getTimezone()) {
|
||||
$testNow = $testNow->setTimezone($tz === null ? date_default_timezone_get() : $tz);
|
||||
if ($relative) {
|
||||
$testNow = $testNow->modify($time);
|
||||
}
|
||||
|
||||
$time = $testNow->format('Y-m-d H:i:s.u');
|
||||
@@ -124,7 +131,7 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
*
|
||||
* @return \Cake\Chronos\MutableDateTime
|
||||
*/
|
||||
public function toMutable()
|
||||
public function toMutable(): MutableDateTime
|
||||
{
|
||||
return MutableDateTime::instance($this);
|
||||
}
|
||||
@@ -132,11 +139,11 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
/**
|
||||
* Get a copy of the instance
|
||||
*
|
||||
* @return $this
|
||||
* @return static
|
||||
*/
|
||||
public function copy()
|
||||
public function copy(): ChronosInterface
|
||||
{
|
||||
return $this;
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,7 +164,7 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
* @param \Cake\Chronos\ChronosInterface|string|null $testNow The instance to use for all future instances.
|
||||
* @return void
|
||||
*/
|
||||
public static function setTestNow($testNow = null)
|
||||
public static function setTestNow($testNow = null): void
|
||||
{
|
||||
static::$testNow = is_string($testNow) ? static::parse($testNow) : $testNow;
|
||||
}
|
||||
@@ -166,9 +173,9 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
* Get the ChronosInterface instance (real or mock) to be returned when a "now"
|
||||
* instance is created.
|
||||
*
|
||||
* @return \Cake\Chronos\ChronosInterface The current instance used for testing
|
||||
* @return \Cake\Chronos\ChronosInterface|null The current instance used for testing
|
||||
*/
|
||||
public static function getTestNow()
|
||||
public static function getTestNow(): ?ChronosInterface
|
||||
{
|
||||
return static::$testNow;
|
||||
}
|
||||
@@ -179,7 +186,7 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
*
|
||||
* @return bool True if there is a test instance, otherwise false
|
||||
*/
|
||||
public static function hasTestNow()
|
||||
public static function hasTestNow(): bool
|
||||
{
|
||||
return static::$testNow !== null;
|
||||
}
|
||||
@@ -189,7 +196,7 @@ class Chronos extends DateTimeImmutable implements ChronosInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo()
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
$properties = [
|
||||
'hasFixedNow' => static::hasTestNow(),
|
||||
|
||||
545
vendor/cakephp/chronos/src/ChronosInterface.php
vendored
545
vendor/cakephp/chronos/src/ChronosInterface.php
vendored
File diff suppressed because it is too large
Load Diff
188
vendor/cakephp/chronos/src/ChronosInterval.php
vendored
188
vendor/cakephp/chronos/src/ChronosInterval.php
vendored
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -12,6 +14,7 @@
|
||||
*/
|
||||
namespace Cake\Chronos;
|
||||
|
||||
use BadMethodCallException;
|
||||
use DateInterval;
|
||||
use InvalidArgumentException;
|
||||
|
||||
@@ -27,61 +30,61 @@ use InvalidArgumentException;
|
||||
* @property int $hours Total hours of the current interval.
|
||||
* @property int $minutes Total minutes of the current interval.
|
||||
* @property int $seconds Total seconds of the current interval.
|
||||
*
|
||||
* @property int $microseconds Total microseconds of the current interval.
|
||||
* @property-read int $dayzExcludeWeeks Total days remaining in the final week of the current instance (days % 7).
|
||||
* @property-read int $daysExcludeWeeks alias of dayzExcludeWeeks
|
||||
*
|
||||
* @method static ChronosInterval years($years = 1) Create instance specifying a number of years.
|
||||
* @method static ChronosInterval year($years = 1) Alias for years
|
||||
* @method static ChronosInterval months($months = 1) Create instance specifying a number of months.
|
||||
* @method static ChronosInterval month($months = 1) Alias for months
|
||||
* @method static ChronosInterval weeks($weeks = 1) Create instance specifying a number of weeks.
|
||||
* @method static ChronosInterval week($weeks = 1) Alias for weeks
|
||||
* @method static ChronosInterval days($days = 1) Create instance specifying a number of days.
|
||||
* @method static ChronosInterval dayz($days = 1) Alias for days
|
||||
* @method static ChronosInterval day($days = 1) Alias for days
|
||||
* @method static ChronosInterval hours($hours = 1) Create instance specifying a number of hours.
|
||||
* @method static ChronosInterval hour($hours = 1) Alias for hours
|
||||
* @method static ChronosInterval minutes($minutes = 1) Create instance specifying a number of minutes.
|
||||
* @method static ChronosInterval minute($minutes = 1) Alias for minutes
|
||||
* @method static ChronosInterval seconds($seconds = 1) Create instance specifying a number of seconds.
|
||||
* @method static ChronosInterval second($seconds = 1) Alias for seconds
|
||||
*
|
||||
* @method ChronosInterval years() years($years = 1) Set the years portion of the current interval.
|
||||
* @method ChronosInterval year() year($years = 1) Alias for years.
|
||||
* @method ChronosInterval months() months($months = 1) Set the months portion of the current interval.
|
||||
* @method ChronosInterval month() month($months = 1) Alias for months.
|
||||
* @method ChronosInterval weeks() weeks($weeks = 1) Set the weeks portion of the current interval. Will overwrite dayz value.
|
||||
* @method ChronosInterval week() week($weeks = 1) Alias for weeks.
|
||||
* @method ChronosInterval days() days($days = 1) Set the days portion of the current interval.
|
||||
* @method ChronosInterval dayz() dayz($days = 1) Alias for days.
|
||||
* @method ChronosInterval day() day($days = 1) Alias for days.
|
||||
* @method ChronosInterval hours() hours($hours = 1) Set the hours portion of the current interval.
|
||||
* @method ChronosInterval hour() hour($hours = 1) Alias for hours.
|
||||
* @method ChronosInterval minutes() minutes($minutes = 1) Set the minutes portion of the current interval.
|
||||
* @method ChronosInterval minute() minute($minutes = 1) Alias for minutes.
|
||||
* @method ChronosInterval seconds() seconds($seconds = 1) Set the seconds portion of the current interval.
|
||||
* @method ChronosInterval second() second($seconds = 1) Alias for seconds.
|
||||
* @method static \Cake\Chronos\ChronosInterval years($years = 1) Create instance specifying a number of years.
|
||||
* @method static \Cake\Chronos\ChronosInterval year($years = 1) Alias for years
|
||||
* @method static \Cake\Chronos\ChronosInterval months($months = 1) Create instance specifying a number of months.
|
||||
* @method static \Cake\Chronos\ChronosInterval month($months = 1) Alias for months
|
||||
* @method static \Cake\Chronos\ChronosInterval weeks($weeks = 1) Create instance specifying a number of weeks.
|
||||
* @method static \Cake\Chronos\ChronosInterval week($weeks = 1) Alias for weeks
|
||||
* @method static \Cake\Chronos\ChronosInterval days($days = 1) Create instance specifying a number of days.
|
||||
* @method static \Cake\Chronos\ChronosInterval dayz($days = 1) Alias for days
|
||||
* @method static \Cake\Chronos\ChronosInterval day($days = 1) Alias for days
|
||||
* @method static \Cake\Chronos\ChronosInterval hours($hours = 1) Create instance specifying a number of hours.
|
||||
* @method static \Cake\Chronos\ChronosInterval hour($hours = 1) Alias for hours
|
||||
* @method static \Cake\Chronos\ChronosInterval minutes($minutes = 1) Create instance specifying a number of minutes.
|
||||
* @method static \Cake\Chronos\ChronosInterval minute($minutes = 1) Alias for minutes
|
||||
* @method static \Cake\Chronos\ChronosInterval seconds($seconds = 1) Create instance specifying a number of seconds.
|
||||
* @method static \Cake\Chronos\ChronosInterval second($seconds = 1) Alias for seconds
|
||||
* @method static \Cake\Chronos\ChronosInterval microseconds($microseconds = 1) Create instance specifying a number of microseconds.
|
||||
* @method static \Cake\Chronos\ChronosInterval microsecond($microseconds = 1) Alias for microseconds
|
||||
*/
|
||||
class ChronosInterval extends DateInterval
|
||||
{
|
||||
/**
|
||||
* Interval spec period designators
|
||||
* @var string
|
||||
*/
|
||||
const PERIOD_PREFIX = 'P';
|
||||
const PERIOD_YEARS = 'Y';
|
||||
const PERIOD_MONTHS = 'M';
|
||||
const PERIOD_DAYS = 'D';
|
||||
const PERIOD_TIME_PREFIX = 'T';
|
||||
const PERIOD_HOURS = 'H';
|
||||
const PERIOD_MINUTES = 'M';
|
||||
const PERIOD_SECONDS = 'S';
|
||||
|
||||
public const PERIOD_PREFIX = 'P';
|
||||
/**
|
||||
* Before PHP 5.4.20/5.5.4 instead of `false` days will be set to -99999 when the interval instance
|
||||
* was created by DateTime:diff().
|
||||
* @var string
|
||||
*/
|
||||
const PHP_DAYS_FALSE = -99999;
|
||||
public const PERIOD_YEARS = 'Y';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const PERIOD_MONTHS = 'M';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const PERIOD_DAYS = 'D';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const PERIOD_TIME_PREFIX = 'T';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const PERIOD_HOURS = 'H';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const PERIOD_MINUTES = 'M';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const PERIOD_SECONDS = 'S';
|
||||
|
||||
/**
|
||||
* Determine if the interval was created via DateTime:diff() or not.
|
||||
@@ -89,9 +92,9 @@ class ChronosInterval extends DateInterval
|
||||
* @param \DateInterval $interval The interval to check.
|
||||
* @return bool
|
||||
*/
|
||||
protected static function wasCreatedFromDiff(DateInterval $interval)
|
||||
protected static function wasCreatedFromDiff(DateInterval $interval): bool
|
||||
{
|
||||
return ($interval->days !== false && $interval->days !== static::PHP_DAYS_FALSE);
|
||||
return $interval->days !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,9 +107,18 @@ class ChronosInterval extends DateInterval
|
||||
* @param int|null $hours The hours to use.
|
||||
* @param int|null $minutes The minutes to use.
|
||||
* @param int|null $seconds The seconds to use.
|
||||
* @param int|null $microseconds The microseconds to use.
|
||||
*/
|
||||
public function __construct($years = 1, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null)
|
||||
{
|
||||
public function __construct(
|
||||
?int $years = 1,
|
||||
?int $months = null,
|
||||
?int $weeks = null,
|
||||
?int $days = null,
|
||||
?int $hours = null,
|
||||
?int $minutes = null,
|
||||
?int $seconds = null,
|
||||
?int $microseconds = null
|
||||
) {
|
||||
$spec = static::PERIOD_PREFIX;
|
||||
|
||||
$spec .= $years > 0 ? $years . static::PERIOD_YEARS : '';
|
||||
@@ -116,7 +128,7 @@ class ChronosInterval extends DateInterval
|
||||
$specDays += $weeks > 0 ? $weeks * ChronosInterface::DAYS_PER_WEEK : 0;
|
||||
$specDays += $days > 0 ? $days : 0;
|
||||
|
||||
$spec .= ($specDays > 0) ? $specDays . static::PERIOD_DAYS : '';
|
||||
$spec .= $specDays > 0 ? $specDays . static::PERIOD_DAYS : '';
|
||||
|
||||
if ($spec === static::PERIOD_PREFIX) {
|
||||
$spec .= '0' . static::PERIOD_YEARS;
|
||||
@@ -130,6 +142,10 @@ class ChronosInterval extends DateInterval
|
||||
}
|
||||
|
||||
parent::__construct($spec);
|
||||
|
||||
if ($microseconds > 0) {
|
||||
$this->f = $microseconds / 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,11 +161,20 @@ class ChronosInterval extends DateInterval
|
||||
* @param int|null $hours The hours to use.
|
||||
* @param int|null $minutes The minutes to use.
|
||||
* @param int|null $seconds The seconds to use.
|
||||
* @param int|null $microseconds The microseconds to use.
|
||||
* @return static
|
||||
*/
|
||||
public static function create($years = 1, $months = null, $weeks = null, $days = null, $hours = null, $minutes = null, $seconds = null)
|
||||
{
|
||||
return new static($years, $months, $weeks, $days, $hours, $minutes, $seconds);
|
||||
public static function create(
|
||||
?int $years = 1,
|
||||
?int $months = null,
|
||||
?int $weeks = null,
|
||||
?int $days = null,
|
||||
?int $hours = null,
|
||||
?int $minutes = null,
|
||||
?int $seconds = null,
|
||||
?int $microseconds = null
|
||||
): self {
|
||||
return new static($years, $months, $weeks, $days, $hours, $minutes, $seconds, $microseconds);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,7 +193,7 @@ class ChronosInterval extends DateInterval
|
||||
* @param array $args Contains the value to use.
|
||||
* @return static
|
||||
*/
|
||||
public static function __callStatic($name, $args)
|
||||
public static function __callStatic(string $name, array $args): self
|
||||
{
|
||||
$arg = count($args) === 0 ? 1 : $args[0];
|
||||
|
||||
@@ -201,7 +226,13 @@ class ChronosInterval extends DateInterval
|
||||
case 'seconds':
|
||||
case 'second':
|
||||
return new static(null, null, null, null, null, null, $arg);
|
||||
|
||||
case 'microseconds':
|
||||
case 'microsecond':
|
||||
return new static(null, null, null, null, null, null, null, $arg);
|
||||
}
|
||||
|
||||
throw new BadMethodCallException(sprintf('Cannot create interval with `%s` units', $name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,15 +244,16 @@ class ChronosInterval extends DateInterval
|
||||
* @throws \InvalidArgumentException
|
||||
* @return static
|
||||
*/
|
||||
public static function instance(DateInterval $di)
|
||||
public static function instance(DateInterval $di): self
|
||||
{
|
||||
if (static::wasCreatedFromDiff($di)) {
|
||||
throw new InvalidArgumentException(
|
||||
"Can not instance a DateInterval object created from DateTime::diff()."
|
||||
'Can not instance a DateInterval object created from DateTime::diff().'
|
||||
);
|
||||
}
|
||||
|
||||
$instance = new static($di->y, $di->m, 0, $di->d, $di->h, $di->i, $di->s);
|
||||
$instance->f = $di->f;
|
||||
$instance->invert = $di->invert;
|
||||
$instance->days = $di->days;
|
||||
|
||||
@@ -235,7 +267,7 @@ class ChronosInterval extends DateInterval
|
||||
* @throws \InvalidArgumentException
|
||||
* @return int
|
||||
*/
|
||||
public function __get($name)
|
||||
public function __get(string $name)
|
||||
{
|
||||
switch ($name) {
|
||||
case 'years':
|
||||
@@ -256,22 +288,16 @@ class ChronosInterval extends DateInterval
|
||||
case 'seconds':
|
||||
return $this->s;
|
||||
|
||||
case 'microseconds':
|
||||
return (int)($this->f * 1000000);
|
||||
|
||||
case 'weeks':
|
||||
return (int)floor($this->d / ChronosInterface::DAYS_PER_WEEK);
|
||||
|
||||
case 'daysExcludeWeeks':
|
||||
case 'dayzExcludeWeeks':
|
||||
return $this->dayz % ChronosInterface::DAYS_PER_WEEK;
|
||||
case 'days':
|
||||
return $this->days;
|
||||
case 'y':
|
||||
case 'm':
|
||||
case 'd':
|
||||
case 'h':
|
||||
case 'i':
|
||||
case 's':
|
||||
case 'invert':
|
||||
return parent::__get($name);
|
||||
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name));
|
||||
}
|
||||
@@ -285,7 +311,7 @@ class ChronosInterval extends DateInterval
|
||||
* @return void
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __set($name, $val)
|
||||
public function __set(string $name, $val): void
|
||||
{
|
||||
switch ($name) {
|
||||
case 'years':
|
||||
@@ -317,6 +343,10 @@ class ChronosInterval extends DateInterval
|
||||
$this->s = $val;
|
||||
break;
|
||||
|
||||
case 'microseconds':
|
||||
$this->f = $val / 1000000;
|
||||
break;
|
||||
|
||||
case 'invert':
|
||||
$this->invert = $val;
|
||||
break;
|
||||
@@ -328,9 +358,9 @@ class ChronosInterval extends DateInterval
|
||||
*
|
||||
* @param int $weeks Number of weeks to set
|
||||
* @param int $days Number of days to set
|
||||
* @return static
|
||||
* @return $this
|
||||
*/
|
||||
public function weeksAndDays($weeks, $days)
|
||||
public function weeksAndDays(int $weeks, int $days)
|
||||
{
|
||||
$this->dayz = ($weeks * ChronosInterface::DAYS_PER_WEEK) + $days;
|
||||
|
||||
@@ -346,9 +376,9 @@ class ChronosInterval extends DateInterval
|
||||
* @param string $name The property name to augment. Accepts plural forms in addition
|
||||
* to singular ones.
|
||||
* @param array $args The value to set.
|
||||
* @return static
|
||||
* @return $this
|
||||
*/
|
||||
public function __call($name, $args)
|
||||
public function __call(string $name, array $args)
|
||||
{
|
||||
$arg = count($args) === 0 ? 1 : $args[0];
|
||||
|
||||
@@ -388,6 +418,11 @@ class ChronosInterval extends DateInterval
|
||||
case 'second':
|
||||
$this->seconds = $arg;
|
||||
break;
|
||||
|
||||
case 'microseconds':
|
||||
case 'microsecond':
|
||||
$this->microseconds = $arg;
|
||||
break;
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -397,11 +432,11 @@ class ChronosInterval extends DateInterval
|
||||
* Add the passed interval to the current instance
|
||||
*
|
||||
* @param \DateInterval $interval The interval to add.
|
||||
* @return static
|
||||
* @return $this
|
||||
*/
|
||||
public function add(DateInterval $interval)
|
||||
{
|
||||
$sign = ($interval->invert === 1) ? -1 : 1;
|
||||
$sign = $interval->invert === 1 ? -1 : 1;
|
||||
|
||||
if (static::wasCreatedFromDiff($interval)) {
|
||||
$this->dayz = $this->dayz + ($interval->days * $sign);
|
||||
@@ -412,6 +447,7 @@ class ChronosInterval extends DateInterval
|
||||
$this->hours = $this->hours + ($interval->h * $sign);
|
||||
$this->minutes = $this->minutes + ($interval->i * $sign);
|
||||
$this->seconds = $this->seconds + ($interval->s * $sign);
|
||||
$this->microseconds = $this->microseconds + (int)($interval->f * 1000000 * $sign);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -422,7 +458,7 @@ class ChronosInterval extends DateInterval
|
||||
*
|
||||
* @return string Interval as string representation
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
// equivalence
|
||||
$oneMinuteInSeconds = 60;
|
||||
|
||||
59
vendor/cakephp/chronos/src/Date.php
vendored
59
vendor/cakephp/chronos/src/Date.php
vendored
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -29,10 +31,11 @@ use DateTimeZone;
|
||||
* @property-read int $hour
|
||||
* @property-read int $minute
|
||||
* @property-read int $second
|
||||
* @property-read int $timestamp seconds since the Unix Epoch
|
||||
* @property-read DateTimeZone $timezone the current timezone
|
||||
* @property-read DateTimeZone $tz alias of timezone
|
||||
* @property-read int $micro
|
||||
* @property-read int $microsecond
|
||||
* @property-read int $timestamp seconds since the Unix Epoch
|
||||
* @property-read \DateTimeZone $timezone the current timezone
|
||||
* @property-read \DateTimeZone $tz alias of timezone
|
||||
* @property-read int $dayOfWeek 1 (for Monday) through 7 (for Sunday)
|
||||
* @property-read int $dayOfYear 0 through 365
|
||||
* @property-read int $weekOfMonth 1 through 5
|
||||
@@ -69,51 +72,47 @@ class Date extends DateTimeImmutable implements ChronosInterface
|
||||
/**
|
||||
* Create a new Immutable Date instance.
|
||||
*
|
||||
* You can specify the timezone for the $time parameter. This timezone will
|
||||
* not be used in any future modifications to the Date instance.
|
||||
*
|
||||
* The $timezone parameter is ignored if $time is a DateTimeInterface
|
||||
* instance.
|
||||
*
|
||||
* Please see the testing aids section (specifically static::setTestNow())
|
||||
* for more on the possibility of this constructor returning a test instance.
|
||||
*
|
||||
* Date instances lack time components, however due to limitations in PHP's
|
||||
* internal Datetime object the time will always be set to 00:00:00, and the
|
||||
* timezone will always be UTC. Normalizing the timezone allows for
|
||||
* timezone will always be the server local time. Normalizing the timezone allows for
|
||||
* subtraction/addition to have deterministic results.
|
||||
*
|
||||
* @param string|null|\DateTimeInterface $time Fixed or relative time
|
||||
* @param \DateTime|\DateTimeImmutable|string|int|null $time Fixed or relative time
|
||||
* @param \DateTimeZone|string|null $tz The timezone in which the date is taken
|
||||
*/
|
||||
public function __construct($time = 'now')
|
||||
public function __construct($time = 'now', $tz = null)
|
||||
{
|
||||
$tz = new DateTimeZone('UTC');
|
||||
$testNow = Chronos::getTestNow();
|
||||
if ($testNow === null) {
|
||||
$time = $this->stripTime($time);
|
||||
|
||||
parent::__construct($time, $tz);
|
||||
|
||||
return;
|
||||
if ($tz !== null) {
|
||||
$tz = $tz instanceof DateTimeZone ? $tz : new DateTimeZone($tz);
|
||||
}
|
||||
|
||||
$relative = static::hasRelativeKeywords($time);
|
||||
if (!empty($time) && $time !== 'now' && !$relative) {
|
||||
$time = $this->stripTime($time);
|
||||
|
||||
parent::__construct($time, $tz);
|
||||
$testNow = Chronos::getTestNow();
|
||||
if ($testNow === null || !static::isRelativeOnly($time)) {
|
||||
$time = $this->stripTime($time, $tz);
|
||||
parent::__construct($time);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$testNow = clone $testNow;
|
||||
if ($relative) {
|
||||
$time = $this->stripRelativeTime($time);
|
||||
if (strlen($time) > 0) {
|
||||
$testNow = $testNow->modify($time);
|
||||
}
|
||||
}
|
||||
|
||||
if ($tz !== $testNow->getTimezone()) {
|
||||
$testNow = $testNow->setTimezone($tz === null ? date_default_timezone_get() : $tz);
|
||||
$testNow = $testNow->setTimezone($tz ?? date_default_timezone_get());
|
||||
}
|
||||
if (!empty($time)) {
|
||||
$testNow = $testNow->modify($time);
|
||||
}
|
||||
|
||||
$time = $testNow->format('Y-m-d 00:00:00');
|
||||
parent::__construct($time, $tz);
|
||||
parent::__construct($time);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,7 +120,7 @@ class Date extends DateTimeImmutable implements ChronosInterface
|
||||
*
|
||||
* @return \Cake\Chronos\MutableDate
|
||||
*/
|
||||
public function toMutable()
|
||||
public function toMutable(): MutableDate
|
||||
{
|
||||
return MutableDate::instance($this);
|
||||
}
|
||||
@@ -131,7 +130,7 @@ class Date extends DateTimeImmutable implements ChronosInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo()
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
$properties = [
|
||||
'hasFixedNow' => static::hasTestNow(),
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -18,9 +20,8 @@ namespace Cake\Chronos;
|
||||
* Provides a swappable component for other libraries to leverage.
|
||||
* when localizing or customizing the difference output.
|
||||
*/
|
||||
class DifferenceFormatter
|
||||
class DifferenceFormatter implements DifferenceFormatterInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* The text translator object
|
||||
*
|
||||
@@ -33,7 +34,7 @@ class DifferenceFormatter
|
||||
*
|
||||
* @param \Cake\Chronos\Translator|null $translate The text translator object.
|
||||
*/
|
||||
public function __construct($translate = null)
|
||||
public function __construct(?Translator $translate = null)
|
||||
{
|
||||
$this->translate = $translate ?: new Translator();
|
||||
}
|
||||
@@ -47,8 +48,11 @@ class DifferenceFormatter
|
||||
* @return string The difference between the two days in a human readable format
|
||||
* @see \Cake\Chronos\ChronosInterface::diffForHumans
|
||||
*/
|
||||
public function diffForHumans(ChronosInterface $date, ChronosInterface $other = null, $absolute = false)
|
||||
{
|
||||
public function diffForHumans(
|
||||
ChronosInterface $date,
|
||||
?ChronosInterface $other = null,
|
||||
bool $absolute = false
|
||||
): string {
|
||||
$isNow = $other === null;
|
||||
if ($isNow) {
|
||||
$other = $date->now($date->tz);
|
||||
@@ -56,15 +60,15 @@ class DifferenceFormatter
|
||||
$diffInterval = $date->diff($other);
|
||||
|
||||
switch (true) {
|
||||
case ($diffInterval->y > 0):
|
||||
case $diffInterval->y > 0:
|
||||
$unit = 'year';
|
||||
$count = $diffInterval->y;
|
||||
break;
|
||||
case ($diffInterval->m > 0):
|
||||
case $diffInterval->m > 0:
|
||||
$unit = 'month';
|
||||
$count = $diffInterval->m;
|
||||
break;
|
||||
case ($diffInterval->d > 0):
|
||||
case $diffInterval->d > 0:
|
||||
$unit = 'day';
|
||||
$count = $diffInterval->d;
|
||||
if ($count >= ChronosInterface::DAYS_PER_WEEK) {
|
||||
@@ -72,11 +76,11 @@ class DifferenceFormatter
|
||||
$count = (int)($count / ChronosInterface::DAYS_PER_WEEK);
|
||||
}
|
||||
break;
|
||||
case ($diffInterval->h > 0):
|
||||
case $diffInterval->h > 0:
|
||||
$unit = 'hour';
|
||||
$count = $diffInterval->h;
|
||||
break;
|
||||
case ($diffInterval->i > 0):
|
||||
case $diffInterval->i > 0:
|
||||
$unit = 'minute';
|
||||
$count = $diffInterval->i;
|
||||
break;
|
||||
|
||||
35
vendor/cakephp/chronos/src/DifferenceFormatterInterface.php
vendored
Normal file
35
vendor/cakephp/chronos/src/DifferenceFormatterInterface.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
namespace Cake\Chronos;
|
||||
|
||||
/**
|
||||
* Interface for formatting differences in text.
|
||||
*/
|
||||
interface DifferenceFormatterInterface
|
||||
{
|
||||
/**
|
||||
* Get the difference in a human readable format.
|
||||
*
|
||||
* @param \Cake\Chronos\ChronosInterface $date The datetime to start with.
|
||||
* @param \Cake\Chronos\ChronosInterface|null $other The datetime to compare against.
|
||||
* @param bool $absolute Removes time difference modifiers ago, after, etc.
|
||||
* @return string The difference between the two days in a human readable format.
|
||||
* @see \Cake\Chronos\ChronosInterface::diffForHumans
|
||||
*/
|
||||
public function diffForHumans(
|
||||
ChronosInterface $date,
|
||||
?ChronosInterface $other = null,
|
||||
bool $absolute = false
|
||||
): string;
|
||||
}
|
||||
59
vendor/cakephp/chronos/src/MutableDate.php
vendored
59
vendor/cakephp/chronos/src/MutableDate.php
vendored
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -28,10 +30,11 @@ use DateTimeZone;
|
||||
* @property-read int $hour
|
||||
* @property-read int $minute
|
||||
* @property-read int $second
|
||||
* @property-read int $timestamp seconds since the Unix Epoch
|
||||
* @property-read DateTimeZone $timezone the current timezone
|
||||
* @property-read DateTimeZone $tz alias of timezone
|
||||
* @property-read int $micro
|
||||
* @property-read int $microsecond
|
||||
* @property-read int $timestamp seconds since the Unix Epoch
|
||||
* @property-read \DateTimeZone $timezone the current timezone
|
||||
* @property-read \DateTimeZone $tz alias of timezone
|
||||
* @property-read int $dayOfWeek 1 (for Monday) through 7 (for Sunday)
|
||||
* @property-read int $dayOfYear 0 through 365
|
||||
* @property-read int $weekOfMonth 1 through 5
|
||||
@@ -68,51 +71,47 @@ class MutableDate extends DateTime implements ChronosInterface
|
||||
/**
|
||||
* Create a new mutable Date instance.
|
||||
*
|
||||
* You can specify the timezone for the $time parameter. This timezone will
|
||||
* not be used in any future modifications to the Date instance.
|
||||
*
|
||||
* The $timezone parameter is ignored if $time is a DateTimeInterface
|
||||
* instance.
|
||||
*
|
||||
* Please see the testing aids section (specifically static::setTestNow())
|
||||
* for more on the possibility of this constructor returning a test instance.
|
||||
*
|
||||
* Date instances lack time components, however due to limitations in PHP's
|
||||
* internal Datetime object the time will always be set to 00:00:00, and the
|
||||
* timezone will always be UTC. Normalizing the timezone allows for
|
||||
* timezone will always be server local timezone. Normalizing the timezone allows for
|
||||
* subtraction/addition to have deterministic results.
|
||||
*
|
||||
* @param string|null|\DateTimeInterface $time Fixed or relative time
|
||||
* @param \DateTime|\DateTimeImmutable|string|int|null $time Fixed or relative time
|
||||
* @param \DateTimeZone|string|null $tz The timezone in which the date is taken
|
||||
*/
|
||||
public function __construct($time = 'now')
|
||||
public function __construct($time = 'now', $tz = null)
|
||||
{
|
||||
$tz = new DateTimeZone('UTC');
|
||||
|
||||
$testNow = Chronos::getTestNow();
|
||||
if ($testNow === null) {
|
||||
$time = $this->stripTime($time);
|
||||
parent::__construct($time, $tz);
|
||||
|
||||
return;
|
||||
if ($tz !== null) {
|
||||
$tz = $tz instanceof DateTimeZone ? $tz : new DateTimeZone($tz);
|
||||
}
|
||||
|
||||
$relative = static::hasRelativeKeywords($time);
|
||||
if (!empty($time) && $time !== 'now' && !$relative) {
|
||||
$time = $this->stripTime($time);
|
||||
|
||||
parent::__construct($time, $tz);
|
||||
$testNow = Chronos::getTestNow();
|
||||
if ($testNow === null || !static::isRelativeOnly($time)) {
|
||||
$time = $this->stripTime($time, $tz);
|
||||
parent::__construct($time);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$testNow = clone $testNow;
|
||||
if ($relative) {
|
||||
$time = $this->stripRelativeTime($time);
|
||||
if (strlen($time) > 0) {
|
||||
$testNow = $testNow->modify($time);
|
||||
}
|
||||
}
|
||||
|
||||
if ($tz !== $testNow->getTimezone()) {
|
||||
$testNow = $testNow->setTimezone($tz === null ? date_default_timezone_get() : $tz);
|
||||
$testNow = $testNow->setTimezone($tz ?? date_default_timezone_get());
|
||||
}
|
||||
if (!empty($time)) {
|
||||
$testNow = $testNow->modify($time);
|
||||
}
|
||||
|
||||
$time = $testNow->format('Y-m-d 00:00:00');
|
||||
parent::__construct($time, $tz);
|
||||
parent::__construct($time);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +119,7 @@ class MutableDate extends DateTime implements ChronosInterface
|
||||
*
|
||||
* @return \Cake\Chronos\Date
|
||||
*/
|
||||
public function toImmutable()
|
||||
public function toImmutable(): Date
|
||||
{
|
||||
return Date::instance($this);
|
||||
}
|
||||
@@ -130,7 +129,7 @@ class MutableDate extends DateTime implements ChronosInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo()
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
$properties = [
|
||||
'hasFixedNow' => static::hasTestNow(),
|
||||
|
||||
50
vendor/cakephp/chronos/src/MutableDateTime.php
vendored
50
vendor/cakephp/chronos/src/MutableDateTime.php
vendored
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -22,17 +24,18 @@ use InvalidArgumentException;
|
||||
* This object can be mutated in place using any setter method,
|
||||
* or __set().
|
||||
*
|
||||
* @property int $year
|
||||
* @property int $yearIso
|
||||
* @property int $month
|
||||
* @property int $day
|
||||
* @property int $hour
|
||||
* @property int $minute
|
||||
* @property int $second
|
||||
* @property int $timestamp seconds since the Unix Epoch
|
||||
* @property DateTimeZone|string $timezone the current timezone
|
||||
* @property DateTimeZone|string $tz alias of timezone
|
||||
* @property int $micro
|
||||
* @property-read int $year
|
||||
* @property-read int $yearIso
|
||||
* @property-read int $month
|
||||
* @property-read int $day
|
||||
* @property-read int $hour
|
||||
* @property-read int $minute
|
||||
* @property-read int $second
|
||||
* @property-read int $micro
|
||||
* @property-read int $microsecond
|
||||
* @property-read int $timestamp seconds since the Unix Epoch
|
||||
* @property-read \DateTimeZone|string $timezone the current timezone
|
||||
* @property-read \DateTimeZone|string $tz alias of timezone
|
||||
* @property-read int $dayOfWeek 1 (for Monday) through 7 (for Sunday)
|
||||
* @property-read int $dayOfYear 0 through 365
|
||||
* @property-read int $weekOfMonth 1 through 5
|
||||
@@ -73,7 +76,7 @@ class MutableDateTime extends DateTime implements ChronosInterface
|
||||
* Please see the testing aids section (specifically static::setTestNow())
|
||||
* for more on the possibility of this constructor returning a test instance.
|
||||
*
|
||||
* @param string|null $time Fixed or relative time
|
||||
* @param \DateTime|\DateTimeImmutable|string|int|null $time Fixed or relative time
|
||||
* @param \DateTimeZone|string|null $tz The timezone for the instance
|
||||
*/
|
||||
public function __construct($time = 'now', $tz = null)
|
||||
@@ -82,9 +85,13 @@ class MutableDateTime extends DateTime implements ChronosInterface
|
||||
$tz = $tz instanceof DateTimeZone ? $tz : new DateTimeZone($tz);
|
||||
}
|
||||
|
||||
if ($time instanceof \DateTimeInterface) {
|
||||
$time = $time->format('Y-m-d H:i:s.u');
|
||||
}
|
||||
|
||||
$testNow = Chronos::getTestNow();
|
||||
if ($testNow === null) {
|
||||
parent::__construct($time === null ? 'now' : $time, $tz);
|
||||
parent::__construct($time ?? 'now', $tz);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -97,14 +104,15 @@ class MutableDateTime extends DateTime implements ChronosInterface
|
||||
}
|
||||
|
||||
$testNow = clone $testNow;
|
||||
$relativetime = static::isTimeExpression($time);
|
||||
if (!$relativetime && $tz !== $testNow->getTimezone()) {
|
||||
$testNow = $testNow->setTimezone($tz ?? date_default_timezone_get());
|
||||
}
|
||||
|
||||
if ($relative) {
|
||||
$testNow = $testNow->modify($time);
|
||||
}
|
||||
|
||||
$relativetime = static::isTimeExpression($time);
|
||||
if (!$relativetime && $tz !== $testNow->getTimezone()) {
|
||||
$testNow = $testNow->setTimezone($tz === null ? date_default_timezone_get() : $tz);
|
||||
}
|
||||
$time = $testNow->format('Y-m-d H:i:s.u');
|
||||
parent::__construct($time, $tz);
|
||||
}
|
||||
@@ -112,9 +120,9 @@ class MutableDateTime extends DateTime implements ChronosInterface
|
||||
/**
|
||||
* Create a new immutable instance from current mutable instance.
|
||||
*
|
||||
* @return Chronos
|
||||
* @return \Cake\Chronos\Chronos
|
||||
*/
|
||||
public function toImmutable()
|
||||
public function toImmutable(): Chronos
|
||||
{
|
||||
return Chronos::instance($this);
|
||||
}
|
||||
@@ -127,7 +135,7 @@ class MutableDateTime extends DateTime implements ChronosInterface
|
||||
* @throws \InvalidArgumentException
|
||||
* @return void
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
public function __set(string $name, $value): void
|
||||
{
|
||||
switch ($name) {
|
||||
case 'year':
|
||||
@@ -173,7 +181,7 @@ class MutableDateTime extends DateTime implements ChronosInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo()
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
$properties = [
|
||||
'hasFixedNow' => static::hasTestNow(),
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -34,7 +36,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getWeekendDays()
|
||||
public static function getWeekendDays(): array
|
||||
{
|
||||
return static::$weekendDays;
|
||||
}
|
||||
@@ -45,7 +47,7 @@ trait ComparisonTrait
|
||||
* @param array $days Which days are 'weekends'.
|
||||
* @return void
|
||||
*/
|
||||
public static function setWeekendDays($days)
|
||||
public static function setWeekendDays(array $days): void
|
||||
{
|
||||
static::$weekendDays = $days;
|
||||
}
|
||||
@@ -56,7 +58,7 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface $dt The instance to compare with.
|
||||
* @return bool
|
||||
*/
|
||||
public function eq(ChronosInterface $dt)
|
||||
public function eq(ChronosInterface $dt): bool
|
||||
{
|
||||
return $this == $dt;
|
||||
}
|
||||
@@ -78,7 +80,7 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface $dt The instance to compare with.
|
||||
* @return bool
|
||||
*/
|
||||
public function ne(ChronosInterface $dt)
|
||||
public function ne(ChronosInterface $dt): bool
|
||||
{
|
||||
return !$this->eq($dt);
|
||||
}
|
||||
@@ -100,7 +102,7 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface $dt The instance to compare with.
|
||||
* @return bool
|
||||
*/
|
||||
public function gt(ChronosInterface $dt)
|
||||
public function gt(ChronosInterface $dt): bool
|
||||
{
|
||||
return $this > $dt;
|
||||
}
|
||||
@@ -122,7 +124,7 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface $dt The instance to compare with.
|
||||
* @return bool
|
||||
*/
|
||||
public function gte(ChronosInterface $dt)
|
||||
public function gte(ChronosInterface $dt): bool
|
||||
{
|
||||
return $this >= $dt;
|
||||
}
|
||||
@@ -144,7 +146,7 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface $dt The instance to compare with.
|
||||
* @return bool
|
||||
*/
|
||||
public function lt(ChronosInterface $dt)
|
||||
public function lt(ChronosInterface $dt): bool
|
||||
{
|
||||
return $this < $dt;
|
||||
}
|
||||
@@ -166,7 +168,7 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface $dt The instance to compare with.
|
||||
* @return bool
|
||||
*/
|
||||
public function lte(ChronosInterface $dt)
|
||||
public function lte(ChronosInterface $dt): bool
|
||||
{
|
||||
return $this <= $dt;
|
||||
}
|
||||
@@ -190,7 +192,7 @@ trait ComparisonTrait
|
||||
* @param bool $equal Indicates if a > and < comparison should be used or <= or >=
|
||||
* @return bool
|
||||
*/
|
||||
public function between(ChronosInterface $dt1, ChronosInterface $dt2, $equal = true)
|
||||
public function between(ChronosInterface $dt1, ChronosInterface $dt2, bool $equal = true): bool
|
||||
{
|
||||
if ($dt1->gt($dt2)) {
|
||||
$temp = $dt1;
|
||||
@@ -212,7 +214,7 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface $dt2 The instance to compare with.
|
||||
* @return \Cake\Chronos\ChronosInterface
|
||||
*/
|
||||
public function closest(ChronosInterface $dt1, ChronosInterface $dt2)
|
||||
public function closest(ChronosInterface $dt1, ChronosInterface $dt2): ChronosInterface
|
||||
{
|
||||
return $this->diffInSeconds($dt1) < $this->diffInSeconds($dt2) ? $dt1 : $dt2;
|
||||
}
|
||||
@@ -224,7 +226,7 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface $dt2 The instance to compare with.
|
||||
* @return \Cake\Chronos\ChronosInterface
|
||||
*/
|
||||
public function farthest(ChronosInterface $dt1, ChronosInterface $dt2)
|
||||
public function farthest(ChronosInterface $dt1, ChronosInterface $dt2): ChronosInterface
|
||||
{
|
||||
return $this->diffInSeconds($dt1) > $this->diffInSeconds($dt2) ? $dt1 : $dt2;
|
||||
}
|
||||
@@ -235,9 +237,9 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface|null $dt The instance to compare with.
|
||||
* @return \Cake\Chronos\ChronosInterface
|
||||
*/
|
||||
public function min(ChronosInterface $dt = null)
|
||||
public function min(?ChronosInterface $dt = null): ChronosInterface
|
||||
{
|
||||
$dt = ($dt === null) ? static::now($this->tz) : $dt;
|
||||
$dt = $dt ?? static::now($this->tz);
|
||||
|
||||
return $this->lt($dt) ? $this : $dt;
|
||||
}
|
||||
@@ -248,9 +250,9 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface|null $dt The instance to compare with.
|
||||
* @return \Cake\Chronos\ChronosInterface
|
||||
*/
|
||||
public function max(ChronosInterface $dt = null)
|
||||
public function max(?ChronosInterface $dt = null): ChronosInterface
|
||||
{
|
||||
$dt = ($dt === null) ? static::now($this->tz) : $dt;
|
||||
$dt = $dt ?? static::now($this->tz);
|
||||
|
||||
return $this->gt($dt) ? $this : $dt;
|
||||
}
|
||||
@@ -260,7 +262,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWeekday()
|
||||
public function isWeekday(): bool
|
||||
{
|
||||
return !$this->isWeekend();
|
||||
}
|
||||
@@ -270,7 +272,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWeekend()
|
||||
public function isWeekend(): bool
|
||||
{
|
||||
return in_array($this->dayOfWeek, self::$weekendDays, true);
|
||||
}
|
||||
@@ -280,7 +282,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isYesterday()
|
||||
public function isYesterday(): bool
|
||||
{
|
||||
return $this->toDateString() === static::yesterday($this->tz)->toDateString();
|
||||
}
|
||||
@@ -290,7 +292,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isToday()
|
||||
public function isToday(): bool
|
||||
{
|
||||
return $this->toDateString() === static::now($this->tz)->toDateString();
|
||||
}
|
||||
@@ -300,7 +302,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isTomorrow()
|
||||
public function isTomorrow(): bool
|
||||
{
|
||||
return $this->toDateString() === static::tomorrow($this->tz)->toDateString();
|
||||
}
|
||||
@@ -310,7 +312,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNextWeek()
|
||||
public function isNextWeek(): bool
|
||||
{
|
||||
return $this->format('W o') === static::now($this->tz)->addWeek()->format('W o');
|
||||
}
|
||||
@@ -320,7 +322,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLastWeek()
|
||||
public function isLastWeek(): bool
|
||||
{
|
||||
return $this->format('W o') === static::now($this->tz)->subWeek()->format('W o');
|
||||
}
|
||||
@@ -330,7 +332,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNextMonth()
|
||||
public function isNextMonth(): bool
|
||||
{
|
||||
return $this->format('m Y') === static::now($this->tz)->addMonth()->format('m Y');
|
||||
}
|
||||
@@ -340,7 +342,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLastMonth()
|
||||
public function isLastMonth(): bool
|
||||
{
|
||||
return $this->format('m Y') === static::now($this->tz)->subMonth()->format('m Y');
|
||||
}
|
||||
@@ -350,7 +352,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNextYear()
|
||||
public function isNextYear(): bool
|
||||
{
|
||||
return $this->year === static::now($this->tz)->addYear()->year;
|
||||
}
|
||||
@@ -360,7 +362,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLastYear()
|
||||
public function isLastYear(): bool
|
||||
{
|
||||
return $this->year === static::now($this->tz)->subYear()->year;
|
||||
}
|
||||
@@ -370,7 +372,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFuture()
|
||||
public function isFuture(): bool
|
||||
{
|
||||
return $this->gt(static::now($this->tz));
|
||||
}
|
||||
@@ -380,7 +382,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPast()
|
||||
public function isPast(): bool
|
||||
{
|
||||
return $this->lt(static::now($this->tz));
|
||||
}
|
||||
@@ -390,7 +392,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLeapYear()
|
||||
public function isLeapYear(): bool
|
||||
{
|
||||
return $this->format('L') === '1';
|
||||
}
|
||||
@@ -401,7 +403,7 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface $dt The instance to check against.
|
||||
* @return bool
|
||||
*/
|
||||
public function isSameDay(ChronosInterface $dt)
|
||||
public function isSameDay(ChronosInterface $dt): bool
|
||||
{
|
||||
return $this->toDateString() === $dt->toDateString();
|
||||
}
|
||||
@@ -411,7 +413,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSunday()
|
||||
public function isSunday(): bool
|
||||
{
|
||||
return $this->dayOfWeek === ChronosInterface::SUNDAY;
|
||||
}
|
||||
@@ -421,7 +423,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMonday()
|
||||
public function isMonday(): bool
|
||||
{
|
||||
return $this->dayOfWeek === ChronosInterface::MONDAY;
|
||||
}
|
||||
@@ -431,7 +433,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isTuesday()
|
||||
public function isTuesday(): bool
|
||||
{
|
||||
return $this->dayOfWeek === ChronosInterface::TUESDAY;
|
||||
}
|
||||
@@ -441,7 +443,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWednesday()
|
||||
public function isWednesday(): bool
|
||||
{
|
||||
return $this->dayOfWeek === ChronosInterface::WEDNESDAY;
|
||||
}
|
||||
@@ -451,7 +453,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isThursday()
|
||||
public function isThursday(): bool
|
||||
{
|
||||
return $this->dayOfWeek === ChronosInterface::THURSDAY;
|
||||
}
|
||||
@@ -461,7 +463,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFriday()
|
||||
public function isFriday(): bool
|
||||
{
|
||||
return $this->dayOfWeek === ChronosInterface::FRIDAY;
|
||||
}
|
||||
@@ -471,7 +473,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSaturday()
|
||||
public function isSaturday(): bool
|
||||
{
|
||||
return $this->dayOfWeek === ChronosInterface::SATURDAY;
|
||||
}
|
||||
@@ -481,7 +483,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isThisWeek()
|
||||
public function isThisWeek(): bool
|
||||
{
|
||||
return static::now($this->getTimezone())->format('W o') === $this->format('W o');
|
||||
}
|
||||
@@ -491,7 +493,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isThisMonth()
|
||||
public function isThisMonth(): bool
|
||||
{
|
||||
return static::now($this->getTimezone())->format('m Y') === $this->format('m Y');
|
||||
}
|
||||
@@ -501,7 +503,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isThisYear()
|
||||
public function isThisYear(): bool
|
||||
{
|
||||
return static::now($this->getTimezone())->format('Y') === $this->format('Y');
|
||||
}
|
||||
@@ -512,11 +514,9 @@ trait ComparisonTrait
|
||||
* @param \Cake\Chronos\ChronosInterface|null $dt The instance to compare with or null to use current day.
|
||||
* @return bool
|
||||
*/
|
||||
public function isBirthday(ChronosInterface $dt = null)
|
||||
public function isBirthday(?ChronosInterface $dt = null): bool
|
||||
{
|
||||
if ($dt === null) {
|
||||
$dt = static::now($this->tz);
|
||||
}
|
||||
$dt = $dt ?? static::now($this->tz);
|
||||
|
||||
return $this->format('md') === $dt->format('md');
|
||||
}
|
||||
@@ -528,7 +528,7 @@ trait ComparisonTrait
|
||||
* Example of valid types: 6 hours, 2 days, 1 minute.
|
||||
* @return bool
|
||||
*/
|
||||
public function wasWithinLast($timeInterval)
|
||||
public function wasWithinLast($timeInterval): bool
|
||||
{
|
||||
$now = new static();
|
||||
$interval = $now->copy()->modify('-' . $timeInterval);
|
||||
@@ -544,7 +544,7 @@ trait ComparisonTrait
|
||||
* Example of valid types: 6 hours, 2 days, 1 minute.
|
||||
* @return bool
|
||||
*/
|
||||
public function isWithinNext($timeInterval)
|
||||
public function isWithinNext($timeInterval): bool
|
||||
{
|
||||
$now = new static();
|
||||
$interval = $now->copy()->modify('+' . $timeInterval);
|
||||
@@ -558,7 +558,7 @@ trait ComparisonTrait
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMutable()
|
||||
public function isMutable(): bool
|
||||
{
|
||||
return $this instanceof DateTime;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -12,6 +14,8 @@
|
||||
*/
|
||||
namespace Cake\Chronos\Traits;
|
||||
|
||||
use Cake\Chronos\ChronosInterface;
|
||||
|
||||
/**
|
||||
* Provides methods for copying datetime objects.
|
||||
*
|
||||
@@ -24,7 +28,7 @@ trait CopyTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function copy()
|
||||
public function copy(): ChronosInterface
|
||||
{
|
||||
return static::instance($this);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -15,8 +17,8 @@ namespace Cake\Chronos\Traits;
|
||||
use Cake\Chronos\ChronosInterface;
|
||||
use Cake\Chronos\ChronosInterval;
|
||||
use Cake\Chronos\DifferenceFormatter;
|
||||
use Cake\Chronos\DifferenceFormatterInterface;
|
||||
use DatePeriod;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
@@ -33,7 +35,7 @@ trait DifferenceTrait
|
||||
/**
|
||||
* Instance of the diff formatting object.
|
||||
*
|
||||
* @var \Cake\Chronos\DifferenceFormatter
|
||||
* @var \Cake\Chronos\DifferenceFormatterInterface
|
||||
*/
|
||||
protected static $diffFormatter;
|
||||
|
||||
@@ -44,11 +46,11 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInYears(ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInYears(?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
$dt = $dt === null ? static::now($this->tz) : $dt;
|
||||
$diff = $this->diff($dt ?? static::now($this->tz), $abs);
|
||||
|
||||
return (int)$this->diff($dt, $abs)->format('%r%y');
|
||||
return $diff->invert ? -$diff->y : $diff->y;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,11 +60,12 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInMonths(ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInMonths(?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
$dt = $dt === null ? static::now($this->tz) : $dt;
|
||||
$diff = $this->diff($dt ?? static::now($this->tz), $abs);
|
||||
$months = $diff->y * ChronosInterface::MONTHS_PER_YEAR + $diff->m;
|
||||
|
||||
return $this->diffInYears($dt, $abs) * ChronosInterface::MONTHS_PER_YEAR + (int)$this->diff($dt, $abs)->format('%r%m');
|
||||
return $diff->invert ? -$months : $months;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,7 +75,7 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInWeeks(ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInWeeks(?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
return (int)($this->diffInDays($dt, $abs) / ChronosInterface::DAYS_PER_WEEK);
|
||||
}
|
||||
@@ -84,11 +87,11 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInDays(ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInDays(?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
$dt = $dt === null ? static::now($this->tz) : $dt;
|
||||
$diff = $this->diff($dt ?? static::now($this->tz), $abs);
|
||||
|
||||
return (int)$this->diff($dt, $abs)->format('%r%a');
|
||||
return $diff->invert ? -$diff->days : $diff->days;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +102,7 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInDaysFiltered(callable $callback, ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInDaysFiltered(callable $callback, ?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
return $this->diffFiltered(ChronosInterval::day(), $callback, $dt, $abs);
|
||||
}
|
||||
@@ -112,7 +115,7 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInHoursFiltered(callable $callback, ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInHoursFiltered(callable $callback, ?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
return $this->diffFiltered(ChronosInterval::hour(), $callback, $dt, $abs);
|
||||
}
|
||||
@@ -126,17 +129,16 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffFiltered(ChronosInterval $ci, callable $callback, ChronosInterface $dt = null, $abs = true)
|
||||
{
|
||||
public function diffFiltered(
|
||||
ChronosInterval $ci,
|
||||
callable $callback,
|
||||
?ChronosInterface $dt = null,
|
||||
bool $abs = true
|
||||
): int {
|
||||
$start = $this;
|
||||
$end = $dt === null ? static::now($this->tz) : $dt;
|
||||
$end = $dt ?? static::now($this->tz);
|
||||
$inverse = false;
|
||||
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$start = new DateTimeImmutable($this->toIso8601String());
|
||||
$end = new DateTimeImmutable($end->toIso8601String());
|
||||
}
|
||||
|
||||
if ($end < $start) {
|
||||
$start = $end;
|
||||
$end = $this;
|
||||
@@ -160,7 +162,7 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInWeekdays(ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInWeekdays(?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
return $this->diffInDaysFiltered(function (ChronosInterface $date) {
|
||||
return $date->isWeekday();
|
||||
@@ -174,7 +176,7 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInWeekendDays(ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInWeekendDays(?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
return $this->diffInDaysFiltered(function (ChronosInterface $date) {
|
||||
return $date->isWeekend();
|
||||
@@ -188,9 +190,13 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInHours(ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInHours(?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
return (int)($this->diffInSeconds($dt, $abs) / ChronosInterface::SECONDS_PER_MINUTE / ChronosInterface::MINUTES_PER_HOUR);
|
||||
return (int)(
|
||||
$this->diffInSeconds($dt, $abs)
|
||||
/ ChronosInterface::SECONDS_PER_MINUTE
|
||||
/ ChronosInterface::MINUTES_PER_HOUR
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,7 +206,7 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInMinutes(ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInMinutes(?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
return (int)($this->diffInSeconds($dt, $abs) / ChronosInterface::SECONDS_PER_MINUTE);
|
||||
}
|
||||
@@ -212,9 +218,9 @@ trait DifferenceTrait
|
||||
* @param bool $abs Get the absolute of the difference
|
||||
* @return int
|
||||
*/
|
||||
public function diffInSeconds(ChronosInterface $dt = null, $abs = true)
|
||||
public function diffInSeconds(?ChronosInterface $dt = null, bool $abs = true): int
|
||||
{
|
||||
$dt = ($dt === null) ? static::now($this->tz) : $dt;
|
||||
$dt = $dt ?? static::now($this->tz);
|
||||
$value = $dt->getTimestamp() - $this->getTimestamp();
|
||||
|
||||
return $abs ? abs($value) : $value;
|
||||
@@ -225,7 +231,7 @@ trait DifferenceTrait
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function secondsSinceMidnight()
|
||||
public function secondsSinceMidnight(): int
|
||||
{
|
||||
return $this->diffInSeconds($this->copy()->startOfDay());
|
||||
}
|
||||
@@ -235,7 +241,7 @@ trait DifferenceTrait
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function secondsUntilEndOfDay()
|
||||
public function secondsUntilEndOfDay(): int
|
||||
{
|
||||
return $this->diffInSeconds($this->copy()->endOfDay());
|
||||
}
|
||||
@@ -276,7 +282,7 @@ trait DifferenceTrait
|
||||
* @param bool $absolute removes time difference modifiers ago, after, etc
|
||||
* @return string
|
||||
*/
|
||||
public function diffForHumans(ChronosInterface $other = null, $absolute = false)
|
||||
public function diffForHumans(?ChronosInterface $other = null, bool $absolute = false): string
|
||||
{
|
||||
return static::diffFormatter()->diffForHumans($this, $other, $absolute);
|
||||
}
|
||||
@@ -284,10 +290,10 @@ trait DifferenceTrait
|
||||
/**
|
||||
* Get the difference formatter instance or overwrite the current one.
|
||||
*
|
||||
* @param \Cake\Chronos\DifferenceFormatter|null $formatter The formatter instance when setting.
|
||||
* @return \Cake\Chronos\DifferenceFormatter The formatter instance.
|
||||
* @param \Cake\Chronos\DifferenceFormatterInterface|null $formatter The formatter instance when setting.
|
||||
* @return \Cake\Chronos\DifferenceFormatterInterface The formatter instance.
|
||||
*/
|
||||
public static function diffFormatter($formatter = null)
|
||||
public static function diffFormatter(?DifferenceFormatterInterface $formatter = null): DifferenceFormatterInterface
|
||||
{
|
||||
if ($formatter === null) {
|
||||
if (static::$diffFormatter === null) {
|
||||
|
||||
109
vendor/cakephp/chronos/src/Traits/FactoryTrait.php
vendored
109
vendor/cakephp/chronos/src/Traits/FactoryTrait.php
vendored
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -12,6 +14,7 @@
|
||||
*/
|
||||
namespace Cake\Chronos\Traits;
|
||||
|
||||
use Cake\Chronos\ChronosInterface;
|
||||
use DateTimeInterface;
|
||||
use DateTimeZone;
|
||||
use InvalidArgumentException;
|
||||
@@ -34,7 +37,7 @@ trait FactoryTrait
|
||||
* @param \DateTimeInterface $dt The datetime instance to convert.
|
||||
* @return static
|
||||
*/
|
||||
public static function instance(DateTimeInterface $dt)
|
||||
public static function instance(DateTimeInterface $dt): ChronosInterface
|
||||
{
|
||||
if ($dt instanceof static) {
|
||||
return clone $dt;
|
||||
@@ -49,11 +52,11 @@ trait FactoryTrait
|
||||
* ChronosInterface::parse('Monday next week')->fn() rather than
|
||||
* (new Chronos('Monday next week'))->fn()
|
||||
*
|
||||
* @param \DateTimeInterface|string $time The strtotime compatible string to parse
|
||||
* @param \DateTimeInterface|string|int $time The strtotime compatible string to parse
|
||||
* @param \DateTimeZone|string|null $tz The DateTimeZone object or timezone name.
|
||||
* @return static
|
||||
*/
|
||||
public static function parse($time = 'now', $tz = null)
|
||||
public static function parse($time = 'now', $tz = null): ChronosInterface
|
||||
{
|
||||
return new static($time, $tz);
|
||||
}
|
||||
@@ -64,7 +67,7 @@ trait FactoryTrait
|
||||
* @param \DateTimeZone|string|null $tz The DateTimeZone object or timezone name.
|
||||
* @return static
|
||||
*/
|
||||
public static function now($tz = null)
|
||||
public static function now($tz = null): ChronosInterface
|
||||
{
|
||||
return new static('now', $tz);
|
||||
}
|
||||
@@ -75,7 +78,7 @@ trait FactoryTrait
|
||||
* @param \DateTimeZone|string|null $tz The timezone to use.
|
||||
* @return static
|
||||
*/
|
||||
public static function today($tz = null)
|
||||
public static function today($tz = null): ChronosInterface
|
||||
{
|
||||
return new static('midnight', $tz);
|
||||
}
|
||||
@@ -86,7 +89,7 @@ trait FactoryTrait
|
||||
* @param \DateTimeZone|string|null $tz The DateTimeZone object or timezone name the new instance should use.
|
||||
* @return static
|
||||
*/
|
||||
public static function tomorrow($tz = null)
|
||||
public static function tomorrow($tz = null): ChronosInterface
|
||||
{
|
||||
return new static('tomorrow, midnight', $tz);
|
||||
}
|
||||
@@ -97,7 +100,7 @@ trait FactoryTrait
|
||||
* @param \DateTimeZone|string|null $tz The DateTimeZone object or timezone name the new instance should use.
|
||||
* @return static
|
||||
*/
|
||||
public static function yesterday($tz = null)
|
||||
public static function yesterday($tz = null): ChronosInterface
|
||||
{
|
||||
return new static('yesterday, midnight', $tz);
|
||||
}
|
||||
@@ -107,7 +110,7 @@ trait FactoryTrait
|
||||
*
|
||||
* @return \Cake\Chronos\ChronosInterface
|
||||
*/
|
||||
public static function maxValue()
|
||||
public static function maxValue(): ChronosInterface
|
||||
{
|
||||
return static::createFromTimestampUTC(PHP_INT_MAX);
|
||||
}
|
||||
@@ -117,7 +120,7 @@ trait FactoryTrait
|
||||
*
|
||||
* @return \Cake\Chronos\ChronosInterface
|
||||
*/
|
||||
public static function minValue()
|
||||
public static function minValue(): ChronosInterface
|
||||
{
|
||||
$max = PHP_INT_SIZE === 4 ? PHP_INT_MAX : PHP_INT_MAX / 10;
|
||||
|
||||
@@ -131,9 +134,9 @@ trait FactoryTrait
|
||||
* will be used.
|
||||
*
|
||||
* If $hour is null it will be set to its now() value and the default values
|
||||
* for $minute and $second will be their now() values.
|
||||
* If $hour is not null then the default values for $minute and $second
|
||||
* will be 0.
|
||||
* for $minute, $second and $microsecond will be their now() values.
|
||||
* If $hour is not null then the default values for $minute, $second
|
||||
* and $microsecond will be 0.
|
||||
*
|
||||
* @param int|null $year The year to create an instance with.
|
||||
* @param int|null $month The month to create an instance with.
|
||||
@@ -141,25 +144,41 @@ trait FactoryTrait
|
||||
* @param int|null $hour The hour to create an instance with.
|
||||
* @param int|null $minute The minute to create an instance with.
|
||||
* @param int|null $second The second to create an instance with.
|
||||
* @param int|null $microsecond The microsecond to create an instance with.
|
||||
* @param \DateTimeZone|string|null $tz The DateTimeZone object or timezone name the new instance should use.
|
||||
* @return static
|
||||
*/
|
||||
public static function create($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null)
|
||||
{
|
||||
$year = ($year === null) ? date('Y') : $year;
|
||||
$month = ($month === null) ? date('n') : $month;
|
||||
$day = ($day === null) ? date('j') : $day;
|
||||
public static function create(
|
||||
?int $year = null,
|
||||
?int $month = null,
|
||||
?int $day = null,
|
||||
?int $hour = null,
|
||||
?int $minute = null,
|
||||
?int $second = null,
|
||||
?int $microsecond = null,
|
||||
$tz = null
|
||||
): ChronosInterface {
|
||||
$now = static::now();
|
||||
$year = $year ?? (int)$now->format('Y');
|
||||
$month = $month ?? $now->format('m');
|
||||
$day = $day ?? $now->format('d');
|
||||
|
||||
if ($hour === null) {
|
||||
$hour = date('G');
|
||||
$minute = ($minute === null) ? date('i') : $minute;
|
||||
$second = ($second === null) ? date('s') : $second;
|
||||
$hour = $now->format('H');
|
||||
$minute = $minute ?? $now->format('i');
|
||||
$second = $second ?? $now->format('s');
|
||||
$microsecond = $microsecond ?? $now->format('u');
|
||||
} else {
|
||||
$minute = ($minute === null) ? 0 : $minute;
|
||||
$second = ($second === null) ? 0 : $second;
|
||||
$minute = $minute ?? 0;
|
||||
$second = $second ?? 0;
|
||||
$microsecond = $microsecond ?? 0;
|
||||
}
|
||||
|
||||
$instance = static::createFromFormat('Y-n-j G:i:s', sprintf('%s-%s-%s %s:%02s:%02s', 0, $month, $day, $hour, $minute, $second), $tz);
|
||||
$instance = static::createFromFormat(
|
||||
'Y-m-d H:i:s.u',
|
||||
sprintf('%s-%s-%s %s:%02s:%02s.%06s', 0, $month, $day, $hour, $minute, $second, $microsecond),
|
||||
$tz
|
||||
);
|
||||
|
||||
return $instance->addYears($year);
|
||||
}
|
||||
@@ -167,15 +186,19 @@ trait FactoryTrait
|
||||
/**
|
||||
* Create a ChronosInterface instance from just a date. The time portion is set to now.
|
||||
*
|
||||
* @param int $year The year to create an instance with.
|
||||
* @param int $month The month to create an instance with.
|
||||
* @param int $day The day to create an instance with.
|
||||
* @param int|null $year The year to create an instance with.
|
||||
* @param int|null $month The month to create an instance with.
|
||||
* @param int|null $day The day to create an instance with.
|
||||
* @param \DateTimeZone|string|null $tz The DateTimeZone object or timezone name the new instance should use.
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromDate($year = null, $month = null, $day = null, $tz = null)
|
||||
{
|
||||
return static::create($year, $month, $day, null, null, null, $tz);
|
||||
public static function createFromDate(
|
||||
?int $year = null,
|
||||
?int $month = null,
|
||||
?int $day = null,
|
||||
$tz = null
|
||||
): ChronosInterface {
|
||||
return static::create($year, $month, $day, null, null, null, null, $tz);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,12 +207,18 @@ trait FactoryTrait
|
||||
* @param int|null $hour The hour to create an instance with.
|
||||
* @param int|null $minute The minute to create an instance with.
|
||||
* @param int|null $second The second to create an instance with.
|
||||
* @param int|null $microsecond The microsecond to create an instance with.
|
||||
* @param \DateTimeZone|string|null $tz The DateTimeZone object or timezone name the new instance should use.
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromTime($hour = null, $minute = null, $second = null, $tz = null)
|
||||
{
|
||||
return static::create(null, null, null, $hour, $minute, $second, $tz);
|
||||
public static function createFromTime(
|
||||
?int $hour = null,
|
||||
?int $minute = null,
|
||||
?int $second = null,
|
||||
?int $microsecond = null,
|
||||
$tz = null
|
||||
): ChronosInterface {
|
||||
return static::create(null, null, null, $hour, $minute, $second, $microsecond, $tz);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,7 +230,7 @@ trait FactoryTrait
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function createFromFormat($format, $time, $tz = null)
|
||||
public static function createFromFormat($format, $time, $tz = null): ChronosInterface
|
||||
{
|
||||
if ($tz !== null) {
|
||||
$dt = parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz));
|
||||
@@ -210,11 +239,11 @@ trait FactoryTrait
|
||||
}
|
||||
|
||||
$errors = parent::getLastErrors();
|
||||
if ($dt == false) {
|
||||
if (!$dt) {
|
||||
throw new InvalidArgumentException(implode(PHP_EOL, $errors['errors']));
|
||||
}
|
||||
|
||||
$dt = static::instance($dt);
|
||||
$dt = new static($dt->format('Y-m-d H:i:s.u'), $dt->getTimezone());
|
||||
static::$_lastErrors = $errors;
|
||||
|
||||
return $dt;
|
||||
@@ -242,7 +271,7 @@ trait FactoryTrait
|
||||
* @param (int|string)[] $values Array of date and time values.
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromArray($values)
|
||||
public static function createFromArray(array $values): ChronosInterface
|
||||
{
|
||||
$values += ['hour' => 0, 'minute' => 0, 'second' => 0, 'microsecond' => 0, 'timezone' => null];
|
||||
|
||||
@@ -282,7 +311,7 @@ trait FactoryTrait
|
||||
* @param \DateTimeZone|string|null $tz The DateTimeZone object or timezone name the new instance should use.
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromTimestamp($timestamp, $tz = null)
|
||||
public static function createFromTimestamp(int $timestamp, $tz = null): ChronosInterface
|
||||
{
|
||||
return static::now($tz)->setTimestamp($timestamp);
|
||||
}
|
||||
@@ -293,7 +322,7 @@ trait FactoryTrait
|
||||
* @param int $timestamp The UTC timestamp to create an instance from.
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromTimestampUTC($timestamp)
|
||||
public static function createFromTimestampUTC(int $timestamp): ChronosInterface
|
||||
{
|
||||
return new static('@' . $timestamp);
|
||||
}
|
||||
@@ -305,7 +334,7 @@ trait FactoryTrait
|
||||
* @return \DateTimeZone
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected static function safeCreateDateTimeZone($object)
|
||||
protected static function safeCreateDateTimeZone($object): DateTimeZone
|
||||
{
|
||||
if ($object === null) {
|
||||
return new DateTimeZone(date_default_timezone_get());
|
||||
@@ -324,7 +353,7 @@ trait FactoryTrait
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getLastErrors()
|
||||
public static function getLastErrors(): array
|
||||
{
|
||||
if (empty(static::$_lastErrors)) {
|
||||
return parent::getLastErrors();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -27,7 +29,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function resetToStringFormat()
|
||||
public static function resetToStringFormat(): void
|
||||
{
|
||||
static::setToStringFormat(ChronosInterface::DEFAULT_TO_STRING_FORMAT);
|
||||
}
|
||||
@@ -38,7 +40,7 @@ trait FormattingTrait
|
||||
* @param string $format The format to use in future __toString() calls.
|
||||
* @return void
|
||||
*/
|
||||
public static function setToStringFormat($format)
|
||||
public static function setToStringFormat($format): void
|
||||
{
|
||||
static::$toStringFormat = $format;
|
||||
}
|
||||
@@ -48,7 +50,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->format(static::$toStringFormat);
|
||||
}
|
||||
@@ -58,7 +60,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toDateString()
|
||||
public function toDateString(): string
|
||||
{
|
||||
return $this->format('Y-m-d');
|
||||
}
|
||||
@@ -68,7 +70,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toFormattedDateString()
|
||||
public function toFormattedDateString(): string
|
||||
{
|
||||
return $this->format('M j, Y');
|
||||
}
|
||||
@@ -78,7 +80,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toTimeString()
|
||||
public function toTimeString(): string
|
||||
{
|
||||
return $this->format('H:i:s');
|
||||
}
|
||||
@@ -88,7 +90,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toDateTimeString()
|
||||
public function toDateTimeString(): string
|
||||
{
|
||||
return $this->format('Y-m-d H:i:s');
|
||||
}
|
||||
@@ -98,7 +100,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toDayDateTimeString()
|
||||
public function toDayDateTimeString(): string
|
||||
{
|
||||
return $this->format('D, M j, Y g:i A');
|
||||
}
|
||||
@@ -108,7 +110,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toAtomString()
|
||||
public function toAtomString(): string
|
||||
{
|
||||
return $this->format(DateTime::ATOM);
|
||||
}
|
||||
@@ -118,7 +120,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toCookieString()
|
||||
public function toCookieString(): string
|
||||
{
|
||||
return $this->format(DateTime::COOKIE);
|
||||
}
|
||||
@@ -128,7 +130,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toIso8601String()
|
||||
public function toIso8601String(): string
|
||||
{
|
||||
return $this->format(DateTime::ATOM);
|
||||
}
|
||||
@@ -138,7 +140,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toRfc822String()
|
||||
public function toRfc822String(): string
|
||||
{
|
||||
return $this->format(DateTime::RFC822);
|
||||
}
|
||||
@@ -148,7 +150,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toRfc850String()
|
||||
public function toRfc850String(): string
|
||||
{
|
||||
return $this->format(DateTime::RFC850);
|
||||
}
|
||||
@@ -158,7 +160,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toRfc1036String()
|
||||
public function toRfc1036String(): string
|
||||
{
|
||||
return $this->format(DateTime::RFC1036);
|
||||
}
|
||||
@@ -168,7 +170,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toRfc1123String()
|
||||
public function toRfc1123String(): string
|
||||
{
|
||||
return $this->format(DateTime::RFC1123);
|
||||
}
|
||||
@@ -178,7 +180,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toRfc2822String()
|
||||
public function toRfc2822String(): string
|
||||
{
|
||||
return $this->format(DateTime::RFC2822);
|
||||
}
|
||||
@@ -188,7 +190,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toRfc3339String()
|
||||
public function toRfc3339String(): string
|
||||
{
|
||||
return $this->format(DateTime::RFC3339);
|
||||
}
|
||||
@@ -198,7 +200,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toRssString()
|
||||
public function toRssString(): string
|
||||
{
|
||||
return $this->format(DateTime::RSS);
|
||||
}
|
||||
@@ -208,7 +210,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toW3cString()
|
||||
public function toW3cString(): string
|
||||
{
|
||||
return $this->format(DateTime::W3C);
|
||||
}
|
||||
@@ -218,7 +220,7 @@ trait FormattingTrait
|
||||
*
|
||||
* @return string UNIX timestamp
|
||||
*/
|
||||
public function toUnixString()
|
||||
public function toUnixString(): string
|
||||
{
|
||||
return $this->format('U');
|
||||
}
|
||||
@@ -229,9 +231,9 @@ trait FormattingTrait
|
||||
* @param bool $range Range.
|
||||
* @return int|array 1, 2, 3, or 4 quarter of year or array if $range true
|
||||
*/
|
||||
public function toQuarter($range = false)
|
||||
public function toQuarter(bool $range = false)
|
||||
{
|
||||
$quarter = ceil($this->format('m') / 3);
|
||||
$quarter = (int)ceil($this->format('m') / 3);
|
||||
if ($range === false) {
|
||||
return $quarter;
|
||||
}
|
||||
@@ -244,15 +246,15 @@ trait FormattingTrait
|
||||
return [$year . '-04-01', $year . '-06-30'];
|
||||
case 3:
|
||||
return [$year . '-07-01', $year . '-09-30'];
|
||||
case 4:
|
||||
default:
|
||||
return [$year . '-10-01', $year . '-12-31'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toWeek()
|
||||
public function toWeek(): int
|
||||
{
|
||||
return (int)$this->format('W');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -11,6 +13,8 @@
|
||||
*/
|
||||
namespace Cake\Chronos\Traits;
|
||||
|
||||
use Cake\Chronos\ChronosInterface;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
|
||||
/**
|
||||
@@ -27,29 +31,26 @@ trait FrozenTimeTrait
|
||||
*
|
||||
* Used to ensure constructed objects always lack time.
|
||||
*
|
||||
* @param string|int|\DateTimeInterface $time The input time. Integer values will be assumed
|
||||
* @param \DateTime|\DateTimeImmutable|string|int|null $time The input time. Integer values will be assumed
|
||||
* to be in UTC. The 'now' and '' values will use the current local time.
|
||||
* @param \DateTimeZone|null $tz The timezone in which the date is taken
|
||||
* @return string The date component of $time.
|
||||
*/
|
||||
protected function stripTime($time)
|
||||
protected function stripTime($time, $tz): string
|
||||
{
|
||||
if (is_int($time) || ctype_digit($time)) {
|
||||
if (is_int($time)) {
|
||||
return gmdate('Y-m-d 00:00:00', $time);
|
||||
}
|
||||
if ($time instanceof DateTimeInterface) {
|
||||
$time = $time->format('Y-m-d 00:00:00');
|
||||
}
|
||||
if (substr($time, 0, 1) === '@') {
|
||||
return gmdate('Y-m-d 00:00:00', substr($time, 1));
|
||||
}
|
||||
if ($time === null || $time === 'now' || $time === '') {
|
||||
return date('Y-m-d 00:00:00');
|
||||
}
|
||||
if ($this->hasRelativeKeywords($time)) {
|
||||
return date('Y-m-d 00:00:00', strtotime($time));
|
||||
|
||||
if (is_string($time) && substr($time, 0, 1) === '@') {
|
||||
return gmdate('Y-m-d 00:00:00', (int)substr($time, 1));
|
||||
}
|
||||
|
||||
return preg_replace('/\d{1,2}:\d{1,2}:\d{1,2}(?:\.\d+)?/', '00:00:00', $time);
|
||||
if (!($time instanceof DateTimeInterface)) {
|
||||
$time = new DateTimeImmutable($time ?? 'now', $tz);
|
||||
}
|
||||
|
||||
return $time->format('Y-m-d 00:00:00');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +59,7 @@ trait FrozenTimeTrait
|
||||
* @param string $time The input expression
|
||||
* @return string The output expression with no time modifiers.
|
||||
*/
|
||||
protected function stripRelativeTime($time)
|
||||
protected function stripRelativeTime(string $time): string
|
||||
{
|
||||
return preg_replace('/([-+]\s*\d+\s(?:minutes|seconds|hours|microseconds))/', '', $time);
|
||||
}
|
||||
@@ -74,13 +75,9 @@ trait FrozenTimeTrait
|
||||
* @param int $microseconds The microseconds to set (ignored)
|
||||
* @return static A modified Date instance.
|
||||
*/
|
||||
public function setTime($hours, $minutes, $seconds = null, $microseconds = null)
|
||||
public function setTime($hours, $minutes, $seconds = null, $microseconds = null): ChronosInterface
|
||||
{
|
||||
if (CHRONOS_SUPPORTS_MICROSECONDS) {
|
||||
return parent::setTime(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
return parent::setTime(0, 0, 0);
|
||||
return parent::setTime(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +88,7 @@ trait FrozenTimeTrait
|
||||
* @param \DateInterval $interval The interval to modify this date by.
|
||||
* @return static A modified Date instance
|
||||
*/
|
||||
public function add($interval)
|
||||
public function add($interval): ChronosInterface
|
||||
{
|
||||
return parent::add($interval)->setTime(0, 0, 0);
|
||||
}
|
||||
@@ -104,7 +101,7 @@ trait FrozenTimeTrait
|
||||
* @param \DateInterval $interval The interval to modify this date by.
|
||||
* @return static A modified Date instance
|
||||
*/
|
||||
public function sub($interval)
|
||||
public function sub($interval): ChronosInterface
|
||||
{
|
||||
return parent::sub($interval)->setTime(0, 0, 0);
|
||||
}
|
||||
@@ -157,7 +154,7 @@ trait FrozenTimeTrait
|
||||
* @param int $value The timestamp value to set.
|
||||
* @return static
|
||||
*/
|
||||
public function setTimestamp($value)
|
||||
public function setTimestamp($value): ChronosInterface
|
||||
{
|
||||
return parent::setTimestamp($value)->setTime(0, 0, 0);
|
||||
}
|
||||
@@ -171,7 +168,7 @@ trait FrozenTimeTrait
|
||||
* @param string $relative The relative change to make.
|
||||
* @return static A new date with the applied date changes.
|
||||
*/
|
||||
public function modify($relative)
|
||||
public function modify($relative): ChronosInterface
|
||||
{
|
||||
if (preg_match('/hour|minute|second/', $relative)) {
|
||||
return $this;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -38,13 +40,14 @@ use InvalidArgumentException;
|
||||
* @property-read int $quarter
|
||||
* @property-read int $offset
|
||||
* @property-read int $offsetHours
|
||||
* @property-read boolean $dst
|
||||
* @property-read boolean $local
|
||||
* @property-read boolean $utc
|
||||
* @property-read bool $dst
|
||||
* @property-read bool $local
|
||||
* @property-read bool $utc
|
||||
* @property-read \DateTimeZone $timezone
|
||||
* @property-read \DateTimeZone $tz
|
||||
* @property-read string $timezoneName
|
||||
* @property-read string $tzName
|
||||
* @property-read string $dayOfWeekName
|
||||
*/
|
||||
trait MagicPropertyTrait
|
||||
{
|
||||
@@ -52,10 +55,10 @@ trait MagicPropertyTrait
|
||||
* Get a part of the ChronosInterface object
|
||||
*
|
||||
* @param string $name The property name to read.
|
||||
* @return mixed The property value.
|
||||
* @return string|int|bool|\DateTimeZone The property value.
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __get($name)
|
||||
public function __get(string $name)
|
||||
{
|
||||
static $formats = [
|
||||
'year' => 'Y',
|
||||
@@ -78,6 +81,9 @@ trait MagicPropertyTrait
|
||||
case isset($formats[$name]):
|
||||
return (int)$this->format($formats[$name]);
|
||||
|
||||
case $name === 'dayOfWeekName':
|
||||
return $this->format('l');
|
||||
|
||||
case $name === 'weekOfMonth':
|
||||
return (int)ceil($this->day / ChronosInterface::DAYS_PER_WEEK);
|
||||
|
||||
@@ -119,7 +125,7 @@ trait MagicPropertyTrait
|
||||
* @param string $name The property name to check.
|
||||
* @return bool Whether or not the property exists.
|
||||
*/
|
||||
public function __isset($name)
|
||||
public function __isset(string $name): bool
|
||||
{
|
||||
try {
|
||||
$this->__get($name);
|
||||
|
||||
446
vendor/cakephp/chronos/src/Traits/ModifierTrait.php
vendored
446
vendor/cakephp/chronos/src/Traits/ModifierTrait.php
vendored
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -13,8 +15,6 @@
|
||||
namespace Cake\Chronos\Traits;
|
||||
|
||||
use Cake\Chronos\ChronosInterface;
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
|
||||
/**
|
||||
* Provides a suite of modifier methods.
|
||||
@@ -28,7 +28,6 @@ use DateTimeImmutable;
|
||||
*/
|
||||
trait ModifierTrait
|
||||
{
|
||||
|
||||
/**
|
||||
* Names of days of the week.
|
||||
*
|
||||
@@ -63,7 +62,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getWeekStartsAt()
|
||||
public static function getWeekStartsAt(): int
|
||||
{
|
||||
return static::$weekStartsAt;
|
||||
}
|
||||
@@ -74,7 +73,7 @@ trait ModifierTrait
|
||||
* @param int $day The day the week starts with.
|
||||
* @return void
|
||||
*/
|
||||
public static function setWeekStartsAt($day)
|
||||
public static function setWeekStartsAt(int $day): void
|
||||
{
|
||||
static::$weekStartsAt = $day;
|
||||
}
|
||||
@@ -84,7 +83,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getWeekEndsAt()
|
||||
public static function getWeekEndsAt(): int
|
||||
{
|
||||
return static::$weekEndsAt;
|
||||
}
|
||||
@@ -95,7 +94,7 @@ trait ModifierTrait
|
||||
* @param int $day The day the week ends with.
|
||||
* @return void
|
||||
*/
|
||||
public static function setWeekEndsAt($day)
|
||||
public static function setWeekEndsAt(int $day): void
|
||||
{
|
||||
static::$weekEndsAt = $day;
|
||||
}
|
||||
@@ -109,9 +108,8 @@ trait ModifierTrait
|
||||
* @param int $month The month to set.
|
||||
* @param int $day The day to set.
|
||||
* @return static
|
||||
* @see https://bugs.php.net/bug.php?id=63863
|
||||
*/
|
||||
public function setDate($year, $month, $day)
|
||||
public function setDate($year, $month, $day): ChronosInterface
|
||||
{
|
||||
return $this->modify('+0 day')->setDateParent($year, $month, $day);
|
||||
}
|
||||
@@ -125,7 +123,7 @@ trait ModifierTrait
|
||||
* @param int $day The day to set.
|
||||
* @return static
|
||||
*/
|
||||
private function setDateParent($year, $month, $day)
|
||||
private function setDateParent(int $year, int $month, int $day): ChronosInterface
|
||||
{
|
||||
return parent::setDate($year, $month, $day);
|
||||
}
|
||||
@@ -141,8 +139,14 @@ trait ModifierTrait
|
||||
* @param int $second The second to set.
|
||||
* @return static
|
||||
*/
|
||||
public function setDateTime($year, $month, $day, $hour, $minute, $second = 0)
|
||||
{
|
||||
public function setDateTime(
|
||||
int $year,
|
||||
int $month,
|
||||
int $day,
|
||||
int $hour,
|
||||
int $minute,
|
||||
int $second = 0
|
||||
): ChronosInterface {
|
||||
return $this->setDate($year, $month, $day)->setTime($hour, $minute, $second);
|
||||
}
|
||||
|
||||
@@ -152,14 +156,14 @@ trait ModifierTrait
|
||||
* @param string $time Time as string.
|
||||
* @return static
|
||||
*/
|
||||
public function setTimeFromTimeString($time)
|
||||
public function setTimeFromTimeString(string $time): ChronosInterface
|
||||
{
|
||||
$time = explode(":", $time);
|
||||
$hour = (int)$time[0];
|
||||
$minute = isset($time[1]) ? (int)$time[1] : 0;
|
||||
$second = isset($time[2]) ? (int)$time[2] : 0;
|
||||
$time = explode(':', $time);
|
||||
$hour = $time[0];
|
||||
$minute = $time[1] ?? 0;
|
||||
$second = $time[2] ?? 0;
|
||||
|
||||
return $this->setTime($hour, $minute, $second);
|
||||
return $this->setTime((int)$hour, (int)$minute, (int)$second);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,7 +172,7 @@ trait ModifierTrait
|
||||
* @param int $value The timestamp value to set.
|
||||
* @return static
|
||||
*/
|
||||
public function timestamp($value)
|
||||
public function timestamp(int $value): ChronosInterface
|
||||
{
|
||||
return $this->setTimestamp($value);
|
||||
}
|
||||
@@ -179,7 +183,7 @@ trait ModifierTrait
|
||||
* @param int $value The year value.
|
||||
* @return static
|
||||
*/
|
||||
public function year($value)
|
||||
public function year(int $value): ChronosInterface
|
||||
{
|
||||
return $this->setDate($value, $this->month, $this->day);
|
||||
}
|
||||
@@ -190,7 +194,7 @@ trait ModifierTrait
|
||||
* @param int $value The month value.
|
||||
* @return static
|
||||
*/
|
||||
public function month($value)
|
||||
public function month(int $value): ChronosInterface
|
||||
{
|
||||
return $this->setDate($this->year, $value, $this->day);
|
||||
}
|
||||
@@ -201,7 +205,7 @@ trait ModifierTrait
|
||||
* @param int $value The day value.
|
||||
* @return static
|
||||
*/
|
||||
public function day($value)
|
||||
public function day(int $value): ChronosInterface
|
||||
{
|
||||
return $this->setDate($this->year, $this->month, $value);
|
||||
}
|
||||
@@ -212,7 +216,7 @@ trait ModifierTrait
|
||||
* @param int $value The hour value.
|
||||
* @return static
|
||||
*/
|
||||
public function hour($value)
|
||||
public function hour(int $value): ChronosInterface
|
||||
{
|
||||
return $this->setTime($value, $this->minute, $this->second);
|
||||
}
|
||||
@@ -223,7 +227,7 @@ trait ModifierTrait
|
||||
* @param int $value The minute value.
|
||||
* @return static
|
||||
*/
|
||||
public function minute($value)
|
||||
public function minute(int $value): ChronosInterface
|
||||
{
|
||||
return $this->setTime($this->hour, $value, $this->second);
|
||||
}
|
||||
@@ -234,7 +238,7 @@ trait ModifierTrait
|
||||
* @param int $value The seconds value.
|
||||
* @return static
|
||||
*/
|
||||
public function second($value)
|
||||
public function second(int $value): ChronosInterface
|
||||
{
|
||||
return $this->setTime($this->hour, $this->minute, $value);
|
||||
}
|
||||
@@ -243,45 +247,128 @@ trait ModifierTrait
|
||||
* Add years to the instance. Positive $value travel forward while
|
||||
* negative $value travel into the past.
|
||||
*
|
||||
* @param int $value The number of years to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addYears($value)
|
||||
{
|
||||
return $this->modify((int)$value . ' year');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a year to the instance
|
||||
* If the new date does not exist, the last day of the month is used
|
||||
* instead instead of overflowing into the next month.
|
||||
*
|
||||
* ### Example:
|
||||
*
|
||||
* ```
|
||||
* (new Chronos('2015-01-03'))->addYears(1); // Results in 2016-01-03
|
||||
*
|
||||
* (new Chronos('2012-02-29'))->addYears(1); // Results in 2013-02-28
|
||||
* ```
|
||||
*
|
||||
* @param int $value The number of years to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addYear($value = 1)
|
||||
public function addYears(int $value): ChronosInterface
|
||||
{
|
||||
$month = $this->month;
|
||||
$date = $this->modify($value . ' year');
|
||||
|
||||
if ($date->month !== $month) {
|
||||
return $date->modify('last day of previous month');
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a year to the instance.
|
||||
*
|
||||
* Has the same behavior as `addYears()`.
|
||||
*
|
||||
* @param int $value The number of years to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addYear(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->addYears($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a year from the instance
|
||||
* Remove years from the instance.
|
||||
*
|
||||
* Has the same behavior as `addYears()`.
|
||||
*
|
||||
* @param int $value The number of years to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subYear($value = 1)
|
||||
public function subYears(int $value): ChronosInterface
|
||||
{
|
||||
return $this->addYears(-1 * $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a year from the instance
|
||||
*
|
||||
* Has the same behavior as `addYears()`.
|
||||
*
|
||||
* @param int $value The number of years to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subYear(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->subYears($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove years from the instance.
|
||||
* Add years with overflowing to the instance. Positive $value
|
||||
* travels forward while negative $value travels into the past.
|
||||
*
|
||||
* If the new date does not exist, the days overflow into the next month.
|
||||
*
|
||||
* ### Example:
|
||||
*
|
||||
* ```
|
||||
* (new Chronos('2012-02-29'))->addYearsWithOverflow(1); // Results in 2013-03-01
|
||||
* ```
|
||||
*
|
||||
* @param int $value The number of years to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addYearsWithOverflow(int $value): ChronosInterface
|
||||
{
|
||||
return $this->modify($value . ' year');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a year with overflow to the instance.
|
||||
*
|
||||
* Has the same behavior as `addYearsWithOverflow()`.
|
||||
*
|
||||
* @param int $value The number of years to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addYearWithOverflow(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->addYearsWithOverflow($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove years with overflow from the instance
|
||||
*
|
||||
* Has the same behavior as `addYeasrWithOverflow()`.
|
||||
*
|
||||
* @param int $value The number of years to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subYears($value)
|
||||
public function subYearsWithOverflow(int $value): ChronosInterface
|
||||
{
|
||||
return $this->addYears(-1 * $value);
|
||||
return $this->addYearsWithOverflow(-1 * $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a year with overflow from the instance.
|
||||
*
|
||||
* Has the same behavior as `addYearsWithOverflow()`.
|
||||
*
|
||||
* @param int $value The number of years to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subYearWithOverflow(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->subYearsWithOverflow($value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,10 +390,10 @@ trait ModifierTrait
|
||||
* @param int $value The number of months to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addMonths($value)
|
||||
public function addMonths(int $value): ChronosInterface
|
||||
{
|
||||
$day = $this->day;
|
||||
$date = $this->modify((int)$value . ' month');
|
||||
$date = $this->modify($value . ' month');
|
||||
|
||||
if ($date->day !== $day) {
|
||||
return $date->modify('last day of previous month');
|
||||
@@ -318,22 +405,12 @@ trait ModifierTrait
|
||||
/**
|
||||
* Add a month to the instance
|
||||
*
|
||||
* When adding or subtracting months, if the resulting time is a date
|
||||
* that does not exist, the result of this operation will always be the
|
||||
* last day of the intended month.
|
||||
*
|
||||
* ### Example:
|
||||
*
|
||||
* ```
|
||||
* (new Chronos('2015-01-03'))->addMonth(); // Results in 2015-02-03
|
||||
*
|
||||
* (new Chronos('2015-01-31'))->addMonth(); // Results in 2015-02-28
|
||||
* ```
|
||||
* Has the same behavior as `addMonths()`.
|
||||
*
|
||||
* @param int $value The number of months to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addMonth($value = 1)
|
||||
public function addMonth(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->addMonths($value);
|
||||
}
|
||||
@@ -341,22 +418,12 @@ trait ModifierTrait
|
||||
/**
|
||||
* Remove a month from the instance
|
||||
*
|
||||
* When adding or subtracting months, if the resulting time is a date
|
||||
* that does not exist, the result of this operation will always be the
|
||||
* last day of the intended month.
|
||||
*
|
||||
* ### Example:
|
||||
*
|
||||
* ```
|
||||
* (new Chronos('2015-03-01'))->subMonth(); // Results in 2015-02-01
|
||||
*
|
||||
* (new Chronos('2015-03-31'))->subMonth(); // Results in 2015-02-28
|
||||
* ```
|
||||
* Has the same behavior as `addMonths()`.
|
||||
*
|
||||
* @param int $value The number of months to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subMonth($value = 1)
|
||||
public function subMonth(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->subMonths($value);
|
||||
}
|
||||
@@ -364,22 +431,12 @@ trait ModifierTrait
|
||||
/**
|
||||
* Remove months from the instance
|
||||
*
|
||||
* When adding or subtracting months, if the resulting time is a date
|
||||
* that does not exist, the result of this operation will always be the
|
||||
* last day of the intended month.
|
||||
*
|
||||
* ### Example:
|
||||
*
|
||||
* ```
|
||||
* (new Chronos('2015-03-01'))->subMonths(1); // Results in 2015-02-01
|
||||
*
|
||||
* (new Chronos('2015-03-31'))->subMonths(1); // Results in 2015-02-28
|
||||
* ```
|
||||
* Has the same behavior as `addMonths()`.
|
||||
*
|
||||
* @param int $value The number of months to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subMonths($value)
|
||||
public function subMonths(int $value): ChronosInterface
|
||||
{
|
||||
return $this->addMonths(-1 * $value);
|
||||
}
|
||||
@@ -388,47 +445,61 @@ trait ModifierTrait
|
||||
* Add months with overflowing to the instance. Positive $value
|
||||
* travels forward while negative $value travels into the past.
|
||||
*
|
||||
* @param int $value The number of months to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addMonthsWithOverflow($value)
|
||||
{
|
||||
return $this->modify((int)$value . ' month');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a month with overflow to the instance
|
||||
* If the new date does not exist, the days overflow into the next month.
|
||||
*
|
||||
* ### Example:
|
||||
*
|
||||
* ```
|
||||
* (new Chronos('2012-01-30'))->addMonthsWithOverflow(1); // Results in 2013-03-01
|
||||
* ```
|
||||
*
|
||||
* @param int $value The number of months to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addMonthWithOverflow($value = 1)
|
||||
public function addMonthsWithOverflow(int $value): ChronosInterface
|
||||
{
|
||||
return $this->modify((int)$value . ' month');
|
||||
return $this->modify($value . ' month');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a month with overflow from the instance
|
||||
* Add a month with overflow to the instance.
|
||||
*
|
||||
* Has the same behavior as `addMonthsWithOverflow()`.
|
||||
*
|
||||
* @param int $value The number of months to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addMonthWithOverflow(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->modify($value . ' month');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove months with overflow from the instance.
|
||||
*
|
||||
* Has the same behavior as `addMonthsWithOverflow()`.
|
||||
*
|
||||
* @param int $value The number of months to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subMonthWithOverflow($value = 1)
|
||||
{
|
||||
return $this->subMonthsWithOverflow($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove months with overflow from the instance
|
||||
*
|
||||
* @param int $value The number of months to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subMonthsWithOverflow($value)
|
||||
public function subMonthsWithOverflow(int $value): ChronosInterface
|
||||
{
|
||||
return $this->addMonthsWithOverflow(-1 * $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a month with overflow from the instance.
|
||||
*
|
||||
* Has the same behavior as `addMonthsWithOverflow()`.
|
||||
*
|
||||
* @param int $value The number of months to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subMonthWithOverflow(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->subMonthsWithOverflow($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add days to the instance. Positive $value travels forward while
|
||||
* negative $value travels into the past.
|
||||
@@ -436,10 +507,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of days to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addDays($value)
|
||||
public function addDays(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value day");
|
||||
}
|
||||
|
||||
@@ -449,10 +518,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of days to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addDay($value = 1)
|
||||
public function addDay(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value day");
|
||||
}
|
||||
|
||||
@@ -462,10 +529,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of days to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subDay($value = 1)
|
||||
public function subDay(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value day");
|
||||
}
|
||||
|
||||
@@ -475,10 +540,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of days to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subDays($value)
|
||||
public function subDays(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value day");
|
||||
}
|
||||
|
||||
@@ -489,7 +552,7 @@ trait ModifierTrait
|
||||
* @param int $value The number of weekdays to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addWeekdays($value)
|
||||
public function addWeekdays(int $value): ChronosInterface
|
||||
{
|
||||
return $this->modify((int)$value . ' weekdays ' . $this->format('H:i:s'));
|
||||
}
|
||||
@@ -500,7 +563,7 @@ trait ModifierTrait
|
||||
* @param int $value The number of weekdays to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addWeekday($value = 1)
|
||||
public function addWeekday(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->addWeekdays($value);
|
||||
}
|
||||
@@ -511,10 +574,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of weekdays to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subWeekdays($value)
|
||||
public function subWeekdays(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value weekdays ago, " . $this->format('H:i:s'));
|
||||
}
|
||||
|
||||
@@ -524,7 +585,7 @@ trait ModifierTrait
|
||||
* @param int $value The number of weekdays to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subWeekday($value = 1)
|
||||
public function subWeekday(int $value = 1): ChronosInterface
|
||||
{
|
||||
return $this->subWeekdays($value);
|
||||
}
|
||||
@@ -536,10 +597,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of weeks to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addWeeks($value)
|
||||
public function addWeeks(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value week");
|
||||
}
|
||||
|
||||
@@ -549,10 +608,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of weeks to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addWeek($value = 1)
|
||||
public function addWeek(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value week");
|
||||
}
|
||||
|
||||
@@ -562,10 +619,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of weeks to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subWeek($value = 1)
|
||||
public function subWeek(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value week");
|
||||
}
|
||||
|
||||
@@ -575,10 +630,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of weeks to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subWeeks($value)
|
||||
public function subWeeks(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value week");
|
||||
}
|
||||
|
||||
@@ -589,10 +642,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of hours to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addHours($value)
|
||||
public function addHours(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value hour");
|
||||
}
|
||||
|
||||
@@ -602,10 +653,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of hours to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addHour($value = 1)
|
||||
public function addHour(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value hour");
|
||||
}
|
||||
|
||||
@@ -615,10 +664,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of hours to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subHour($value = 1)
|
||||
public function subHour(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value hour");
|
||||
}
|
||||
|
||||
@@ -628,10 +675,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of hours to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subHours($value)
|
||||
public function subHours(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value hour");
|
||||
}
|
||||
|
||||
@@ -642,10 +687,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of minutes to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addMinutes($value)
|
||||
public function addMinutes(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value minute");
|
||||
}
|
||||
|
||||
@@ -655,10 +698,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of minutes to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addMinute($value = 1)
|
||||
public function addMinute(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value minute");
|
||||
}
|
||||
|
||||
@@ -668,10 +709,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of minutes to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subMinute($value = 1)
|
||||
public function subMinute(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value minute");
|
||||
}
|
||||
|
||||
@@ -681,10 +720,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of minutes to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subMinutes($value)
|
||||
public function subMinutes(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value minute");
|
||||
}
|
||||
|
||||
@@ -695,10 +732,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of seconds to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addSeconds($value)
|
||||
public function addSeconds(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value second");
|
||||
}
|
||||
|
||||
@@ -708,10 +743,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of seconds to add.
|
||||
* @return static
|
||||
*/
|
||||
public function addSecond($value = 1)
|
||||
public function addSecond(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("$value second");
|
||||
}
|
||||
|
||||
@@ -721,10 +754,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of seconds to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subSecond($value = 1)
|
||||
public function subSecond(int $value = 1): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value second");
|
||||
}
|
||||
|
||||
@@ -734,10 +765,8 @@ trait ModifierTrait
|
||||
* @param int $value The number of seconds to remove.
|
||||
* @return static
|
||||
*/
|
||||
public function subSeconds($value)
|
||||
public function subSeconds(int $value): ChronosInterface
|
||||
{
|
||||
$value = (int)$value;
|
||||
|
||||
return $this->modify("-$value second");
|
||||
}
|
||||
|
||||
@@ -746,7 +775,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function startOfDay()
|
||||
public function startOfDay(): ChronosInterface
|
||||
{
|
||||
return $this->modify('midnight');
|
||||
}
|
||||
@@ -756,7 +785,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function endOfDay()
|
||||
public function endOfDay(): ChronosInterface
|
||||
{
|
||||
return $this->modify('23:59:59');
|
||||
}
|
||||
@@ -766,7 +795,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function startOfMonth()
|
||||
public function startOfMonth(): ChronosInterface
|
||||
{
|
||||
return $this->modify('first day of this month midnight');
|
||||
}
|
||||
@@ -776,7 +805,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function endOfMonth()
|
||||
public function endOfMonth(): ChronosInterface
|
||||
{
|
||||
return $this->modify('last day of this month, 23:59:59');
|
||||
}
|
||||
@@ -786,7 +815,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function startOfYear()
|
||||
public function startOfYear(): ChronosInterface
|
||||
{
|
||||
return $this->modify('first day of january midnight');
|
||||
}
|
||||
@@ -796,7 +825,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function endOfYear()
|
||||
public function endOfYear(): ChronosInterface
|
||||
{
|
||||
return $this->modify('last day of december, 23:59:59');
|
||||
}
|
||||
@@ -806,7 +835,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function startOfDecade()
|
||||
public function startOfDecade(): ChronosInterface
|
||||
{
|
||||
$year = $this->year - $this->year % ChronosInterface::YEARS_PER_DECADE;
|
||||
|
||||
@@ -818,7 +847,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function endOfDecade()
|
||||
public function endOfDecade(): ChronosInterface
|
||||
{
|
||||
$year = $this->year - $this->year % ChronosInterface::YEARS_PER_DECADE + ChronosInterface::YEARS_PER_DECADE - 1;
|
||||
|
||||
@@ -830,9 +859,11 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function startOfCentury()
|
||||
public function startOfCentury(): ChronosInterface
|
||||
{
|
||||
$year = $this->startOfYear()->year(($this->year - 1) - ($this->year - 1) % ChronosInterface::YEARS_PER_CENTURY + 1)->year;
|
||||
$year = $this->startOfYear()
|
||||
->year($this->year - 1 - ($this->year - 1) % ChronosInterface::YEARS_PER_CENTURY + 1)
|
||||
->year;
|
||||
|
||||
return $this->modify("first day of january $year, midnight");
|
||||
}
|
||||
@@ -842,9 +873,16 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function endOfCentury()
|
||||
public function endOfCentury(): ChronosInterface
|
||||
{
|
||||
$year = $this->endOfYear()->year(($this->year - 1) - ($this->year - 1) % ChronosInterface::YEARS_PER_CENTURY + ChronosInterface::YEARS_PER_CENTURY)->year;
|
||||
$y = $this->year - 1
|
||||
- ($this->year - 1)
|
||||
% ChronosInterface::YEARS_PER_CENTURY
|
||||
+ ChronosInterface::YEARS_PER_CENTURY;
|
||||
|
||||
$year = $this->endOfYear()
|
||||
->year($y)
|
||||
->year;
|
||||
|
||||
return $this->modify("last day of december $year, 23:59:59");
|
||||
}
|
||||
@@ -854,7 +892,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function startOfWeek()
|
||||
public function startOfWeek(): ChronosInterface
|
||||
{
|
||||
$dt = $this;
|
||||
if ($dt->dayOfWeek !== static::$weekStartsAt) {
|
||||
@@ -869,7 +907,7 @@ trait ModifierTrait
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function endOfWeek()
|
||||
public function endOfWeek(): ChronosInterface
|
||||
{
|
||||
$dt = $this;
|
||||
if ($dt->dayOfWeek !== static::$weekEndsAt) {
|
||||
@@ -888,7 +926,7 @@ trait ModifierTrait
|
||||
* @param int|null $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function next($dayOfWeek = null)
|
||||
public function next(?int $dayOfWeek = null)
|
||||
{
|
||||
if ($dayOfWeek === null) {
|
||||
$dayOfWeek = $this->dayOfWeek;
|
||||
@@ -908,7 +946,7 @@ trait ModifierTrait
|
||||
* @param int|null $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function previous($dayOfWeek = null)
|
||||
public function previous(?int $dayOfWeek = null)
|
||||
{
|
||||
if ($dayOfWeek === null) {
|
||||
$dayOfWeek = $this->dayOfWeek;
|
||||
@@ -928,7 +966,7 @@ trait ModifierTrait
|
||||
* @param int|null $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function firstOfMonth($dayOfWeek = null)
|
||||
public function firstOfMonth(?int $dayOfWeek = null)
|
||||
{
|
||||
$day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek];
|
||||
|
||||
@@ -944,7 +982,7 @@ trait ModifierTrait
|
||||
* @param int|null $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function lastOfMonth($dayOfWeek = null)
|
||||
public function lastOfMonth(?int $dayOfWeek = null)
|
||||
{
|
||||
$day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek];
|
||||
|
||||
@@ -961,13 +999,13 @@ trait ModifierTrait
|
||||
* @param int $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function nthOfMonth($nth, $dayOfWeek)
|
||||
public function nthOfMonth(int $nth, int $dayOfWeek)
|
||||
{
|
||||
$dt = $this->copy()->firstOfMonth();
|
||||
$check = $dt->format('Y-m');
|
||||
$dt = $dt->modify("+$nth " . static::$days[$dayOfWeek]);
|
||||
|
||||
return ($dt->format('Y-m') === $check) ? $dt : false;
|
||||
return $dt->format('Y-m') === $check ? $dt : false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -979,9 +1017,12 @@ trait ModifierTrait
|
||||
* @param int|null $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function firstOfQuarter($dayOfWeek = null)
|
||||
public function firstOfQuarter(?int $dayOfWeek = null)
|
||||
{
|
||||
return $this->day(1)->month($this->quarter * ChronosInterface::MONTHS_PER_QUARTER - 2)->firstOfMonth($dayOfWeek);
|
||||
return $this
|
||||
->day(1)
|
||||
->month($this->quarter * ChronosInterface::MONTHS_PER_QUARTER - 2)
|
||||
->firstOfMonth($dayOfWeek);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -993,9 +1034,12 @@ trait ModifierTrait
|
||||
* @param int|null $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function lastOfQuarter($dayOfWeek = null)
|
||||
public function lastOfQuarter(?int $dayOfWeek = null)
|
||||
{
|
||||
return $this->day(1)->month($this->quarter * ChronosInterface::MONTHS_PER_QUARTER)->lastOfMonth($dayOfWeek);
|
||||
return $this
|
||||
->day(1)
|
||||
->month($this->quarter * ChronosInterface::MONTHS_PER_QUARTER)
|
||||
->lastOfMonth($dayOfWeek);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1008,14 +1052,14 @@ trait ModifierTrait
|
||||
* @param int $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function nthOfQuarter($nth, $dayOfWeek)
|
||||
public function nthOfQuarter(int $nth, int $dayOfWeek)
|
||||
{
|
||||
$dt = $this->copy()->day(1)->month($this->quarter * ChronosInterface::MONTHS_PER_QUARTER);
|
||||
$lastMonth = $dt->month;
|
||||
$year = $dt->year;
|
||||
$dt = $dt->firstOfQuarter()->modify("+$nth" . static::$days[$dayOfWeek]);
|
||||
|
||||
return ($lastMonth < $dt->month || $year !== $dt->year) ? false : $dt;
|
||||
return $lastMonth < $dt->month || $year !== $dt->year ? false : $dt;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1027,7 +1071,7 @@ trait ModifierTrait
|
||||
* @param int|null $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function firstOfYear($dayOfWeek = null)
|
||||
public function firstOfYear(?int $dayOfWeek = null)
|
||||
{
|
||||
$day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek];
|
||||
|
||||
@@ -1043,7 +1087,7 @@ trait ModifierTrait
|
||||
* @param int|null $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function lastOfYear($dayOfWeek = null)
|
||||
public function lastOfYear(?int $dayOfWeek = null)
|
||||
{
|
||||
$day = $dayOfWeek === null ? 'day' : static::$days[$dayOfWeek];
|
||||
|
||||
@@ -1060,7 +1104,7 @@ trait ModifierTrait
|
||||
* @param int $dayOfWeek The day of the week to move to.
|
||||
* @return mixed
|
||||
*/
|
||||
public function nthOfYear($nth, $dayOfWeek)
|
||||
public function nthOfYear(int $nth, int $dayOfWeek)
|
||||
{
|
||||
$dt = $this->copy()->firstOfYear()->modify("+$nth " . static::$days[$dayOfWeek]);
|
||||
|
||||
@@ -1073,9 +1117,9 @@ trait ModifierTrait
|
||||
* @param \Cake\Chronos\ChronosInterface|null $dt The instance to compare with.
|
||||
* @return static
|
||||
*/
|
||||
public function average(ChronosInterface $dt = null)
|
||||
public function average(?ChronosInterface $dt = null): ChronosInterface
|
||||
{
|
||||
$dt = ($dt === null) ? static::now($this->tz) : $dt;
|
||||
$dt = $dt ?? static::now($this->tz);
|
||||
|
||||
return $this->addSeconds((int)($this->diffInSeconds($dt, false) / 2));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -18,6 +20,11 @@ namespace Cake\Chronos\Traits;
|
||||
*/
|
||||
trait RelativeKeywordTrait
|
||||
{
|
||||
/**
|
||||
* Regex for relative period.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $relativePattern = '/this|next|last|tomorrow|yesterday|midnight|today|[+-]|first|last|ago/i';
|
||||
|
||||
/**
|
||||
@@ -29,7 +36,7 @@ trait RelativeKeywordTrait
|
||||
private static function isTimeExpression($time)
|
||||
{
|
||||
// Just a time
|
||||
if (preg_match('/^[0-2]?[0-9]:[0-5][0-9](?::[0-5][0-9])?$/', $time)) {
|
||||
if (is_string($time) && preg_match('/^[0-2]?[0-9]:[0-5][0-9](?::[0-5][0-9](?:\.[0-9]{1,6})?)?$/', $time)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -40,19 +47,39 @@ trait RelativeKeywordTrait
|
||||
* Determine if there is a relative keyword in the time string, this is to
|
||||
* create dates relative to now for test instances. e.g.: next tuesday
|
||||
*
|
||||
* @param string $time The time string to check.
|
||||
* @param string|null $time The time string to check.
|
||||
* @return bool true if there is a keyword, otherwise false
|
||||
*/
|
||||
public static function hasRelativeKeywords($time)
|
||||
public static function hasRelativeKeywords(?string $time): bool
|
||||
{
|
||||
if (self::isTimeExpression($time)) {
|
||||
return true;
|
||||
}
|
||||
// skip common format with a '-' in it
|
||||
if (preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $time) !== 1) {
|
||||
if ($time && preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $time) !== 1) {
|
||||
return preg_match(static::$relativePattern, $time) > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if there is no fixed date in the time string.
|
||||
*
|
||||
* @param \DateTimeInterface|string|null $time The time string to check
|
||||
* @return bool true if doesn't contain a fixed date
|
||||
*/
|
||||
private static function isRelativeOnly($time): bool
|
||||
{
|
||||
if ($time === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!is_string($time)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// must not contain fixed date before relative keywords or time expression
|
||||
return preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $time) !== 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -22,7 +24,6 @@ use Cake\Chronos\ChronosInterface;
|
||||
*/
|
||||
trait TestingAidTrait
|
||||
{
|
||||
|
||||
/**
|
||||
* Set the test now used by Date and Time classes provided by Chronos
|
||||
*
|
||||
@@ -30,7 +31,7 @@ trait TestingAidTrait
|
||||
* @param \Cake\Chronos\ChronosInterface|string|null $testNow The instance to use for all future instances.
|
||||
* @return void
|
||||
*/
|
||||
public static function setTestNow($testNow = null)
|
||||
public static function setTestNow($testNow = null): void
|
||||
{
|
||||
Chronos::setTestNow($testNow);
|
||||
}
|
||||
@@ -41,7 +42,7 @@ trait TestingAidTrait
|
||||
* @see \Cake\Chronos\Chronos::getTestNow()
|
||||
* @return \Cake\Chronos\ChronosInterface|null the current instance used for testing or null.
|
||||
*/
|
||||
public static function getTestNow()
|
||||
public static function getTestNow(): ?ChronosInterface
|
||||
{
|
||||
return Chronos::getTestNow();
|
||||
}
|
||||
@@ -52,7 +53,7 @@ trait TestingAidTrait
|
||||
* @see \Cake\Chronos\Chronos::hasTestNow()
|
||||
* @return bool True if there is a test instance, otherwise false
|
||||
*/
|
||||
public static function hasTestNow()
|
||||
public static function hasTestNow(): bool
|
||||
{
|
||||
return Chronos::hasTestNow();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -13,6 +15,8 @@
|
||||
*/
|
||||
namespace Cake\Chronos\Traits;
|
||||
|
||||
use Cake\Chronos\ChronosInterface;
|
||||
|
||||
/**
|
||||
* Methods for modifying/reading timezone data.
|
||||
*/
|
||||
@@ -24,7 +28,7 @@ trait TimezoneTrait
|
||||
* @param \DateTimeZone|string $value The DateTimeZone object or timezone name to use.
|
||||
* @return static
|
||||
*/
|
||||
public function timezone($value)
|
||||
public function timezone($value): ChronosInterface
|
||||
{
|
||||
return $this->setTimezone($value);
|
||||
}
|
||||
@@ -35,7 +39,7 @@ trait TimezoneTrait
|
||||
* @param \DateTimeZone|string $value The DateTimeZone object or timezone name to use.
|
||||
* @return static
|
||||
*/
|
||||
public function tz($value)
|
||||
public function tz($value): ChronosInterface
|
||||
{
|
||||
return $this->setTimezone($value);
|
||||
}
|
||||
@@ -46,15 +50,8 @@ trait TimezoneTrait
|
||||
* @param \DateTimeZone|string $value The DateTimeZone object or timezone name to use.
|
||||
* @return static
|
||||
*/
|
||||
public function setTimezone($value)
|
||||
public function setTimezone($value): ChronosInterface
|
||||
{
|
||||
$date = parent::setTimezone(static::safeCreateDateTimeZone($value));
|
||||
|
||||
// https://bugs.php.net/bug.php?id=72338
|
||||
// this is workaround for this bug
|
||||
// Needed for PHP below 7.0 version
|
||||
$date->getTimestamp();
|
||||
|
||||
return $date;
|
||||
return parent::setTimezone(static::safeCreateDateTimeZone($value));
|
||||
}
|
||||
}
|
||||
|
||||
8
vendor/cakephp/chronos/src/Translator.php
vendored
8
vendor/cakephp/chronos/src/Translator.php
vendored
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -48,7 +50,7 @@ class Translator
|
||||
* @param string $key The key to check.
|
||||
* @return bool Whether or not the key exists.
|
||||
*/
|
||||
public function exists($key)
|
||||
public function exists(string $key): bool
|
||||
{
|
||||
return isset(static::$strings[$key]);
|
||||
}
|
||||
@@ -61,7 +63,7 @@ class Translator
|
||||
* @param array $vars Additional context variables.
|
||||
* @return string The translated message or ''.
|
||||
*/
|
||||
public function plural($key, $count, array $vars = [])
|
||||
public function plural(string $key, int $count, array $vars = []): string
|
||||
{
|
||||
if ($count === 1) {
|
||||
return $this->singular($key, $vars);
|
||||
@@ -77,7 +79,7 @@ class Translator
|
||||
* @param array $vars Additional context variables.
|
||||
* @return string The translated message or ''.
|
||||
*/
|
||||
public function singular($key, array $vars = [])
|
||||
public function singular(string $key, array $vars = []): string
|
||||
{
|
||||
if (isset(static::$strings[$key])) {
|
||||
$varKeys = array_keys($vars);
|
||||
|
||||
7
vendor/cakephp/chronos/src/carbon_compat.php
vendored
7
vendor/cakephp/chronos/src/carbon_compat.php
vendored
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
@@ -10,9 +12,10 @@
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
define('CHRONOS_SUPPORTS_MICROSECONDS', version_compare(PHP_VERSION, '7.1.0', '>='));
|
||||
|
||||
if (!class_exists('Carbon\Carbon')) {
|
||||
// Check if the interface alias exists and don't redeclare it in case we are in
|
||||
// a preloaded context.
|
||||
if (!\class_exists('Carbon\Carbon') && !\interface_exists('Carbon\CarbonInterface', false)) {
|
||||
// Create class aliases for Carbon so applications
|
||||
// can upgrade more easily.
|
||||
class_alias('Cake\Chronos\Chronos', 'Carbon\MutableDateTime');
|
||||
|
||||
10
vendor/composer/ClassLoader.php
vendored
10
vendor/composer/ClassLoader.php
vendored
@@ -37,8 +37,8 @@ namespace Composer\Autoload;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see http://www.php-fig.org/psr/psr-0/
|
||||
* @see http://www.php-fig.org/psr/psr-4/
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
@@ -60,7 +60,7 @@ class ClassLoader
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
@@ -279,7 +279,7 @@ class ClassLoader
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,7 +377,7 @@ class ClassLoader
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath.'\\';
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
|
||||
1404
vendor/composer/InstalledVersions.php
vendored
Normal file
1404
vendor/composer/InstalledVersions.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1844
vendor/composer/autoload_classmap.php
vendored
1844
vendor/composer/autoload_classmap.php
vendored
File diff suppressed because it is too large
Load Diff
10
vendor/composer/autoload_files.php
vendored
10
vendor/composer/autoload_files.php
vendored
@@ -7,12 +7,12 @@ $baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
|
||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
@@ -21,14 +21,16 @@ return array(
|
||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
|
||||
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
|
||||
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
|
||||
'538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php',
|
||||
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
|
||||
'34122c0574b76bf21c9a8db62b5b9cf3' => $vendorDir . '/cakephp/chronos/src/carbon_compat.php',
|
||||
'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
|
||||
'58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
|
||||
'6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
|
||||
'801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php',
|
||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
|
||||
'0d8253363903f0ac7b0978dcde4e28a0' => $vendorDir . '/beyondcode/laravel-dump-server/helpers.php',
|
||||
'664e151c91315b3715336cbec9a6600a' => $vendorDir . '/eveseat/eseye/src/Helpers/helpers.php',
|
||||
'17d016dc52a631c1e74d2eb8fdd57342' => $vendorDir . '/laravel/helpers/src/helpers.php',
|
||||
'f18cc91337d49233e5754e93f3ed9ec3' => $vendorDir . '/laravelcollective/html/src/helpers.php',
|
||||
);
|
||||
|
||||
1
vendor/composer/autoload_namespaces.php
vendored
1
vendor/composer/autoload_namespaces.php
vendored
@@ -6,6 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Parsedown' => array($vendorDir . '/erusev/parsedown'),
|
||||
'Mockery' => array($vendorDir . '/mockery/mockery/library'),
|
||||
);
|
||||
|
||||
22
vendor/composer/autoload_psr4.php
vendored
22
vendor/composer/autoload_psr4.php
vendored
@@ -6,8 +6,8 @@ $vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'),
|
||||
'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'),
|
||||
'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
|
||||
'Whoops\\' => array($vendorDir . '/filp/whoops/src/Whoops'),
|
||||
'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
|
||||
'TijsVerkoyen\\CssToInlineStyles\\' => array($vendorDir . '/tijsverkoyen/css-to-inline-styles/src'),
|
||||
@@ -18,6 +18,7 @@ return array(
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'),
|
||||
'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'),
|
||||
'Symfony\\Polyfill\\Intl\\Grapheme\\' => array($vendorDir . '/symfony/polyfill-intl-grapheme'),
|
||||
'Symfony\\Polyfill\\Iconv\\' => array($vendorDir . '/symfony/polyfill-iconv'),
|
||||
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
|
||||
'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'),
|
||||
@@ -26,6 +27,7 @@ return array(
|
||||
'Symfony\\Contracts\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher-contracts'),
|
||||
'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
|
||||
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
|
||||
'Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'),
|
||||
'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
|
||||
'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
|
||||
'Symfony\\Component\\Mime\\' => array($vendorDir . '/symfony/mime'),
|
||||
@@ -34,19 +36,16 @@ return array(
|
||||
'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
|
||||
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
|
||||
'Symfony\\Component\\ErrorHandler\\' => array($vendorDir . '/symfony/error-handler'),
|
||||
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
|
||||
'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'),
|
||||
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
|
||||
'Seat\\Eseye\\' => array($vendorDir . '/eveseat/eseye/src'),
|
||||
'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'),
|
||||
'Psy\\' => array($vendorDir . '/psy/psysh/src'),
|
||||
'Ramsey\\Collection\\' => array($vendorDir . '/ramsey/collection/src'),
|
||||
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
|
||||
'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'),
|
||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||
'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src/Prophecy'),
|
||||
'Predis\\' => array($vendorDir . '/predis/predis/src'),
|
||||
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
||||
'PhpOption\\' => array($vendorDir . '/phpoption/phpoption/src/PhpOption'),
|
||||
'Opis\\Closure\\' => array($vendorDir . '/opis/closure/src'),
|
||||
'NunoMaduro\\Collision\\' => array($vendorDir . '/nunomaduro/collision/src'),
|
||||
@@ -54,31 +53,30 @@ return array(
|
||||
'League\\OAuth1\\Client\\' => array($vendorDir . '/league/oauth1-client/src'),
|
||||
'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),
|
||||
'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
|
||||
'Laravel\\Tinker\\' => array($vendorDir . '/laravel/tinker/src'),
|
||||
'League\\CommonMark\\' => array($vendorDir . '/league/commonmark/src'),
|
||||
'Laravel\\Ui\\' => array($vendorDir . '/laravel/ui/src'),
|
||||
'Laravel\\Socialite\\' => array($vendorDir . '/laravel/socialite/src'),
|
||||
'Laravel\\Horizon\\' => array($vendorDir . '/laravel/horizon/src'),
|
||||
'Khill\\Lavacharts\\' => array($vendorDir . '/khill/lavacharts/src'),
|
||||
'JakubOnderka\\PhpConsoleHighlighter\\' => array($vendorDir . '/jakub-onderka/php-console-highlighter/src'),
|
||||
'JakubOnderka\\PhpConsoleColor\\' => array($vendorDir . '/jakub-onderka/php-console-color/src'),
|
||||
'Illuminate\\Foundation\\Auth\\' => array($vendorDir . '/laravel/ui/auth-backend'),
|
||||
'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'),
|
||||
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
||||
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
|
||||
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
|
||||
'Fideloper\\Proxy\\' => array($vendorDir . '/fideloper/proxy/src'),
|
||||
'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'),
|
||||
'Facade\\IgnitionContracts\\' => array($vendorDir . '/facade/ignition-contracts/src'),
|
||||
'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/src'),
|
||||
'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'),
|
||||
'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
|
||||
'Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector'),
|
||||
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer'),
|
||||
'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Common/Inflector'),
|
||||
'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
|
||||
'Cron\\' => array($vendorDir . '/dragonmantank/cron-expression/src/Cron'),
|
||||
'ConsoleTVs\\Charts\\' => array($vendorDir . '/consoletvs/charts/src'),
|
||||
'Collective\\Html\\' => array($vendorDir . '/laravelcollective/html/src'),
|
||||
'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
|
||||
'Cake\\Chronos\\' => array($vendorDir . '/cakephp/chronos/src'),
|
||||
'Brick\\Math\\' => array($vendorDir . '/brick/math/src'),
|
||||
'BeyondCode\\DumpServer\\' => array($vendorDir . '/beyondcode/laravel-dump-server/src'),
|
||||
'Balping\\JsonRaw\\' => array($vendorDir . '/balping/json-raw-encoder/src'),
|
||||
'App\\' => array($baseDir . '/app'),
|
||||
);
|
||||
|
||||
7
vendor/composer/autoload_real.php
vendored
7
vendor/composer/autoload_real.php
vendored
@@ -13,19 +13,24 @@ class ComposerAutoloaderInitc3f953f8a7291d41a76e1664339777c9
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInitc3f953f8a7291d41a76e1664339777c9', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitc3f953f8a7291d41a76e1664339777c9', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require_once __DIR__ . '/autoload_static.php';
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitc3f953f8a7291d41a76e1664339777c9::getInitializer($loader));
|
||||
} else {
|
||||
|
||||
1968
vendor/composer/autoload_static.php
vendored
1968
vendor/composer/autoload_static.php
vendored
File diff suppressed because it is too large
Load Diff
12856
vendor/composer/installed.json
vendored
12856
vendor/composer/installed.json
vendored
File diff suppressed because it is too large
Load Diff
1209
vendor/composer/installed.php
vendored
Normal file
1209
vendor/composer/installed.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
26
vendor/composer/platform_check.php
vendored
Normal file
26
vendor/composer/platform_check.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 70205)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
2
vendor/consoletvs/charts/.gitattributes
vendored
2
vendor/consoletvs/charts/.gitattributes
vendored
@@ -1,2 +0,0 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
3
vendor/consoletvs/charts/.github/FUNDING.yml
vendored
3
vendor/consoletvs/charts/.github/FUNDING.yml
vendored
@@ -1,3 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
patreon: ErikCampobadal
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[BUG]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Required information**
|
||||
- Charts Version [e.g. 6]
|
||||
- Laravel Version [e.g. 5.8]
|
||||
- PHP Version [e.g. 7.2]
|
||||
- Frontend JS Library Used: [e.g. Chart.js]
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Code To Reproduce**
|
||||
If applicable, add a code to reproduce the problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: "[FEATURE]"
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Questions and troubleshooting
|
||||
title: "[QUESTION]"
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
1
vendor/consoletvs/charts/.gitignore
vendored
1
vendor/consoletvs/charts/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
.DS_Store
|
||||
21
vendor/consoletvs/charts/LICENSE
vendored
21
vendor/consoletvs/charts/LICENSE
vendored
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Èrik Campobadal Forés <soc@erik.cat>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
32
vendor/consoletvs/charts/README.md
vendored
32
vendor/consoletvs/charts/README.md
vendored
@@ -1,32 +0,0 @@
|
||||
<p align="center"><a href="https://charts.erik.cat"><img src="https://i.gyazo.com/b33ab534d6fdfa7d4eba2abd91a155c3.png"></a></p>
|
||||
<p align="center">
|
||||
<a href="https://styleci.io/repos/69124179"><img src="https://styleci.io/repos/69124179/shield?branch=master&style=flat" alt="StyleCI Status"></a>
|
||||
<a class="badge-align" href="https://www.codacy.com/app/consoletvs/Charts?utm_source=github.com&utm_medium=referral&utm_content=ConsoleTVs/Charts&utm_campaign=Badge_Grade"><img src="https://api.codacy.com/project/badge/Grade/b96ce6dd50de4a69ba191336a04a59e5"/></a>
|
||||
<a href="https://styleci.io/repos/69124179"><img src="https://img.shields.io/badge/Built_for-Laravel-orange.svg" alt="Build For Laravel"></a>
|
||||
<a href="https://packagist.org/packages/consoletvs/charts"><img src="https://poser.pugx.org/consoletvs/charts/d/total.svg" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/consoletvs/charts"><img src="https://poser.pugx.org/consoletvs/charts/v/stable.svg" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/consoletvs/charts"><img src="https://poser.pugx.org/consoletvs/charts/license.svg" alt="License"></a>
|
||||
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2FConsoleTVs%2FCharts?ref=badge_shield" alt="FOSSA Status"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2FConsoleTVs%2FCharts.svg?type=shield"/></a>
|
||||
</p>
|
||||
|
||||
## What is charts?
|
||||
|
||||
Charts is a PHP (Laravel) library to handle all the charts in your application. It supports multiple
|
||||
charting libraries and they allow to be loaded over AJAX with a nice loading animation.
|
||||
|
||||
It uses a simple API to create all the JS logic for you. You just need to write a few PHP lines :)
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation for the latest version of charts can be found here by pressing the image below.
|
||||
|
||||
<p align="center"><a href="https://charts.erik.cat"><img height="250" src="https://i.imgur.com/F0PDyYE.png"></a></p>
|
||||
|
||||
## Example screenshot
|
||||
|
||||
A sample screenshot of a chartjs chart created using Charts.
|
||||
|
||||
<p align="center"><img src="https://image.prntscr.com/image/FDJCr7ywShKMUlFitEc_Ww.png"></p>
|
||||
|
||||
## License
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2FConsoleTVs%2FCharts?ref=badge_large)
|
||||
31
vendor/consoletvs/charts/composer.json
vendored
31
vendor/consoletvs/charts/composer.json
vendored
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"name": "consoletvs/charts",
|
||||
"description": "The laravel charting package",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"illuminate/support": "^5.0|^6.0|^7.0|^8.0",
|
||||
"illuminate/console": "^5.0|^6.0|^7.0|^8.0",
|
||||
"balping/json-raw-encoder": "^1.0"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Èrik Campobadal Forés ",
|
||||
"email": "soc@erik.cat"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ConsoleTVs\\Charts\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"ConsoleTVs\\Charts\\ChartsServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts;
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class ChartsServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot(Router $router)
|
||||
{
|
||||
$this->publishes([
|
||||
__DIR__.'/Config/charts.php' => config_path('charts.php'),
|
||||
], 'charts_config');
|
||||
|
||||
$this->loadViewsFrom(__DIR__.'/Views', 'charts');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__.'/Views' => resource_path('views/vendor/charts'),
|
||||
]);
|
||||
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->commands([
|
||||
\ConsoleTVs\Charts\Commands\ChartsCommand::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->mergeConfigFrom(
|
||||
__DIR__.'/Config/charts.php',
|
||||
'charts'
|
||||
);
|
||||
}
|
||||
}
|
||||
542
vendor/consoletvs/charts/src/Classes/BaseChart.php
vendored
542
vendor/consoletvs/charts/src/Classes/BaseChart.php
vendored
@@ -1,542 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes;
|
||||
|
||||
use Balping\JsonRaw\Encoder;
|
||||
use Balping\JsonRaw\Raw;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\View;
|
||||
|
||||
class BaseChart
|
||||
{
|
||||
/**
|
||||
* Stores the chart ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* Stores the chart datasets.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $datasets = [];
|
||||
|
||||
/**
|
||||
* Stores the dataset class to be used.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $dataset = DatasetClass::class;
|
||||
|
||||
/**
|
||||
* Stores the chart labels.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $labels = [];
|
||||
|
||||
/**
|
||||
* Stores the chart container.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $container = '';
|
||||
|
||||
/**
|
||||
* Stores the chart options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options = [];
|
||||
|
||||
/**
|
||||
* Stores the plugins options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $plugins = [];
|
||||
|
||||
/**
|
||||
* Stores the plugin views.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $pluginsViews = [];
|
||||
|
||||
/**
|
||||
* Stores the chart script.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $script = '';
|
||||
|
||||
/**
|
||||
* Stores the chart type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = '';
|
||||
|
||||
/**
|
||||
* Stores the API url if the chart is loaded over API.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $api_url = '';
|
||||
|
||||
/**
|
||||
* Determines if the loader is show.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $loader = true;
|
||||
|
||||
/**
|
||||
* Determines if the loader color.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $loaderColor = '#22292F';
|
||||
|
||||
/**
|
||||
* Stores the height of the chart.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $height = 400;
|
||||
|
||||
/**
|
||||
* Stores the width of the chart.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $width = null;
|
||||
|
||||
/**
|
||||
* Stores the available chart letters to create the ID.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $scriptAttributes = [
|
||||
'type' => 'text/javascript',
|
||||
];
|
||||
|
||||
/**
|
||||
* Stores the available chart letters to create the ID.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $chartLetters = 'abcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
/**
|
||||
* Chart constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->id = substr(str_shuffle(str_repeat($x = $this->chartLetters, ceil(25 / strlen($x)))), 1, 25);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new dataset to the chart.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array|Collection $data
|
||||
*/
|
||||
public function dataset(string $name, string $type, $data)
|
||||
{
|
||||
if ($data instanceof Collection) {
|
||||
$data = $data->toArray();
|
||||
}
|
||||
|
||||
$dataset = new $this->dataset($name, $type, $data);
|
||||
|
||||
array_push($this->datasets, $dataset);
|
||||
|
||||
return $dataset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the chart labels.
|
||||
*
|
||||
* @param array|Collection $labels
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function labels($labels)
|
||||
{
|
||||
if ($labels instanceof Collection) {
|
||||
$labels = $labels->toArray();
|
||||
}
|
||||
|
||||
$this->labels = $labels;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the chart options.
|
||||
*
|
||||
* @param array|Collection $options
|
||||
* @param bool $overwrite
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function options($options, bool $overwrite = false)
|
||||
{
|
||||
if (!empty($options['plugins'])) {
|
||||
$options['plugins'] = new Raw(trim(preg_replace('/\s\s+/', ' ', $options['plugins'])));
|
||||
}
|
||||
|
||||
if ($options instanceof Collection) {
|
||||
$options = $options->toArray();
|
||||
}
|
||||
if ($overwrite) {
|
||||
$this->options = $options;
|
||||
} else {
|
||||
$this->options = array_replace_recursive($this->options, $options);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the plugins options.
|
||||
*
|
||||
* @param array|Collection $options
|
||||
* @param bool $overwrite
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function plugins($plugins, bool $overwrite = true)
|
||||
{
|
||||
if ($plugins instanceof Collection) {
|
||||
$plugins = $plugins->toArray();
|
||||
}
|
||||
if ($overwrite) {
|
||||
$this->plugins = $plugins;
|
||||
} else {
|
||||
$this->plugins = array_replace_recursive($this->plugins, $plugins);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the chart container.
|
||||
*
|
||||
* @param string $container
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function container(string $container = null)
|
||||
{
|
||||
if (!$container) {
|
||||
return View::make($this->container, ['chart' => $this]);
|
||||
}
|
||||
|
||||
$this->container = $container;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the chart script.
|
||||
*
|
||||
* @param string $script
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function script(string $script = null)
|
||||
{
|
||||
if (count($this->datasets) == 0 && !$this->api_url) {
|
||||
throw new \Exception('No datasets provided, please provide at least one dataset to generate a chart');
|
||||
}
|
||||
|
||||
if (!$script) {
|
||||
return View::make($this->script, ['chart' => $this]);
|
||||
}
|
||||
|
||||
$this->script = $script;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the chart type.
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function type(string $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the chart height.
|
||||
*
|
||||
* @param int $height
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function height(int $height)
|
||||
{
|
||||
$this->height = $height;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the chart width.
|
||||
*
|
||||
* @param int $width
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function width(int $width)
|
||||
{
|
||||
$this->width = $width;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the type to be a correct output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatType()
|
||||
{
|
||||
return $this->type ? $this->type : $this->datasets[0]->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the labels to be a correct output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatLabels()
|
||||
{
|
||||
return Encoder::encode($this->labels);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the chart options.
|
||||
*
|
||||
* @param bool $strict
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatOptions(bool $strict = false, bool $noBraces = false)
|
||||
{
|
||||
if (!$strict && count($this->options) === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$options = Encoder::encode($this->options);
|
||||
|
||||
return $noBraces ? substr($options, 1, -1) : $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the plugins options.
|
||||
*
|
||||
* @param bool $strict
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatPlugins(bool $strict = false, bool $noBraces = false)
|
||||
{
|
||||
if (!$strict && count($this->plugins) === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$plugins = str_replace('"', '', Encoder::encode($this->plugins));
|
||||
|
||||
return $noBraces ? substr($plugins, 1, -1) : $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to pass values to json without any modification
|
||||
* Useful for defining callbacks.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return \Balping\JsonRaw\Raw
|
||||
*/
|
||||
public function rawObject(string $value)
|
||||
{
|
||||
return new Raw($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the chart options.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
return $this->options([], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the datasets for the output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatDatasets()
|
||||
{
|
||||
// This little boy was commented because it's not compatible
|
||||
// in laravel < 5.4
|
||||
//
|
||||
// return Collection::make($this->datasets)
|
||||
// ->each
|
||||
// ->matchValues(count($this->labels))
|
||||
// ->map
|
||||
// ->format($this->labels)
|
||||
// ->toJson();
|
||||
|
||||
return Encoder::encode(
|
||||
Collection::make($this->datasets)
|
||||
->each(function ($dataset) {
|
||||
$dataset->matchValues(count($this->labels));
|
||||
})
|
||||
->map(function ($dataset) {
|
||||
return $dataset->format($this->labels);
|
||||
})
|
||||
->toArray()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the chart information will be loaded over API.
|
||||
*
|
||||
* @param string $api_url
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function load(string $api_url)
|
||||
{
|
||||
$this->api_url = $api_url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the chart should show a loader.
|
||||
*
|
||||
* @param bool $loader
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function loader(bool $loader)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the loader color.
|
||||
*
|
||||
* @param string $color
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function loaderColor(string $color)
|
||||
{
|
||||
$this->loaderColor = $color;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for the formatDatasets() method.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function api()
|
||||
{
|
||||
return $this->formatDatasets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an HTML attribute the the script tag of the chart.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setScriptAttribute(string $key, string $value)
|
||||
{
|
||||
$this->scriptAttributes[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string formatting of the script attributes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function displayScriptAttributes(): string
|
||||
{
|
||||
$result = '';
|
||||
foreach ($this->scriptAttributes as $key => $value) {
|
||||
echo " {$key}=\"{$value}\"";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the container options.
|
||||
*
|
||||
* @param string $type
|
||||
* @param bool $maxIfNull
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatContainerOptions(string $type = 'css', bool $maxIfNull = false)
|
||||
{
|
||||
$options = '';
|
||||
$height = ($maxIfNull && !$this->height) ? '100%' : $this->height;
|
||||
$width = ($maxIfNull && !$this->width) ? '100%' : $this->width;
|
||||
|
||||
switch ($type) {
|
||||
case 'css':
|
||||
$options .= " style='";
|
||||
(!$height) ?: $options .= "height: {$height}px !important;";
|
||||
(!$width) ?: $options .= "width: {$width}px !important;";
|
||||
$options .= "' ";
|
||||
break;
|
||||
case 'js':
|
||||
if ($height) {
|
||||
if (is_int($height)) {
|
||||
$options .= "height: {$height}, ";
|
||||
} else {
|
||||
$options .= "height: '{$height}', ";
|
||||
}
|
||||
}
|
||||
if ($width) {
|
||||
if (is_int($width)) {
|
||||
$options .= "width: {$width}, ";
|
||||
} else {
|
||||
$options .= "width: '{$width}', ";
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
(!$height) ?: $options .= " height='{$this->height}' ";
|
||||
(!$this->width) ?: $options .= " width='{$this->width}' ";
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes\C3;
|
||||
|
||||
use ConsoleTVs\Charts\Classes\BaseChart;
|
||||
use ConsoleTVs\Charts\Features\C3\Chart as ChartFeatures;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class Chart extends BaseChart
|
||||
{
|
||||
use ChartFeatures;
|
||||
|
||||
/**
|
||||
* C3 dataset class.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $dataset = Dataset::class;
|
||||
|
||||
/**
|
||||
* Initiates the C3 Line Chart.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->container = 'charts::c3.container';
|
||||
$this->script = 'charts::c3.script';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the datasets.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function formatDatasets()
|
||||
{
|
||||
$datasets = Collection::make($this->datasets);
|
||||
|
||||
return json_encode([
|
||||
'columns' => Collection::make($this->datasets)
|
||||
->each(function ($dataset) {
|
||||
$dataset->matchValues(count($this->labels));
|
||||
})
|
||||
->map(function ($dataset) {
|
||||
return $dataset->format($this->labels);
|
||||
})
|
||||
->toArray(),
|
||||
'type' => $datasets->first()->type,
|
||||
'types' => $datasets->mapWithKeys(function ($d) {
|
||||
return [$d->name => $d->type];
|
||||
})->toArray(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes\C3;
|
||||
|
||||
use ConsoleTVs\Charts\Classes\DatasetClass;
|
||||
use ConsoleTVs\Charts\Features\C3\Dataset as DatasetFeatures;
|
||||
|
||||
class Dataset extends DatasetClass
|
||||
{
|
||||
use DatasetFeatures;
|
||||
|
||||
/**
|
||||
* Creates a new dataset with the given values.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct(string $name, string $type, array $values)
|
||||
{
|
||||
parent::__construct($name, $type, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the dataset for chartjs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function format()
|
||||
{
|
||||
return array_merge([$this->name], $this->values);
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes\Chartjs;
|
||||
|
||||
use ConsoleTVs\Charts\Classes\BaseChart;
|
||||
use ConsoleTVs\Charts\Features\Chartjs\Chart as ChartFeatures;
|
||||
|
||||
class Chart extends BaseChart
|
||||
{
|
||||
use ChartFeatures;
|
||||
|
||||
/**
|
||||
* Chartjs dataset class.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $dataset = Dataset::class;
|
||||
|
||||
/**
|
||||
* Initiates the Chartjs Line Chart.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->container = 'charts::chartjs.container';
|
||||
$this->script = 'charts::chartjs.script';
|
||||
|
||||
return $this->options([
|
||||
'maintainAspectRatio' => false,
|
||||
'scales' => [
|
||||
'xAxes' => [],
|
||||
'yAxes' => [
|
||||
[
|
||||
'ticks' => [
|
||||
'beginAtZero' => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes\Chartjs;
|
||||
|
||||
use ConsoleTVs\Charts\Classes\DatasetClass;
|
||||
use ConsoleTVs\Charts\Features\Chartjs\Dataset as DatasetFeatures;
|
||||
|
||||
class Dataset extends DatasetClass
|
||||
{
|
||||
use DatasetFeatures;
|
||||
|
||||
/**
|
||||
* Creates a new dataset with the given values.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct(string $name, string $type, array $values)
|
||||
{
|
||||
parent::__construct($name, $type, $values);
|
||||
|
||||
$this->options([
|
||||
'borderWidth' => 2,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the dataset for chartjs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function format()
|
||||
{
|
||||
return array_merge($this->options, [
|
||||
'data' => $this->values,
|
||||
'label' => $this->name,
|
||||
'type' => $this->type,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class DatasetClass
|
||||
{
|
||||
/**
|
||||
* Defines the name of the dataset.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'Undefined';
|
||||
|
||||
/**
|
||||
* Defines the dataset type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = '';
|
||||
|
||||
/**
|
||||
* Stores the dataset values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $values = [];
|
||||
|
||||
/**
|
||||
* Stores the dataset options.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options = [];
|
||||
|
||||
/**
|
||||
* Defines the undefined color.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $undefinedColor = '#22292F';
|
||||
|
||||
/**
|
||||
* Creates a new dataset with the given values.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct(string $name, string $type, array $values)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->values = $values;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dataset type.
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function type(string $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dataset values.
|
||||
*
|
||||
* @param array|Collection $values
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function values($values)
|
||||
{
|
||||
if ($values instanceof Collection) {
|
||||
$values = $values->toArray();
|
||||
}
|
||||
|
||||
$this->values = $values;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dataset options.
|
||||
*
|
||||
* @param array|Collection $options
|
||||
* @param bool $overwrite
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function options($options, bool $overwrite = false)
|
||||
{
|
||||
if ($overwrite) {
|
||||
$this->options = $options;
|
||||
} else {
|
||||
$this->options = array_replace_recursive($this->options, $options);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the values of the dataset with the given number.
|
||||
*
|
||||
* @param int $values
|
||||
* @param bool $strict
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function matchValues(int $values, bool $strict = false)
|
||||
{
|
||||
while (count($this->values) < $values) {
|
||||
array_push($this->values, 0);
|
||||
}
|
||||
|
||||
if ($strict) {
|
||||
$this->values = array_slice($this->values, 0, $values);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes\Echarts;
|
||||
|
||||
use ConsoleTVs\Charts\Classes\BaseChart;
|
||||
use ConsoleTVs\Charts\Features\Echarts\Chart as ChartFeatures;
|
||||
|
||||
class Chart extends BaseChart
|
||||
{
|
||||
use ChartFeatures;
|
||||
|
||||
/**
|
||||
* Chartjs dataset class.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $dataset = Dataset::class;
|
||||
|
||||
/**
|
||||
* Store the theme for the chart.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $theme = 'default';
|
||||
|
||||
/**
|
||||
* Initiates the Chartjs Line Chart.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->container = 'charts::echarts.container';
|
||||
$this->script = 'charts::echarts.script';
|
||||
|
||||
return $this->options([
|
||||
'legend' => [
|
||||
'show' => true,
|
||||
],
|
||||
'tooltip' => [
|
||||
'show' => true,
|
||||
],
|
||||
'xAxis' => [
|
||||
'show' => true,
|
||||
],
|
||||
'yAxis' => [
|
||||
'show' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the options.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function formatOptions(bool $strict = false, bool $noBraces = false)
|
||||
{
|
||||
$this->options([
|
||||
'xAxis' => [
|
||||
'data' => json_decode($this->formatLabels()),
|
||||
],
|
||||
]);
|
||||
|
||||
return parent::formatOptions($strict, $noBraces);
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes\Echarts;
|
||||
|
||||
use ConsoleTVs\Charts\Classes\DatasetClass;
|
||||
use ConsoleTVs\Charts\Features\Echarts\Dataset as DatasetFeatures;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class Dataset extends DatasetClass
|
||||
{
|
||||
use DatasetFeatures;
|
||||
|
||||
/**
|
||||
* Store the private datasets that contains a special formating.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $specialDatasets = ['pie'];
|
||||
|
||||
/**
|
||||
* Creates a new dataset with the given values.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct(string $name, string $type, array $values)
|
||||
{
|
||||
parent::__construct($name, $type, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the dataset for chartjs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function format(array $labels = [])
|
||||
{
|
||||
return array_merge($this->options, [
|
||||
'data' => $this->getValues($labels),
|
||||
'name' => $this->name,
|
||||
'type' => strtolower($this->type),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formated values.
|
||||
*
|
||||
* @param array $labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getValues(array $labels)
|
||||
{
|
||||
if (in_array(strtolower($this->type), $this->specialDatasets)) {
|
||||
return Collection::make($this->values)
|
||||
->map(function ($value, $key) use ($labels) {
|
||||
return [
|
||||
'name' => $labels[$key],
|
||||
'value' => $value,
|
||||
];
|
||||
})->toArray();
|
||||
}
|
||||
|
||||
return $this->values;
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes\Frappe;
|
||||
|
||||
use ConsoleTVs\Charts\Classes\BaseChart;
|
||||
use ConsoleTVs\Charts\Features\Frappe\Chart as ChartFeatures;
|
||||
|
||||
class Chart extends BaseChart
|
||||
{
|
||||
use ChartFeatures;
|
||||
|
||||
/**
|
||||
* Frappe dataset class.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $dataset = Dataset::class;
|
||||
|
||||
/**
|
||||
* Stores the default colors.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $default_colors = [
|
||||
'#E3342F', '#F6993F', '#FFED4A', '#38C172', '#4DC0B5', '#3490DC', '#6574CD', '#9561E2', '#F66D9B',
|
||||
];
|
||||
|
||||
/**
|
||||
* Determines the special charts.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $special_datasets = [
|
||||
'pie', 'percentage',
|
||||
];
|
||||
|
||||
/**
|
||||
* Initiates the Frappe Chart.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->container = 'charts::frappe.container';
|
||||
$this->script = 'charts::frappe.script';
|
||||
|
||||
return $this->options([
|
||||
'barOptions' => [
|
||||
'spaceRatio' => 0.75,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the datasets.
|
||||
*
|
||||
* @param bool $strict
|
||||
* @param bool $noBraces
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function formatOptions(bool $strict = false, bool $noBraces = false)
|
||||
{
|
||||
$colors = [];
|
||||
$default = 0;
|
||||
foreach ($this->datasets as $dataset) {
|
||||
$color = $this->default_colors[$default];
|
||||
if (array_key_exists('color', $dataset->options)) {
|
||||
$color = $dataset->options['color'];
|
||||
unset($dataset->options['color']);
|
||||
} else {
|
||||
$default++;
|
||||
}
|
||||
array_push($colors, $color);
|
||||
}
|
||||
|
||||
$this->options([
|
||||
'colors' => $colors,
|
||||
]);
|
||||
|
||||
return parent::formatOptions($strict, $noBraces);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ConsoleTVs\Charts\Classes\Frappe;
|
||||
|
||||
use ConsoleTVs\Charts\Classes\DatasetClass;
|
||||
use ConsoleTVs\Charts\Features\Frappe\Dataset as DatasetFeatures;
|
||||
|
||||
class Dataset extends DatasetClass
|
||||
{
|
||||
use DatasetFeatures;
|
||||
|
||||
/**
|
||||
* Creates a new dataset with the given values.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct(string $name, string $type, array $values)
|
||||
{
|
||||
parent::__construct($name, $type, $values);
|
||||
|
||||
$this->options([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the dataset for chartjs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function format()
|
||||
{
|
||||
return array_merge($this->options, [
|
||||
'values' => $this->values,
|
||||
'name' => $this->name,
|
||||
'chartType' => $this->type,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user