Update package for Yunohost 2.4.0
675
LICENSE
Normal file
|
@ -0,0 +1,675 @@
|
||||||
|
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>.
|
||||||
|
|
62
check_process
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
;; Test complet sans multisite
|
||||||
|
auto_remove=1
|
||||||
|
; Manifest
|
||||||
|
domain="domain.tld" (DOMAIN)
|
||||||
|
path="/path" (PATH)
|
||||||
|
admin="john" (USER)
|
||||||
|
language="fr_FR"
|
||||||
|
multisite="No"
|
||||||
|
is_public="Yes" (PUBLIC|public=Yes|private=No)
|
||||||
|
; Checks
|
||||||
|
pkg_linter=1
|
||||||
|
setup_sub_dir=1
|
||||||
|
setup_root=1
|
||||||
|
setup_nourl=0
|
||||||
|
setup_private=1
|
||||||
|
setup_public=1
|
||||||
|
upgrade=1
|
||||||
|
backup_restore=1
|
||||||
|
multi_instance=1
|
||||||
|
wrong_user=1
|
||||||
|
wrong_path=1
|
||||||
|
incorrect_path=1
|
||||||
|
corrupt_source=0
|
||||||
|
fail_download_source=0
|
||||||
|
port_already_use=0
|
||||||
|
final_path_already_use=0
|
||||||
|
;; Test avec multisite
|
||||||
|
auto_remove=1
|
||||||
|
; Manifest
|
||||||
|
domain="domain.tld" (DOMAIN)
|
||||||
|
path="/path" (PATH)
|
||||||
|
admin="john" (USER)
|
||||||
|
language="fr_FR"
|
||||||
|
multisite="Yes"
|
||||||
|
is_public="Yes" (PUBLIC|public=Yes|private=No)
|
||||||
|
; Checks
|
||||||
|
setup_sub_dir=1
|
||||||
|
setup_root=0
|
||||||
|
setup_nourl=0
|
||||||
|
setup_private=1
|
||||||
|
setup_public=1
|
||||||
|
upgrade=1
|
||||||
|
backup_restore=1
|
||||||
|
multi_instance=1
|
||||||
|
wrong_user=0
|
||||||
|
wrong_path=0
|
||||||
|
incorrect_path=0
|
||||||
|
corrupt_source=0
|
||||||
|
fail_download_source=0
|
||||||
|
port_already_use=0
|
||||||
|
final_path_already_use=0
|
||||||
|
;;; Levels
|
||||||
|
Level 1=auto
|
||||||
|
Level 2=auto
|
||||||
|
Level 3=auto
|
||||||
|
Level 4=1
|
||||||
|
Level 5=1
|
||||||
|
Level 6=auto
|
||||||
|
Level 7=auto
|
||||||
|
Level 8=0
|
||||||
|
Level 9=0
|
||||||
|
Level 10=0
|
3
conf/php-fpm.ini
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
upload_max_filesize=30M
|
||||||
|
post_max_size=30M
|
||||||
|
; max_execution_time=60
|
205
scripts/.fonctions
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
ynh_version="2.4"
|
||||||
|
|
||||||
|
YNH_VERSION () { # Renvoi le numéro de version de la moulinette Yunohost
|
||||||
|
ynh_version=$(sudo yunohost -v | grep "moulinette:" | cut -d' ' -f2 | cut -d'.' -f1,2)
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_VAR () { # Vérifie que la variable n'est pas vide.
|
||||||
|
# $1 = Variable à vérifier
|
||||||
|
# $2 = Texte à afficher en cas d'erreur
|
||||||
|
test -n "$1" || (echo "$2" >&2 && false)
|
||||||
|
}
|
||||||
|
|
||||||
|
EXIT_PROPERLY () { # Provoque l'arrêt du script en cas d'erreur. Et nettoye les résidus.
|
||||||
|
trap '' ERR
|
||||||
|
echo -e "\e[91m \e[1m" # Shell in light red bold
|
||||||
|
echo -e "!!\n $app install's script has encountered an error. Installation was cancelled.\n!!" >&2
|
||||||
|
|
||||||
|
CLEAN_SETUP # Appel la fonction de nettoyage spécifique du script install.
|
||||||
|
|
||||||
|
# Compense le bug de ssowat qui ne supprime pas l'entrée de l'app en cas d'erreur d'installation.
|
||||||
|
sudo sed -i "\@\"$domain$path/\":@d" /etc/ssowat/conf.json
|
||||||
|
|
||||||
|
if [ "$ynh_version" = "2.2" ]; then
|
||||||
|
/bin/bash $script_dir/remove # Appel le script remove. En 2.2, ce comportement n'est pas automatique.
|
||||||
|
fi
|
||||||
|
|
||||||
|
ynh_die
|
||||||
|
}
|
||||||
|
|
||||||
|
TRAP_ON () { # Activate signal capture
|
||||||
|
trap EXIT_PROPERLY ERR # Capturing exit signals on error
|
||||||
|
}
|
||||||
|
|
||||||
|
TRAP_OFF () { # Ignoring signal capture until TRAP_ON
|
||||||
|
# Pour une raison que j'ignore, la fonction TRAP_ON fonctionne très bien.
|
||||||
|
# Mais pas la fonction TRAP_OFF...
|
||||||
|
# Utiliser directement `trap '' ERR` dans le code pour l'utiliser, à la place de la fonction.
|
||||||
|
trap '' ERR # Ignoring exit signals
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_USER () { # Vérifie la validité de l'user admin
|
||||||
|
# $1 = Variable de l'user admin.
|
||||||
|
ynh_user_exists "$1" || (echo "Wrong admin" >&2 && false)
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_PATH () { # Vérifie la présence du / en début de path. Et son absence à la fin.
|
||||||
|
if [ "${path:0:1}" != "/" ]; then # Si le premier caractère n'est pas un /
|
||||||
|
path="/$path" # Ajoute un / en début de path
|
||||||
|
fi
|
||||||
|
if [ "${path:${#path}-1}" == "/" ] && [ ${#path} -gt 1 ]; then # Si le dernier caractère est un / et que ce n'est pas le seul caractère.
|
||||||
|
path="${path:0:${#path}-1}" # Supprime le dernier caractère
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_DOMAINPATH () { # Vérifie la disponibilité du path et du domaine.
|
||||||
|
sudo yunohost app checkurl $domain$path -a $app
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_FINALPATH () { # Vérifie que le dossier de destination n'est pas déjà utilisé.
|
||||||
|
final_path=/var/www/$app
|
||||||
|
if [ -e "$final_path" ]
|
||||||
|
then
|
||||||
|
echo "This path already contains a folder" >&2
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
GENERATE_DB () { # Créer une base de données et un utilisateur dédié au nom de l'app.
|
||||||
|
# $1 = Nom de la base de donnée
|
||||||
|
# Génère un mot de passe aléatoire.
|
||||||
|
db_user=$1
|
||||||
|
db_pwd=$(head -n20 /dev/urandom | tr -c -d 'A-Za-z0-9' | head -c20)
|
||||||
|
CHECK_VAR "$db_pwd" "db_pwd empty"
|
||||||
|
# Utilise '$app' comme nom d'utilisateur et de base de donnée
|
||||||
|
# Initialise la base de donnée et stocke le mot de passe mysql.
|
||||||
|
ynh_mysql_create_db "$db_user" "$db_user" $db_pwd
|
||||||
|
ynh_app_setting_set $app mysqlpwd $db_pwd
|
||||||
|
}
|
||||||
|
|
||||||
|
SETUP_SOURCE () { # Télécharge la source, décompresse et copie dans $final_path
|
||||||
|
# $1 = Nom de l'archive téléchargée.
|
||||||
|
wget -nv --show-progress -i ../sources/source_url -O $1
|
||||||
|
# Vérifie la somme de contrôle de la source téléchargée.
|
||||||
|
md5sum -c ../sources/source_md5 --status || (echo "Corrupt source" >&2 && false)
|
||||||
|
# Décompresse la source
|
||||||
|
if [ "$(echo ${1##*.})" == "gz" ]; then
|
||||||
|
tar -x -f $1
|
||||||
|
elif [ "$(echo ${1##*.})" == "zip" ]; then
|
||||||
|
unzip -q $1
|
||||||
|
else
|
||||||
|
false # Format d'archive non pris en charge.
|
||||||
|
fi
|
||||||
|
# Copie les fichiers sources
|
||||||
|
sudo cp -a $(cat ../sources/source_dir)/. "$final_path"
|
||||||
|
# Copie les fichiers additionnels ou modifiés.
|
||||||
|
if test -e "../sources/ajouts"; then
|
||||||
|
sudo cp -a ../sources/ajouts/. "$final_path"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
POOL_FPM () { # Créer le fichier de configuration du pool php-fpm et le configure.
|
||||||
|
sed -i "s@__NAMETOCHANGE__@$app@g" ../conf/php-fpm.conf
|
||||||
|
sed -i "s@__FINALPATH__@$final_path@g" ../conf/php-fpm.conf
|
||||||
|
finalphpconf=/etc/php5/fpm/pool.d/$app.conf
|
||||||
|
sudo cp ../conf/php-fpm.conf $finalphpconf
|
||||||
|
sudo chown root: $finalphpconf
|
||||||
|
finalphpini=/etc/php5/fpm/conf.d/20-$app.ini
|
||||||
|
sudo cp ../conf/php-fpm.ini $finalphpini
|
||||||
|
sudo chown root: $finalphpini
|
||||||
|
sudo service php5-fpm reload
|
||||||
|
}
|
||||||
|
|
||||||
|
STORE_MD5_CONFIG () { # Enregistre la somme de contrôle du fichier de config
|
||||||
|
# $1 = Nom du fichier de conf pour le stockage dans settings.yml
|
||||||
|
# $2 = Nom complet et chemin du fichier de conf.
|
||||||
|
ynh_app_setting_set $app $1_file_md5 $(sudo md5sum "$2" | cut -d' ' -f1)
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_MD5_CONFIG () { # Créé un backup du fichier de config si il a été modifié.
|
||||||
|
# $1 = Nom du fichier de conf pour le stockage dans settings.yml
|
||||||
|
# $2 = Nom complet et chemin du fichier de conf.
|
||||||
|
if [ "$(ynh_app_setting_get $app $1_file_md5)" != $(sudo md5sum "$2" | cut -d' ' -f1) ]; then
|
||||||
|
sudo cp -a "$2" "$2.backup.$(date '+%d.%m.%y_%Hh%M,%Ss')" # Si le fichier de config a été modifié, créer un backup.
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
FIND_PORT () { # Cherche un port libre.
|
||||||
|
# $1 = Numéro de port pour débuter la recherche.
|
||||||
|
port=$1
|
||||||
|
while ! sudo yunohost app checkport $port ; do
|
||||||
|
port=$((port+1))
|
||||||
|
done
|
||||||
|
CHECK_VAR "$port" "port empty"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### REMOVE SCRIPT
|
||||||
|
|
||||||
|
REMOVE_NGINX_CONF () { # Suppression de la configuration nginx
|
||||||
|
if [ -e "/etc/nginx/conf.d/$domain.d/$app.conf" ]; then # Delete nginx config
|
||||||
|
echo "Delete nginx config"
|
||||||
|
sudo rm "/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
|
sudo service nginx reload
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
REMOVE_FPM_CONF () { # Suppression de la configuration du pool php-fpm
|
||||||
|
if [ -e "/etc/php5/fpm/pool.d/$app.conf" ]; then # Delete fpm config
|
||||||
|
echo "Delete fpm config"
|
||||||
|
sudo rm "/etc/php5/fpm/pool.d/$app.conf"
|
||||||
|
fi
|
||||||
|
if [ -e "/etc/php5/fpm/conf.d/20-$app.ini" ]; then # Delete php config
|
||||||
|
echo "Delete php config"
|
||||||
|
sudo rm "/etc/php5/fpm/conf.d/20-$app.ini"
|
||||||
|
fi
|
||||||
|
sudo service php5-fpm reload
|
||||||
|
}
|
||||||
|
|
||||||
|
REMOVE_LOGROTATE_CONF () { # Suppression de la configuration de logrotate
|
||||||
|
if [ -e "/etc/logrotate.d/$app" ]; then
|
||||||
|
echo "Delete logrotate config"
|
||||||
|
sudo rm "/etc/logrotate.d/$app"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
SECURE_REMOVE () { # Suppression de dossier avec vérification des variables
|
||||||
|
chaine="$1" # L'argument doit être donné entre quotes simple '', pour éviter d'interpréter les variables.
|
||||||
|
no_var=0
|
||||||
|
while (echo "$chaine" | grep -q '\$') # Boucle tant qu'il y a des $ dans la chaine
|
||||||
|
do
|
||||||
|
no_var=1
|
||||||
|
global_var=$(echo "$chaine" | cut -d '$' -f 2) # Isole la première variable trouvée.
|
||||||
|
only_var=\$$(expr "$global_var" : '\([A-Za-z0-9_]*\)') # Isole complètement la variable en ajoutant le $ au début et en gardant uniquement le nom de la variable. Se débarrasse surtout du / et d'un éventuel chemin derrière.
|
||||||
|
real_var=$(eval "echo ${only_var}") # `eval "echo ${var}` permet d'interpréter une variable contenue dans une variable.
|
||||||
|
if test -z "$real_var" || [ "$real_var" = "/" ]; then
|
||||||
|
echo "Variable $only_var is empty, suppression of $chaine cancelled." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
chaine=$(echo "$chaine" | sed "s@$only_var@$real_var@") # remplace la variable par sa valeur dans la chaine.
|
||||||
|
done
|
||||||
|
if [ "$no_var" -eq 1 ]
|
||||||
|
then
|
||||||
|
if [ -e "$chaine" ]; then
|
||||||
|
echo "Delete directory $chaine"
|
||||||
|
sudo rm -r "$chaine"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "No detected variable." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
REMOVE_BDD () { # Suppression de la base de donnée et de l'utilisateur associé.
|
||||||
|
# $1 = Nom de la base de donnée
|
||||||
|
# Utilise '$app' comme nom d'utilisateur et de base de donnée
|
||||||
|
db_user=$1
|
||||||
|
if mysqlshow -u root -p$(sudo cat $MYSQL_ROOT_PWD_FILE) | grep -q "^| $db_user"; then
|
||||||
|
echo "Delete db"
|
||||||
|
ynh_mysql_drop_db $db_user
|
||||||
|
ynh_mysql_drop_user $db_user
|
||||||
|
fi
|
||||||
|
}
|
28
scripts/backup
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Exit on command errors and treat unset variables as an error
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# The parameter $1 is the backup directory location dedicated to the app
|
||||||
|
backup_dir=$1
|
||||||
|
|
||||||
|
# The parameter $2 is theid of the app instance
|
||||||
|
app=$2
|
||||||
|
|
||||||
|
# Source app helpers
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
|
domain=$(ynh_app_setting_get $app domain)
|
||||||
|
final_path=$(ynh_app_setting_get $app final_path)
|
||||||
|
|
||||||
|
# Copy the app files
|
||||||
|
sudo mkdir -p ${backup_dir}/var/www
|
||||||
|
sudo cp -a $final_path "${backup_dir}/var/www/$app"
|
||||||
|
|
||||||
|
# Copy the conf files
|
||||||
|
sudo mkdir -p "${backup_dir}/conf"
|
||||||
|
sudo cp -a /etc/nginx/conf.d/$domain.d/$app.conf "${backup_dir}/conf/nginx.conf"
|
||||||
|
|
||||||
|
# Copy dedicated php-fpm process to backup folder
|
||||||
|
sudo cp -a /etc/php5/fpm/pool.d/$app.conf "${backup_dir}/conf/php-fpm.conf"
|
||||||
|
sudo cp -a /etc/php5/fpm/conf.d/20-$app.ini "${backup_dir}/conf/php-fpm.ini"
|
113
scripts/install
|
@ -1,46 +1,95 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Retrieve arguments
|
# Exit on command errors and treat unset variables as an error
|
||||||
domain=$1
|
set -eu
|
||||||
path=$2
|
|
||||||
admin_grav=$3
|
|
||||||
|
|
||||||
# Check if admin exists
|
source .fonctions # Charge les fonctions génériques habituellement utilisées dans le script
|
||||||
sudo yunohost user list --json | grep -q "\"username\": \"$admin_grav\""
|
|
||||||
if [[ ! $? -eq 0 ]]; then
|
|
||||||
echo "Wrong admin"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
sudo yunohost app setting grav admin -v $admin_grav
|
|
||||||
|
|
||||||
# Check domain/path availability
|
CLEAN_SETUP () {
|
||||||
sudo yunohost app checkurl $domain$path -a grav
|
# Nettoyage des résidus d'installation non pris en charge par le script remove.
|
||||||
if [[ ! $? -eq 0 ]]; then
|
# Clean hosts
|
||||||
exit 1
|
sudo sed -i '/#GRAV/d' /etc/hosts
|
||||||
fi
|
}
|
||||||
|
TRAP_ON # Active trap pour arrêter le script si une erreur est détectée.
|
||||||
|
|
||||||
# Copy files to the right place
|
domain=$YNH_APP_ARG_DOMAIN
|
||||||
final_path=/var/www/grav
|
path=$YNH_APP_ARG_PATH
|
||||||
sudo mkdir -p $final_path
|
admin_grav=$YNH_APP_ARG_ADMIN
|
||||||
sudo cp -aR ../src/* $final_path
|
language=$YNH_APP_ARG_LANGUAGE
|
||||||
|
multisite=$YNH_APP_ARG_MULTISITE
|
||||||
|
is_public=$YNH_APP_ARG_IS_PUBLIC
|
||||||
|
|
||||||
# Set permissions to roundcube directory
|
app=$YNH_APP_INSTANCE_NAME
|
||||||
|
|
||||||
|
# Source app helpers
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
|
CHECK_VAR "$app" "app name not set"
|
||||||
|
|
||||||
|
CHECK_USER "$admin_grav"
|
||||||
|
|
||||||
|
CHECK_PATH
|
||||||
|
|
||||||
|
CHECK_DOMAINPATH
|
||||||
|
|
||||||
|
CHECK_FINALPATH
|
||||||
|
|
||||||
|
ynh_app_setting_set $app domain $domain
|
||||||
|
ynh_app_setting_set $app path $path
|
||||||
|
ynh_app_setting_set $app admin $admin_grav
|
||||||
|
ynh_app_setting_set $app is_public $is_public
|
||||||
|
ynh_app_setting_set $app language $language
|
||||||
|
ynh_app_setting_set $app multisite $multisite
|
||||||
|
|
||||||
|
GENERATE_DB $app # Créer une base de données et un utilisateur dédié au nom de l'app.
|
||||||
|
|
||||||
|
# Crée le repertoire de destination et stocke son emplacement.
|
||||||
|
sudo mkdir "$final_path"
|
||||||
|
ynh_app_setting_set $app final_path $final_path
|
||||||
|
|
||||||
|
SETUP_SOURCE "grav-admin-v1.1.17.zip"
|
||||||
|
|
||||||
|
# Set permissions to grav directory
|
||||||
sudo chown -R www-data: $final_path
|
sudo chown -R www-data: $final_path
|
||||||
|
|
||||||
# Modify Nginx configuration file and copy it to Nginx conf directory
|
echo -e "127.0.0.1 $domain #GRAV" | sudo tee -a /etc/hosts
|
||||||
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf
|
|
||||||
sed -i "s@ALIASTOCHANGE@$final_path@g" ../conf/nginx.conf
|
|
||||||
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/grav.conf
|
|
||||||
|
|
||||||
sed -i "s@NAMETOCHANGE@grav@g" ../conf/php-fpm.conf
|
# Et copie le fichier de config nginx
|
||||||
finalphpconf=/etc/php5/fpm/pool.d/grav.conf
|
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
sudo cp ../conf/php-fpm.conf $finalphpconf
|
|
||||||
sudo chown root: $finalphpconf
|
# Modifie les variables dans le fichier de configuration nginx
|
||||||
sudo chmod 644 $finalphpconf
|
sudo sed -i "s@__PATHTOCHANGE__@$path@g" /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
# sudo $final_path/bin/grav install
|
sudo sed -i "s@__FINALPATH__@$final_path@g" /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
sudo sed -i "s@__NAMETOCHANGE__@$app@g" /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
|
||||||
|
if [ "$multisite" = "Yes" ];
|
||||||
|
then
|
||||||
|
sudo sed -i "s@#--MULTISITE--@@g" /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$is_public" = "Yes" ];
|
||||||
|
then
|
||||||
|
sudo sed -i "s@#--PRIVATE--@@g" /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
POOL_FPM
|
||||||
|
|
||||||
|
# Donne un accès public pour curl
|
||||||
|
ynh_app_setting_set $app unprotected_uris "/"
|
||||||
|
|
||||||
|
# Régénère la configuration de SSOwat
|
||||||
|
sudo yunohost app ssowatconf
|
||||||
|
|
||||||
# Reload Nginx and regenerate SSOwat conf
|
# Reload Nginx and regenerate SSOwat conf
|
||||||
sudo service php5-fpm restart
|
sudo service php5-fpm restart
|
||||||
sudo service nginx reload
|
sudo service nginx reload
|
||||||
sudo yunohost app setting grav skipped_uris -v "/"
|
|
||||||
|
if [ "$is_public" = "No" ];
|
||||||
|
then
|
||||||
|
# Retire l'accès public
|
||||||
|
ynh_app_setting_delete $app unprotected_uris
|
||||||
sudo yunohost app ssowatconf
|
sudo yunohost app ssowatconf
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Nettoyer hosts
|
||||||
|
sudo sed -i '/#GRAV/d' /etc/hosts
|
|
@ -1,10 +1,26 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
domain=$(sudo yunohost app setting grav domain)
|
# Exit on command errors and treat unset variables as an error
|
||||||
|
set -u
|
||||||
|
|
||||||
sudo rm -rf /var/www/grav
|
source .fonctions # Charge les fonctions génériques habituellement utilisées dans le script
|
||||||
sudo rm -f /etc/nginx/conf.d/$domain.d/grav.conf
|
|
||||||
sudo rm -f /etc/php5/fpm/pool.d/grav.conf
|
|
||||||
|
|
||||||
sudo service php5-fpm restart
|
# Source app helpers
|
||||||
sudo service nginx reload
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
|
# Récupère les infos de l'application.
|
||||||
|
app=$YNH_APP_INSTANCE_NAME
|
||||||
|
domain=$(ynh_app_setting_get $app domain)
|
||||||
|
|
||||||
|
REMOVE_BDD $app # Suppression de la base de donnée et de l'utilisateur associé.
|
||||||
|
|
||||||
|
SECURE_REMOVE '/var/www/$app' # Suppression du dossier de l'application
|
||||||
|
|
||||||
|
REMOVE_NGINX_CONF # Suppression de la configuration nginx
|
||||||
|
|
||||||
|
REMOVE_FPM_CONF # Suppression de la configuration du pool php-fpm
|
||||||
|
|
||||||
|
# Régénère la configuration de SSOwat
|
||||||
|
sudo yunohost app ssowatconf
|
||||||
|
|
||||||
|
echo -e "\e[0m" # Restore normal color
|
53
scripts/restore
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# This restore script is adapted to Yunohost >=2.4
|
||||||
|
|
||||||
|
# Exit on command errors and treat unset variables as an error
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# The parameter $1 is the backup directory location dedicated to the app
|
||||||
|
backup_dir=$1
|
||||||
|
|
||||||
|
# The parameter $2 is the id of the app instance ex: ynhexample__2
|
||||||
|
app=$2
|
||||||
|
|
||||||
|
# Source app helpers
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
|
# Get old parameter of the app
|
||||||
|
domain=$(ynh_app_setting_get $app domain)
|
||||||
|
path=$(ynh_app_setting_get $app path)
|
||||||
|
is_public=$(ynh_app_setting_get $app is_public)
|
||||||
|
final_path=$(ynh_app_setting_get $app final_path)
|
||||||
|
|
||||||
|
if [ -d $final_path ]; then
|
||||||
|
ynh_die "There is already a directory: $final_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
conf=/etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
if [ -f $conf ]; then
|
||||||
|
ynh_die "There is already a nginx conf file at this path: $conf"
|
||||||
|
fi
|
||||||
|
# Restore conf files
|
||||||
|
sudo cp -a "${backup_dir}/conf/nginx.conf" $conf
|
||||||
|
|
||||||
|
# Reload Nginx
|
||||||
|
sudo service nginx reload
|
||||||
|
|
||||||
|
sudo cp -a "${backup_dir}/var/www/$app" $final_path
|
||||||
|
|
||||||
|
# Set permissions
|
||||||
|
# Les fichiers appartiennent à www-data, pour permettre les mises à jour.
|
||||||
|
sudo chown -R www-data: $final_path
|
||||||
|
|
||||||
|
# Copy dedicated php-fpm process from backup folder to the right location
|
||||||
|
sudo cp -a $backup_dir/conf/php-fpm.conf /etc/php5/fpm/pool.d/$app.conf
|
||||||
|
sudo cp -a $backup_dir/conf/php-fpm.ini /etc/php5/fpm/conf.d/20-$app.ini
|
||||||
|
# And restart service
|
||||||
|
sudo service php5-fpm reload
|
||||||
|
|
||||||
|
# Set ssowat config
|
||||||
|
if [ "$is_public" = "No" ];
|
||||||
|
then
|
||||||
|
ynh_app_setting_delete $app skipped_uris
|
||||||
|
fi
|
||||||
|
sudo yunohost app ssowatconf
|
|
@ -1,20 +1,38 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Retrieve arguments
|
# Exit on command errors and treat unset variables as an error
|
||||||
domain=$(sudo yunohost app setting grav domain)
|
set -eu
|
||||||
path=$(sudo yunohost app setting grav path)
|
|
||||||
admin_grav=$(sudo yunohost app setting grav admin)
|
|
||||||
language=$(sudo yunohost app setting grav language)
|
|
||||||
is_public=$(sudo yunohost app setting grav is_public)
|
|
||||||
|
|
||||||
final_path=/var/www/grav
|
source .fonctions # Charge les fonctions génériques habituellement utilisées dans le script
|
||||||
|
|
||||||
|
# See comments in install script
|
||||||
|
app=$YNH_APP_INSTANCE_NAME
|
||||||
|
|
||||||
|
# Source YunoHost helpers
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
|
# Retrieve app settings
|
||||||
|
domain=$(ynh_app_setting_get "$app" domain)
|
||||||
|
path=$(ynh_app_setting_get "$app" path)
|
||||||
|
admin=$(ynh_app_setting_get "$app" admin)
|
||||||
|
is_public=$(ynh_app_setting_get "$app" is_public)
|
||||||
|
language=$(ynh_app_setting_get "$app" language)
|
||||||
|
|
||||||
|
CHECK_PATH # Vérifie et corrige la syntaxe du path.
|
||||||
|
|
||||||
# Check if admin is not null
|
# Check if admin is not null
|
||||||
if [[ "$admin_grav" = "" || "$is_public" = "" || "$language" = "" ]]; then
|
if [[ "$admin" = "" || "$is_public" = "" || "$language" = "" ]]; then
|
||||||
echo "Unable to upgrade, please contact support"
|
echo "Unable to upgrade, please contact support"
|
||||||
exit 1
|
ynh_die
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
root_pwd=$(sudo cat /etc/yunohost/mysql)
|
||||||
|
|
||||||
|
final_path=/var/www/$app
|
||||||
|
|
||||||
|
db_name=$app
|
||||||
|
|
||||||
|
# CHECK_MD5_CONFIG "connect.php" "$final_path/config/connect.php" # Créé un backup du fichier de config si il a été modifié.
|
||||||
|
|
||||||
# Modify Nginx configuration file and copy it to Nginx conf directory
|
# Modify Nginx configuration file and copy it to Nginx conf directory
|
||||||
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf*
|
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf*
|
||||||
|
@ -22,9 +40,18 @@ sed -i "s@ALIASTOCHANGE@$final_path/@g" ../conf/nginx.conf*
|
||||||
|
|
||||||
if [ $is_public = "Yes" ];
|
if [ $is_public = "Yes" ];
|
||||||
then
|
then
|
||||||
sudo cp ../conf/nginx.conf-public /etc/nginx/conf.d/$domain.d/grav.conf
|
sudo cp ../conf/nginx.conf-public /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
else
|
else
|
||||||
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/grav.conf
|
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If app is public, add url to SSOWat conf as skipped_uris
|
||||||
|
if [[ $is_public -eq 1 ]]; then
|
||||||
|
# See install script
|
||||||
|
ynh_app_setting_set "$app" unprotected_uris "/"
|
||||||
|
sudo cp ../conf/nginx.conf-public /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
|
else
|
||||||
|
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Reload Nginx
|
# Reload Nginx
|
||||||
|
|
1
sources/source_dir
Normal file
|
@ -0,0 +1 @@
|
||||||
|
grav
|
1
sources/source_md5.
Normal file
|
@ -0,0 +1 @@
|
||||||
|
5593142893cfb1c8bc90a407ede00c09 grav-admin-v1.1.17.zip
|
1
sources/source_url
Normal file
|
@ -0,0 +1 @@
|
||||||
|
https://getgrav.org/download/core/grav-admin/1.1.17
|
233
src/.config
|
@ -1,233 +0,0 @@
|
||||||
<?php
|
|
||||||
date_default_timezone_set('EST'); //set to the timezone of your application
|
|
||||||
session_start(); //if no use for sessions, comment this line out
|
|
||||||
/**
|
|
||||||
* Framework configuration - this object contains your application-specific settings
|
|
||||||
*/
|
|
||||||
class config extends configDefaults {
|
|
||||||
/**
|
|
||||||
* The SITE_NAME and SITE_DOMAIN constants are used in the default templates; you must set this if you will use the
|
|
||||||
* default framework functionality such as the "default" layout or the preset email-elements.
|
|
||||||
* You can always access these from anywhere in your application via:
|
|
||||||
* get::$config->SITE_NAME
|
|
||||||
* get::$config->SITE_DOMAIN
|
|
||||||
*/
|
|
||||||
const SITE_NAME = 'YourSite';
|
|
||||||
const SITE_DOMAIN = 'YourSite.com';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Database name - create new constants for additional connections (commented out example for DB_SLAVE_NAME follows)
|
|
||||||
* Defining DB-name constants is a good practice but not required if you hard-code them in dbConnect() below
|
|
||||||
*/
|
|
||||||
const DB_NAME = 'vork';
|
|
||||||
//const DB_SLAVE_NAME = 'slave4readonly';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Most RDBMS users will only need to adjust the connection string in the first $db object. The syntax of this must
|
|
||||||
* always match the syntax of the constructor or connect method of your relational-database PHP extension.
|
|
||||||
*
|
|
||||||
* For the MySQLi extension all arguments are optional and formatted as:
|
|
||||||
* self::$db = new $db($host, $username, $passwd, $dbname, $port, $socket);
|
|
||||||
*
|
|
||||||
* Note: in most setups $host is either "localhost" or set to an IP address
|
|
||||||
* for Amazon RDS it would be something like: myinstance.crwjauxgijdf.us-east-1.rds.amazonaws.com
|
|
||||||
*
|
|
||||||
* For the syntax of other extensions refer to: http://www.php.net/manual/en/refs.database.vendors.php
|
|
||||||
*
|
|
||||||
* @param string $modelObject One of the values in self::$modelObjects determining which DB connection to establish
|
|
||||||
*/
|
|
||||||
public function dbConnect($modelObject) {
|
|
||||||
$db = (!DEBUG_MODE ? 'db' : 'dbDebug');
|
|
||||||
switch ($modelObject) { //a case must exist for each value in self::$modelObjects (additional cases are benign)
|
|
||||||
case 'db':
|
|
||||||
self::$db = new $db('HOSTNAME', 'USERNAME', 'PASSWORD', self::DB_NAME);
|
|
||||||
break;
|
|
||||||
case 'mongo':
|
|
||||||
if (!class_exists('vorkMongo')) {
|
|
||||||
require self::basepath() . 'sql' . self::DS . 'mongodb';
|
|
||||||
}
|
|
||||||
$m = new vorkMongo();
|
|
||||||
self::$mongo = $m->selectDB(self::DB_NAME);
|
|
||||||
//Upsert arg is array in newer MongoDB (leave as-is), Boolean in older- remove comments around (Boolean)
|
|
||||||
$this->mongoUpsert = /* (Boolean) */ array('upsert' => true);
|
|
||||||
break;
|
|
||||||
case 'dbro':
|
|
||||||
//if an additional connection is needed, adjust credentials below and follow the instructions in the
|
|
||||||
//comment for $modelObjects just after this class.
|
|
||||||
self::$dbro = new $db('HOSTNAME', 'USERNAME', 'PASSWORD', self::DB_SLAVE_NAME);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Using multiple database connections and/or NoSQL like MongoDB or CouchDB
|
|
||||||
*
|
|
||||||
* If you are only using one DB connection and it is an RDBMS (any databaes except non-relational like Mongo)
|
|
||||||
* then you should skip this step.
|
|
||||||
*
|
|
||||||
* Each database connection (both RDBMS & NoSQL) needs to be defined in the $modelObjects array and have a static
|
|
||||||
* propery existing by the same name. "db" exists by default so to add a second read-only connection you set
|
|
||||||
* $modelObjects to array('db', 'dbro') and create a new $dbro static property (commented-out examples follow).
|
|
||||||
*
|
|
||||||
* Use the same process for adding a MongoDB connection in conjuction with an RDBMS (substituting in the last
|
|
||||||
* example "mongo" for "dbro"). To use MongoDB as the sole database just overwrite $modelObjects with
|
|
||||||
* array('mongo') - this is instead of keeping the default 'db' connection within the array. You will also want to
|
|
||||||
* comment out the last line in this file which is RDBMS-specific: require '.config-rdbms';
|
|
||||||
*
|
|
||||||
* Important: each connection defined here must establish the connection within the dbConnect() method above, an
|
|
||||||
* example for both mongo and dbro exists, for other connections just provide a unique name and access from within
|
|
||||||
* your models by name: $this->mydbname->query(...);
|
|
||||||
*
|
|
||||||
* Caution: do NOT uncomment more than one of the following examples; it will trigger a PHP fatal error if you do!
|
|
||||||
*/
|
|
||||||
//Adds MongoDB support in conjunction with other databases
|
|
||||||
//public static $modelObjects = array('db', 'mongo'); public static $mongo;
|
|
||||||
|
|
||||||
//Uses MongoDB as the exclusive datasource
|
|
||||||
//public static $modelObjects = array('mongo'); public static $mongo;
|
|
||||||
|
|
||||||
//Adds an additional database connection called "dbro"
|
|
||||||
//public static $modelObjects = array('db', 'dbro'); public static $dbro;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true all self::$modelObjects database connections are made upon loading the first model
|
|
||||||
* If false your connections are lazy-loaded when needed but each of your models must extend the model abstract
|
|
||||||
* eg.: class wikiModel extends model {...}
|
|
||||||
*/
|
|
||||||
const MODEL_AUTOCONNECT = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables the caching functions by initializing get::$cache with a cache object (Memcache is default, but
|
|
||||||
* can be any object-oriented cache mechanism.)
|
|
||||||
*/
|
|
||||||
public function cache() {
|
|
||||||
/* // uncomment this section to enable Memcache caching (Memcache must be installed and enabled in PHP)
|
|
||||||
if (!class_exists('memcache')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
get::$cache = new Memcache;
|
|
||||||
//get::$cache->addServer('HOSTNAME', 'PORT')
|
|
||||||
//Following is the typical setting for a single-server configuration:
|
|
||||||
get::$cache->addServer('localhost', 11211);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables special AJAX handling - eg.: AJAX requests will skip the layout file and just return the view contents
|
|
||||||
*
|
|
||||||
* Can be set globally here and then overridden form within any controller-action or component
|
|
||||||
*
|
|
||||||
* Valid values:
|
|
||||||
* (Boolean) true or false will enable or disable AJAX in all controllers
|
|
||||||
* array('controlerName1' => true,
|
|
||||||
* 'controlerName2' => 'actionName',
|
|
||||||
* 'controlerName3' => array('action1', 'action2'))
|
|
||||||
*
|
|
||||||
* @var mixed Boolean or an array with controller-name keys & val either true, an action name or an array of actions
|
|
||||||
*/
|
|
||||||
public $ajaxEnabled = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a file that is global to the application before the page loads
|
|
||||||
* File must be in the root of the mvc directory
|
|
||||||
*/
|
|
||||||
const APP_CONSTRUCT = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute a file that is global to the application after the page loads
|
|
||||||
* File must be in the root of the mvc directory
|
|
||||||
*/
|
|
||||||
const APP_DESTRUCT = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter your ShareThis publisher code to enable the shareThis tools helper
|
|
||||||
*/
|
|
||||||
//const SHARE_THIS = 'd123456789-1234-1234-1234-a1e123456f';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter your AddThis publisher code to enable the addThis tools helper
|
|
||||||
*/
|
|
||||||
//const ADD_THIS = 'xa-1234567890123e';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter your Google AdSense client ID to enable use of the adSense tools helper
|
|
||||||
*/
|
|
||||||
//const GOOGLE_AD_CLIENT = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter your Google Checkout credentials to enable use of the helper
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
public $GOOGLE_CHECKOUT = array('useSandbox' => false,
|
|
||||||
'live' => array('id' => 'YOURID', 'key' => 'YOURKEY'),
|
|
||||||
'sandbox' => array('id' => 'YOURID', 'key' => 'YOURKEY'));
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter your AuthorizeNet credentials to enable use of the chargeAuthNet method of the cc component
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
const AUTHNET_LOGIN = '';
|
|
||||||
const AUTHNET_PASSWORD = '';
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Meetup API key - enables usage of the Meetup tools-helper
|
|
||||||
*/
|
|
||||||
//const MEETUP_API_KEY = '47e794a9c4766374c761a57833a77';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter your UPS account credentials and XML Access Key (refer to ups.com for signup) to enable use of
|
|
||||||
* the UPS functions in the shipping component
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
//public $UPS = array('xmlAccessKey' => 'YOURKEY000000000', 'userid' => 'YOURID', 'password' => 'YOURPASS');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter your Amazon Web Services credentials to enable use of the amazon component
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
public $AMAZON = array('id' => '0000-0000-1234', 'accessKey' => 'AAAABBBBX12345CCDDDD',
|
|
||||||
'secretKey' => 'aA01234560bB01234560cC01234560dD');
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enter your PayPal email to enable use of the PayPal component
|
|
||||||
*/
|
|
||||||
//const PAYPAL_EMAIL = 'you@yourdomain.com';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience function to determine if a user is a "superuser" (someone who gets complete access to
|
|
||||||
* all information) and by default only used in the errorhandler view (to determine verbosity) but typical applications
|
|
||||||
* find many uses for this
|
|
||||||
*
|
|
||||||
* Note, if your application uses this method to grant access to private resources then you are highly-recommended
|
|
||||||
* to use a stronger authentication method than just checking the IP address (IPs can easily be spoofed.)
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function isSuperuser() {
|
|
||||||
return (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] == '127.0.0.1'); // <--change this before use
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set any application-specific constants or properties after this comment.
|
|
||||||
* examples:
|
|
||||||
* const MY_CONSTANT = 'Hello, Shalom and Bonjour';
|
|
||||||
* public $myProperty = array(1, 2, 3);
|
|
||||||
*
|
|
||||||
* Access them from any MVC element via:
|
|
||||||
* get::$config->MY_CONSTANT
|
|
||||||
* get::$config->myProperty
|
|
||||||
*/
|
|
||||||
//const EXAMPLE_CONSTANT = 'your data...';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If you are using a relational-database other than MySQL or Amazon RDS (eg. SQLite, Oracle, etc.) then you need to
|
|
||||||
* set your RDBMS-type in the .config-rdbms file. If you are NOT using a relational-database then comment out the
|
|
||||||
* next line. Note: MongoDB and other NoSQL databases are NOT relational and do not require the .config-rdbms file
|
|
||||||
*/
|
|
||||||
require '.config-rdbms';
|
|
221
src/.debug
|
@ -1,221 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Valid output methods are: auto, FirePHP, html and text
|
|
||||||
* The auto mode will select FirePHP if it is available, otherwise it will use html
|
|
||||||
* Using FirePHP requires FireBug with the FirePHP extension enabled in FireFox (instructions at firephp.org)
|
|
||||||
*/
|
|
||||||
define('DEBUG_OUTPUT_METHOD', 'auto');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Powers the debug system
|
|
||||||
*/
|
|
||||||
class debug {
|
|
||||||
/**
|
|
||||||
* Internal buffer exposing data between methods
|
|
||||||
* @var float $_timeStart
|
|
||||||
* @var string $_mode, $_modeStatic
|
|
||||||
*/
|
|
||||||
protected $_timeStart, $_mode;
|
|
||||||
protected static $_modeStatic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time storage for the timer
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public static $timer = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal buffer to store SQL queries and log messages
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private static $_queries = array(), $_log = array(), $_initTime = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the PHP microtime() relative to the start of the instance
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public static function microtime() {
|
|
||||||
$now = microtime(true);
|
|
||||||
if (!self::$_initTime) {
|
|
||||||
self::$_initTime = $now;
|
|
||||||
}
|
|
||||||
return ($now - self::$_initTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Timer - sets breakpoints (aka. split times) and returns time since last breakpoint
|
|
||||||
*
|
|
||||||
* @param mixed $breakpointId Optional, any vector type is valid
|
|
||||||
* @param mixed $id Optional, any vector type is valid
|
|
||||||
* @return string Nicely formatted float
|
|
||||||
*/
|
|
||||||
public static function timer($breakpointId = null, $id = 'default') {
|
|
||||||
if (!isset(self::$timer[$id])) {
|
|
||||||
$return = 0;
|
|
||||||
}
|
|
||||||
if (!$breakpointId) {
|
|
||||||
self::$timer[$id][] = self::microtime();
|
|
||||||
} else {
|
|
||||||
self::$timer[$id][$breakpointId] = self::microtime();
|
|
||||||
}
|
|
||||||
if (!isset($return)) {
|
|
||||||
$return = (end(self::$timer[$id]) - prev(self::$timer[$id]));
|
|
||||||
}
|
|
||||||
return number_format($return, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the total execution time for a timer - minimum of two breakpoints required for a non-zero return
|
|
||||||
*
|
|
||||||
* @param mixed $id Optional, any vector type is valid
|
|
||||||
* @return string Nicely formatted float
|
|
||||||
*/
|
|
||||||
public static function timerTotal($id = 'default') {
|
|
||||||
$return = 0;
|
|
||||||
if (isset(self::$timer[$id]) && count(self::$timer[$id]) > 1) {
|
|
||||||
$return = (end(self::$timer[$id]) - reset(self::$timer[$id]));
|
|
||||||
}
|
|
||||||
return number_format($return, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reports the total time table for a timer via the debug output mode
|
|
||||||
*
|
|
||||||
* @param mixed $id Optional, any vector type is valid
|
|
||||||
* @return string Nicely formatted float
|
|
||||||
*/
|
|
||||||
public static function timerReport($id = 'default') {
|
|
||||||
if (!isset(self::$timer[$id])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$last = reset(self::$timer[$id]);
|
|
||||||
if (self::$_modeStatic == 'FirePHP') {
|
|
||||||
$FirePHP = FirePHP::getInstance(true);
|
|
||||||
foreach (self::$timer[$id] as $breakpointId => $val) {
|
|
||||||
$FirePHP->info((string) $breakpointId, number_format(($val - $last), 5));
|
|
||||||
$last = $val;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foreach (self::$timer[$id] as $breakpointId => $val) {
|
|
||||||
$return[] = number_format(($val - $last), 5) . ' - ' . $breakpointId;
|
|
||||||
$last = $val;
|
|
||||||
}
|
|
||||||
if (self::$_modeStatic == 'html' || self::$_modeStatic == 'text') {
|
|
||||||
$recordDelimiter = PHP_EOL . PHP_EOL;
|
|
||||||
if (self::$_modeStatic == 'html') {
|
|
||||||
$recordDelimiter .= '<hr />';
|
|
||||||
}
|
|
||||||
echo $recordDelimiter . implode($recordDelimiter, $return) . $recordDelimiter;
|
|
||||||
}
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a SQL query
|
|
||||||
*
|
|
||||||
* @param string $query
|
|
||||||
* @param float $executionTime Optional
|
|
||||||
* @param string $error Optional
|
|
||||||
*/
|
|
||||||
public static function logQuery($query, $executionTime = null, $error = null) {
|
|
||||||
self::$_queries[] = array('query' => $query, 'executionTime' => $executionTime, 'error' => $error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a message
|
|
||||||
*
|
|
||||||
* @param str $data
|
|
||||||
* @param str $type Valid options are log, info, warn and error
|
|
||||||
*/
|
|
||||||
public static function log($data, $type = 'log') {
|
|
||||||
self::$_log[] = array('data' => $data, 'method' => $type, 'time' => self::microtime());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the debug system
|
|
||||||
*
|
|
||||||
* @param string $mode Optional. Mode of output by default is html, but the framework automatically overrides
|
|
||||||
* this with your DEBUG_OUTPUT_METHOD setting
|
|
||||||
*/
|
|
||||||
public function __construct($mode = 'html') {
|
|
||||||
if ($mode == 'auto') {
|
|
||||||
$mode = (strpos($_SERVER['HTTP_USER_AGENT'], 'FirePHP') !== false ? 'FirePHP' : 'html');
|
|
||||||
}
|
|
||||||
if ($mode == 'FirePHP' && !class_exists('FirePHP')) {
|
|
||||||
$configInit = new configInit;
|
|
||||||
$firephpDir = $configInit->packagesPath() . 'FirePHPCore' . $configInit->DS;
|
|
||||||
if (is_dir($firephpDir)) {
|
|
||||||
require_once $firephpDir . 'FirePHP.class.php';
|
|
||||||
}
|
|
||||||
if (!class_exists('FirePHP')) {
|
|
||||||
$mode = 'html';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($mode == 'FirePHP' && ini_get('output_buffering') != 'On') {
|
|
||||||
ob_start();
|
|
||||||
}
|
|
||||||
self::$_modeStatic = $this->_mode = $mode;
|
|
||||||
$this->_timeStart = self::microtime();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tallies up the debug info and outputs it
|
|
||||||
*/
|
|
||||||
public function __destruct() {
|
|
||||||
$execTime = 'Page execution time: ' . number_format(self::microtime() - $this->_timeStart, 5);
|
|
||||||
$sqlExecString = 'Execution time of previous SQL: ';
|
|
||||||
if ($this->_mode == 'FirePHP') {
|
|
||||||
$FirePHP = FirePHP::getInstance(true);
|
|
||||||
$FirePHP->info($execTime);
|
|
||||||
if (!empty(self::$_log)) {
|
|
||||||
$timeLast = $this->_timeStart;
|
|
||||||
foreach (self::$_log as $logArray) {
|
|
||||||
$data = '(' . number_format($logArray['time'] - $timeLast, 5) . ') ' . $logArray['data'];
|
|
||||||
$FirePHP->{$logArray['method']}($data);
|
|
||||||
$timeLast = $logArray['time'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!empty(self::$_queries)) {
|
|
||||||
foreach (self::$_queries as $queryArray) {
|
|
||||||
$FirePHP->group('SQL');
|
|
||||||
$FirePHP->log($queryArray['query']);
|
|
||||||
if ($queryArray['executionTime'] !== null) {
|
|
||||||
$FirePHP->info($sqlExecString . $queryArray['executionTime']);
|
|
||||||
}
|
|
||||||
if ($queryArray['error'] !== null) {
|
|
||||||
$FirePHP->error($queryArray['error']);
|
|
||||||
}
|
|
||||||
$FirePHP->groupEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$recordDelimiter = PHP_EOL . PHP_EOL;
|
|
||||||
$lineDelimiter = PHP_EOL;
|
|
||||||
if ($this->_mode == 'html') {
|
|
||||||
echo '<br style="clear: both;" />';
|
|
||||||
$recordDelimiter .= '<hr />';
|
|
||||||
$lineDelimiter .= '<br />';
|
|
||||||
}
|
|
||||||
echo $recordDelimiter . $execTime;
|
|
||||||
if (!empty(self::$_log)) {
|
|
||||||
foreach (self::$_log as $logArray) {
|
|
||||||
echo $lineDelimiter . $logArray['method'] . ': ' . get::htmlentities($logArray['data']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!empty(self::$_queries)) {
|
|
||||||
foreach (self::$_queries as $queryArray) {
|
|
||||||
echo $recordDelimiter . ($this->_mode == 'html' ? get::htmlentities($queryArray['query'])
|
|
||||||
: $queryArray['query']);
|
|
||||||
if ($queryArray['executionTime'] !== null) {
|
|
||||||
echo $lineDelimiter . $sqlExecString . $queryArray['executionTime'];
|
|
||||||
}
|
|
||||||
if ($queryArray['error'] !== null) {
|
|
||||||
echo $lineDelimiter . $queryArray['error'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$debugObject = new debug(DEBUG_OUTPUT_METHOD);
|
|
|
@ -1,26 +0,0 @@
|
||||||
git:
|
|
||||||
problems:
|
|
||||||
url: https://github.com/getgrav/grav-plugin-problems
|
|
||||||
path: user/plugins/problems
|
|
||||||
branch: master
|
|
||||||
error:
|
|
||||||
url: https://github.com/getgrav/grav-plugin-error
|
|
||||||
path: user/plugins/error
|
|
||||||
branch: master
|
|
||||||
antimatter:
|
|
||||||
url: https://github.com/getgrav/grav-theme-antimatter
|
|
||||||
path: user/themes/antimatter
|
|
||||||
branch: master
|
|
||||||
links:
|
|
||||||
problems:
|
|
||||||
src: grav-plugin-problems
|
|
||||||
path: user/plugins/problems
|
|
||||||
scm: github
|
|
||||||
error:
|
|
||||||
src: grav-plugin-error
|
|
||||||
path: user/plugins/error
|
|
||||||
scm: github
|
|
||||||
antimatter:
|
|
||||||
src: grav-theme-antimatter
|
|
||||||
path: user/themes/antimatter
|
|
||||||
scm: github
|
|
|
@ -1,5 +0,0 @@
|
||||||
repo: 4bb20edbf41fe2cf5294bfad1428e943f7d3fe65
|
|
||||||
node: 01251bf0ea8aeaec434f4226bee735eaf1bc14ba
|
|
||||||
branch: default
|
|
||||||
latesttag: null
|
|
||||||
latesttagdistance: 25
|
|
|
@ -1 +0,0 @@
|
||||||
.DS_Store
|
|
|
@ -1,63 +0,0 @@
|
||||||
<IfModule mod_rewrite.c>
|
|
||||||
|
|
||||||
RewriteEngine On
|
|
||||||
|
|
||||||
## Begin RewriteBase
|
|
||||||
# If you are getting 404 errors on subpages, you may have to uncomment the RewriteBase entry
|
|
||||||
# You should change the '/' to your appropriate subfolder. For example if you have
|
|
||||||
# your Grav install at the root of your site '/' should work, else it might be something
|
|
||||||
# along the lines of: RewriteBase /<your_sub_folder>
|
|
||||||
##
|
|
||||||
|
|
||||||
# RewriteBase /
|
|
||||||
|
|
||||||
## End - RewriteBase
|
|
||||||
|
|
||||||
## Begin - Exploits
|
|
||||||
# If you experience problems on your site block out the operations listed below
|
|
||||||
# This attempts to block the most common type of exploit `attempts` to Grav
|
|
||||||
#
|
|
||||||
# Block out any script trying to base64_encode data within the URL.
|
|
||||||
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
|
|
||||||
# Block out any script that includes a <script> tag in URL.
|
|
||||||
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
|
|
||||||
# Block out any script trying to set a PHP GLOBALS variable via URL.
|
|
||||||
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
|
|
||||||
# Block out any script trying to modify a _REQUEST variable via URL.
|
|
||||||
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
|
|
||||||
# Return 403 Forbidden header and show the content of the root homepage
|
|
||||||
RewriteRule .* index.php [F]
|
|
||||||
#
|
|
||||||
## End - Exploits
|
|
||||||
|
|
||||||
## Begin - Index
|
|
||||||
# If the requested path and file is not /index.php and the request
|
|
||||||
# has not already been internally rewritten to the index.php script
|
|
||||||
RewriteCond %{REQUEST_URI} !^/index\.php
|
|
||||||
# and the requested path and file doesn't directly match a physical file
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
|
||||||
# and the requested path and file doesn't directly match a physical folder
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-d
|
|
||||||
# internally rewrite the request to the index.php script
|
|
||||||
RewriteRule .* index.php [L]
|
|
||||||
## End - Index
|
|
||||||
|
|
||||||
## Begin - Security
|
|
||||||
# Block all direct access for these folders
|
|
||||||
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [L]
|
|
||||||
# Block access to specific file types for these folders
|
|
||||||
RewriteRule ^(system|user|vendor)/(.*)\.(txt|md|html|yaml|php|twig|sh|bat)$ error [L]
|
|
||||||
# Block all direct access to .md files:
|
|
||||||
RewriteRule \.md$ error [L]
|
|
||||||
# Block all direct access to files and folders beginning with a dot
|
|
||||||
RewriteRule (^\.|/\.) - [F]
|
|
||||||
# Block access to specific files in the root folder
|
|
||||||
RewriteRule ^(LICENSE|composer.lock|composer.json|nginx.conf|web.config)$ error [F]
|
|
||||||
## End - Security
|
|
||||||
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# Begin - Prevent Browsing and Set Default Resources
|
|
||||||
Options -Indexes
|
|
||||||
DirectoryIndex index.php index.html index.htm
|
|
||||||
# End - Prevent Browsing and Set Default Resources
|
|
170
src/.installer
|
@ -1,170 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Upgrades the Vork framework and installs Vork Apps
|
|
||||||
*/
|
|
||||||
class vorkInstaller {
|
|
||||||
/**
|
|
||||||
* ID of the upload-form field
|
|
||||||
*/
|
|
||||||
const fileId = 'file';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Path to the install log - default is in the root of the Vork installation (one level below webroot)
|
|
||||||
*/
|
|
||||||
const logFile = '../.install.log';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cache of the vorkInstall object contained in the install/upgrade package
|
|
||||||
* @var vorkInstall
|
|
||||||
*/
|
|
||||||
public $vorkInstall;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy instance-scope temp file into a regular persistant temp-file
|
|
||||||
* @return string Filename of the new temp-file
|
|
||||||
*/
|
|
||||||
protected function _makeUploadPersist() {
|
|
||||||
$persistantName = $_FILES[self::fileId]['tmp_name'] . '.vorkcache';
|
|
||||||
copy($_FILES[self::fileId]['tmp_name'], $persistantName);
|
|
||||||
return $persistantName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Install/upgrade engine
|
|
||||||
*/
|
|
||||||
protected function _install($file = null) {
|
|
||||||
$iniFilename = 'vork.ini';
|
|
||||||
$za = new ZipArchive();
|
|
||||||
$za->open(!$file ? $_FILES[self::fileId]['tmp_name'] : $file);
|
|
||||||
if (!($fileCount = $za->numFiles) || !($this->vorkInstall = $za->statName($iniFilename))) {
|
|
||||||
$_POST['errors'][self::fileId] = 'Not a valid Vork app or Vork upgrade file (missing the ' . $iniFilename
|
|
||||||
. ' file), try re-downloading from www.Vork.us';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fp = $za->getStream($iniFilename);
|
|
||||||
while (!feof($fp)) {
|
|
||||||
$contents[] = fread($fp, 8192);
|
|
||||||
}
|
|
||||||
fclose($fp);
|
|
||||||
if (isset($contents)) {
|
|
||||||
$contents = implode($contents);
|
|
||||||
if (function_exists('parse_ini_string')) { //PHP 5.3+
|
|
||||||
$ini = parse_ini_string($contents);
|
|
||||||
} else {
|
|
||||||
$tmpName = tempnam(sys_get_temp_dir(), 'ini_');
|
|
||||||
file_put_contents($tmpName, $contents);
|
|
||||||
$ini = parse_ini_file($tmpName);
|
|
||||||
unlink($tmpName);
|
|
||||||
}
|
|
||||||
$ini['ts'] = time();
|
|
||||||
} else {
|
|
||||||
$_POST['errors'][self::fileId] = 'The ' . $iniFilename . ' file in this Vork app is invalid';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$file && $za->statName('.installer')) { //upgrade installer, then re-run using the newest installer
|
|
||||||
$za->extractTo('..', '.installer');
|
|
||||||
$file = $this->_makeUploadPersist();
|
|
||||||
load::redirect('/vork?install=' . urlencode($file));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->vorkInstall = new vorkInstall;
|
|
||||||
for ($i = 0; $i < $fileCount; $i++) {
|
|
||||||
$filepath = str_replace('\\', '/', $za->getNameIndex($i));
|
|
||||||
$filepathParts = explode('/', $filepath);
|
|
||||||
$fileName = array_pop($filepathParts);
|
|
||||||
$path = '';
|
|
||||||
foreach ($filepathParts as $part) {
|
|
||||||
$path .= $part;
|
|
||||||
if (!file_exists('../' . $path)) {
|
|
||||||
mkdir('../' . $path); //.. to drop back from webroot to Vork base directory
|
|
||||||
}
|
|
||||||
$path .= '/';
|
|
||||||
}
|
|
||||||
if ($fileName && $path . $fileName != $iniFilename && $path . $fileName != '.installer') {
|
|
||||||
$files[] = $path . $fileName; //directories are skipped since they have an empty string for $fileName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isset($files)) {
|
|
||||||
$za->extractTo('..', $files);
|
|
||||||
}
|
|
||||||
$za->close();
|
|
||||||
if ($file) {
|
|
||||||
unlink($file);
|
|
||||||
}
|
|
||||||
file_put_contents(self::logFile, json_encode($ini) . PHP_EOL, FILE_APPEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify file upload
|
|
||||||
*/
|
|
||||||
protected function _fileUploaded() {
|
|
||||||
if ($_FILES[self::fileId]['error'] == UPLOAD_ERR_OK && !$_FILES[self::fileId]['size']) {
|
|
||||||
$_FILES[self::fileId]['error'] = UPLOAD_ERR_NO_FILE;
|
|
||||||
}
|
|
||||||
switch ($_FILES[self::fileId]['error']) {
|
|
||||||
case UPLOAD_ERR_INI_SIZE:
|
|
||||||
$ini = 'upload_max_filesize';
|
|
||||||
//break intentionally omitted
|
|
||||||
case UPLOAD_ERR_FORM_SIZE:
|
|
||||||
$error = 'Error: file is too large to be uploaded - increase the '
|
|
||||||
. (isset($ini) ? $ini : 'MAX_FILE_SIZE') . ' setting in your php.ini file';
|
|
||||||
break;
|
|
||||||
case UPLOAD_ERR_PARTIAL:
|
|
||||||
case UPLOAD_ERR_NO_FILE:
|
|
||||||
$error = 'Error: the upload did not complete, please try again';
|
|
||||||
break;
|
|
||||||
case UPLOAD_ERR_NO_TMP_DIR:
|
|
||||||
$error = 'Error: your PHP installation has no temp-directory, create a folder at'
|
|
||||||
. realpath(sys_get_temp_dir()) . ' and grant PHP read/write access';
|
|
||||||
break;
|
|
||||||
case UPLOAD_ERR_CANT_WRITE:
|
|
||||||
$error = 'Error: cannot write to temp-directory, adjust your file-write permissions';
|
|
||||||
break;
|
|
||||||
case UPLOAD_ERR_OK:
|
|
||||||
$this->_install();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isset($error)) {
|
|
||||||
$_POST['errors'][self::fileId] = $error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* View
|
|
||||||
*/
|
|
||||||
public function __construct() {
|
|
||||||
$html = get::helper('html');
|
|
||||||
$form = get::helper('form');
|
|
||||||
$title = 'Vork Installer + Upgrader';
|
|
||||||
echo $html->header(array('title' => $title, 'cssInline' =>
|
|
||||||
'body {background: #feeebd url(http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/sunny/images/'
|
|
||||||
. 'ui-bg_highlight-soft_100_feeebd_1x100.png) 50% top repeat-x; font-family: "Arial";} '
|
|
||||||
. 'fieldset {border: 0px solid;} h1 {margin: 0px;} .errormessage {color: #ff0000;}'));
|
|
||||||
echo $html->h1($title);
|
|
||||||
$formArgs['enctype'] = 'multipart/form-data';
|
|
||||||
|
|
||||||
if (isset($_FILES[self::fileId])) {
|
|
||||||
$this->_fileUploaded();
|
|
||||||
} else if (isset($_GET['install'])) {
|
|
||||||
$this->_install($_GET['install']);
|
|
||||||
}
|
|
||||||
if (!isset($_POST['errors']) && $this->vorkInstall) {
|
|
||||||
$formArgs['alert'] = 'Install/upgrade of ' . $this->vorkInstall->meta['package'] . ' '
|
|
||||||
. $this->vorkInstall->meta['version'] . ' completed';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $form->getFormOpen($formArgs);
|
|
||||||
echo $html->div($form->getInput(array('name' => self::fileId, 'type' => 'file',
|
|
||||||
'label' => 'Upload Vork App or Vork Framework Upgrade'))
|
|
||||||
. $form->getInput(array('type' => 'submit', 'value' => 'Install app/upgade')));
|
|
||||||
echo $form->getFormClose();
|
|
||||||
|
|
||||||
echo $html->footer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new vorkInstaller;
|
|
||||||
exit(0);
|
|
892
src/CHANGELOG.md
|
@ -1,892 +0,0 @@
|
||||||
# v1.0.0-rc.4
|
|
||||||
## 10/29/2015
|
|
||||||
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fixed a fatal error if you have a collection with missing or invalid `@page: /route`
|
|
||||||
|
|
||||||
# v1.0.0-rc.3
|
|
||||||
## 10/29/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* New Page collection options! `@self.parent, @self.siblings, @self.descendants` + more
|
|
||||||
* Whitelist of file types for fallback route functionality (images by default)
|
|
||||||
1. [](#improved)
|
|
||||||
* Assets switched from defines to streams
|
|
||||||
1. [](#bugfix)
|
|
||||||
* README.md typos fixed
|
|
||||||
* Fixed issue with routes that have lang string in them (`/en/english`)
|
|
||||||
* Trim strings before validation so whitespace is not satisfy 'required'
|
|
||||||
|
|
||||||
# v1.0.0-rc.2
|
|
||||||
## 10/27/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added support for CSS Asset groups
|
|
||||||
* Added a `wrapped_site` system option for themes/plugins to use
|
|
||||||
* Pass `Page` object as event to `onTwigPageVariables()` event hook
|
|
||||||
* New `Data.items()` method to get all items
|
|
||||||
1. [](#improved)
|
|
||||||
* Missing pipelined remote asset will now fail quietly
|
|
||||||
* More reliably handle inline JS and CSS to remove only surrounding HTML tags
|
|
||||||
* `Medium.meta` returns new Data object so null checks are possible
|
|
||||||
* Improved Medium metadata merging to allow for automatic title/alt/class attributes
|
|
||||||
* Moved Grav object to global variable rather than template variable (useful for macros)
|
|
||||||
* German language improvements
|
|
||||||
* Updated bundled composer
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Accept variety of `true` values in `User.authorize()` method
|
|
||||||
* Fix for `Validation` throwing an error if no label set
|
|
||||||
|
|
||||||
# v1.0.0-rc.1
|
|
||||||
## 10/23/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Use native PECL YAML parser if installed for 4X speed boost in parsing YAML files
|
|
||||||
* Support for inherited theme class
|
|
||||||
* Added new default language prepend system configuration option
|
|
||||||
* New `|evaluate` Twig filter to evaluate a string as twig
|
|
||||||
* New system option to ignore all **hidden** files and folders
|
|
||||||
* New system option for default redirect code
|
|
||||||
* Added ability to append specific `[30x]` codes to redirect URLs
|
|
||||||
* Added `url_taxonomy_filters` for page collections
|
|
||||||
* Added `@root` page and `recurse` flag for page collections
|
|
||||||
* Support for **multiple** page collection types as an array
|
|
||||||
* Added Dutch language file
|
|
||||||
* Added Russian language file
|
|
||||||
* Added `remove` method to User object
|
|
||||||
1. [](#improved)
|
|
||||||
* Moved hardcoded mimetypes to `media.yaml` to be treated as Page media files
|
|
||||||
* Set `errors: display: false` by default in `system.yaml`
|
|
||||||
* Strip out extra slashes in the URI
|
|
||||||
* Validate hostname to ensure it is valid
|
|
||||||
* Ignore more SCM folders in Backups
|
|
||||||
* Removed `home_redirect` settings from `system.yaml`
|
|
||||||
* Added Page `media` as root twig object for consistency
|
|
||||||
* Updated to latest vendor libraries
|
|
||||||
* Optimizations to Asset pipeline logic for minor speed increase
|
|
||||||
* Block direct access to a variety of files in `.htaccess` for increased security
|
|
||||||
* Debugbar vendor library update
|
|
||||||
* Always fallback to english if other translations are not available
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fix for redirecting external URL with multi-language
|
|
||||||
* Fix for Asset pipeline not respecting asset groups
|
|
||||||
* Fix language files with child/parent theme relationships
|
|
||||||
* Fixed a regression issue resulting in incorrect default language
|
|
||||||
* Ensure error handler is initialized before URI is processed
|
|
||||||
* Use default language in Twig if active language is not set
|
|
||||||
* Fixed issue with `safeEmailFilter()` Twig filter not separating with `;` properly
|
|
||||||
* Fixed empty YAML file causing error with native PECL YAML parser
|
|
||||||
* Fixed `SVG` mimetype
|
|
||||||
* Fixed incorrect `Cache-control: max-age` value format
|
|
||||||
|
|
||||||
# v0.9.45
|
|
||||||
## 10/08/2015
|
|
||||||
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fixed a regression issue resulting in incorrect default language
|
|
||||||
|
|
||||||
# v0.9.44
|
|
||||||
## 10/07/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added Redis back as a supported cache mechanism
|
|
||||||
* Allow Twig `nicetime` translations
|
|
||||||
* Added `-y` option for 'Yes to all' in `bin/gpm update`
|
|
||||||
* Added CSS `media` attribute to the Assets manager
|
|
||||||
* New German language support
|
|
||||||
* New Czech language support
|
|
||||||
* New French language support
|
|
||||||
* Added `modulus` twig filter
|
|
||||||
1. [](#improved)
|
|
||||||
* URL decode in medium actions to allow complex syntax
|
|
||||||
* Take into account `HTTP_HOST` before `SERVER_NAME` (helpful with Nginx)
|
|
||||||
* More friendly cache naming to ease manual management of cache systems
|
|
||||||
* Added default Apache resource for `DirectoryIndex`
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fix GPM failure when offline
|
|
||||||
* Fix `open_basedir` error in `bin/gpm install`
|
|
||||||
* Fix an HHVM error in Truncator
|
|
||||||
* Fix for XSS vulnerability with params
|
|
||||||
* Fix chaining for responsive size derivatives
|
|
||||||
* Fix for saving pages when removing the page title and all other header elements
|
|
||||||
* Fix when saving array fields
|
|
||||||
* Fix for ports being included in `HTTP_HOST`
|
|
||||||
* Fix for Truncator to handle PHP tags gracefully
|
|
||||||
* Fix for locate style lang codes in `getNativeName()`
|
|
||||||
* Urldecode image basenames in markdown
|
|
||||||
|
|
||||||
# v0.9.43
|
|
||||||
## 09/16/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added new `AudioMedium` for HTML5 audio
|
|
||||||
* Added ability for Assets to be added and displayed in separate *groups*
|
|
||||||
* New support for responsive image derivative sizes
|
|
||||||
1. [](#improved)
|
|
||||||
* GPM theme install now uses a `copy` method so new files are not lost (e.g. `/css/custom.css`)
|
|
||||||
* Code analysis improvements and cleanup
|
|
||||||
* Removed Twig panel from debugger (no longer supported in Twig 1.20)
|
|
||||||
* Updated composer packages
|
|
||||||
* Prepend active language to `convertUrl()` when used in markdown links
|
|
||||||
* Added some pre/post flight options for installer via blueprints
|
|
||||||
* Hyphenize the site name in the backup filename
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fix broken routable logic
|
|
||||||
* Check for `phpinfo()` method in case it is restricted by hosting provider
|
|
||||||
* Fixes for windows when running GPM
|
|
||||||
* Fix for ampersand (`&`) causing error in `truncateHtml()` via `Page.summary()`
|
|
||||||
|
|
||||||
# v0.9.42
|
|
||||||
## 09/11/2015
|
|
||||||
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fixed `User.authorise()` to be backwards compabile
|
|
||||||
|
|
||||||
# v0.9.41
|
|
||||||
## 09/11/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* New and improved multibyte-safe TruncateHTML function and filter
|
|
||||||
* Added support for custom page date format
|
|
||||||
* Added a `string` Twig filter to render as json_encoded string
|
|
||||||
* Added `authorize` Twig filter
|
|
||||||
* Added support for theme inheritance in the admin
|
|
||||||
* Support for multiple content collections on a page
|
|
||||||
* Added configurable files/folders ignores for pages
|
|
||||||
* Added the ability to set the default PHP locale and override via multi-lang configuration
|
|
||||||
* Added ability to save as YAML via admin
|
|
||||||
* Added check for `mbstring` support
|
|
||||||
* Added new `redirect` header for pages
|
|
||||||
1. [](#improved)
|
|
||||||
* Changed dependencies from `develop` to `master`
|
|
||||||
* Updated logging to log everything from `debug` level on (was `warning`)
|
|
||||||
* Added missing `accounts/` folder
|
|
||||||
* Default to performing a 301 redirect for URIs with trailing slashes
|
|
||||||
* Improved Twig error messages
|
|
||||||
* Allow validating of forms from anywhere such as plugins
|
|
||||||
* Added logic so modular pages are by default non-routable
|
|
||||||
* Hide password input in `bin/grav newuser` command
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fixed `Pages.all()` not returning modular pages
|
|
||||||
* Fix for modular template types not getting found
|
|
||||||
* Fix for `markdown_extra:` overriding `markdown:extra:` setting
|
|
||||||
* Fix for multi-site routing
|
|
||||||
* Fix for multi-lang page name error
|
|
||||||
* Fixed a redirect loop in `URI` class
|
|
||||||
* Fixed a potential error when `unsupported_inline_types` is empty
|
|
||||||
* Correctly generate 2x retina image
|
|
||||||
* Typo fixes in page publish/unpublish blueprint
|
|
||||||
|
|
||||||
# v0.9.40
|
|
||||||
## 08/31/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added some new Twig filters: `defined`, `rtrim`, `ltrim`
|
|
||||||
* Admin support for customizable page file name + template override
|
|
||||||
1. [](#improved)
|
|
||||||
* Better message for incompatible/unsupported Twig template
|
|
||||||
* Improved User blueprints with better help
|
|
||||||
* Switched to composer **install** rather than **update** by default
|
|
||||||
* Admin autofocus on page title
|
|
||||||
* `.htaccess` hardening (`.htaccess` & `htaccess.txt`)
|
|
||||||
* Cache safety checks for missing folders
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fixed issue with unescaped `o` character in date formats
|
|
||||||
|
|
||||||
# v0.9.39
|
|
||||||
## 08/25/2015
|
|
||||||
|
|
||||||
1. [](#bugfix)
|
|
||||||
* `Page.active()` not triggering on **homepage**
|
|
||||||
* Fix for invalid session name in Opera browser
|
|
||||||
|
|
||||||
# v0.9.38
|
|
||||||
## 08/24/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added `language` to **user** blueprint
|
|
||||||
* Added translations to blueprints
|
|
||||||
* New extending logic for blueprints
|
|
||||||
* Blueprints are now loaded with Streams to allow for better overrides
|
|
||||||
* Added new Symfony `dump()` method
|
|
||||||
1. [](#improved)
|
|
||||||
* Catch YAML header parse exception so site doesn't die
|
|
||||||
* Better `Page.parent()` logic
|
|
||||||
* Improved GPM display layout
|
|
||||||
* Tweaked default page layout
|
|
||||||
* Unset route and slug for improved reliability of route changes
|
|
||||||
* Added requirements to README.md
|
|
||||||
* Updated various libraries
|
|
||||||
* Allow use of custom page date field for dateRange collections
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Slug fixes with GPM
|
|
||||||
* Unset plaintext password on save
|
|
||||||
* Fix for trailing `/` not matching active children
|
|
||||||
|
|
||||||
# v0.9.37
|
|
||||||
## 08/12/2015
|
|
||||||
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fixed issue when saving `header.process` in page forms via the **admin plugin**
|
|
||||||
* Fixed error due to use of `set_time_limit` that might be disabled on some hosts
|
|
||||||
|
|
||||||
# v0.9.36
|
|
||||||
## 08/11/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added a new `newuser` CLI command to create user accounts
|
|
||||||
* Added `default` blueprint for all templates
|
|
||||||
* Support `user` and `system` language translation merging
|
|
||||||
1. [](#improved)
|
|
||||||
* Added isSymlink method in GPM to determine if Grav is symbolically linked or not
|
|
||||||
* Refactored page recursing
|
|
||||||
* Updated blueprints to use new toggles
|
|
||||||
* Updated blueprints to use current date for date format fields
|
|
||||||
* Updated composer.phar
|
|
||||||
* Use sessions for admin even when disabled for site
|
|
||||||
* Use `GRAV_ROOT` in session identifier
|
|
||||||
|
|
||||||
# v0.9.35
|
|
||||||
## 08/06/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added `body_classes` field
|
|
||||||
* Added `visiblity` toggle and help tooltips on new page form
|
|
||||||
* Added new `Page.unsetRoute()` method to allow admin to regenerate the route
|
|
||||||
2. [](#improved)
|
|
||||||
* User save no longer stores username each time
|
|
||||||
* Page list form field now shows all pages except root
|
|
||||||
* Removed required option from page title
|
|
||||||
* Added configuration settings for running Nginx in sub directory
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fixed deep translation merging
|
|
||||||
* Fixed broken **metadata** merging with site defaults
|
|
||||||
* Fixed broken **summary** field
|
|
||||||
* Fixed broken robots field
|
|
||||||
* Fixed GPM issue when using cURL, throwing an `Undefined offset: 1` exception
|
|
||||||
* Removed duplicate hidden page `type` field
|
|
||||||
|
|
||||||
# v0.9.34
|
|
||||||
## 08/04/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added new `cache_all` system setting + media `cache()` method
|
|
||||||
* Added base languages configuration
|
|
||||||
* Added property language to page to help plugins identify page language
|
|
||||||
* New `Utils::arrayFilterRecursive()` method
|
|
||||||
2. [](#improved)
|
|
||||||
* Improved Session handling to support site and admin independently
|
|
||||||
* Allow Twig variables to be modified in other events
|
|
||||||
* Blueprint updates in preparation for Admin plugin
|
|
||||||
* Changed `Inflector` from static to object and added multi-language support
|
|
||||||
* Support for admin override of a page's blueprints
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Removed unused `use` in `VideoMedium` that was causing error
|
|
||||||
* Array fix in `User.authorise()` method
|
|
||||||
* Fix for typo in `translations_fallback`
|
|
||||||
* Fixed moving page to the root
|
|
||||||
|
|
||||||
# v0.9.33
|
|
||||||
## 07/21/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added new `onImageMediumSaved()` event (useful for post-image processing)
|
|
||||||
* Added `Vary: Accept-Encoding` option
|
|
||||||
2. [](#improved)
|
|
||||||
* Multilang-safe delimeter position
|
|
||||||
* Refactored Twig classes and added optional umask setting
|
|
||||||
* Removed `pageinit()` timing
|
|
||||||
* `Page->routable()` now takes `published()` state into account
|
|
||||||
* Improved how page extension is set
|
|
||||||
* Support `Language->translate()` method taking string and array
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fixed `backup` command to include empty folders
|
|
||||||
|
|
||||||
# v0.9.32
|
|
||||||
## 07/14/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Detect users preferred language via `http_accept_language` setting
|
|
||||||
* Added new `translateArray()` language method
|
|
||||||
2. [](#improved)
|
|
||||||
* Support `en` translations by default for plugins & themes
|
|
||||||
* Improved default generator tag
|
|
||||||
* Minor language tweaks and fixes
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix for session active language and homepage redirects
|
|
||||||
* Ignore root-level page rather than throwing error
|
|
||||||
|
|
||||||
# v0.9.31
|
|
||||||
## 07/09/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added xml, json, css and js to valid media file types
|
|
||||||
2. [](#improved)
|
|
||||||
* Better handling of unsupported media type downloads
|
|
||||||
* Improved `bin/grav backup` command to mimic admin plugin location/name
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Critical fix for broken language translations
|
|
||||||
* Fix for Twig markdown filter error
|
|
||||||
* Safety check for download extension
|
|
||||||
|
|
||||||
# v0.9.30
|
|
||||||
## 07/08/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* BIG NEWS! Extensive Multi-Language support is all new in 0.9.30!
|
|
||||||
* Translation support via Twig filter/function and PHP method
|
|
||||||
* Page specific default route
|
|
||||||
* Page specific route aliases
|
|
||||||
* Canonical URL route support
|
|
||||||
* Added built-in session support
|
|
||||||
* New `Page.rawRoute()` to get a consistent folder-based route to a page
|
|
||||||
* Added option to always redirect to default page on alias URL
|
|
||||||
* Added language safe redirect function for use in core and plugins
|
|
||||||
2. [](#improved)
|
|
||||||
* Improved `Page.active()` and `Page.activeChild()` methods to support route aliases
|
|
||||||
* Various spelling corrections in `.php` comments, `.md` and `.yaml` files
|
|
||||||
* `Utils::startsWith()` and `Utils::endsWith()` now support needle arrays
|
|
||||||
* Added a new timer around `pageInitialized` event
|
|
||||||
* Updated jQuery library to v2.1.4
|
|
||||||
3. [](#bugfix)
|
|
||||||
* In-page CSS and JS files are now handled properly
|
|
||||||
* Fix for `enable_media_timestamp` not working properly
|
|
||||||
|
|
||||||
# v0.9.29
|
|
||||||
## 06/22/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* New and improved Regex-powered redirect and route alias logic
|
|
||||||
* Added new `onBuildPagesInitialized` event for memory critical or time-consuming plugins
|
|
||||||
* Added a `setSummary()` method for pages
|
|
||||||
2. [](#improved)
|
|
||||||
* Improved `MergeConfig()` logic for more control
|
|
||||||
* Travis skeleton build trigger implemented
|
|
||||||
* Set composer.json versions to stable versions where possible
|
|
||||||
* Disabled `last_modified` and `etag` page headers by default (causing too much page caching)
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Preload classes during `bin/gpm selfupgrade` to avoid issues with updated classes
|
|
||||||
* Fix for directory relative _down_ links
|
|
||||||
|
|
||||||
# v0.9.28
|
|
||||||
## 06/16/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added method to set raw markdown on a page
|
|
||||||
* Added ability to enabled system and page level `etag` and `last_modified` headers
|
|
||||||
2. [](#improved)
|
|
||||||
* Improved image path processing
|
|
||||||
* Improved query string handling
|
|
||||||
* Optimization to image handling supporting URL encoded filenames
|
|
||||||
* Use global `composer` when available rather than Grv provided one
|
|
||||||
* Use `PHP_BINARY` contant rather than `php` executable
|
|
||||||
* Updated Doctrine Cache library
|
|
||||||
* Updated Symfony libraries
|
|
||||||
* Moved `convertUrl()` method to Uri object
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix incorrect slug causing problems with CLI `uninstall`
|
|
||||||
* Fix Twig runtime error with assets pipeline in sufolder installations
|
|
||||||
* Fix for `+` in image filenames
|
|
||||||
* Fix for dot files causing issues with page processing
|
|
||||||
* Fix for Uri path detection on Windows platform
|
|
||||||
* Fix for alternative media resolutions
|
|
||||||
* Fix for modularTypes key properties
|
|
||||||
|
|
||||||
# v0.9.27
|
|
||||||
## 05/09/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added new composer CLI command
|
|
||||||
* Added page-level summary header overrides
|
|
||||||
* Added `size` back for Media objects
|
|
||||||
* Refactored Backup command in preparation for admin plugin
|
|
||||||
* Added a new `parseLinks` method to Plugins class
|
|
||||||
* Added `starts_with` and `ends_with` Twig filters
|
|
||||||
2. [](#improved)
|
|
||||||
* Optimized install of vendor libraries for speed improvement
|
|
||||||
* Improved configuration handling in preparation for admin plugin
|
|
||||||
* Cache optimization: Don't cache Twig templates when you pass dynamic params
|
|
||||||
* Moved `Utils::rcopy` to `Folder::rcopy`
|
|
||||||
* Improved `Folder::doDelete`
|
|
||||||
* Added check for required Curl in GPM
|
|
||||||
* Updated included composer.phar to latest version
|
|
||||||
* Various blueprint fixes for admin plugin
|
|
||||||
* Various PSR and code cleanup tasks
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix issue with Gzip not working with `onShutDown()` event
|
|
||||||
* Fix for URLs with trailing slashes
|
|
||||||
* Handle condition where certain errors resulted in blank page
|
|
||||||
* Fix for issue with theme name equal to base_url and asset pipeline
|
|
||||||
* Fix to properly normalize font rewrite path
|
|
||||||
* Fix for absolute URLs below the current page
|
|
||||||
* Fix for `..` page references
|
|
||||||
|
|
||||||
# v0.9.26
|
|
||||||
## 04/24/2015
|
|
||||||
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fixed issue with homepage routes failing with 'dirname' error
|
|
||||||
|
|
||||||
# v0.9.25
|
|
||||||
## 04/24/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added support for E-Tag, Last-Modified, Cache-Control and Page-based expires headers
|
|
||||||
2. [](#improved)
|
|
||||||
* Refactored media image handling to make it more flexible and support absolute paths
|
|
||||||
* Refactored page modification check process to make it faster
|
|
||||||
* User account improvements in preparation for admin plugin
|
|
||||||
* Protect against timing attacks
|
|
||||||
* Reset default system expires time to 0 seconds (can override if you need to)
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix issues with spaces in webroot when using `bin/grav install`
|
|
||||||
* Fix for spaces in relative directory
|
|
||||||
* Bug fix in collection filtering
|
|
||||||
|
|
||||||
# v0.9.24
|
|
||||||
## 04/15/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added support for chunked downloads of Assets
|
|
||||||
* Added new `onBeforeDownload()` event
|
|
||||||
* Added new `download()` and `getMimeType()` methods to Utils class
|
|
||||||
* Added configuration option for supported page types
|
|
||||||
* Added assets and media timestamp options (off by default)
|
|
||||||
* Added page expires configuration option
|
|
||||||
2. [](#bugfix)
|
|
||||||
* Fixed issue with Nginx/Gzip and `ob_flush()` throwing error
|
|
||||||
* Fixed assets actions on 'direct media' URLs
|
|
||||||
* Fix for 'direct assets` with any parameters
|
|
||||||
|
|
||||||
# v0.9.23
|
|
||||||
## 04/09/2015
|
|
||||||
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fix for broken GPM `selfupgrade` (Grav 0.9.21 and 0.9.22 will need to manually upgrade to this version)
|
|
||||||
|
|
||||||
# v0.9.22
|
|
||||||
## 04/08/2015
|
|
||||||
|
|
||||||
1. [](#bugfix)
|
|
||||||
* Fix to normalize GRAV_ROOT path for Windows
|
|
||||||
* Fix to normalize Media image paths for Windows
|
|
||||||
* Fix for GPM `selfupgrade` when you are on latest version
|
|
||||||
|
|
||||||
# v0.9.21
|
|
||||||
## 04/07/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Major Media functionality enhancements: SVG, Animated GIF, Video support!
|
|
||||||
* Added ability to configure default image quality in system configuration
|
|
||||||
* Added `sizes` attributes for custom retina image breakpoints
|
|
||||||
2. [](#improved)
|
|
||||||
* Don't scale @1x retina images
|
|
||||||
* Add filter to Iterator class
|
|
||||||
* Updated various composer packages
|
|
||||||
* Various PSR fixes
|
|
||||||
|
|
||||||
# v0.9.20
|
|
||||||
## 03/24/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added `addAsyncJs()` and `addDeferJs()` to Assets manager
|
|
||||||
* Added support for extranal URL redirects
|
|
||||||
2. [](#improved)
|
|
||||||
* Fix unpredictable asset ordering when set from plugin/system
|
|
||||||
* Updated `nginx.conf` to ensure system assets are accessible
|
|
||||||
* Ensure images are served as static files in Nginx
|
|
||||||
* Updated vendor libraries to latest versions
|
|
||||||
* Updated included composer.phar to latest version
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fixed issue with markdown links to `#` breaking HTML
|
|
||||||
|
|
||||||
# v0.9.19
|
|
||||||
## 02/28/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added named assets capability and bundled jQuery into Grav core
|
|
||||||
* Added `first()` and `last()` to `Iterator` class
|
|
||||||
2. [](#improved)
|
|
||||||
* Improved page modification routine to skip _dot files_
|
|
||||||
* Only use files to calculate page modification dates
|
|
||||||
* Broke out Folder iterators into their own classes
|
|
||||||
* Various Sensiolabs Insight fixes
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fixed `Iterator.nth()` method
|
|
||||||
|
|
||||||
# v0.9.18
|
|
||||||
## 02/19/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added ability for GPM `install` to automatically install `_demo` content if found (w/backup)
|
|
||||||
* Added ability for themes and plugins to have dependencies required to install via GPM
|
|
||||||
* Added ability to override the system timezone rather than relying on server setting only
|
|
||||||
* Added new Twig filter `random_string` for generating random id values
|
|
||||||
* Added new Twig filter `markdown` for on-the-fly markdown processing
|
|
||||||
* Added new Twig filter `absoluteUrl` to convert relative to absolute URLs
|
|
||||||
* Added new `processTemplate()` method to Twig object for on-the-fly processing of twig template
|
|
||||||
* Added `rcopy()` and `contains()` helper methods in Utils
|
|
||||||
2. [](#improved)
|
|
||||||
* Provided new `param_sep` variable to better support Apache on Windows
|
|
||||||
* Moved parsedown configuration into the trait
|
|
||||||
* Added optional **deep-copy** option to `mergeConfig()` for plugins
|
|
||||||
* Updated bundled `composer.phar` package
|
|
||||||
* Various Sensiolabs Insight fixes - Silver level now!
|
|
||||||
* Various PSR Fixes
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix for windows platforms not displaying installed themes/plugins via GPM
|
|
||||||
* Fix page IDs not picking up folder-only pages
|
|
||||||
|
|
||||||
# v0.9.17
|
|
||||||
## 02/05/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added **full HHVM support!** Get your speed on with Facebook's crazy fast PHP JIT compiler
|
|
||||||
2. [](#improved)
|
|
||||||
* More flexible page summary control
|
|
||||||
* Support **CamelCase** plugin and theme class names. Replaces dashes and underscores
|
|
||||||
* Moved summary delimiter into `site.yaml` so it can be configurable
|
|
||||||
* Various PSR fixes
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix for `mergeConfig()` not falling back to defaults
|
|
||||||
* Fix for `addInlineCss()` and `addInlineJs()` Assets not working between Twig tags
|
|
||||||
* Fix for Markdown adding HTML tags into inline CSS and JS
|
|
||||||
|
|
||||||
# v0.9.16
|
|
||||||
## 01/30/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added **Retina** and **Responsive** image support via Grav media and `srcset` image attribute
|
|
||||||
* Added image debug option that overlays responsive resolution
|
|
||||||
* Added a new image cache stream
|
|
||||||
2. [](#improved)
|
|
||||||
* Improved the markdown Lightbox functionality to better mimic Twig version
|
|
||||||
* Fullsize Lightbox can now have filters applied
|
|
||||||
* Added a new `mergeConfig()` method to Plugin class to merge system + page header configuration
|
|
||||||
* Added a new `disable()` method to Plugin class to programmatically disable a plugin
|
|
||||||
* Updated Parsedown and Parsedown Extra to address bugs
|
|
||||||
* Various PSR fixes
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix bug with image dispatch in traditionally _non-routable_ pages
|
|
||||||
* Fix for markdown link not working on non-current pages
|
|
||||||
* Fix for markdown images not being found on homepage
|
|
||||||
|
|
||||||
# v0.9.15
|
|
||||||
## 01/23/2015
|
|
||||||
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Typo in video mime types
|
|
||||||
* Fix for old `markdown_extra` system setting not getting picked up
|
|
||||||
* Fix in regex for Markdown links with numeric values in path
|
|
||||||
* Fix for broken image routing mechanism that got broken at some point
|
|
||||||
* Fix for markdown images/links in pages with page slug override
|
|
||||||
|
|
||||||
# v0.9.14
|
|
||||||
## 01/23/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added **GZip** support
|
|
||||||
* Added multiple configurations via `setup.php`
|
|
||||||
* Added base structure for unit tests
|
|
||||||
* New `onPageContentRaw()` plugin event that processes before any page processing
|
|
||||||
* Added ability to dynamically set Metadata on page
|
|
||||||
* Added ability to dynamically configure Markdown processing via Parsedown options
|
|
||||||
2. [](#improved)
|
|
||||||
* Refactored `page.content()` method to be more flexible and reliable
|
|
||||||
* Various updates and fixes for streams resulting in better multi-site support
|
|
||||||
* Updated Twig, Parsedown, ParsedownExtra, DoctrineCache libraries
|
|
||||||
* Refactored Parsedown trait
|
|
||||||
* Force modular pages to be non-visible in menus
|
|
||||||
* Moved RewriteBase before Exploits in `.htaccess`
|
|
||||||
* Added standard video formats to Media support
|
|
||||||
* Added priority for inline assets
|
|
||||||
* Check for uniqueness when adding multiple inline assets
|
|
||||||
* Improved support for Twig-based URLs inside Markdown links and images
|
|
||||||
* Improved Twig `url()` function
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix for HTML entities quotes in Metadata values
|
|
||||||
* Fix for `published` setting to have precedent of `publish_date` and `unpublish_date`
|
|
||||||
* Fix for `onShutdown()` events not closing connections properly in **php-fpm** environments
|
|
||||||
|
|
||||||
# v0.9.13
|
|
||||||
## 01/09/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added new published `true|false` state in page headers
|
|
||||||
* Added `publish_date` in page headers to automatically publish page
|
|
||||||
* Added `unpublish_date` in page headers to automatically unpublish page
|
|
||||||
* Added `dateRange()` capability for collections
|
|
||||||
* Added ability to dynamically control Cache lifetime programmatically
|
|
||||||
* Added ability to sort by anything in the page header. E.g. `sort: header.taxonomy.year`
|
|
||||||
* Added various helper methods to collections: `copy, nonVisible, modular, nonModular, published, nonPublished, nonRoutable`
|
|
||||||
2. [](#improved)
|
|
||||||
* Modified all Collection methods so they can be chained together: `$collection->published()->visible()`
|
|
||||||
* Set default Cache lifetime to default of 1 week (604800 seconds) - was infinite
|
|
||||||
* House-cleaning of some unused methods in Pages object
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix `uninstall` GPM command that was broken in last release
|
|
||||||
* Fix for intermittent `undefined index` error when working with Collections
|
|
||||||
* Fix for date of some pages being set to incorrect future timestamps
|
|
||||||
|
|
||||||
# v0.9.12
|
|
||||||
## 01/06/2015
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added an all-access robots.txt file for search engines
|
|
||||||
* Added new GPM `uninstall` command
|
|
||||||
* Added support for **in-page** Twig processing in **modular** pages
|
|
||||||
* Added configurable support for `undefined` Twig functions and filters
|
|
||||||
2. [](#improved)
|
|
||||||
* Fall back to default `.html` template if error occurs on non-html pages
|
|
||||||
* Added ability to have PSR-1 friendly plugin names (CamelCase, no-dashes)
|
|
||||||
* Fix to `composer.json` to deter API rate-limit errors
|
|
||||||
* Added **non-exception-throwing** handler for undefined methods on `Medium` objects
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix description for `self-upgrade` method of GPM command
|
|
||||||
* Fix for incorrect version number when performing GPM `update`
|
|
||||||
* Fix for argument description of GPM `install` command
|
|
||||||
* Fix for recalcitrant CodeKit mac application
|
|
||||||
|
|
||||||
# v0.9.11
|
|
||||||
## 12/21/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added support for simple redirects as well as routes
|
|
||||||
2. [](#improved)
|
|
||||||
* Handle Twig errors more cleanly
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix for error caused by invalid or missing user agent string
|
|
||||||
* Fix for directory relative links and URL fragments (#pagelink)
|
|
||||||
* Fix for relative links with no subfolder in `base_url`
|
|
||||||
|
|
||||||
# v0.9.10
|
|
||||||
## 12/12/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added Facebook-style `nicetime` date Twig filter
|
|
||||||
2. [](#improved)
|
|
||||||
* Moved `clear-cache` functionality into Cache object required for Admin plugin
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix for undefined index with previous/next buttons
|
|
||||||
|
|
||||||
# v0.9.9
|
|
||||||
## 12/05/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added new `@page` collection type
|
|
||||||
* Added `ksort` and `contains` Twig filters
|
|
||||||
* Added `gist` Twig function
|
|
||||||
2. [](#improved)
|
|
||||||
* Refactored Page previous/next/adjacent functionality
|
|
||||||
* Updated to Symfony 2.6 for yaml/console/event-dispatcher libraries
|
|
||||||
* More PSR code fixes
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix for over-escaped apostrophes in YAML
|
|
||||||
|
|
||||||
# v0.9.8
|
|
||||||
## 12/01/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added configuration option to set default lifetime on cache saves
|
|
||||||
* Added ability to set HTTP status code from page header
|
|
||||||
* Implemented simple wild-card custom routing
|
|
||||||
2. [](#improved)
|
|
||||||
* Fixed elusive double load to fully cache issue (crossing fingers...)
|
|
||||||
* Ensure Twig tags are treated as block items in markdown
|
|
||||||
* Removed some older deprecated methods
|
|
||||||
* Ensure onPageContentProcessed() event only fires when not cached
|
|
||||||
* More PSR code fixes
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix issue with miscalculation of blog separator location `===`
|
|
||||||
|
|
||||||
# v0.9.7
|
|
||||||
## 11/24/2014
|
|
||||||
|
|
||||||
1. [](#improved)
|
|
||||||
* Nginx configuration updated
|
|
||||||
* Added gitter.im badge to README
|
|
||||||
* Removed `set_time_limit()` and put checks around `ignore_user_abort`
|
|
||||||
* More PSR code fixes
|
|
||||||
2. [](#bugfix)
|
|
||||||
* Fix issue with non-valid asset path showing up when they shouldn't
|
|
||||||
* Fix for JS asset pipeline and scripts that don't end in `;`
|
|
||||||
* Fix for schema-based markdown URLs broken routes (eg `mailto:`)
|
|
||||||
|
|
||||||
# v0.9.6
|
|
||||||
## 11/17/2014
|
|
||||||
|
|
||||||
1. [](#improved)
|
|
||||||
* Moved base_url variables into Grav container
|
|
||||||
* Forced media sorting to use natural sort order by default
|
|
||||||
* Various PSR code tidying
|
|
||||||
* Added filename, extension, thumb to all medium objects
|
|
||||||
2. [](#bugfix)
|
|
||||||
* Fix for infinite loop in page.content()
|
|
||||||
* Fix hostname for configuration overrides
|
|
||||||
* Fix for cached configuration
|
|
||||||
* Fix for relative URLs in markdown on installs with no base_url
|
|
||||||
* Fix for page media images with uppercase extension
|
|
||||||
|
|
||||||
# v0.9.5
|
|
||||||
## 11/09/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added quality setting to medium for compression configuration of images
|
|
||||||
* Added new onPageContentProcessed() event that is post-content processing but pre-caching
|
|
||||||
2. [](#improved)
|
|
||||||
* Added support for AND and OR taxonomy filtering. AND by default (was OR)
|
|
||||||
* Added specific clearing options for CLI clear-cache command
|
|
||||||
* Moved environment method to URI so it can be accessible in plugins and themes
|
|
||||||
* Set Grav's output variable to public so it can be manipulated in onOutputGenerated event
|
|
||||||
* Updated vendor libraries to latest versions
|
|
||||||
* Better handing of 'home' in active menu state detection
|
|
||||||
* Various PSR code tidying
|
|
||||||
* Improved some error messages and notices
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Force route rebuild when configuration changes
|
|
||||||
* Fix for 'installed undefined' error in CLI versions command
|
|
||||||
* Do not remove the JSON/Text error handlers
|
|
||||||
* Fix for supporting inline JS and CSS when Asset pipeline enabled
|
|
||||||
* Fix for Data URLs in CSS being badly formed
|
|
||||||
* Fix Markdown links with fragment and query elements
|
|
||||||
|
|
||||||
# v0.9.4
|
|
||||||
## 10/29/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* New improved Debugbar with messages, timing, config, twig information
|
|
||||||
* New exception handling system utilizing Whoops
|
|
||||||
* New logging system utilizing Monolog
|
|
||||||
* Support for auto-detecting environment configuration
|
|
||||||
* New version command for CLI
|
|
||||||
* Integrate Twig dump() calls into Debugbar
|
|
||||||
2. [](#improved)
|
|
||||||
* Selfupgrade now clears cache on successful upgrade
|
|
||||||
* Selfupgrade now supports files without extensions
|
|
||||||
* Improved error messages when plugin is missing
|
|
||||||
* Improved security in .htaccess
|
|
||||||
* Support CSS/JS/Image assets in vendor/system folders via .htaccess
|
|
||||||
* Add support for system timers
|
|
||||||
* Improved and optimized configuration loading
|
|
||||||
* Automatically disable Debugbar on non-HTML pages
|
|
||||||
* Disable Debugbar by default
|
|
||||||
3. [](#bugfix)
|
|
||||||
* More YAML blueprint fixes
|
|
||||||
* Fix potential double // in assets
|
|
||||||
* Load debugger as early as possible
|
|
||||||
|
|
||||||
# v0.9.3
|
|
||||||
## 10/09/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* GPM (Grav Package Manager) Added
|
|
||||||
* Support for multiple Grav configurations
|
|
||||||
* Dynamic media support via URL
|
|
||||||
* Added inlineCss and inlineJs support for Assets
|
|
||||||
2. [](#improved)
|
|
||||||
* YAML caching for increased performance
|
|
||||||
* Use stream wrapper in pages, plugins and themes
|
|
||||||
* Switched to RocketTheme toolbox for some core functionality
|
|
||||||
* Renamed `setup` CLI command to `sandbox`
|
|
||||||
* Broke cache types out into multiple directories in the cache folder
|
|
||||||
* Removed vendor libs from github repository
|
|
||||||
* Various PSR cleanup of code
|
|
||||||
* Various Blueprint updates to support upcoming admin plugin
|
|
||||||
* Added ability to filter page children for normal/modular/all
|
|
||||||
* Added `sort_by_key` twig filter
|
|
||||||
* Added `visible()` and `routable()` filters to page collections
|
|
||||||
* Use session class in shutdown process
|
|
||||||
* Improvements to modular page loading
|
|
||||||
* Various code cleanup and optimizations
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fixed file checking not updating the last modified time. For real this time!
|
|
||||||
* Switched debugger to PRODUCTION mode by default
|
|
||||||
* Various fixes in URI class for increased reliability
|
|
||||||
|
|
||||||
# v0.9.2
|
|
||||||
## 09/15/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* New flexible site and page metadata support including ObjectGraph and Facebook
|
|
||||||
* New method to get user IP address in URI object
|
|
||||||
* Added new onShutdown() event that fires after connection is closed for Async features
|
|
||||||
2. [](#improved)
|
|
||||||
* Skip assets pipeline minify on Windows platforms by default due to PHP issue 47689
|
|
||||||
* Fixed multiple level menus not highlighting correctly
|
|
||||||
* Updated some blueprints in preparation for admin plugin
|
|
||||||
* Fail gracefully when theme does not exist
|
|
||||||
* Add stream support into ResourceLocator::addPath()
|
|
||||||
* Separate themes from plugins, add themes:// stream and onTask events
|
|
||||||
* Added barDump() to Debugger
|
|
||||||
* Removed stray test page
|
|
||||||
* Override modified only if a non-markdown file was modified
|
|
||||||
* Added assets attributes support
|
|
||||||
* Auto-run composer install when running the Grav CLI
|
|
||||||
* Vendor folder removed from repository
|
|
||||||
* Minor configuration performance optimizations
|
|
||||||
* Minor debugger performance optimizations
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fix url() twig function when Grav isn't installed at root
|
|
||||||
* Workaround for PHP bug 52065
|
|
||||||
* Fixed getList() method on Pages object that was not working
|
|
||||||
* Fix for open_basedir error
|
|
||||||
* index.php now warns if not running on PHP 5.4
|
|
||||||
* Removed memcached option (redundant)
|
|
||||||
* Removed memcache from auto setup, added memcache server configuration option
|
|
||||||
* Fix broken password validation
|
|
||||||
* Back to proper PSR-4 Autoloader
|
|
||||||
|
|
||||||
# v0.9.1
|
|
||||||
## 09/02/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Added new `theme://` PHP stream for current theme
|
|
||||||
2. [](#improved)
|
|
||||||
* Default to new `file` modification checking rather than `folder`
|
|
||||||
* Added support for various markdown link formats to convert to Grav-friendly URLs
|
|
||||||
* Moved configure() from Theme to Themes class
|
|
||||||
* Fix autoloading without composer update -o
|
|
||||||
* Added support for Twig url method
|
|
||||||
* Minor code cleanup
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fixed issue with page changes not being picked up
|
|
||||||
* Fixed Minify to provide `@supports` tag compatibility
|
|
||||||
* Fixed ResourceLocator not working with multiple paths
|
|
||||||
* Fixed issue with Markdown process not stripping LFs
|
|
||||||
* Restrict file type extensions for added security
|
|
||||||
* Fixed template inheritance
|
|
||||||
* Moved Browser class to proper location
|
|
||||||
|
|
||||||
# v0.9.0
|
|
||||||
## 08/25/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Addition of Dependency Injection Container
|
|
||||||
* Refactored plugins to use Symfony Event Dispatcher
|
|
||||||
* New Asset Manager to provide unified management of JavaScript and CSS
|
|
||||||
* Asset Pipelining to provide unification, minify, and optimization of JavaScript and CSS
|
|
||||||
* Grav Media support directly in Markdown syntax
|
|
||||||
* Additional Grav Generator meta tag in default themes
|
|
||||||
* Added support for PHP Stream Wrapper for resource location
|
|
||||||
* Markdown Extra support
|
|
||||||
* Browser object for fast browser detection
|
|
||||||
2. [](#improved)
|
|
||||||
* PSR-4 Autoloader mechanism
|
|
||||||
* Tracy Debugger new `detect` option to detect running environment
|
|
||||||
* Added new `random` collection sort option
|
|
||||||
* Make media images progressive by default
|
|
||||||
* Additional URI filtering for improved security
|
|
||||||
* Safety checks to ensure PHP 5.4.0+
|
|
||||||
* Move to Slidebars side navigation in default Antimatter theme
|
|
||||||
* Updates to `.htaccess` including section on `RewriteBase` which is needed for some hosting providers
|
|
||||||
3. [](#bugfix)
|
|
||||||
* Fixed issue when installing in an apache userdir (~username) folder
|
|
||||||
* Various mobile CSS issues in default themes
|
|
||||||
* Various minor bug fixes
|
|
||||||
|
|
||||||
|
|
||||||
# v0.8.0
|
|
||||||
## 08/13/2014
|
|
||||||
|
|
||||||
1. [](#new)
|
|
||||||
* Initial Release
|
|
21
src/LICENSE
|
@ -1,21 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2014 Grav
|
|
||||||
|
|
||||||
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.
|
|
110
src/README.md
|
@ -1,110 +0,0 @@
|
||||||
# ![](https://avatars1.githubusercontent.com/u/8237355?v=2&s=50) Grav
|
|
||||||
|
|
||||||
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad/mini.png)](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/getgrav/grav?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
||||||
|
|
||||||
Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself.
|
|
||||||
|
|
||||||
The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies to ensure that Grav is simple to use and easy to extend. Some of these key technologies include:
|
|
||||||
|
|
||||||
* [Twig Templating](http://twig.sensiolabs.org/): for powerful control of the user interface
|
|
||||||
* [Markdown](http://en.wikipedia.org/wiki/Markdown): for easy content creation
|
|
||||||
* [YAML](http://yaml.org): for simple configuration
|
|
||||||
* [Parsedown](http://parsedown.org/): for fast Markdown and Markdown Extra support
|
|
||||||
* [Doctrine Cache](http://docs.doctrine-project.org/en/2.0.x/reference/caching.html): layer for performance
|
|
||||||
* [Pimple Dependency Injection Container](http://pimple.sensiolabs.org/): for extensibility and maintainability
|
|
||||||
* [Symfony Event Dispatcher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
|
|
||||||
* [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html): for CLI interface
|
|
||||||
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation
|
|
||||||
|
|
||||||
# Requirements
|
|
||||||
|
|
||||||
- PHP 5.4 or higher. Check the [required modules list](http://learn.getgrav.org/basics/requirements#php-requirements)
|
|
||||||
- Check the [Apache](http://learn.getgrav.org/basics/requirements#apache-requirements) or [IIS](http://learn.getgrav.org/basics/requirements#iis-requirements) requirements
|
|
||||||
|
|
||||||
# QuickStart
|
|
||||||
|
|
||||||
You have two options to get Grav:
|
|
||||||
|
|
||||||
### Downloading a Grav Package
|
|
||||||
|
|
||||||
You can download a **ready-built** package from the [Downloads page on http://getgrav.org](http://getgrav.org/downloads)
|
|
||||||
|
|
||||||
### From GitHub
|
|
||||||
|
|
||||||
1. Clone the Grav repository from [https://github.com/getgrav/grav]() to a folder in the webroot of your server, e.g. `~/webroot/grav`. Launch a **terminal** or **console** and navigate to the webroot folder:
|
|
||||||
```
|
|
||||||
$ cd ~/webroot
|
|
||||||
$ git clone https://github.com/getgrav/grav.git
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Install the **plugin** and **theme dependencies** by using the [Grav CLI application](http://learn.getgrav.org/advanced/grav-cli) `bin/grav`:
|
|
||||||
```
|
|
||||||
$ cd ~/webroot/grav
|
|
||||||
$ bin/grav install
|
|
||||||
```
|
|
||||||
|
|
||||||
Check out the [install procedures](http://learn.getgrav.org/basics/installation) for more information.
|
|
||||||
|
|
||||||
# Adding Functionality
|
|
||||||
|
|
||||||
You can download [plugins](http://getgrav.org/downloads/plugins) or [themes](http://getgrav.org/downloads/themes) manually from the appropriate tab on the [Downloads page on http://getgrav.org](http://getgrav.org/downloads), but the preferred solution is to use the [Grav Package Manager](http://learn.getgrav.org/advanced/grav-gpm) or `GPM`:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ bin/gpm index
|
|
||||||
```
|
|
||||||
|
|
||||||
This will display all the available plugins and then you can install one or more with:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ bin/gpm install <plugin/theme>
|
|
||||||
```
|
|
||||||
|
|
||||||
# Updating
|
|
||||||
|
|
||||||
To update Grav you should use the [Grav Package Manager](http://learn.getgrav.org/advanced/grav-gpm) or `GPM`:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ bin/gpm selfupgrade
|
|
||||||
```
|
|
||||||
|
|
||||||
To update plugins and themes:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ bin/gpm update
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
# Contributing
|
|
||||||
We appreciate any contribution to Grav, whether it is related to bugs, grammar, or simply a suggestion or improvement.
|
|
||||||
However, we ask that any contributions follow our simple guidelines in order to be properly received.
|
|
||||||
|
|
||||||
All our projects follow the [GitFlow branching model][gitflow-model], from development to release. If you are not familiar with it, there are several guides and tutorials to make you understand what it is about.
|
|
||||||
|
|
||||||
You will probably want to get started by installing [this very good collection of git extensions][gitflow-extensions].
|
|
||||||
|
|
||||||
What you mainly want to know is that:
|
|
||||||
|
|
||||||
- All the main activity happens in the `develop` branch. Any pull request should be addressed only to that branch. We will not consider pull requests made to the `master`.
|
|
||||||
- It's very well appreciated, and highly suggested, to start a new feature whenever you want to make changes or add functionalities. It will make it much easier for us to just checkout your feature branch and test it, before merging it into `develop`
|
|
||||||
|
|
||||||
# Getting Started
|
|
||||||
|
|
||||||
* [What is Grav?](http://learn.getgrav.org/basics/what-is-grav)
|
|
||||||
* [Install](http://learn.getgrav.org/basics/installation) Grav in few seconds
|
|
||||||
* Understand the [Configuration](http://learn.getgrav.org/basics/grav-configuration)
|
|
||||||
* Take a peek at our available free [Skeletons](http://getgrav.org/downloads/skeletons#extras)
|
|
||||||
* If you have questions, check out `#grav` on irc.freenode.net
|
|
||||||
* Have fun!
|
|
||||||
|
|
||||||
# Exploring more
|
|
||||||
|
|
||||||
* Have a look at our [Basic Tutorial](http://learn.getgrav.org/basics/basic-tutorial)
|
|
||||||
* Dive into more [advanced](http://learn.getgrav.org/advanced) functions
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
See [LICENSE](LICENSE)
|
|
||||||
|
|
||||||
|
|
||||||
[gitflow-model]: http://nvie.com/posts/a-successful-git-branching-model/
|
|
||||||
[gitflow-extensions]: https://github.com/nvie/gitflow
|
|
56
src/bin/gpm
|
@ -1,56 +0,0 @@
|
||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
define('GRAV_CLI', true);
|
|
||||||
|
|
||||||
if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) {
|
|
||||||
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file_exists(__DIR__ . '/../vendor')){
|
|
||||||
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
use Grav\Common\Composer;
|
|
||||||
|
|
||||||
if (!file_exists(__DIR__ . '/../vendor')){
|
|
||||||
// Before we can even start, we need to run composer first
|
|
||||||
$composer = Composer::getComposerExecutor();
|
|
||||||
echo "Preparing to install vendor dependencies...\n\n";
|
|
||||||
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
|
|
||||||
echo "\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
use Symfony\Component\Console\Application;
|
|
||||||
use Grav\Common\Grav;
|
|
||||||
|
|
||||||
$autoload = require_once(__DIR__ . '/../vendor/autoload.php');
|
|
||||||
|
|
||||||
if (!ini_get('date.timezone')) {
|
|
||||||
date_default_timezone_set('UTC');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file_exists(ROOT_DIR . 'index.php')) {
|
|
||||||
exit('FATAL: Must be run from ROOT directory of Grav!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!function_exists('curl_version')) {
|
|
||||||
exit('FATAL: GPM requires PHP Curl module to be installed');
|
|
||||||
}
|
|
||||||
|
|
||||||
$grav = Grav::instance(array('loader' => $autoload));
|
|
||||||
$grav['config']->init();
|
|
||||||
$grav['streams'];
|
|
||||||
$grav['plugins']->init();
|
|
||||||
$grav['themes']->init();
|
|
||||||
|
|
||||||
$app = new Application('Grav Package Manager', GRAV_VERSION);
|
|
||||||
$app->addCommands(array(
|
|
||||||
new \Grav\Console\Gpm\IndexCommand(),
|
|
||||||
new \Grav\Console\Gpm\VersionCommand(),
|
|
||||||
new \Grav\Console\Gpm\InfoCommand(),
|
|
||||||
new \Grav\Console\Gpm\InstallCommand(),
|
|
||||||
new \Grav\Console\Gpm\UninstallCommand(),
|
|
||||||
new \Grav\Console\Gpm\UpdateCommand(),
|
|
||||||
new \Grav\Console\Gpm\SelfupgradeCommand(),
|
|
||||||
));
|
|
||||||
$app->run();
|
|
46
src/bin/grav
|
@ -1,46 +0,0 @@
|
||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
define('GRAV_CLI', true);
|
|
||||||
|
|
||||||
if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) {
|
|
||||||
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file_exists(__DIR__ . '/../vendor')){
|
|
||||||
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
use Grav\Common\Composer;
|
|
||||||
|
|
||||||
if (!file_exists(__DIR__ . '/../vendor')){
|
|
||||||
// Before we can even start, we need to run composer first
|
|
||||||
$composer = Composer::getComposerExecutor();
|
|
||||||
echo "Preparing to install vendor dependencies...\n\n";
|
|
||||||
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
|
|
||||||
echo "\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
use Symfony\Component\Console\Application;
|
|
||||||
|
|
||||||
require_once __DIR__ . '/../vendor/autoload.php';
|
|
||||||
|
|
||||||
if (!ini_get('date.timezone')) {
|
|
||||||
date_default_timezone_set('UTC');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file_exists(ROOT_DIR . 'index.php')) {
|
|
||||||
exit('FATAL: Must be run from ROOT directory of Grav!');
|
|
||||||
}
|
|
||||||
|
|
||||||
$app = new Application('Grav CLI Application', '0.1.0');
|
|
||||||
$app->addCommands(array(
|
|
||||||
new Grav\Console\Cli\InstallCommand(),
|
|
||||||
new Grav\Console\Cli\ComposerCommand(),
|
|
||||||
new Grav\Console\Cli\SandboxCommand(),
|
|
||||||
new Grav\Console\Cli\CleanCommand(),
|
|
||||||
new Grav\Console\Cli\ClearCacheCommand(),
|
|
||||||
new Grav\Console\Cli\BackupCommand(),
|
|
||||||
new Grav\Console\Cli\NewProjectCommand(),
|
|
||||||
new Grav\Console\Cli\NewUserCommand(),
|
|
||||||
));
|
|
||||||
$app->run();
|
|
0
src/cache/.gitkeep
vendored
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
"name": "getgrav/grav",
|
|
||||||
"type": "library",
|
|
||||||
"description": "Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS",
|
|
||||||
"keywords": ["cms","flat-file cms","flat cms","flatfile cms","php"],
|
|
||||||
"homepage": "http://getgrav.org",
|
|
||||||
"license": "MIT",
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.4.0",
|
|
||||||
"twig/twig": "~1.16",
|
|
||||||
"erusev/parsedown-extra": "~0.7",
|
|
||||||
"symfony/yaml": "~2.7",
|
|
||||||
"symfony/console": "~2.7",
|
|
||||||
"symfony/event-dispatcher": "~2.7",
|
|
||||||
"symfony/var-dumper": "~2.7",
|
|
||||||
"doctrine/cache": "~1.4",
|
|
||||||
"filp/whoops": "1.2.*@dev",
|
|
||||||
"monolog/monolog": "~1.0",
|
|
||||||
"gregwar/image": "~2.0",
|
|
||||||
"ircmaxell/password-compat": "1.0.*",
|
|
||||||
"mrclay/minify": "~2.2",
|
|
||||||
"donatj/phpuseragentparser": "~0.3",
|
|
||||||
"pimple/pimple": "~3.0",
|
|
||||||
"rockettheme/toolbox": "1.1.*",
|
|
||||||
"maximebf/debugbar": "~1.10"
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Grav\\": "system/src/Grav"
|
|
||||||
},
|
|
||||||
"files": ["system/defines.php"]
|
|
||||||
},
|
|
||||||
"archive": {
|
|
||||||
"exclude": ["VERSION"]
|
|
||||||
}
|
|
||||||
}
|
|
1012
src/composer.lock
generated
|
@ -1,63 +0,0 @@
|
||||||
<IfModule mod_rewrite.c>
|
|
||||||
|
|
||||||
RewriteEngine On
|
|
||||||
|
|
||||||
## Begin RewriteBase
|
|
||||||
# If you are getting 404 errors on subpages, you may have to uncomment the RewriteBase entry
|
|
||||||
# You should change the '/' to your appropriate subfolder. For example if you have
|
|
||||||
# your Grav install at the root of your site '/' should work, else it might be something
|
|
||||||
# along the lines of: RewriteBase /<your_sub_folder>
|
|
||||||
##
|
|
||||||
|
|
||||||
# RewriteBase /
|
|
||||||
|
|
||||||
## End - RewriteBase
|
|
||||||
|
|
||||||
## Begin - Exploits
|
|
||||||
# If you experience problems on your site block out the operations listed below
|
|
||||||
# This attempts to block the most common type of exploit `attempts` to Grav
|
|
||||||
#
|
|
||||||
# Block out any script trying to base64_encode data within the URL.
|
|
||||||
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
|
|
||||||
# Block out any script that includes a <script> tag in URL.
|
|
||||||
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
|
|
||||||
# Block out any script trying to set a PHP GLOBALS variable via URL.
|
|
||||||
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
|
|
||||||
# Block out any script trying to modify a _REQUEST variable via URL.
|
|
||||||
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
|
|
||||||
# Return 403 Forbidden header and show the content of the root homepage
|
|
||||||
RewriteRule .* index.php [F]
|
|
||||||
#
|
|
||||||
## End - Exploits
|
|
||||||
|
|
||||||
## Begin - Index
|
|
||||||
# If the requested path and file is not /index.php and the request
|
|
||||||
# has not already been internally rewritten to the index.php script
|
|
||||||
RewriteCond %{REQUEST_URI} !^/index\.php
|
|
||||||
# and the requested path and file doesn't directly match a physical file
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
|
||||||
# and the requested path and file doesn't directly match a physical folder
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-d
|
|
||||||
# internally rewrite the request to the index.php script
|
|
||||||
RewriteRule .* index.php [L]
|
|
||||||
## End - Index
|
|
||||||
|
|
||||||
## Begin - Security
|
|
||||||
# Block all direct access for these folders
|
|
||||||
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [L]
|
|
||||||
# Block access to specific file types for these folders
|
|
||||||
RewriteRule ^(system|user|vendor)/(.*)\.(txt|md|html|yaml|php|twig|sh|bat)$ error [L]
|
|
||||||
# Block all direct access to .md files:
|
|
||||||
RewriteRule \.md$ error [L]
|
|
||||||
# Block all direct access to files and folders beginning with a dot
|
|
||||||
RewriteRule (^\.|/\.) - [F]
|
|
||||||
# Block access to specific files in the root folder
|
|
||||||
RewriteRule ^(LICENSE|composer.lock|composer.json|nginx.conf|web.config)$ error [F]
|
|
||||||
## End - Security
|
|
||||||
|
|
||||||
</IfModule>
|
|
||||||
|
|
||||||
# Begin - Prevent Browsing and Set Default Resources
|
|
||||||
Options -Indexes
|
|
||||||
DirectoryIndex index.php index.html index.htm
|
|
||||||
# End - Prevent Browsing and Set Default Resources
|
|
|
@ -1,42 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav;
|
|
||||||
|
|
||||||
if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) {
|
|
||||||
throw new \RuntimeException(sprintf('You are running PHP %s, but Grav needs at least <strong>PHP %s</strong> to run.', $ver, $req));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure vendor libraries exist
|
|
||||||
$autoload = __DIR__ . '/vendor/autoload.php';
|
|
||||||
if (!is_file($autoload)) {
|
|
||||||
throw new \RuntimeException("Please run: <i>bin/grav install</i>");
|
|
||||||
}
|
|
||||||
|
|
||||||
use Grav\Common\Grav;
|
|
||||||
|
|
||||||
// Register the auto-loader.
|
|
||||||
$loader = require_once $autoload;
|
|
||||||
|
|
||||||
// Set timezone to default, falls back to system if php.ini not set
|
|
||||||
date_default_timezone_set(@date_default_timezone_get());
|
|
||||||
|
|
||||||
// Set internal encoding if mbstring loaded
|
|
||||||
if (!extension_loaded('mbstring')) {
|
|
||||||
throw new \RuntimeException("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
|
||||||
}
|
|
||||||
mb_internal_encoding('UTF-8');
|
|
||||||
|
|
||||||
// Get the Grav instance
|
|
||||||
$grav = Grav::instance(
|
|
||||||
array(
|
|
||||||
'loader' => $loader
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Process the page
|
|
||||||
try {
|
|
||||||
$grav->process();
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
$grav->fireEvent('onFatalException');
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
worker_processes 1;
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
include mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
sendfile on;
|
|
||||||
keepalive_timeout 65;
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name localhost;
|
|
||||||
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
|
||||||
location = /50x.html {
|
|
||||||
root html;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
root html;
|
|
||||||
index index.php;
|
|
||||||
if (!-e $request_filename){ rewrite ^(.*)$ /index.php last; }
|
|
||||||
}
|
|
||||||
|
|
||||||
# if you want grav in a sub-directory of your main site
|
|
||||||
# (for example, example.com/mygrav) then you need this rewrite:
|
|
||||||
location /mygrav {
|
|
||||||
index index.php;
|
|
||||||
if (!-e $request_filename){ rewrite ^(.*)$ /mygrav/$2 last; }
|
|
||||||
try_files $uri $uri/ /index.php?$args;
|
|
||||||
}
|
|
||||||
|
|
||||||
# if using grav in a sub-directory of your site,
|
|
||||||
# prepend the actual path to each location
|
|
||||||
# for example: /mygrav/images
|
|
||||||
# and: /mygrav/user
|
|
||||||
# and: /mygrav/cache
|
|
||||||
# and so on
|
|
||||||
|
|
||||||
location /images/ {
|
|
||||||
# Serve images as static
|
|
||||||
}
|
|
||||||
|
|
||||||
location /user {
|
|
||||||
rewrite ^/user/accounts/(.*)$ /error redirect;
|
|
||||||
rewrite ^/user/config/(.*)$ /error redirect;
|
|
||||||
rewrite ^/user/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /cache {
|
|
||||||
rewrite ^/cache/(.*) /error redirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /bin {
|
|
||||||
rewrite ^/bin/(.*)$ /error redirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /backup {
|
|
||||||
rewrite ^/backup/(.*) /error redirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /system {
|
|
||||||
rewrite ^/system/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /vendor {
|
|
||||||
rewrite ^/vendor/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remember to change 127.0.0.1:9000 to the Ip/port
|
|
||||||
# you configured php-cgi.exe to run from
|
|
||||||
|
|
||||||
location ~ \.php$ {
|
|
||||||
try_files $uri =404;
|
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
|
||||||
fastcgi_pass 127.0.0.1:9000;
|
|
||||||
fastcgi_index index.php;
|
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
||||||
include fastcgi_params;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
User-agent: *
|
|
||||||
Disallow:
|
|
|
@ -1,54 +0,0 @@
|
||||||
div.phpdebugbar {
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar pre {
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar div.phpdebugbar-header > div > * {
|
|
||||||
padding: 5px 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar div.phpdebugbar-header > div.phpdebugbar-header-right > * {
|
|
||||||
padding: 5px 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar div.phpdebugbar-header, .phpdebugbar a.phpdebugbar-restore-btn {
|
|
||||||
background-image: url(grav.png);
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar a.phpdebugbar-restore-btn {
|
|
||||||
width: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar a.phpdebugbar-tab.phpdebugbar-active {
|
|
||||||
background: #3DB9EC;
|
|
||||||
color: #fff;
|
|
||||||
margin-top: -1px;
|
|
||||||
padding-top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar .phpdebugbar-widgets-toolbar {
|
|
||||||
padding-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar input[type=text] {
|
|
||||||
padding: 0;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar dl.phpdebugbar-widgets-varlist, ul.phpdebugbar-widgets-timeline li span.phpdebugbar-widgets-label {
|
|
||||||
font-family: "DejaVu Sans Mono", Menlo, Monaco, Consolas, Courier, monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.phpdebugbar-widgets-timeline li span.phpdebugbar-widgets-label {
|
|
||||||
text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phpdebugbar pre, .phpdebugbar code {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
Before Width: | Height: | Size: 548 B |
4
src/system/assets/jquery/jquery-2.1.4.min.js
vendored
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 5.1 KiB |
|
@ -1,110 +0,0 @@
|
||||||
body {
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
body header {
|
|
||||||
background: #349886;
|
|
||||||
border-left: 8px solid #29796B;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .clipboard {
|
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcAQMAAABIw03XAAAAA3NCSVQICAjb4U/gAAAABlBMVEX///////9VfPVsAAAAAnRSTlP/AOW3MEoAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzbovLKMAAAAFnRFWHRDcmVhdGlvbiBUaW1lADEwLzE1LzE0xr/LJAAAADhJREFUCJlj+P///wcGBPGDQR5E8OMi2IEEczOIaAQRHSCioQBGHAAR/7AT/z+DiA8MMALVXhABAJf9Sr5aY+UFAAAAAElFTkSuQmCC);
|
|
||||||
}
|
|
||||||
|
|
||||||
body .exc-title-primary {
|
|
||||||
color: #1C3631;
|
|
||||||
text-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .exc-title {
|
|
||||||
color: #2F5B52;
|
|
||||||
text-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .data-table-container label {
|
|
||||||
color: #0082BA;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frames-container {
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .active .frame-class {
|
|
||||||
color: #E3D8E9;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame-class {
|
|
||||||
color: #9055AF;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame.active {
|
|
||||||
border: 0;
|
|
||||||
box-shadow: none;
|
|
||||||
background-color: #9055AF;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame:not(.active):hover {
|
|
||||||
background: #e9e9e9;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame-file, body .data-table tbody {
|
|
||||||
font-family: "DejaVu Sans Mono", Menlo, Monaco, Consolas, Courier, monospace;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame-code {
|
|
||||||
background: #305669;
|
|
||||||
border-left: 8px solid #253A47;
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame-code .frame-file {
|
|
||||||
background: #253A47;
|
|
||||||
color: #eee;
|
|
||||||
text-shadow: none;
|
|
||||||
box-shadow: none;
|
|
||||||
font-family: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame-code .frame-file strong {
|
|
||||||
color: #fff;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame-comments {
|
|
||||||
background: #283E4D;
|
|
||||||
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .frame-comments.empty:before {
|
|
||||||
color: #789AAB;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .details-container {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .details {
|
|
||||||
background-color: #eee;
|
|
||||||
border-left: 8px solid #ddd;
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .code-block {
|
|
||||||
background: #2C4454;
|
|
||||||
box-shadow: none;
|
|
||||||
font-family: "DejaVu Sans Mono", Menlo, Monaco, Consolas, Courier, monospace;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .handler.active {
|
|
||||||
background: #666;
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
title: PLUGIN_ADMIN.MEDIA
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
|
@ -1,116 +0,0 @@
|
||||||
title: PLUGIN_ADMIN.SITE
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
|
|
||||||
content:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.DEFAULTS
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
title:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.SITE_TITLE
|
|
||||||
size: large
|
|
||||||
placeholder: PLUGIN_ADMIN.SITE_TITLE_PLACEHOLDER
|
|
||||||
help: PLUGIN_ADMIN.SITE_TITLE_HELP
|
|
||||||
|
|
||||||
author.name:
|
|
||||||
type: text
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.DEFAULT_AUTHOR
|
|
||||||
help: PLUGIN_ADMIN.DEFAULT_AUTHOR_HELP
|
|
||||||
|
|
||||||
author.email:
|
|
||||||
type: text
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.DEFAULT_EMAIL
|
|
||||||
help: PLUGIN_ADMIN.DEFAULT_EMAIL_HELP
|
|
||||||
validate:
|
|
||||||
type: email
|
|
||||||
|
|
||||||
taxonomies:
|
|
||||||
type: selectize
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.TAXONOMY_TYPES
|
|
||||||
classes: fancy
|
|
||||||
help: PLUGIN_ADMIN.TAXONOMY_TYPES_HELP
|
|
||||||
validate:
|
|
||||||
type: commalist
|
|
||||||
|
|
||||||
summary:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.PAGE_SUMMARY
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
summary.enabled:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.ENABLED
|
|
||||||
highlight: 1
|
|
||||||
help: PLUGIN_ADMIN.ENABLED_HELP
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
summary.size:
|
|
||||||
type: text
|
|
||||||
size: x-small
|
|
||||||
label: PLUGIN_ADMIN.SUMMARY_SIZE
|
|
||||||
help: PLUGIN_ADMIN.SUMMARY_SIZE_HELP
|
|
||||||
validate:
|
|
||||||
type: int
|
|
||||||
min: 0
|
|
||||||
max: 65536
|
|
||||||
|
|
||||||
summary.format:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.FORMAT
|
|
||||||
classes: fancy
|
|
||||||
help: PLUGIN_ADMIN.FORMAT_HELP
|
|
||||||
highlight: short
|
|
||||||
options:
|
|
||||||
'short': PLUGIN_ADMIN.SHORT
|
|
||||||
'long': PLUGIN_ADMIN.LONG
|
|
||||||
|
|
||||||
summary.delimiter:
|
|
||||||
type: text
|
|
||||||
size: x-small
|
|
||||||
label: PLUGIN_ADMIN.DELIMITER
|
|
||||||
help: PLUGIN_ADMIN.DELIMITER_HELP
|
|
||||||
|
|
||||||
metadata:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.METADATA
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
metadata:
|
|
||||||
type: array
|
|
||||||
label: PLUGIN_ADMIN.METADATA
|
|
||||||
help: PLUGIN_ADMIN.METADATA_HELP
|
|
||||||
placeholder_key: PLUGIN_ADMIN.METADATA_KEY
|
|
||||||
placeholder_value: PLUGIN_ADMIN.METADATA_VALUE
|
|
||||||
|
|
||||||
routes:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.REDIRECTS_AND_ROUTES
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
redirects:
|
|
||||||
type: array
|
|
||||||
label: PLUGIN_ADMIN.CUSTOM_REDIRECTS
|
|
||||||
help: PLUGIN_ADMIN.CUSTOM_REDIRECTS_HELP
|
|
||||||
placeholder_key: PLUGIN_ADMIN.CUSTOM_REDIRECTS_PLACEHOLDER_KEY
|
|
||||||
placeholder_value: PLUGIN_ADMIN.CUSTOM_REDIRECTS_PLACEHOLDER_VALUE
|
|
||||||
|
|
||||||
routes:
|
|
||||||
type: array
|
|
||||||
label: PLUGIN_ADMIN.CUSTOM_ROUTES
|
|
||||||
help: PLUGIN_ADMIN.CUSTOM_ROUTES_HELP
|
|
||||||
placeholder_key: PLUGIN_ADMIN.CUSTOM_ROUTES_PLACEHOLDER_KEY
|
|
||||||
placeholder_value: PLUGIN_ADMIN.CUSTOM_ROUTES_PLACEHOLDER_VALUE
|
|
|
@ -1,7 +0,0 @@
|
||||||
title: PLUGIN_ADMIN.FILE_STREAMS
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
schemes.xxx:
|
|
||||||
type: array
|
|
|
@ -1,793 +0,0 @@
|
||||||
title: PLUGIN_ADMIN.SYSTEM
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
|
|
||||||
content:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.CONTENT
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
home.alias:
|
|
||||||
type: pages
|
|
||||||
size: medium
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.HOME_PAGE
|
|
||||||
show_all: false
|
|
||||||
show_modular: false
|
|
||||||
show_root: false
|
|
||||||
help: PLUGIN_ADMIN.HOME_PAGE_HELP
|
|
||||||
|
|
||||||
pages.theme:
|
|
||||||
type: themeselect
|
|
||||||
classes: fancy
|
|
||||||
selectize: true
|
|
||||||
size: medium
|
|
||||||
label: PLUGIN_ADMIN.DEFAULT_THEME
|
|
||||||
help: PLUGIN_ADMIN.DEFAULT_THEME_HELP
|
|
||||||
|
|
||||||
pages.process:
|
|
||||||
type: checkboxes
|
|
||||||
label: PLUGIN_ADMIN.PROCESS
|
|
||||||
help: PLUGIN_ADMIN.PROCESS_HELP
|
|
||||||
default: [markdown: true, twig: true]
|
|
||||||
options:
|
|
||||||
markdown: Markdown
|
|
||||||
twig: Twig
|
|
||||||
use: keys
|
|
||||||
|
|
||||||
timezone:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.TIMEZONE
|
|
||||||
size: medium
|
|
||||||
classes: fancy
|
|
||||||
help: PLUGIN_ADMIN.TIMEZONE_HELP
|
|
||||||
'@data-options': '\Grav\Common\Utils::timezones'
|
|
||||||
default: ''
|
|
||||||
options:
|
|
||||||
'': 'Default (Server Timezone)'
|
|
||||||
|
|
||||||
pages.dateformat.default:
|
|
||||||
type: select
|
|
||||||
size: medium
|
|
||||||
selectize:
|
|
||||||
create: true
|
|
||||||
label: PLUGIN_ADMIN.DEFAULT_DATE_FORMAT
|
|
||||||
help: PLUGIN_ADMIN.DEFAULT_DATE_FORMAT_HELP
|
|
||||||
placeholder: PLUGIN_ADMIN.DEFAULT_DATE_FORMAT_PLACEHOLDER
|
|
||||||
'@data-options': '\Grav\Common\Utils::dateFormats'
|
|
||||||
options:
|
|
||||||
"": Auto Guess or Enter Custom
|
|
||||||
validate:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
pages.dateformat.short:
|
|
||||||
type: dateformat
|
|
||||||
size: medium
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.SHORT_DATE_FORMAT
|
|
||||||
help: PLUGIN_ADMIN.SHORT_DATE_FORMAT_HELP
|
|
||||||
default: "jS M Y"
|
|
||||||
options:
|
|
||||||
"F jS \\a\\t g:ia": Date1
|
|
||||||
"l jS \\of F g:i A": Date2
|
|
||||||
"D, m M Y G:i:s": Date3
|
|
||||||
"d-m-y G:i": Date4
|
|
||||||
"jS M Y": Date5
|
|
||||||
|
|
||||||
pages.dateformat.long:
|
|
||||||
type: dateformat
|
|
||||||
size: medium
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.LONG_DATE_FORMAT
|
|
||||||
help: PLUGIN_ADMIN.LONG_DATE_FORMAT_HELP
|
|
||||||
options:
|
|
||||||
"F jS \\a\\t g:ia": Date1
|
|
||||||
"l jS \\of F g:i A": Date2
|
|
||||||
"D, m M Y G:i:s": Date3
|
|
||||||
"d-m-y G:i": Date4
|
|
||||||
"jS M Y": Date5
|
|
||||||
|
|
||||||
pages.order.by:
|
|
||||||
type: select
|
|
||||||
size: long
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.DEFAULT_ORDERING
|
|
||||||
help: PLUGIN_ADMIN.DEFAULT_ORDERING_HELP
|
|
||||||
options:
|
|
||||||
default: PLUGIN_ADMIN.DEFAULT_ORDERING_DEFAULT
|
|
||||||
folder: PLUGIN_ADMIN.DEFAULT_ORDERING_FOLDER
|
|
||||||
title: PLUGIN_ADMIN.DEFAULT_ORDERING_TITLE
|
|
||||||
date: PLUGIN_ADMIN.DEFAULT_ORDERING_DATE
|
|
||||||
|
|
||||||
pages.order.dir:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.DEFAULT_ORDER_DIRECTION
|
|
||||||
highlight: asc
|
|
||||||
default: desc
|
|
||||||
help: PLUGIN_ADMIN.DEFAULT_ORDER_DIRECTION_HELP
|
|
||||||
options:
|
|
||||||
asc: PLUGIN_ADMIN.ASCENDING
|
|
||||||
desc: PLUGIN_ADMIN.DESCENDING
|
|
||||||
|
|
||||||
pages.list.count:
|
|
||||||
type: text
|
|
||||||
size: x-small
|
|
||||||
label: PLUGIN_ADMIN.DEFAULT_PAGE_COUNT
|
|
||||||
help: PLUGIN_ADMIN.DEFAULT_PAGE_COUNT_HELP
|
|
||||||
validate:
|
|
||||||
type: number
|
|
||||||
min: 1
|
|
||||||
|
|
||||||
pages.publish_dates:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.DATE_BASED_PUBLISHING
|
|
||||||
help: PLUGIN_ADMIN.DATE_BASED_PUBLISHING_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
pages.events:
|
|
||||||
type: checkboxes
|
|
||||||
label: PLUGIN_ADMIN.EVENTS
|
|
||||||
help: PLUGIN_ADMIN.EVENTS_HELP
|
|
||||||
default: [page: true, twig: true]
|
|
||||||
options:
|
|
||||||
page: Page Events
|
|
||||||
twig: Twig Events
|
|
||||||
use: keys
|
|
||||||
|
|
||||||
pages.redirect_default_route:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.REDIRECT_DEFAULT_ROUTE
|
|
||||||
help: PLUGIN_ADMIN.REDIRECT_DEFAULT_ROUTE_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
pages.redirect_default_code:
|
|
||||||
type: select
|
|
||||||
size: medium
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.REDIRECT_DEFAULT_CODE
|
|
||||||
help: PLUGIN_ADMIN.REDIRECT_DEFAULT_CODE_HELP
|
|
||||||
options:
|
|
||||||
301: 301 - Permanent
|
|
||||||
303: 303 - Other
|
|
||||||
307: 307 - Temporary
|
|
||||||
|
|
||||||
pages.redirect_trailing_slash:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.REDIRECT_TRAILING_SLASH
|
|
||||||
help: PLUGIN_ADMIN.REDIRECT_TRAILING_SLASH_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
pages.ignore_hidden:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.IGNORE_HIDDEN
|
|
||||||
help: PLUGIN_ADMIN.IGNORE_HIDDEN_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
pages.ignore_files:
|
|
||||||
type: selectize
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.IGNORE_FILES
|
|
||||||
help: PLUGIN_ADMIN.IGNORE_FILES_HELP
|
|
||||||
classes: fancy
|
|
||||||
validate:
|
|
||||||
type: commalist
|
|
||||||
|
|
||||||
pages.ignore_folders:
|
|
||||||
type: selectize
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.IGNORE_FOLDERS
|
|
||||||
help: PLUGIN_ADMIN.IGNORE_FOLDERS_HELP
|
|
||||||
classes: fancy
|
|
||||||
validate:
|
|
||||||
type: commalist
|
|
||||||
|
|
||||||
pages.url_taxonomy_filters:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.ALLOW_URL_TAXONOMY_FILTERS
|
|
||||||
help: PLUGIN_ADMIN.ALLOW_URL_TAXONOMY_FILTERS_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
pages.fallback_types:
|
|
||||||
type: selectize
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.FALLBACK_TYPES
|
|
||||||
help: PLUGIN_ADMIN.FALLBACK_TYPES_HELP
|
|
||||||
classes: fancy
|
|
||||||
validate:
|
|
||||||
type: commalist
|
|
||||||
|
|
||||||
languages:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.LANGUAGES
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
|
|
||||||
languages.supported:
|
|
||||||
type: selectize
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.SUPPORTED
|
|
||||||
help: PLUGIN_ADMIN.SUPPORTED_HELP
|
|
||||||
classes: fancy
|
|
||||||
validate:
|
|
||||||
type: commalist
|
|
||||||
|
|
||||||
languages.include_default_lang:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.INCLUDE_DEFAULT_LANG
|
|
||||||
help: PLUGIN_ADMIN.INCLUDE_DEFAULT_LANG_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
|
|
||||||
languages.translations:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.TRANSLATIONS_ENABLED
|
|
||||||
help: PLUGIN_ADMIN.TRANSLATIONS_ENABLED_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
languages.translations_fallback:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.TRANSLATIONS_FALLBACK
|
|
||||||
help: PLUGIN_ADMIN.TRANSLATIONS_FALLBACK_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
languages.session_store_active:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.ACTIVE_LANGUAGE_IN_SESSION
|
|
||||||
help: PLUGIN_ADMIN.ACTIVE_LANGUAGE_IN_SESSION_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
languages.http_accept_language:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.HTTP_ACCEPT_LANGUAGE
|
|
||||||
help: PLUGIN_ADMIN.HTTP_ACCEPT_LANGUAGE_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
languages.override_locale:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.OVERRIDE_LOCALE
|
|
||||||
help: PLUGIN_ADMIN.OVERRIDE_LOCALE_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
http_headers:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.HTTP_HEADERS
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
pages.expires:
|
|
||||||
type: text
|
|
||||||
size: small
|
|
||||||
label: PLUGIN_ADMIN.EXPIRES
|
|
||||||
help: PLUGIN_ADMIN.EXPIRES_HELP
|
|
||||||
validate:
|
|
||||||
type: number
|
|
||||||
min: 1
|
|
||||||
pages.last_modified:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.LAST_MODIFIED
|
|
||||||
help: PLUGIN_ADMIN.LAST_MODIFIED_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
pages.etag:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.ETAG
|
|
||||||
help: PLUGIN_ADMIN.ETAG_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
pages.vary_accept_encoding:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.VARY_ACCEPT_ENCODING
|
|
||||||
help: PLUGIN_ADMIN.VARY_ACCEPT_ENCODING_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
markdown:
|
|
||||||
type: section
|
|
||||||
title: Markdown
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
pages.markdown.extra:
|
|
||||||
type: toggle
|
|
||||||
label: Markdown extra
|
|
||||||
help: PLUGIN_ADMIN.MARKDOWN_EXTRA_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
pages.markdown.auto_line_breaks:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.AUTO_LINE_BREAKS
|
|
||||||
help: PLUGIN_ADMIN.AUTO_LINE_BREAKS_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
pages.markdown.auto_url_links:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.AUTO_URL_LINKS
|
|
||||||
help: PLUGIN_ADMIN.AUTO_URL_LINKS_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
pages.markdown.escape_markup:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.ESCAPE_MARKUP
|
|
||||||
help: PLUGIN_ADMIN.ESCAPE_MARKUP_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
caching:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.CACHING
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
cache.enabled:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.CACHING
|
|
||||||
help: PLUGIN_ADMIN.CACHING_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
cache.check.method:
|
|
||||||
type: select
|
|
||||||
size: small
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.CACHE_CHECK_METHOD
|
|
||||||
help: PLUGIN_ADMIN.CACHE_CHECK_METHOD_HELP
|
|
||||||
options:
|
|
||||||
file: File
|
|
||||||
folder: Folder
|
|
||||||
none: None
|
|
||||||
|
|
||||||
cache.driver:
|
|
||||||
type: select
|
|
||||||
size: small
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.CACHE_DRIVER
|
|
||||||
help: PLUGIN_ADMIN.CACHE_DRIVER_HELP
|
|
||||||
options:
|
|
||||||
auto: Auto detect
|
|
||||||
file: File
|
|
||||||
apc: APC
|
|
||||||
xcache: XCache
|
|
||||||
memcache: MemCache
|
|
||||||
wincache: WinCache
|
|
||||||
|
|
||||||
cache.prefix:
|
|
||||||
type: text
|
|
||||||
size: x-small
|
|
||||||
label: PLUGIN_ADMIN.CACHE_PREFIX
|
|
||||||
help: PLUGIN_ADMIN.CACHE_PREFIX_HELP
|
|
||||||
placeholder: PLUGIN_ADMIN.CACHE_PREFIX_PLACEHOLDER
|
|
||||||
|
|
||||||
cache.lifetime:
|
|
||||||
type: text
|
|
||||||
size: small
|
|
||||||
label: PLUGIN_ADMIN.LIFETIME
|
|
||||||
help: PLUGIN_ADMIN.LIFETIME_HELP
|
|
||||||
validate:
|
|
||||||
type: number
|
|
||||||
|
|
||||||
cache.gzip:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.GZIP_COMPRESSION
|
|
||||||
help: PLUGIN_ADMIN.GZIP_COMPRESSION_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
|
|
||||||
twig:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.TWIG_TEMPLATING
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
twig.cache:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.TWIG_CACHING
|
|
||||||
help: PLUGIN_ADMIN.TWIG_CACHING_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
twig.debug:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.TWIG_DEBUG
|
|
||||||
help: PLUGIN_ADMIN.TWIG_DEBUG_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
twig.auto_reload:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.DETECT_CHANGES
|
|
||||||
help: PLUGIN_ADMIN.DETECT_CHANGES_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
twig.autoescape:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.AUTOESCAPE_VARIABLES
|
|
||||||
help: PLUGIN_ADMIN.AUTOESCAPE_VARIABLES_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
assets:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.ASSETS
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
assets.css_pipeline:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.CSS_PIPELINE
|
|
||||||
help: PLUGIN_ADMIN.CSS_PIPELINE_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
assets.css_minify:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.CSS_MINIFY
|
|
||||||
help: PLUGIN_ADMIN.CSS_MINIFY_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
assets.css_minify_windows:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.CSS_MINIFY_WINDOWS_OVERRIDE
|
|
||||||
help: PLUGIN_ADMIN.CSS_MINIFY_WINDOWS_OVERRIDE_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
assets.css_rewrite:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.CSS_REWRITE
|
|
||||||
help: PLUGIN_ADMIN.CSS_REWRITE_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
assets.js_pipeline:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.JAVASCRIPT_PIPELINE
|
|
||||||
help: PLUGIN_ADMIN.JAVASCRIPT_PIPELINE_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
assets.js_minify:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.JAVASCRIPT_MINIFY
|
|
||||||
help: PLUGIN_ADMIN.JAVASCRIPT_MINIFY_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
assets.enable_asset_timestamp:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.ENABLED_TIMESTAMPS_ON_ASSETS
|
|
||||||
help: PLUGIN_ADMIN.ENABLED_TIMESTAMPS_ON_ASSETS_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
assets.collections:
|
|
||||||
type: array
|
|
||||||
label: PLUGIN_ADMIN.COLLECTIONS
|
|
||||||
placeholder_key: collection_name
|
|
||||||
placeholder_value: collection_path
|
|
||||||
|
|
||||||
errors:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.ERROR_HANDLER
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
errors.display:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.DISPLAY_ERRORS
|
|
||||||
help: PLUGIN_ADMIN.DISPLAY_ERRORS_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
errors.log:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.LOG_ERRORS
|
|
||||||
help: PLUGIN_ADMIN.LOG_ERRORS_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
debugger:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.DEBUGGER
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
debugger.enabled:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.DEBUGGER
|
|
||||||
help: PLUGIN_ADMIN.DEBUGGER_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
debugger.shutdown.close_connection:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.SHUTDOWN_CLOSE_CONNECTION
|
|
||||||
help: PLUGIN_ADMIN.SHUTDOWN_CLOSE_CONNECTION_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
media:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.MEDIA
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
images.default_image_quality:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.DEFAULT_IMAGE_QUALITY
|
|
||||||
help: PLUGIN_ADMIN.DEFAULT_IMAGE_QUALITY_HELP
|
|
||||||
classes: x-small
|
|
||||||
validate:
|
|
||||||
type: number
|
|
||||||
min: 1
|
|
||||||
max: 100
|
|
||||||
|
|
||||||
images.cache_all:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.CACHE_ALL
|
|
||||||
help: PLUGIN_ADMIN.CACHE_ALL_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
images.debug:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.IMAGES_DEBUG
|
|
||||||
help: PLUGIN_ADMIN.IMAGES_DEBUG_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
media.upload_limit:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.UPLOAD_LIMIT
|
|
||||||
help: PLUGIN_ADMIN.UPLOAD_LIMIT_HELP
|
|
||||||
classes: small
|
|
||||||
validate:
|
|
||||||
type: number
|
|
||||||
|
|
||||||
media.enable_media_timestamp:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.ENABLE_MEDIA_TIMESTAMP
|
|
||||||
help: PLUGIN_ADMIN.ENABLE_MEDIA_TIMESTAMP_HELP
|
|
||||||
highlight: 0
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
session:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.SESSION
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
session.enabled:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.ENABLED
|
|
||||||
help: PLUGIN_ADMIN.SESSION_ENABLED_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
session.timeout:
|
|
||||||
type: text
|
|
||||||
size: small
|
|
||||||
label: PLUGIN_ADMIN.TIMEOUT
|
|
||||||
help: PLUGIN_ADMIN.TIMEOUT_HELP
|
|
||||||
validate:
|
|
||||||
type: number
|
|
||||||
min: 1
|
|
||||||
|
|
||||||
session.name:
|
|
||||||
type: text
|
|
||||||
size: small
|
|
||||||
label: PLUGIN_ADMIN.NAME
|
|
||||||
help: PLUGIN_ADMIN.SESSION_NAME_HELP
|
|
||||||
|
|
||||||
|
|
||||||
advanced:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.ADVANCED
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
wrapped_site:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.WRAPPED_SITE
|
|
||||||
highlight: 0
|
|
||||||
help: PLUGIN_ADMIN.WRAPPED_SITE_HELP
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
absolute_urls:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.ABSOLUTE_URLS
|
|
||||||
highlight: 0
|
|
||||||
help: PLUGIN_ADMIN.ABSOLUTE_URLS_HELP
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
param_sep:
|
|
||||||
type: select
|
|
||||||
size: medium
|
|
||||||
label: PLUGIN_ADMIN.PARAMETER_SEPARATOR
|
|
||||||
classes: fancy
|
|
||||||
help: PLUGIN_ADMIN.PARAMETER_SEPARATOR_HELP
|
|
||||||
default: ''
|
|
||||||
options:
|
|
||||||
':': ': (default)'
|
|
||||||
';': '; (for Apache running on Windows)'
|
|
|
@ -1,276 +0,0 @@
|
||||||
title: PLUGIN_ADMIN.DEFAULT
|
|
||||||
|
|
||||||
rules:
|
|
||||||
slug:
|
|
||||||
pattern: "[a-z][a-z0-9_\-]+"
|
|
||||||
min: 2
|
|
||||||
max: 80
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
|
|
||||||
fields:
|
|
||||||
|
|
||||||
tabs:
|
|
||||||
type: tabs
|
|
||||||
active: 1
|
|
||||||
|
|
||||||
fields:
|
|
||||||
content:
|
|
||||||
type: tab
|
|
||||||
title: PLUGIN_ADMIN.CONTENT
|
|
||||||
|
|
||||||
fields:
|
|
||||||
header.title:
|
|
||||||
type: text
|
|
||||||
autofocus: true
|
|
||||||
style: vertical
|
|
||||||
label: PLUGIN_ADMIN.TITLE
|
|
||||||
|
|
||||||
content:
|
|
||||||
type: markdown
|
|
||||||
label: PLUGIN_ADMIN.CONTENT
|
|
||||||
validate:
|
|
||||||
type: textarea
|
|
||||||
|
|
||||||
uploads:
|
|
||||||
type: pagemedia
|
|
||||||
label: PLUGIN_ADMIN.PAGE_MEDIA
|
|
||||||
|
|
||||||
options:
|
|
||||||
type: tab
|
|
||||||
title: PLUGIN_ADMIN.OPTIONS
|
|
||||||
|
|
||||||
fields:
|
|
||||||
|
|
||||||
publishing:
|
|
||||||
type: section
|
|
||||||
title: Publishing
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
header.published:
|
|
||||||
type: toggle
|
|
||||||
toggleable: true
|
|
||||||
label: PLUGIN_ADMIN.PUBLISHED
|
|
||||||
help: PLUGIN_ADMIN.PUBLISHED_HELP
|
|
||||||
highlight: 1
|
|
||||||
size: medium
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
header.date:
|
|
||||||
type: datetime
|
|
||||||
label: PLUGIN_ADMIN.DATE
|
|
||||||
toggleable: true
|
|
||||||
help: PLUGIN_ADMIN.DATE_HELP
|
|
||||||
|
|
||||||
header.publish_date:
|
|
||||||
type: datetime
|
|
||||||
label: PLUGIN_ADMIN.PUBLISHED_DATE
|
|
||||||
toggleable: true
|
|
||||||
help: PLUGIN_ADMIN.PUBLISHED_DATE_HELP
|
|
||||||
|
|
||||||
header.unpublish_date:
|
|
||||||
type: datetime
|
|
||||||
label: PLUGIN_ADMIN.UNPUBLISHED_DATE
|
|
||||||
toggleable: true
|
|
||||||
help: PLUGIN_ADMIN.UNPUBLISHED_DATE_HELP
|
|
||||||
|
|
||||||
header.metadata:
|
|
||||||
toggleable: true
|
|
||||||
type: array
|
|
||||||
label: PLUGIN_ADMIN.METADATA
|
|
||||||
help: PLUGIN_ADMIN.METADATA_HELP
|
|
||||||
placeholder_key: PLUGIN_ADMIN.METADATA_KEY
|
|
||||||
placeholder_value: PLUGIN_ADMIN.METADATA_VALUE
|
|
||||||
|
|
||||||
|
|
||||||
taxonomies:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.TAXONOMIES
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
header.taxonomy:
|
|
||||||
type: taxonomy
|
|
||||||
label: PLUGIN_ADMIN.TAXONOMY
|
|
||||||
multiple: true
|
|
||||||
validate:
|
|
||||||
type: array
|
|
||||||
|
|
||||||
advanced:
|
|
||||||
type: tab
|
|
||||||
title: PLUGIN_ADMIN.ADVANCED
|
|
||||||
|
|
||||||
fields:
|
|
||||||
columns:
|
|
||||||
type: columns
|
|
||||||
fields:
|
|
||||||
column1:
|
|
||||||
type: column
|
|
||||||
fields:
|
|
||||||
|
|
||||||
settings:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.SETTINGS
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
ordering:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX
|
|
||||||
help: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.ENABLED
|
|
||||||
0: PLUGIN_ADMIN.DISABLED
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
folder:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.FOLDER_NAME
|
|
||||||
validate:
|
|
||||||
type: slug
|
|
||||||
|
|
||||||
route:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.PARENT
|
|
||||||
classes: fancy
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::parents'
|
|
||||||
'@data-default': '\Grav\Plugin\admin::route'
|
|
||||||
options:
|
|
||||||
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
|
|
||||||
|
|
||||||
name:
|
|
||||||
type: select
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.PAGE_FILE
|
|
||||||
help: PLUGIN_ADMIN.PAGE_FILE_HELP
|
|
||||||
default: default
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::pageTypes'
|
|
||||||
|
|
||||||
header.body_classes:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.BODY_CLASSES
|
|
||||||
|
|
||||||
|
|
||||||
column2:
|
|
||||||
type: column
|
|
||||||
|
|
||||||
fields:
|
|
||||||
order_title:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.ORDERING
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
order:
|
|
||||||
type: order
|
|
||||||
label: PLUGIN_ADMIN.PAGE_ORDER
|
|
||||||
sitemap:
|
|
||||||
|
|
||||||
overrides:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.OVERRIDES
|
|
||||||
underline: true
|
|
||||||
|
|
||||||
fields:
|
|
||||||
|
|
||||||
header.menu:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.MENU
|
|
||||||
toggleable: true
|
|
||||||
help: PLUGIN_ADMIN.MENU_HELP
|
|
||||||
|
|
||||||
header.slug:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.SLUG
|
|
||||||
toggleable: true
|
|
||||||
help: PLUGIN_ADMIN.SLUG_HELP
|
|
||||||
validate:
|
|
||||||
message: PLUGIN_ADMIN.SLUG_VALIDATE_MESSAGE
|
|
||||||
rule: slug
|
|
||||||
|
|
||||||
header.redirect:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.REDIRECT
|
|
||||||
toggleable: true
|
|
||||||
help: PLUGIN_ADMIN.REDIRECT_HELP
|
|
||||||
|
|
||||||
header.process:
|
|
||||||
type: checkboxes
|
|
||||||
label: PLUGIN_ADMIN.PROCESS
|
|
||||||
toggleable: true
|
|
||||||
'@config-default': system.pages.process
|
|
||||||
default:
|
|
||||||
markdown: true
|
|
||||||
twig: false
|
|
||||||
options:
|
|
||||||
markdown: Markdown
|
|
||||||
twig: Twig
|
|
||||||
use: keys
|
|
||||||
|
|
||||||
header.child_type:
|
|
||||||
type: select
|
|
||||||
toggleable: true
|
|
||||||
label: PLUGIN_ADMIN.DEFAULT_CHILD_TYPE
|
|
||||||
default: default
|
|
||||||
placeholder: PLUGIN_ADMIN.USE_GLOBAL
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::types'
|
|
||||||
|
|
||||||
header.routable:
|
|
||||||
type: toggle
|
|
||||||
toggleable: true
|
|
||||||
label: PLUGIN_ADMIN.ROUTABLE
|
|
||||||
help: PLUGIN_ADMIN.ROUTABLE_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.ENABLED
|
|
||||||
0: PLUGIN_ADMIN.DISABLED
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
header.cache_enable:
|
|
||||||
type: toggle
|
|
||||||
toggleable: true
|
|
||||||
label: PLUGIN_ADMIN.CACHING
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.ENABLED
|
|
||||||
0: PLUGIN_ADMIN.DISABLED
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
header.visible:
|
|
||||||
type: toggle
|
|
||||||
toggleable: true
|
|
||||||
label: PLUGIN_ADMIN.VISIBLE
|
|
||||||
help: PLUGIN_ADMIN.VISIBLE_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.ENABLED
|
|
||||||
0: PLUGIN_ADMIN.DISABLED
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
header.template:
|
|
||||||
type: select
|
|
||||||
toggleable: true
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.DISPLAY_TEMPLATE
|
|
||||||
default: default
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::types'
|
|
||||||
|
|
||||||
header.order_by:
|
|
||||||
type: hidden
|
|
||||||
|
|
||||||
header.order_manual:
|
|
||||||
type: hidden
|
|
||||||
validate:
|
|
||||||
type: commalist
|
|
||||||
|
|
||||||
blueprint:
|
|
||||||
type: blueprint
|
|
|
@ -1,47 +0,0 @@
|
||||||
title: PLUGIN_ADMIN.MODULAR
|
|
||||||
@extends:
|
|
||||||
type: default
|
|
||||||
context: blueprints://pages
|
|
||||||
|
|
||||||
form:
|
|
||||||
fields:
|
|
||||||
tabs:
|
|
||||||
type: tabs
|
|
||||||
active: 1
|
|
||||||
|
|
||||||
fields:
|
|
||||||
content:
|
|
||||||
fields:
|
|
||||||
|
|
||||||
header.content.items:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.ITEMS
|
|
||||||
default: '@self.modular'
|
|
||||||
options:
|
|
||||||
'@self.modular': Children
|
|
||||||
|
|
||||||
header.content.order.by:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.ORDER_BY
|
|
||||||
default: date
|
|
||||||
options:
|
|
||||||
folder: PLUGIN_ADMIN.FOLDER
|
|
||||||
title: PLUGIN_ADMIN.TITLE
|
|
||||||
date: PLUGIN_ADMIN.DATE
|
|
||||||
default: PLUGIN_ADMIN.DEFAULT
|
|
||||||
|
|
||||||
header.content.order.dir:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.ORDER
|
|
||||||
default: desc
|
|
||||||
options:
|
|
||||||
asc: PLUGIN_ADMIN.ASCENDING
|
|
||||||
desc: PLUGIN_ADMIN.DESCENDING
|
|
||||||
|
|
||||||
header.process:
|
|
||||||
type: ignore
|
|
||||||
content:
|
|
||||||
type: ignore
|
|
||||||
uploads:
|
|
||||||
type: ignore
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
rules:
|
|
||||||
slug:
|
|
||||||
pattern: "[a-z][a-z0-9_\-]+"
|
|
||||||
min: 2
|
|
||||||
max: 80
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
|
|
||||||
section:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.ADD_MODULAR_CONTENT
|
|
||||||
|
|
||||||
title:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.PAGE_TITLE
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
folder:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.FOLDER_NAME
|
|
||||||
validate:
|
|
||||||
type: slug
|
|
||||||
required: true
|
|
||||||
|
|
||||||
route:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.PAGE
|
|
||||||
classes: fancy
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::parents'
|
|
||||||
'@data-default': '\Grav\Plugin\admin::route'
|
|
||||||
options:
|
|
||||||
'': PLUGIN_ADMIN.DEFAULT_OPTION_SELECT
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
name:
|
|
||||||
type: select
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.MODULAR_TEMPLATE
|
|
||||||
help: PLUGIN_ADMIN.PAGE_FILE_HELP
|
|
||||||
default: default
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
modular:
|
|
||||||
type: hidden
|
|
||||||
default: 1
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
blueprint:
|
|
||||||
type: blueprint
|
|
|
@ -1,97 +0,0 @@
|
||||||
rules:
|
|
||||||
slug:
|
|
||||||
pattern: "[a-z][a-z0-9_\-]+"
|
|
||||||
min: 2
|
|
||||||
max: 80
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
|
|
||||||
tabs:
|
|
||||||
type: tabs
|
|
||||||
active: 1
|
|
||||||
|
|
||||||
fields:
|
|
||||||
content:
|
|
||||||
type: tab
|
|
||||||
title: PLUGIN_ADMIN.CONTENT
|
|
||||||
|
|
||||||
fields:
|
|
||||||
frontmatter:
|
|
||||||
type: frontmatter
|
|
||||||
label: PLUGIN_ADMIN.FRONTMATTER
|
|
||||||
|
|
||||||
|
|
||||||
content:
|
|
||||||
type: markdown
|
|
||||||
label: PLUGIN_ADMIN.CONTENT
|
|
||||||
|
|
||||||
uploads:
|
|
||||||
type: pagemedia
|
|
||||||
label: PLUGIN_ADMIN.PAGE_MEDIA
|
|
||||||
|
|
||||||
|
|
||||||
options:
|
|
||||||
type: tab
|
|
||||||
title: PLUGIN_ADMIN.OPTIONS
|
|
||||||
|
|
||||||
fields:
|
|
||||||
|
|
||||||
columns:
|
|
||||||
type: columns
|
|
||||||
|
|
||||||
fields:
|
|
||||||
column1:
|
|
||||||
type: column
|
|
||||||
|
|
||||||
fields:
|
|
||||||
|
|
||||||
ordering:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX
|
|
||||||
help: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.ENABLED
|
|
||||||
0: PLUGIN_ADMIN.DISABLED
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
folder:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.FILENAME
|
|
||||||
validate:
|
|
||||||
type: slug
|
|
||||||
required: true
|
|
||||||
|
|
||||||
route:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.PARENT
|
|
||||||
classes: fancy
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::parents'
|
|
||||||
'@data-default': '\Grav\Plugin\admin::route'
|
|
||||||
options:
|
|
||||||
'': PLUGIN_ADMIN.DEFAULT_OPTION_SELECT
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
name:
|
|
||||||
type: select
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.MODULAR_TEMPLATE
|
|
||||||
default: default
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::modularTypes'
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
column2:
|
|
||||||
type: column
|
|
||||||
|
|
||||||
fields:
|
|
||||||
order:
|
|
||||||
type: order
|
|
||||||
label: PLUGIN_ADMIN.ORDERING
|
|
||||||
|
|
||||||
blueprint:
|
|
||||||
type: blueprint
|
|
|
@ -1,17 +0,0 @@
|
||||||
rules:
|
|
||||||
slug:
|
|
||||||
pattern: "[a-z][a-z0-9_\-]+"
|
|
||||||
min: 2
|
|
||||||
max: 80
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
route:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.PARENT
|
|
||||||
classes: fancy
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::parents'
|
|
||||||
'@data-default': '\Grav\Plugin\admin::route'
|
|
||||||
options:
|
|
||||||
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
|
|
|
@ -1,66 +0,0 @@
|
||||||
rules:
|
|
||||||
slug:
|
|
||||||
pattern: "[a-z][a-z0-9_\-]+"
|
|
||||||
min: 2
|
|
||||||
max: 80
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
|
|
||||||
section:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.ADD_PAGE
|
|
||||||
|
|
||||||
title:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.PAGE_TITLE
|
|
||||||
help: PLUGIN_ADMIN.PAGE_TITLE_HELP
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
folder:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.FOLDER_NAME
|
|
||||||
help: PLUGIN_ADMIN.FOLDER_NAME_HELP
|
|
||||||
validate:
|
|
||||||
type: slug
|
|
||||||
required: true
|
|
||||||
|
|
||||||
route:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.PARENT_PAGE
|
|
||||||
classes: fancy
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::parents'
|
|
||||||
'@data-default': '\Grav\Plugin\admin::getLastPageRoute'
|
|
||||||
options:
|
|
||||||
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
name:
|
|
||||||
type: select
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.PAGE_FILE
|
|
||||||
help: PLUGIN_ADMIN.PAGE_FILE_HELP
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::types'
|
|
||||||
'@data-default': '\Grav\Plugin\admin::getLastPageName'
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
visible:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.VISIBLE
|
|
||||||
help: PLUGIN_ADMIN.VISIBLE_HELP
|
|
||||||
highlight: ''
|
|
||||||
default: ''
|
|
||||||
options:
|
|
||||||
'': Auto
|
|
||||||
1: PLUGIN_ADMIN.YES
|
|
||||||
0: PLUGIN_ADMIN.NO
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
required: true
|
|
||||||
|
|
||||||
blueprint:
|
|
||||||
type: blueprint
|
|
|
@ -1,96 +0,0 @@
|
||||||
rules:
|
|
||||||
slug:
|
|
||||||
pattern: "[a-z][a-z0-9_\-]+"
|
|
||||||
min: 2
|
|
||||||
max: 80
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
|
|
||||||
tabs:
|
|
||||||
type: tabs
|
|
||||||
active: 1
|
|
||||||
|
|
||||||
fields:
|
|
||||||
content:
|
|
||||||
type: tab
|
|
||||||
title: PLUGIN_ADMIN.CONTENT
|
|
||||||
|
|
||||||
fields:
|
|
||||||
frontmatter:
|
|
||||||
type: frontmatter
|
|
||||||
label: PLUGIN_ADMIN.FRONTMATTER
|
|
||||||
autofocus: true
|
|
||||||
|
|
||||||
content:
|
|
||||||
type: markdown
|
|
||||||
label: PLUGIN_ADMIN.CONTENT
|
|
||||||
|
|
||||||
uploads:
|
|
||||||
type: pagemedia
|
|
||||||
label: PLUGIN_ADMIN.PAGE_MEDIA
|
|
||||||
|
|
||||||
options:
|
|
||||||
type: tab
|
|
||||||
title: PLUGIN_ADMIN.OPTIONS
|
|
||||||
|
|
||||||
fields:
|
|
||||||
|
|
||||||
columns:
|
|
||||||
type: columns
|
|
||||||
|
|
||||||
fields:
|
|
||||||
column1:
|
|
||||||
type: column
|
|
||||||
|
|
||||||
fields:
|
|
||||||
|
|
||||||
ordering:
|
|
||||||
type: toggle
|
|
||||||
label: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX
|
|
||||||
help: PLUGIN_ADMIN.FOLDER_NUMERIC_PREFIX_HELP
|
|
||||||
highlight: 1
|
|
||||||
options:
|
|
||||||
1: PLUGIN_ADMIN.ENABLED
|
|
||||||
0: PLUGIN_ADMIN.DISABLED
|
|
||||||
validate:
|
|
||||||
type: bool
|
|
||||||
|
|
||||||
folder:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.FOLDER_NAME
|
|
||||||
help: PLUGIN_ADMIN.FOLDER_NAME_HELP
|
|
||||||
validate:
|
|
||||||
type: slug
|
|
||||||
required: true
|
|
||||||
|
|
||||||
route:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.PARENT
|
|
||||||
classes: fancy
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::parents'
|
|
||||||
'@data-default': '\Grav\Plugin\admin::route'
|
|
||||||
options:
|
|
||||||
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
|
|
||||||
|
|
||||||
name:
|
|
||||||
type: select
|
|
||||||
classes: fancy
|
|
||||||
label: PLUGIN_ADMIN.DISPLAY_TEMPLATE
|
|
||||||
help: PLUGIN_ADMIN.DISPLAY_TEMPLATE_HELP
|
|
||||||
default: default
|
|
||||||
'@data-options': '\Grav\Common\Page\Pages::types'
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
column2:
|
|
||||||
type: column
|
|
||||||
|
|
||||||
fields:
|
|
||||||
order:
|
|
||||||
type: order
|
|
||||||
label: PLUGIN_ADMIN.ORDERING
|
|
||||||
|
|
||||||
blueprint:
|
|
||||||
type: blueprint
|
|
|
@ -1,56 +0,0 @@
|
||||||
title: Site
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
|
|
||||||
content:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.ACCOUNT
|
|
||||||
|
|
||||||
fields:
|
|
||||||
username:
|
|
||||||
type: text
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.USERNAME
|
|
||||||
disabled: true
|
|
||||||
readonly: true
|
|
||||||
|
|
||||||
email:
|
|
||||||
type: email
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.EMAIL
|
|
||||||
validate:
|
|
||||||
type: email
|
|
||||||
message: PLUGIN_ADMIN.EMAIL_VALIDATION_MESSAGE
|
|
||||||
required: true
|
|
||||||
|
|
||||||
password:
|
|
||||||
type: password
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.PASSWORD
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
message: PLUGIN_ADMIN.PASSWORD_VALIDATION_MESSAGE
|
|
||||||
pattern: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}'
|
|
||||||
|
|
||||||
fullname:
|
|
||||||
type: text
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.FULL_NAME
|
|
||||||
validate:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
title:
|
|
||||||
type: text
|
|
||||||
size: large
|
|
||||||
label: PLUGIN_ADMIN.TITLE
|
|
||||||
|
|
||||||
language:
|
|
||||||
type: select
|
|
||||||
label: PLUGIN_ADMIN.LANGUAGE
|
|
||||||
size: medium
|
|
||||||
classes: fancy
|
|
||||||
'@data-options': '\Grav\Plugin\admin::adminLanguages'
|
|
||||||
default: 'en'
|
|
||||||
help: PLUGIN_ADMIN.LANGUAGE_HELP
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
title: PLUGIN_ADMIN.ADD_ACCOUNT
|
|
||||||
|
|
||||||
form:
|
|
||||||
validation: loose
|
|
||||||
fields:
|
|
||||||
|
|
||||||
content:
|
|
||||||
type: section
|
|
||||||
title: PLUGIN_ADMIN.ADD_ACCOUNT
|
|
||||||
|
|
||||||
username:
|
|
||||||
type: text
|
|
||||||
label: PLUGIN_ADMIN.USERNAME
|
|
||||||
help: PLUGIN_ADMIN.USERNAME_HELP
|
|
||||||
validate:
|
|
||||||
required: true
|
|
|
@ -1,190 +0,0 @@
|
||||||
defaults:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb.png
|
|
||||||
mime: application/octet-stream
|
|
||||||
image:
|
|
||||||
filters:
|
|
||||||
default:
|
|
||||||
- enableProgressive
|
|
||||||
|
|
||||||
jpg:
|
|
||||||
type: image
|
|
||||||
thumb: media/thumb-jpg.png
|
|
||||||
mime: image/jpeg
|
|
||||||
jpe:
|
|
||||||
type: image
|
|
||||||
thumb: media/thumb-jpg.png
|
|
||||||
mime: image/jpeg
|
|
||||||
jpeg:
|
|
||||||
type: image
|
|
||||||
thumb: media/thumb-jpeg.png
|
|
||||||
mime: image/jpeg
|
|
||||||
png:
|
|
||||||
type: image
|
|
||||||
thumb: media/thumb-png.png
|
|
||||||
mime: image/png
|
|
||||||
gif:
|
|
||||||
type: animated
|
|
||||||
thumb: media/thumb-gif.png
|
|
||||||
mime: image/gif
|
|
||||||
|
|
||||||
svg:
|
|
||||||
type: vector
|
|
||||||
thumb: media/thumb-gif.png
|
|
||||||
mime: image/svg+xml
|
|
||||||
|
|
||||||
mp4:
|
|
||||||
type: video
|
|
||||||
thumb: media/thumb-mp4.png
|
|
||||||
mime: video/mp4
|
|
||||||
mov:
|
|
||||||
type: video
|
|
||||||
thumb: media/thumb-mov.png
|
|
||||||
mime: video/quicktime
|
|
||||||
m4v:
|
|
||||||
type: video
|
|
||||||
thumb: media/thumb-m4v.png
|
|
||||||
mime: video/x-m4v
|
|
||||||
swf:
|
|
||||||
type: video
|
|
||||||
thumb: media/thumb-swf.png
|
|
||||||
mime: video/x-flv
|
|
||||||
flv:
|
|
||||||
type: video
|
|
||||||
thumb: media/thumb-flv.png
|
|
||||||
mime: video/x-flv
|
|
||||||
|
|
||||||
mp3:
|
|
||||||
type: audio
|
|
||||||
thumb: media/thumb-mp3.png
|
|
||||||
mime: audio/mp3
|
|
||||||
ogg:
|
|
||||||
type: audio
|
|
||||||
thumb: media/thumb-ogg.png
|
|
||||||
mime: audio/ogg
|
|
||||||
wma:
|
|
||||||
type: audio
|
|
||||||
thumb: media/thumb-wma.png
|
|
||||||
mime: audio/wma
|
|
||||||
m4a:
|
|
||||||
type: audio
|
|
||||||
thumb: media/thumb-m4a.png
|
|
||||||
mime: audio/m4a
|
|
||||||
wav:
|
|
||||||
type: audio
|
|
||||||
thumb: media/thumb-wav.png
|
|
||||||
mime: audio/wav
|
|
||||||
aiff:
|
|
||||||
type: audio
|
|
||||||
mime: audio/aiff
|
|
||||||
aif:
|
|
||||||
type: audio
|
|
||||||
mime: audio/aif
|
|
||||||
|
|
||||||
txt:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-txt.png
|
|
||||||
mime: text/plain
|
|
||||||
xml:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-xml.png
|
|
||||||
mime: application/xml
|
|
||||||
doc:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-doc.png
|
|
||||||
mime: application/msword
|
|
||||||
docx:
|
|
||||||
type: file
|
|
||||||
mime: application/msword
|
|
||||||
xls:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-excel
|
|
||||||
xlt:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-excel
|
|
||||||
xlm:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-excel
|
|
||||||
xld:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-excel
|
|
||||||
xla:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-excel
|
|
||||||
xlc:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-excel
|
|
||||||
xlw:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-excel
|
|
||||||
xll:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-excel
|
|
||||||
ppt:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-powerpoint
|
|
||||||
pps:
|
|
||||||
type: file
|
|
||||||
mime: application/vnd.ms-powerpoint
|
|
||||||
rtf:
|
|
||||||
type: file
|
|
||||||
mime: application/rtf
|
|
||||||
|
|
||||||
bmp:
|
|
||||||
type: file
|
|
||||||
mime: image/bmp
|
|
||||||
tiff:
|
|
||||||
type: file
|
|
||||||
mime: image/tiff
|
|
||||||
mpeg:
|
|
||||||
type: file
|
|
||||||
mime: video/mpeg
|
|
||||||
mpg:
|
|
||||||
type: file
|
|
||||||
mime: video/mpeg
|
|
||||||
mpe:
|
|
||||||
type: file
|
|
||||||
mime: video/mpeg
|
|
||||||
avi:
|
|
||||||
type: file
|
|
||||||
mime: video/msvideo
|
|
||||||
wmv:
|
|
||||||
type: file
|
|
||||||
mime: video/x-ms-wmv
|
|
||||||
|
|
||||||
html:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-html.png
|
|
||||||
mime: text/html
|
|
||||||
htm:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-html.png
|
|
||||||
mime: text/html
|
|
||||||
pdf:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-pdf.png
|
|
||||||
mime: application/pdf
|
|
||||||
zip:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-zip.png
|
|
||||||
mime: application/zip
|
|
||||||
gz:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-gz.png
|
|
||||||
mime: application/gzip
|
|
||||||
tar:
|
|
||||||
type: file
|
|
||||||
mime: application/x-tar
|
|
||||||
css:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-css.png
|
|
||||||
mime: text/css
|
|
||||||
js:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-js.png
|
|
||||||
mime: application/javascript
|
|
||||||
json:
|
|
||||||
type: file
|
|
||||||
thumb: media/thumb-json.png
|
|
||||||
mime: application/json
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
title: Grav # Name of the site
|
|
||||||
|
|
||||||
author:
|
|
||||||
name: John Appleseed # Default author name
|
|
||||||
email: 'john@email.com' # Default author email
|
|
||||||
|
|
||||||
taxonomies: [category,tag] # Arbitrary list of taxonomy types
|
|
||||||
|
|
||||||
metadata:
|
|
||||||
description: 'My Grav Site' # Site description
|
|
||||||
|
|
||||||
summary:
|
|
||||||
enabled: true # enable or disable summary of page
|
|
||||||
format: short # long = summary delimiter will be ignored; short = use the first occurrence of delimiter or size
|
|
||||||
size: 300 # Maximum length of summary (characters)
|
|
||||||
delimiter: === # The summary delimiter
|
|
||||||
|
|
||||||
redirects:
|
|
||||||
/redirect-test: / # Redirect test goes to home page
|
|
||||||
/old/(.*): /new/$1 # Would redirect /old/my-page to /new/my-page
|
|
||||||
|
|
||||||
routes:
|
|
||||||
/something/else: '/blog/sample-3' # Alias for /blog/sample-3
|
|
||||||
/new/(.*): '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route
|
|
||||||
|
|
||||||
blog:
|
|
||||||
route: '/blog' # Custom value added (accessible via system.blog.route)
|
|
||||||
|
|
||||||
#menu: # Sample Menu Example
|
|
||||||
# - text: Source
|
|
||||||
# icon: github
|
|
||||||
# url: https://github.com/getgrav/grav
|
|
||||||
# - icon: twitter
|
|
||||||
# url: http://twitter.com/getgrav
|
|
|
@ -1,21 +0,0 @@
|
||||||
schemes:
|
|
||||||
asset:
|
|
||||||
type: ReadOnlyStream
|
|
||||||
paths:
|
|
||||||
- assets
|
|
||||||
|
|
||||||
image:
|
|
||||||
type: ReadOnlyStream
|
|
||||||
paths:
|
|
||||||
- user://images
|
|
||||||
- system://images
|
|
||||||
|
|
||||||
page:
|
|
||||||
type: ReadOnlyStream
|
|
||||||
paths:
|
|
||||||
- user://pages
|
|
||||||
|
|
||||||
account:
|
|
||||||
type: ReadOnlyStream
|
|
||||||
paths:
|
|
||||||
- user://accounts
|
|
|
@ -1,112 +0,0 @@
|
||||||
absolute_urls: false # Absolute or relative URLs for `base_url`
|
|
||||||
timezone: '' # Valid values: http://php.net/manual/en/timezones.php
|
|
||||||
default_locale: # Default locale (defaults to system)
|
|
||||||
param_sep: ':' # Parameter separator, use ';' for Apache on windows
|
|
||||||
wrapped_site: false # For themes/plugins to know if Grav is wrapped by another platform
|
|
||||||
|
|
||||||
languages:
|
|
||||||
supported: [] # List of languages supported. eg: [en, fr, de]
|
|
||||||
include_default_lang: true # Include the default lang prefix in all URLs
|
|
||||||
translations: true # Enable translations by default
|
|
||||||
translations_fallback: true # Fallback through supported translations if active lang doesn't exist
|
|
||||||
session_store_active: false # Store active language in session
|
|
||||||
http_accept_language: false # Attempt to set the language based on http_accept_language header in the browser
|
|
||||||
override_locale: false # Override the default or system locale with language specific one
|
|
||||||
|
|
||||||
home:
|
|
||||||
alias: '/home' # Default path for home, ie /
|
|
||||||
|
|
||||||
pages:
|
|
||||||
theme: antimatter # Default theme (defaults to "antimatter" theme)
|
|
||||||
order:
|
|
||||||
by: default # Order pages by "default", "alpha" or "date"
|
|
||||||
dir: asc # Default ordering direction, "asc" or "desc"
|
|
||||||
list:
|
|
||||||
count: 20 # Default item count per page
|
|
||||||
dateformat:
|
|
||||||
default: # The default date format Grav expects in the `date: ` field
|
|
||||||
short: 'jS M Y' # Short date format
|
|
||||||
long: 'F jS \a\t g:ia' # Long date format
|
|
||||||
publish_dates: true # automatically publish/unpublish based on dates
|
|
||||||
process:
|
|
||||||
markdown: true # Process Markdown
|
|
||||||
twig: false # Process Twig
|
|
||||||
events:
|
|
||||||
page: true # Enable page level events
|
|
||||||
twig: true # Enable twig level events
|
|
||||||
markdown:
|
|
||||||
extra: false # Enable support for Markdown Extra support (GFM by default)
|
|
||||||
auto_line_breaks: false # Enable automatic line breaks
|
|
||||||
auto_url_links: false # Enable automatic HTML links
|
|
||||||
escape_markup: false # Escape markup tags into entities
|
|
||||||
special_chars: # List of special characters to automatically convert to entities
|
|
||||||
'>': 'gt'
|
|
||||||
'<': 'lt'
|
|
||||||
types: [txt,xml,html,json,rss,atom] # list of valid page types
|
|
||||||
expires: 604800 # Page expires time in seconds (604800 seconds = 7 days)
|
|
||||||
last_modified: false # Set the last modified date header based on file modifcation timestamp
|
|
||||||
etag: false # Set the etag header tag
|
|
||||||
vary_accept_encoding: false # Add `Vary: Accept-Encoding` header
|
|
||||||
redirect_default_route: false # Automatically redirect to a page's default route
|
|
||||||
redirect_default_code: 301 # Default code to use for redirects
|
|
||||||
redirect_trailing_slash: true # Handle automatically or 301 redirect a trailing / URL
|
|
||||||
ignore_files: [.DS_Store] # Files to ignore in Pages
|
|
||||||
ignore_folders: [.git, .idea] # Folders to ignore in Pages
|
|
||||||
ignore_hidden: true # Ignore all Hidden files and folders
|
|
||||||
url_taxonomy_filters: true # Enable auto-magic URL-based taxonomy filters for page collections
|
|
||||||
fallback_types: [png,jpg,jpeg,gif] # Allowed types of files found if accessed via Page route
|
|
||||||
|
|
||||||
cache:
|
|
||||||
enabled: true # Set to true to enable caching
|
|
||||||
check:
|
|
||||||
method: file # Method to check for updates in pages: file|folder|none
|
|
||||||
driver: auto # One of: auto|file|apc|xcache|memcache|wincache
|
|
||||||
prefix: 'g' # Cache prefix string (prevents cache conflicts)
|
|
||||||
lifetime: 604800 # Lifetime of cached data in seconds (0 = infinite)
|
|
||||||
gzip: false # GZip compress the page output
|
|
||||||
|
|
||||||
twig:
|
|
||||||
cache: true # Set to true to enable twig caching
|
|
||||||
debug: false # Enable Twig debug
|
|
||||||
auto_reload: true # Refresh cache on changes
|
|
||||||
autoescape: false # Autoescape Twig vars
|
|
||||||
undefined_functions: true # Allow undefined functions
|
|
||||||
undefined_filters: true # Allow undefined filters
|
|
||||||
|
|
||||||
assets: # Configuration for Assets Manager (JS, CSS)
|
|
||||||
css_pipeline: false # The CSS pipeline is the unification of multiple CSS resources into one file
|
|
||||||
css_minify: true # Minify the CSS during pipelining
|
|
||||||
css_minify_windows: false # Minify Override for Windows platforms. False by default due to ThreadStackSize
|
|
||||||
css_rewrite: true # Rewrite any CSS relative URLs during pipelining
|
|
||||||
js_pipeline: false # The JS pipeline is the unification of multiple JS resources into one file
|
|
||||||
js_minify: true # Minify the JS during pipelining
|
|
||||||
enable_asset_timestamp: false # Enable asset timestamps
|
|
||||||
collections:
|
|
||||||
jquery: system://assets/jquery/jquery-2.1.4.min.js
|
|
||||||
|
|
||||||
errors:
|
|
||||||
display: false # Display full backtrace-style error page
|
|
||||||
log: true # Log errors to /logs folder
|
|
||||||
|
|
||||||
debugger:
|
|
||||||
enabled: false # Enable Grav debugger and following settings
|
|
||||||
shutdown:
|
|
||||||
close_connection: true # Close the connection before calling onShutdown(). false for debugging
|
|
||||||
|
|
||||||
images:
|
|
||||||
default_image_quality: 85 # Default image quality to use when resampling images (85%)
|
|
||||||
cache_all: false # Cache all image by default
|
|
||||||
debug: false # Show an overlay over images indicating the pixel depth of the image when working with retina for example
|
|
||||||
|
|
||||||
media:
|
|
||||||
enable_media_timestamp: false # Enable media timetsamps
|
|
||||||
upload_limit: 0 # Set maximum upload size in bytes (0 is unlimited)
|
|
||||||
unsupported_inline_types: [] # Array of unsupported media file types to try to display inline
|
|
||||||
|
|
||||||
session:
|
|
||||||
enabled: true # Enable Session support
|
|
||||||
timeout: 1800 # Timeout in seconds
|
|
||||||
name: grav-site # Name prefix of the session cookie
|
|
||||||
|
|
||||||
security:
|
|
||||||
default_hash: $2y$10$kwsyMVwM8/7j0K/6LHT.g.Fs49xOCTp2b8hh/S5.dPJuJcJB6T.UK
|
|
|
@ -1,42 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
// Some standard defines
|
|
||||||
define('GRAV', true);
|
|
||||||
define('GRAV_VERSION', '1.0.0-rc.4');
|
|
||||||
define('DS', '/');
|
|
||||||
|
|
||||||
// Directories and Paths
|
|
||||||
if (!defined('GRAV_ROOT')) {
|
|
||||||
define('GRAV_ROOT', str_replace(DIRECTORY_SEPARATOR, DS, getcwd()));
|
|
||||||
}
|
|
||||||
define('ROOT_DIR', GRAV_ROOT . '/');
|
|
||||||
define('USER_PATH', 'user/');
|
|
||||||
define('USER_DIR', ROOT_DIR . USER_PATH);
|
|
||||||
define('SYSTEM_DIR', ROOT_DIR .'system/');
|
|
||||||
define('CACHE_DIR', ROOT_DIR . 'cache/');
|
|
||||||
define('LOG_DIR', ROOT_DIR .'logs/');
|
|
||||||
|
|
||||||
// DEPRECATED: Do not use!
|
|
||||||
define('ASSETS_DIR', ROOT_DIR . 'assets/');
|
|
||||||
define('IMAGES_DIR', ROOT_DIR . 'images/');
|
|
||||||
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
|
|
||||||
define('PAGES_DIR', USER_DIR .'pages/');
|
|
||||||
define('DATA_DIR', USER_DIR .'data/');
|
|
||||||
define('LIB_DIR', SYSTEM_DIR .'src/');
|
|
||||||
define('PLUGINS_DIR', USER_DIR .'plugins/');
|
|
||||||
define('THEMES_DIR', USER_DIR .'themes/');
|
|
||||||
define('VENDOR_DIR', ROOT_DIR .'vendor/');
|
|
||||||
// END DEPRECATED
|
|
||||||
|
|
||||||
// Some extensions
|
|
||||||
define('CONTENT_EXT', '.md');
|
|
||||||
define('TEMPLATE_EXT', '.html.twig');
|
|
||||||
define('TWIG_EXT', '.twig');
|
|
||||||
define('PLUGIN_EXT', '.php');
|
|
||||||
define('YAML_EXT', '.yaml');
|
|
||||||
|
|
||||||
// Content types
|
|
||||||
define('RAW_CONTENT', 1);
|
|
||||||
define('TWIG_CONTENT', 2);
|
|
||||||
define('TWIG_CONTENT_LIST', 3);
|
|
||||||
define('TWIG_TEMPLATES', 4);
|
|
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB |
|
@ -1,37 +0,0 @@
|
||||||
NICETIME:
|
|
||||||
NO_DATE_PROVIDED: Datum nebylo vloženo
|
|
||||||
BAD_DATE: Chybné datum
|
|
||||||
AGO: zpět
|
|
||||||
FROM_NOW: od teď
|
|
||||||
SECOND: sekunda
|
|
||||||
MINUTE: minuta
|
|
||||||
HOUR: hodina
|
|
||||||
DAY: den
|
|
||||||
WEEK: týden
|
|
||||||
MONTH: měsíc
|
|
||||||
YEAR: rok
|
|
||||||
DECADE: dekáda
|
|
||||||
SEC: sek
|
|
||||||
MIN: min
|
|
||||||
HR: hod
|
|
||||||
DAY: den
|
|
||||||
WK: t
|
|
||||||
MO: m
|
|
||||||
YR: r
|
|
||||||
DEC: dek
|
|
||||||
SECOND_PLURAL: sekundy
|
|
||||||
MINUTE_PLURAL: minuty
|
|
||||||
HOUR_PLURAL: hodiny
|
|
||||||
DAY_PLURAL: dny
|
|
||||||
WEEK_PLURAL: týdny
|
|
||||||
MONTH_PLURAL: měsíce
|
|
||||||
YEAR_PLURAL: roky
|
|
||||||
DECADE_PLURAL: dekády
|
|
||||||
SEC_PLURAL: sek
|
|
||||||
MIN_PLURAL: min
|
|
||||||
HR_PLURAL: hod
|
|
||||||
DAY_PLURAL: dny
|
|
||||||
WK_PLURAL: t
|
|
||||||
MO_PLURAL: m
|
|
||||||
YR_PLURAL: r
|
|
||||||
DEC_PLURAL: dek
|
|
|
@ -1,43 +0,0 @@
|
||||||
INFLECTOR_IRREGULAR:
|
|
||||||
'person': 'Personen'
|
|
||||||
'man': 'Menschen'
|
|
||||||
'child': 'Kinder'
|
|
||||||
'sex': 'Geschlecht'
|
|
||||||
'move': 'Züge'
|
|
||||||
NICETIME:
|
|
||||||
NO_DATE_PROVIDED: Keine Daten vorhanden
|
|
||||||
BAD_DATE: Falsches Datum
|
|
||||||
AGO: her
|
|
||||||
FROM_NOW: ab jetzt
|
|
||||||
SECOND: Sekunde
|
|
||||||
MINUTE: Minute
|
|
||||||
HOUR: Stunde
|
|
||||||
DAY: Tag
|
|
||||||
WEEK: Woche
|
|
||||||
MONTH: Monat
|
|
||||||
YEAR: Jahr
|
|
||||||
DECADE: Dekade
|
|
||||||
SEC: sek
|
|
||||||
MIN: min
|
|
||||||
HR: std
|
|
||||||
DAY: Tag
|
|
||||||
WK: wo
|
|
||||||
MO: mo
|
|
||||||
YR: yh
|
|
||||||
DEC: dec
|
|
||||||
SECOND_PLURAL: Sekunden
|
|
||||||
MINUTE_PLURAL: Minuten
|
|
||||||
HOUR_PLURAL: Stunden
|
|
||||||
DAY_PLURAL: Tage
|
|
||||||
WEEK_PLURAL: Wochen
|
|
||||||
MONTH_PLURAL: Monate
|
|
||||||
YEAR_PLURAL: Jahre
|
|
||||||
DECADE_PLURAL: Dekaden
|
|
||||||
SEC_PLURAL: Sekunden
|
|
||||||
MIN_PLURAL: Minuten
|
|
||||||
HR_PLURAL: Stunden
|
|
||||||
DAY_PLURAL: Tage
|
|
||||||
WK_PLURAL: Wochen
|
|
||||||
MO_PLURAL: Monate
|
|
||||||
YR_PLURAL: Jahre
|
|
||||||
DEC_PLURAL: Dekaden
|
|
|
@ -1,94 +0,0 @@
|
||||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Error: Invalid Frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
|
||||||
INFLECTOR_PLURALS:
|
|
||||||
'/(quiz)$/i': '\1zes'
|
|
||||||
'/^(ox)$/i': '\1en'
|
|
||||||
'/([m|l])ouse$/i': '\1ice'
|
|
||||||
'/(matr|vert|ind)ix|ex$/i': '\1ices'
|
|
||||||
'/(x|ch|ss|sh)$/i': '\1es'
|
|
||||||
'/([^aeiouy]|qu)ies$/i': '\1y'
|
|
||||||
'/([^aeiouy]|qu)y$/i': '\1ies'
|
|
||||||
'/(hive)$/i': '\1s'
|
|
||||||
'/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
|
|
||||||
'/sis$/i': 'ses'
|
|
||||||
'/([ti])um$/i': '\1a'
|
|
||||||
'/(buffal|tomat)o$/i': '\1oes'
|
|
||||||
'/(bu)s$/i': '\1ses'
|
|
||||||
'/(alias|status)/i': '\1es'
|
|
||||||
'/(octop|vir)us$/i': '\1i'
|
|
||||||
'/(ax|test)is$/i': '\1es'
|
|
||||||
'/s$/i': 's'
|
|
||||||
'/$/': 's'
|
|
||||||
INFLECTOR_SINGULAR:
|
|
||||||
'/(quiz)zes$/i': '\1'
|
|
||||||
'/(matr)ices$/i': '\1ix'
|
|
||||||
'/(vert|ind)ices$/i': '\1ex'
|
|
||||||
'/^(ox)en/i': '\1'
|
|
||||||
'/(alias|status)es$/i': '\1'
|
|
||||||
'/([octop|vir])i$/i': '\1us'
|
|
||||||
'/(cris|ax|test)es$/i': '\1is'
|
|
||||||
'/(shoe)s$/i': '\1'
|
|
||||||
'/(o)es$/i': '\1'
|
|
||||||
'/(bus)es$/i': '\1'
|
|
||||||
'/([m|l])ice$/i': '\1ouse'
|
|
||||||
'/(x|ch|ss|sh)es$/i': '\1'
|
|
||||||
'/(m)ovies$/i': '\1ovie'
|
|
||||||
'/(s)eries$/i': '\1eries'
|
|
||||||
'/([^aeiouy]|qu)ies$/i': '\1y'
|
|
||||||
'/([lr])ves$/i': '\1f'
|
|
||||||
'/(tive)s$/i': '\1'
|
|
||||||
'/(hive)s$/i': '\1'
|
|
||||||
'/([^f])ves$/i': '\1fe'
|
|
||||||
'/(^analy)ses$/i': '\1sis'
|
|
||||||
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i': '\1\2sis'
|
|
||||||
'/([ti])a$/i': '\1um'
|
|
||||||
'/(n)ews$/i': '\1ews'
|
|
||||||
'/s$/i': ''
|
|
||||||
INFLECTOR_UNCOUNTABLE: ['equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep']
|
|
||||||
INFLECTOR_IRREGULAR:
|
|
||||||
'person': 'people'
|
|
||||||
'man': 'men'
|
|
||||||
'child': 'children'
|
|
||||||
'sex': 'sexes'
|
|
||||||
'move': 'moves'
|
|
||||||
INFLECTOR_ORDINALS:
|
|
||||||
'default': 'th'
|
|
||||||
'first': 'st'
|
|
||||||
'second': 'nd'
|
|
||||||
'third': 'rd'
|
|
||||||
NICETIME:
|
|
||||||
NO_DATE_PROVIDED: No date provided
|
|
||||||
BAD_DATE: Bad date
|
|
||||||
AGO: ago
|
|
||||||
FROM_NOW: from now
|
|
||||||
SECOND: second
|
|
||||||
MINUTE: minute
|
|
||||||
HOUR: hour
|
|
||||||
DAY: day
|
|
||||||
WEEK: week
|
|
||||||
MONTH: month
|
|
||||||
YEAR: year
|
|
||||||
DECADE: decade
|
|
||||||
SEC: sec
|
|
||||||
MIN: min
|
|
||||||
HR: hr
|
|
||||||
DAY: day
|
|
||||||
WK: wk
|
|
||||||
MO: mo
|
|
||||||
YR: yr
|
|
||||||
DEC: dec
|
|
||||||
SECOND_PLURAL: seconds
|
|
||||||
MINUTE_PLURAL: minutes
|
|
||||||
HOUR_PLURAL: hours
|
|
||||||
DAY_PLURAL: days
|
|
||||||
WEEK_PLURAL: weeks
|
|
||||||
MONTH_PLURAL: months
|
|
||||||
YEAR_PLURAL: years
|
|
||||||
DECADE_PLURAL: decades
|
|
||||||
SEC_PLURAL: secs
|
|
||||||
MIN_PLURAL: mins
|
|
||||||
HR_PLURAL: hrs
|
|
||||||
DAY_PLURAL: days
|
|
||||||
WK_PLURAL: wks
|
|
||||||
MO_PLURAL: mos
|
|
||||||
YR_PLURAL: yrs
|
|
||||||
DEC_PLURAL: decs
|
|
|
@ -1,60 +0,0 @@
|
||||||
INFLECTOR_PLURALS:
|
|
||||||
'/$/': 's'
|
|
||||||
'/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)$/': '\1x'
|
|
||||||
'/(bleu|émeu|landau|lieu|pneu|sarrau)$/': '\1s'
|
|
||||||
'/(b|cor|ém|gemm|soupir|trav|vant|vitr)ail$/': '\1aux'
|
|
||||||
'/(s|x|z)$/': '\1'
|
|
||||||
'/ail$/': 'ails'
|
|
||||||
'/al$/': 'aux'
|
|
||||||
'/s$/i': 's'
|
|
||||||
INFLECTOR_SINGULAR:
|
|
||||||
'/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)x$/': '\1'
|
|
||||||
'/(b|cor|ém|gemm|soupir|trav|vant|vitr)aux$/': '\1ail'
|
|
||||||
'/(journ|chev)aux$/': '\1al'
|
|
||||||
'/ails$/': 'ail'
|
|
||||||
'/s$/i': ''
|
|
||||||
INFLECTOR_IRREGULAR:
|
|
||||||
'madame': 'mesdames'
|
|
||||||
'mademoiselle': 'mesdemoiselles'
|
|
||||||
'monsieur': 'messieurs'
|
|
||||||
INFLECTOR_ORDINALS:
|
|
||||||
'default': 'ème'
|
|
||||||
'first': 'er'
|
|
||||||
'second': 'nd'
|
|
||||||
NICETIME:
|
|
||||||
NO_DATE_PROVIDED: Aucune date
|
|
||||||
BAD_DATE: Date erronée
|
|
||||||
AGO: plus tôt
|
|
||||||
FROM_NOW: à partir de maintenant
|
|
||||||
SECOND: seconde
|
|
||||||
MINUTE: minute
|
|
||||||
HOUR: heure
|
|
||||||
DAY: jour
|
|
||||||
WEEK: semaine
|
|
||||||
MONTH: mois
|
|
||||||
YEAR: an
|
|
||||||
DECADE: décennie
|
|
||||||
SEC: s
|
|
||||||
MIN: m
|
|
||||||
HR: h
|
|
||||||
DAY: j
|
|
||||||
WK: s
|
|
||||||
MO: m
|
|
||||||
YR: a
|
|
||||||
DEC: d
|
|
||||||
SECOND_PLURAL: secondes
|
|
||||||
MINUTE_PLURAL: minutes
|
|
||||||
HOUR_PLURAL: heures
|
|
||||||
DAY_PLURAL: jours
|
|
||||||
WEEK_PLURAL: semaines
|
|
||||||
MONTH_PLURAL: mois
|
|
||||||
YEAR_PLURAL: ans
|
|
||||||
DECADE_PLURAL: décennies
|
|
||||||
SEC_PLURAL: s
|
|
||||||
MIN_PLURAL: m
|
|
||||||
HR_PLURAL: h
|
|
||||||
DAY_PLURAL: j
|
|
||||||
WK_PLURAL: s
|
|
||||||
MO_PLURAL: m
|
|
||||||
YR_PLURAL: a
|
|
||||||
DEC_PLURAL: d
|
|
|
@ -1,21 +0,0 @@
|
||||||
NICETIME:
|
|
||||||
NO_DATE_PROVIDED: Nessuna data fornita
|
|
||||||
BAD_DATE: Data errata
|
|
||||||
AGO: fa
|
|
||||||
FROM_NOW: da adesso
|
|
||||||
SECOND: secondo
|
|
||||||
MINUTE: minuto
|
|
||||||
HOUR: ora
|
|
||||||
DAY: giorno
|
|
||||||
WEEK: settimana
|
|
||||||
MONTH: mese
|
|
||||||
YEAR: anno
|
|
||||||
DECADE: decade
|
|
||||||
SECOND_PLURAL: secondi
|
|
||||||
MINUTE_PLURAL: minuti
|
|
||||||
HOUR_PLURAL: ore
|
|
||||||
DAY_PLURAL: giorni
|
|
||||||
WEEK_PLURAL: settimane
|
|
||||||
MONTH_PLURAL: mesi
|
|
||||||
YEAR_PLURAL: anni
|
|
||||||
DECADE_PLURAL: decadi
|
|
|
@ -1,43 +0,0 @@
|
||||||
INFLECTOR_IRREGULAR:
|
|
||||||
'person': 'personen'
|
|
||||||
'man': 'mensen'
|
|
||||||
'child': 'kinderen'
|
|
||||||
'sex': 'geslacht'
|
|
||||||
'move': 'verplaatsen'
|
|
||||||
NICETIME:
|
|
||||||
NO_DATE_PROVIDED: geen datum opgegeven
|
|
||||||
BAD_DATE: Datumformaat onjuist
|
|
||||||
AGO: geleden
|
|
||||||
FROM_NOW: vanaf nu
|
|
||||||
SECOND: seconde
|
|
||||||
MINUTE: minuut
|
|
||||||
HOUR: uur
|
|
||||||
DAY: dag
|
|
||||||
WEEK: week
|
|
||||||
MONTH: maand
|
|
||||||
YEAR: jaar
|
|
||||||
DECADE: decenium
|
|
||||||
SEC: sec
|
|
||||||
MIN: min
|
|
||||||
HR: hr
|
|
||||||
DAY: dag
|
|
||||||
WK: wk
|
|
||||||
MO: ma
|
|
||||||
YR: yr
|
|
||||||
DEC: dec
|
|
||||||
SECOND_PLURAL: seconden
|
|
||||||
MINUTE_PLURAL: minuten
|
|
||||||
HOUR_PLURAL: uren
|
|
||||||
DAY_PLURAL: dagen
|
|
||||||
WEEK_PLURAL: weken
|
|
||||||
MONTH_PLURAL: maanden
|
|
||||||
YEAR_PLURAL: jaren
|
|
||||||
DECADE_PLURAL: decennia
|
|
||||||
SEC_PLURAL: seconden
|
|
||||||
MIN_PLURAL: minuten
|
|
||||||
HR_PLURAL: uren
|
|
||||||
DAY_PLURAL: dagen
|
|
||||||
WK_PLURAL: weken
|
|
||||||
MO_PLURAL: maanden
|
|
||||||
YR_PLURAL: jaren
|
|
||||||
DEC_PLURAL: decs
|
|
|
@ -1,43 +0,0 @@
|
||||||
INFLECTOR_IRREGULAR:
|
|
||||||
'person': 'люди'
|
|
||||||
'man': 'человек'
|
|
||||||
'child': 'ребенок'
|
|
||||||
'sex': 'пол'
|
|
||||||
'move': 'движется'
|
|
||||||
NICETIME:
|
|
||||||
NO_DATE_PROVIDED: Дата не указана
|
|
||||||
BAD_DATE: Неверная дата
|
|
||||||
AGO: назад
|
|
||||||
FROM_NOW: теперь
|
|
||||||
SECOND: секунда
|
|
||||||
MINUTE: минута
|
|
||||||
HOUR: час
|
|
||||||
DAY: день
|
|
||||||
WEEK: неделя
|
|
||||||
MONTH: месяц
|
|
||||||
YEAR: год
|
|
||||||
DECADE: десятилетие
|
|
||||||
SEC: с
|
|
||||||
MIN: мин
|
|
||||||
HR: ч
|
|
||||||
DAY: д
|
|
||||||
WK: нед
|
|
||||||
MO: мес
|
|
||||||
YR: г.
|
|
||||||
DEC: гг.
|
|
||||||
SECOND_PLURAL: секунды
|
|
||||||
MINUTE_PLURAL: минуты
|
|
||||||
HOUR_PLURAL: часы
|
|
||||||
DAY_PLURAL: дни
|
|
||||||
WEEK_PLURAL: недели
|
|
||||||
MONTH_PLURAL: месяцы
|
|
||||||
YEAR_PLURAL: годы
|
|
||||||
DECADE_PLURAL: десятилетия
|
|
||||||
SEC_PLURAL: с
|
|
||||||
MIN_PLURAL: мин
|
|
||||||
HR_PLURAL: ч
|
|
||||||
DAY_PLURAL: д
|
|
||||||
WK_PLURAL: нед
|
|
||||||
MO_PLURAL: мес
|
|
||||||
YR_PLURAL: г.
|
|
||||||
DEC_PLURAL: гг.
|
|
|
@ -1,130 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Backup;
|
|
||||||
|
|
||||||
use Grav\Common\GravTrait;
|
|
||||||
use Grav\Common\Filesystem\Folder;
|
|
||||||
use Grav\Common\Inflector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The ZipBackup class lets you create simple zip-backups of a grav site
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class ZipBackup
|
|
||||||
{
|
|
||||||
use GravTrait;
|
|
||||||
|
|
||||||
protected static $ignorePaths = [
|
|
||||||
'backup',
|
|
||||||
'cache',
|
|
||||||
'images',
|
|
||||||
'logs'
|
|
||||||
];
|
|
||||||
|
|
||||||
protected static $ignoreFolders = [
|
|
||||||
'.git',
|
|
||||||
'.svn',
|
|
||||||
'.hg',
|
|
||||||
'.idea'
|
|
||||||
];
|
|
||||||
|
|
||||||
public static function backup($destination = null, callable $messager = null)
|
|
||||||
{
|
|
||||||
if (!$destination) {
|
|
||||||
$destination = self::getGrav()['locator']->findResource('backup://', true);
|
|
||||||
|
|
||||||
if (!$destination)
|
|
||||||
throw new \RuntimeException('The backup folder is missing.');
|
|
||||||
|
|
||||||
Folder::mkdir($destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
$name = self::getGrav()['config']->get('site.title', basename(GRAV_ROOT));
|
|
||||||
|
|
||||||
$inflector = new Inflector();
|
|
||||||
|
|
||||||
if (is_dir($destination)) {
|
|
||||||
$date = date('YmdHis', time());
|
|
||||||
$filename = trim($inflector->hyphenize($name), '-') . '-' . $date . '.zip';
|
|
||||||
$destination = rtrim($destination, DS) . DS . $filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
$messager && $messager([
|
|
||||||
'type' => 'message',
|
|
||||||
'level' => 'info',
|
|
||||||
'message' => 'Creating new Backup "' . $destination . '"'
|
|
||||||
]);
|
|
||||||
$messager && $messager([
|
|
||||||
'type' => 'message',
|
|
||||||
'level' => 'info',
|
|
||||||
'message' => ''
|
|
||||||
]);
|
|
||||||
|
|
||||||
$zip = new \ZipArchive();
|
|
||||||
$zip->open($destination, \ZipArchive::CREATE);
|
|
||||||
|
|
||||||
static::folderToZip(GRAV_ROOT, $zip, strlen(rtrim(GRAV_ROOT, DS) . DS), $messager);
|
|
||||||
|
|
||||||
$messager && $messager([
|
|
||||||
'type' => 'progress',
|
|
||||||
'percentage' => false,
|
|
||||||
'complete' => true
|
|
||||||
]);
|
|
||||||
|
|
||||||
$messager && $messager([
|
|
||||||
'type' => 'message',
|
|
||||||
'level' => 'info',
|
|
||||||
'message' => ''
|
|
||||||
]);
|
|
||||||
$messager && $messager([
|
|
||||||
'type' => 'message',
|
|
||||||
'level' => 'info',
|
|
||||||
'message' => 'Saving and compressing archive...'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$zip->close();
|
|
||||||
|
|
||||||
return $destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $folder
|
|
||||||
* @param $zipFile
|
|
||||||
* @param $exclusiveLength
|
|
||||||
* @param $messager
|
|
||||||
*/
|
|
||||||
private static function folderToZip($folder, \ZipArchive &$zipFile, $exclusiveLength, callable $messager = null)
|
|
||||||
{
|
|
||||||
$handle = opendir($folder);
|
|
||||||
while (false !== $f = readdir($handle)) {
|
|
||||||
if ($f != '.' && $f != '..') {
|
|
||||||
$filePath = "$folder/$f";
|
|
||||||
// Remove prefix from file path before add to zip.
|
|
||||||
$localPath = substr($filePath, $exclusiveLength);
|
|
||||||
|
|
||||||
if (in_array($f, static::$ignoreFolders)) {
|
|
||||||
continue;
|
|
||||||
} elseif (in_array($localPath, static::$ignorePaths)) {
|
|
||||||
$zipFile->addEmptyDir($f);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_file($filePath)) {
|
|
||||||
$zipFile->addFile($filePath, $localPath);
|
|
||||||
|
|
||||||
$messager && $messager([
|
|
||||||
'type' => 'progress',
|
|
||||||
'percentage' => false,
|
|
||||||
'complete' => false
|
|
||||||
]);
|
|
||||||
} elseif (is_dir($filePath)) {
|
|
||||||
// Add sub-directory.
|
|
||||||
$zipFile->addEmptyDir($localPath);
|
|
||||||
static::folderToZip($filePath, $zipFile, $exclusiveLength, $messager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir($handle);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple wrapper for the very simple parse_user_agent() function
|
|
||||||
*/
|
|
||||||
class Browser
|
|
||||||
{
|
|
||||||
|
|
||||||
protected $useragent = [];
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$this->useragent = parse_user_agent();
|
|
||||||
} catch (\InvalidArgumentException $e) {
|
|
||||||
$this->useragent = parse_user_agent("Mozilla/5.0 (compatible; Unknown;)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBrowser()
|
|
||||||
{
|
|
||||||
return strtolower($this->useragent['browser']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPlatform()
|
|
||||||
{
|
|
||||||
return strtolower($this->useragent['platform']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLongVersion()
|
|
||||||
{
|
|
||||||
return $this->useragent['version'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVersion()
|
|
||||||
{
|
|
||||||
$version = explode('.', $this->getLongVersion());
|
|
||||||
return intval($version[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the request comes from a human, or from a bot/crawler
|
|
||||||
*/
|
|
||||||
public function isHuman()
|
|
||||||
{
|
|
||||||
$browser = $this->getBrowser();
|
|
||||||
if (empty($browser)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preg_match('~(bot|crawl)~i', $browser)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,314 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common;
|
|
||||||
|
|
||||||
use \Doctrine\Common\Cache\Cache as DoctrineCache;
|
|
||||||
use Grav\Common\Config\Config;
|
|
||||||
use Grav\Common\Filesystem\Folder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The GravCache object is used throughout Grav to store and retrieve cached data.
|
|
||||||
* It uses DoctrineCache library and supports a variety of caching mechanisms. Those include:
|
|
||||||
*
|
|
||||||
* APC
|
|
||||||
* XCache
|
|
||||||
* RedisCache
|
|
||||||
* MemCache
|
|
||||||
* MemCacheD
|
|
||||||
* FileSystem
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class Cache extends Getters
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var string Cache key.
|
|
||||||
*/
|
|
||||||
protected $key;
|
|
||||||
|
|
||||||
protected $lifetime;
|
|
||||||
protected $now;
|
|
||||||
|
|
||||||
protected $config;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var DoctrineCache
|
|
||||||
*/
|
|
||||||
protected $driver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
protected $enabled;
|
|
||||||
|
|
||||||
protected $cache_dir;
|
|
||||||
|
|
||||||
protected static $standard_remove = [
|
|
||||||
'cache/twig/',
|
|
||||||
'cache/doctrine/',
|
|
||||||
'cache/compiled/',
|
|
||||||
'cache/validated-',
|
|
||||||
'images/',
|
|
||||||
'assets/',
|
|
||||||
];
|
|
||||||
|
|
||||||
protected static $all_remove = [
|
|
||||||
'cache/',
|
|
||||||
'images/',
|
|
||||||
'assets/'
|
|
||||||
];
|
|
||||||
|
|
||||||
protected static $assets_remove = [
|
|
||||||
'assets/'
|
|
||||||
];
|
|
||||||
|
|
||||||
protected static $images_remove = [
|
|
||||||
'images/'
|
|
||||||
];
|
|
||||||
|
|
||||||
protected static $cache_remove = [
|
|
||||||
'cache/'
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @params Grav $grav
|
|
||||||
*/
|
|
||||||
public function __construct(Grav $grav)
|
|
||||||
{
|
|
||||||
$this->init($grav);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization that sets a base key and the driver based on configuration settings
|
|
||||||
*
|
|
||||||
* @param Grav $grav
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function init(Grav $grav)
|
|
||||||
{
|
|
||||||
/** @var Config $config */
|
|
||||||
$this->config = $grav['config'];
|
|
||||||
$this->now = time();
|
|
||||||
|
|
||||||
$this->cache_dir = $grav['locator']->findResource('cache://doctrine', true, true);
|
|
||||||
|
|
||||||
/** @var Uri $uri */
|
|
||||||
$uri = $grav['uri'];
|
|
||||||
|
|
||||||
$prefix = $this->config->get('system.cache.prefix');
|
|
||||||
|
|
||||||
$this->enabled = (bool) $this->config->get('system.cache.enabled');
|
|
||||||
|
|
||||||
// Cache key allows us to invalidate all cache on configuration changes.
|
|
||||||
$this->key = ($prefix ? $prefix : 'g') . '-' . substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8);
|
|
||||||
|
|
||||||
$this->driver = $this->getCacheDriver();
|
|
||||||
|
|
||||||
// Set the cache namespace to our unique key
|
|
||||||
$this->driver->setNamespace($this->key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Automatically picks the cache mechanism to use. If you pick one manually it will use that
|
|
||||||
* If there is no config option for $driver in the config, or it's set to 'auto', it will
|
|
||||||
* pick the best option based on which cache extensions are installed.
|
|
||||||
*
|
|
||||||
* @return DoctrineCacheDriver The cache driver to use
|
|
||||||
*/
|
|
||||||
public function getCacheDriver()
|
|
||||||
{
|
|
||||||
$setting = $this->config->get('system.cache.driver');
|
|
||||||
$driver_name = 'file';
|
|
||||||
|
|
||||||
if (!$setting || $setting == 'auto') {
|
|
||||||
if (extension_loaded('apc')) {
|
|
||||||
$driver_name = 'apc';
|
|
||||||
} elseif (extension_loaded('wincache')) {
|
|
||||||
$driver_name = 'wincache';
|
|
||||||
} elseif (extension_loaded('xcache')) {
|
|
||||||
$driver_name = 'xcache';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$driver_name = $setting;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($driver_name) {
|
|
||||||
case 'apc':
|
|
||||||
$driver = new \Doctrine\Common\Cache\ApcCache();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'wincache':
|
|
||||||
$driver = new \Doctrine\Common\Cache\WinCacheCache();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'xcache':
|
|
||||||
$driver = new \Doctrine\Common\Cache\XcacheCache();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'memcache':
|
|
||||||
$memcache = new \Memcache();
|
|
||||||
$memcache->connect($this->config->get('system.cache.memcache.server','localhost'),
|
|
||||||
$this->config->get('system.cache.memcache.port', 11211));
|
|
||||||
$driver = new \Doctrine\Common\Cache\MemcacheCache();
|
|
||||||
$driver->setMemcache($memcache);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'redis':
|
|
||||||
$redis = new \Redis();
|
|
||||||
$redis->connect($this->config->get('system.cache.redis.server','localhost'),
|
|
||||||
$this->config->get('system.cache.redis.port', 6379));
|
|
||||||
|
|
||||||
$driver = new \Doctrine\Common\Cache\RedisCache();
|
|
||||||
$driver->setRedis($redis);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$driver = new \Doctrine\Common\Cache\FilesystemCache($this->cache_dir);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a cached entry if it exists based on an id. If it does not exist, it returns false
|
|
||||||
*
|
|
||||||
* @param string $id the id of the cached entry
|
|
||||||
* @return object returns the cached entry, can be any type, or false if doesn't exist
|
|
||||||
*/
|
|
||||||
public function fetch($id)
|
|
||||||
{
|
|
||||||
if ($this->enabled) {
|
|
||||||
return $this->driver->fetch($id);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores a new cached entry.
|
|
||||||
*
|
|
||||||
* @param string $id the id of the cached entry
|
|
||||||
* @param array|object $data the data for the cached entry to store
|
|
||||||
* @param int $lifetime the lifetime to store the entry in seconds
|
|
||||||
*/
|
|
||||||
public function save($id, $data, $lifetime = null)
|
|
||||||
{
|
|
||||||
if ($this->enabled) {
|
|
||||||
if ($lifetime === null) {
|
|
||||||
$lifetime = $this->getLifetime();
|
|
||||||
}
|
|
||||||
$this->driver->save($id, $data, $lifetime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter method to get the cache key
|
|
||||||
*/
|
|
||||||
public function getKey()
|
|
||||||
{
|
|
||||||
return $this->key;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to clear all Grav caches
|
|
||||||
*
|
|
||||||
* @param string $remove standard|all|assets-only|images-only|cache-only
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function clearCache($remove = 'standard')
|
|
||||||
{
|
|
||||||
|
|
||||||
$output = [];
|
|
||||||
$user_config = USER_DIR . 'config/system.yaml';
|
|
||||||
|
|
||||||
switch($remove) {
|
|
||||||
case 'all':
|
|
||||||
$remove_paths = self::$all_remove;
|
|
||||||
break;
|
|
||||||
case 'assets-only':
|
|
||||||
$remove_paths = self::$assets_remove;
|
|
||||||
break;
|
|
||||||
case 'images-only':
|
|
||||||
$remove_paths = self::$images_remove;
|
|
||||||
break;
|
|
||||||
case 'cache-only':
|
|
||||||
$remove_paths = self::$cache_remove;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$remove_paths = self::$standard_remove;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
foreach ($remove_paths as $path) {
|
|
||||||
|
|
||||||
$anything = false;
|
|
||||||
$files = glob(ROOT_DIR . $path . '*');
|
|
||||||
|
|
||||||
if (is_array($files)) {
|
|
||||||
foreach ($files as $file) {
|
|
||||||
if (is_file($file)) {
|
|
||||||
if (@unlink($file)) {
|
|
||||||
$anything = true;
|
|
||||||
}
|
|
||||||
} elseif (is_dir($file)) {
|
|
||||||
if (@Folder::delete($file)) {
|
|
||||||
$anything = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($anything) {
|
|
||||||
$output[] = '<red>Cleared: </red>' . $path . '*';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$output[] = '';
|
|
||||||
|
|
||||||
if (($remove == 'all' || $remove == 'standard') && file_exists($user_config)) {
|
|
||||||
touch($user_config);
|
|
||||||
|
|
||||||
$output[] = '<red>Touched: </red>' . $user_config;
|
|
||||||
$output[] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the cache lifetime programmatically
|
|
||||||
*
|
|
||||||
* @param int $future timestamp
|
|
||||||
*/
|
|
||||||
public function setLifetime($future)
|
|
||||||
{
|
|
||||||
if (!$future) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$interval = $future - $this->now;
|
|
||||||
if ($interval > 0 && $interval < $this->getLifetime()) {
|
|
||||||
$this->lifetime = $interval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the cache lifetime (in seconds)
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getLifetime()
|
|
||||||
{
|
|
||||||
if ($this->lifetime === null) {
|
|
||||||
$this->lifetime = $this->config->get('system.cache.lifetime') ?: 604800; // 1 week default
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->lifetime;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Grav\Common;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Offers composer helper methods.
|
|
||||||
*
|
|
||||||
* @author eschmar
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class Composer
|
|
||||||
{
|
|
||||||
/** @const Default composer location */
|
|
||||||
const DEFAULT_PATH = "bin/composer.phar";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the location of composer.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function getComposerLocation()
|
|
||||||
{
|
|
||||||
if (!function_exists('shell_exec') || strtolower(substr(PHP_OS, 0, 3)) === 'win') {
|
|
||||||
return self::DEFAULT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for global composer install
|
|
||||||
$path = trim(shell_exec("command -v composer"));
|
|
||||||
|
|
||||||
// fall back to grav bundled composer
|
|
||||||
if (!$path || !preg_match('/(composer|composer\.phar)$/', $path)) {
|
|
||||||
$path = self::DEFAULT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getComposerExecutor()
|
|
||||||
{
|
|
||||||
$executor = PHP_BINARY . ' ';
|
|
||||||
$composer = static::getComposerLocation();
|
|
||||||
|
|
||||||
if ($composer !== static::DEFAULT_PATH && is_executable($composer)) {
|
|
||||||
$file = fopen($composer, 'r');
|
|
||||||
$firstLine = fgets($file);
|
|
||||||
fclose($file);
|
|
||||||
|
|
||||||
if (!preg_match('/^#!.+php/i', $firstLine)) {
|
|
||||||
$executor = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $executor . $composer;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,207 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Config;
|
|
||||||
|
|
||||||
use Grav\Common\File\CompiledYamlFile;
|
|
||||||
use Grav\Common\Grav;
|
|
||||||
use Grav\Common\Filesystem\Folder;
|
|
||||||
use RocketTheme\Toolbox\Blueprints\Blueprints as BaseBlueprints;
|
|
||||||
use RocketTheme\Toolbox\File\PhpFile;
|
|
||||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Blueprints class contains configuration rules.
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class Blueprints extends BaseBlueprints
|
|
||||||
{
|
|
||||||
protected $grav;
|
|
||||||
protected $files = [];
|
|
||||||
protected $blueprints;
|
|
||||||
|
|
||||||
public function __construct(array $serialized = null, Grav $grav = null)
|
|
||||||
{
|
|
||||||
parent::__construct($serialized);
|
|
||||||
$this->grav = $grav ?: Grav::instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function init()
|
|
||||||
{
|
|
||||||
/** @var UniformResourceLocator $locator */
|
|
||||||
$locator = $this->grav['locator'];
|
|
||||||
|
|
||||||
$blueprints = $locator->findResources('blueprints://config');
|
|
||||||
$plugins = $locator->findResources('plugins://');
|
|
||||||
|
|
||||||
$blueprintFiles = $this->getBlueprintFiles($blueprints, $plugins);
|
|
||||||
|
|
||||||
$this->loadCompiledBlueprints($plugins + $blueprints, $blueprintFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function loadCompiledBlueprints($blueprints, $blueprintFiles)
|
|
||||||
{
|
|
||||||
$checksum = md5(serialize($blueprints));
|
|
||||||
$filename = CACHE_DIR . 'compiled/blueprints/' . $checksum .'.php';
|
|
||||||
$checksum .= ':'.md5(serialize($blueprintFiles));
|
|
||||||
$class = get_class($this);
|
|
||||||
$file = PhpFile::instance($filename);
|
|
||||||
|
|
||||||
if ($file->exists()) {
|
|
||||||
$cache = $file->exists() ? $file->content() : null;
|
|
||||||
} else {
|
|
||||||
$cache = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Load real file if cache isn't up to date (or is invalid).
|
|
||||||
if (
|
|
||||||
!is_array($cache)
|
|
||||||
|| empty($cache['checksum'])
|
|
||||||
|| empty($cache['$class'])
|
|
||||||
|| $cache['checksum'] != $checksum
|
|
||||||
|| $cache['@class'] != $class
|
|
||||||
) {
|
|
||||||
// Attempt to lock the file for writing.
|
|
||||||
$file->lock(false);
|
|
||||||
|
|
||||||
// Load blueprints.
|
|
||||||
$this->blueprints = new Blueprints();
|
|
||||||
foreach ($blueprintFiles as $key => $files) {
|
|
||||||
$this->loadBlueprints($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
$cache = [
|
|
||||||
'@class' => $class,
|
|
||||||
'checksum' => $checksum,
|
|
||||||
'files' => $blueprintFiles,
|
|
||||||
'data' => $this->blueprints->toArray()
|
|
||||||
];
|
|
||||||
|
|
||||||
// If compiled file wasn't already locked by another process, save it.
|
|
||||||
if ($file->locked() !== false) {
|
|
||||||
$file->save($cache);
|
|
||||||
$file->unlock();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$this->blueprints = new Blueprints($cache['data']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load global blueprints.
|
|
||||||
*
|
|
||||||
* @param string $key
|
|
||||||
* @param array $files
|
|
||||||
*/
|
|
||||||
public function loadBlueprints($key, array $files = null)
|
|
||||||
{
|
|
||||||
if (is_null($files)) {
|
|
||||||
$files = $this->files[$key];
|
|
||||||
}
|
|
||||||
foreach ($files as $name => $item) {
|
|
||||||
$file = CompiledYamlFile::instance($item['file']);
|
|
||||||
$this->blueprints->embed($name, $file->content(), '/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all blueprint files (including plugins).
|
|
||||||
*
|
|
||||||
* @param array $blueprints
|
|
||||||
* @param array $plugins
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getBlueprintFiles(array $blueprints, array $plugins)
|
|
||||||
{
|
|
||||||
$list = [];
|
|
||||||
foreach (array_reverse($plugins) as $folder) {
|
|
||||||
$list += $this->detectPlugins($folder, true);
|
|
||||||
}
|
|
||||||
foreach (array_reverse($blueprints) as $folder) {
|
|
||||||
$list += $this->detectConfig($folder, true);
|
|
||||||
}
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects all plugins with a configuration file and returns last modification time.
|
|
||||||
*
|
|
||||||
* @param string $lookup Location to look up from.
|
|
||||||
* @param bool $blueprints
|
|
||||||
* @return array
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function detectPlugins($lookup = SYSTEM_DIR, $blueprints = false)
|
|
||||||
{
|
|
||||||
$find = $blueprints ? 'blueprints.yaml' : '.yaml';
|
|
||||||
$location = $blueprints ? 'blueprintFiles' : 'configFiles';
|
|
||||||
$path = trim(Folder::getRelativePath($lookup), '/');
|
|
||||||
if (isset($this->{$location}[$path])) {
|
|
||||||
return [$path => $this->{$location}[$path]];
|
|
||||||
}
|
|
||||||
|
|
||||||
$list = [];
|
|
||||||
|
|
||||||
if (is_dir($lookup)) {
|
|
||||||
$iterator = new \DirectoryIterator($lookup);
|
|
||||||
|
|
||||||
/** @var \DirectoryIterator $directory */
|
|
||||||
foreach ($iterator as $directory) {
|
|
||||||
if (!$directory->isDir() || $directory->isDot()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$name = $directory->getBasename();
|
|
||||||
$filename = "{$path}/{$name}/" . ($find && $find[0] != '.' ? $find : $name . $find);
|
|
||||||
|
|
||||||
if (is_file($filename)) {
|
|
||||||
$list["plugins/{$name}"] = ['file' => $filename, 'modified' => filemtime($filename)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->{$location}[$path] = $list;
|
|
||||||
|
|
||||||
return [$path => $list];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects all plugins with a configuration file and returns last modification time.
|
|
||||||
*
|
|
||||||
* @param string $lookup Location to look up from.
|
|
||||||
* @param bool $blueprints
|
|
||||||
* @return array
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function detectConfig($lookup = SYSTEM_DIR, $blueprints = false)
|
|
||||||
{
|
|
||||||
$location = $blueprints ? 'blueprintFiles' : 'configFiles';
|
|
||||||
$path = trim(Folder::getRelativePath($lookup), '/');
|
|
||||||
if (isset($this->{$location}[$path])) {
|
|
||||||
return [$path => $this->{$location}[$path]];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_dir($lookup)) {
|
|
||||||
// Find all system and user configuration files.
|
|
||||||
$options = [
|
|
||||||
'compare' => 'Filename',
|
|
||||||
'pattern' => '|\.yaml$|',
|
|
||||||
'filters' => [
|
|
||||||
'key' => '|\.yaml$|',
|
|
||||||
'value' => function (\RecursiveDirectoryIterator $file) use ($path) {
|
|
||||||
return ['file' => "{$path}/{$file->getSubPathname()}", 'modified' => $file->getMTime()];
|
|
||||||
}],
|
|
||||||
'key' => 'SubPathname'
|
|
||||||
];
|
|
||||||
|
|
||||||
$list = Folder::all($lookup, $options);
|
|
||||||
} else {
|
|
||||||
$list = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->{$location}[$path] = $list;
|
|
||||||
|
|
||||||
return [$path => $list];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,479 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Config;
|
|
||||||
|
|
||||||
use Grav\Common\File\CompiledYamlFile;
|
|
||||||
use Grav\Common\Grav;
|
|
||||||
use Grav\Common\Data\Data;
|
|
||||||
use RocketTheme\Toolbox\Blueprints\Blueprints;
|
|
||||||
use RocketTheme\Toolbox\File\PhpFile;
|
|
||||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Config class contains configuration information.
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class Config extends Data
|
|
||||||
{
|
|
||||||
protected $grav;
|
|
||||||
protected $streams = [
|
|
||||||
'system' => [
|
|
||||||
'type' => 'ReadOnlyStream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['system'],
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'user' => [
|
|
||||||
'type' => 'ReadOnlyStream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['user'],
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'blueprints' => [
|
|
||||||
'type' => 'ReadOnlyStream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['user://blueprints', 'system/blueprints'],
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'config' => [
|
|
||||||
'type' => 'ReadOnlyStream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['user://config', 'system/config'],
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'plugins' => [
|
|
||||||
'type' => 'ReadOnlyStream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['user://plugins'],
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'plugin' => [
|
|
||||||
'type' => 'ReadOnlyStream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['user://plugins'],
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'themes' => [
|
|
||||||
'type' => 'ReadOnlyStream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['user://themes'],
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'languages' => [
|
|
||||||
'type' => 'ReadOnlyStream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['user://languages', 'system/languages'],
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'cache' => [
|
|
||||||
'type' => 'Stream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['cache'],
|
|
||||||
'images' => ['images']
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'log' => [
|
|
||||||
'type' => 'Stream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['logs']
|
|
||||||
]
|
|
||||||
],
|
|
||||||
'backup' => [
|
|
||||||
'type' => 'Stream',
|
|
||||||
'prefixes' => [
|
|
||||||
'' => ['backup']
|
|
||||||
]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
protected $setup = [];
|
|
||||||
|
|
||||||
protected $blueprintFiles = [];
|
|
||||||
protected $configFiles = [];
|
|
||||||
protected $languageFiles = [];
|
|
||||||
protected $checksum;
|
|
||||||
protected $timestamp;
|
|
||||||
|
|
||||||
protected $configLookup;
|
|
||||||
protected $blueprintLookup;
|
|
||||||
protected $pluginLookup;
|
|
||||||
protected $languagesLookup;
|
|
||||||
|
|
||||||
protected $finder;
|
|
||||||
protected $environment;
|
|
||||||
protected $messages = [];
|
|
||||||
|
|
||||||
protected $languages;
|
|
||||||
|
|
||||||
public function __construct(array $setup = array(), Grav $grav = null, $environment = null)
|
|
||||||
{
|
|
||||||
$this->grav = $grav ?: Grav::instance();
|
|
||||||
$this->finder = new ConfigFinder;
|
|
||||||
$this->environment = $environment ?: 'localhost';
|
|
||||||
$this->messages[] = 'Environment Name: ' . $this->environment;
|
|
||||||
|
|
||||||
// Make sure that
|
|
||||||
if (!isset($setup['streams']['schemes'])) {
|
|
||||||
$setup['streams']['schemes'] = [];
|
|
||||||
}
|
|
||||||
$setup['streams']['schemes'] += $this->streams;
|
|
||||||
|
|
||||||
$setup = $this->autoDetectEnvironmentConfig($setup);
|
|
||||||
|
|
||||||
$this->setup = $setup;
|
|
||||||
parent::__construct($setup);
|
|
||||||
|
|
||||||
$this->check();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function key()
|
|
||||||
{
|
|
||||||
return $this->checksum();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function reload()
|
|
||||||
{
|
|
||||||
$this->items = $this->setup;
|
|
||||||
$this->check();
|
|
||||||
$this->init();
|
|
||||||
$this->debug();
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function check()
|
|
||||||
{
|
|
||||||
$streams = isset($this->items['streams']['schemes']) ? $this->items['streams']['schemes'] : null;
|
|
||||||
if (!is_array($streams)) {
|
|
||||||
throw new \InvalidArgumentException('Configuration is missing streams.schemes!');
|
|
||||||
}
|
|
||||||
$diff = array_keys(array_diff_key($this->streams, $streams));
|
|
||||||
if ($diff) {
|
|
||||||
throw new \InvalidArgumentException(
|
|
||||||
sprintf('Configuration is missing keys %s from streams.schemes!', implode(', ', $diff))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function debug()
|
|
||||||
{
|
|
||||||
foreach ($this->messages as $message) {
|
|
||||||
$this->grav['debugger']->addMessage($message);
|
|
||||||
}
|
|
||||||
$this->messages = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function init()
|
|
||||||
{
|
|
||||||
/** @var UniformResourceLocator $locator */
|
|
||||||
$locator = $this->grav['locator'];
|
|
||||||
|
|
||||||
$this->configLookup = $locator->findResources('config://');
|
|
||||||
$this->blueprintLookup = $locator->findResources('blueprints://config');
|
|
||||||
$this->pluginLookup = $locator->findResources('plugins://');
|
|
||||||
|
|
||||||
|
|
||||||
$this->loadCompiledBlueprints($this->blueprintLookup, $this->pluginLookup, 'master');
|
|
||||||
$this->loadCompiledConfig($this->configLookup, $this->pluginLookup, 'master');
|
|
||||||
|
|
||||||
// process languages if supported
|
|
||||||
if ($this->get('system.languages.translations', true)) {
|
|
||||||
$this->languagesLookup = $locator->findResources('languages://');
|
|
||||||
$this->loadCompiledLanguages($this->languagesLookup, $this->pluginLookup, 'master');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->initializeLocator($locator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checksum()
|
|
||||||
{
|
|
||||||
if (empty($this->checksum)) {
|
|
||||||
$checkBlueprints = $this->get('system.cache.check.blueprints', false);
|
|
||||||
$checkLanguages = $this->get('system.cache.check.languages', false);
|
|
||||||
$checkConfig = $this->get('system.cache.check.config', true);
|
|
||||||
$checkSystem = $this->get('system.cache.check.system', true);
|
|
||||||
|
|
||||||
if (!$checkBlueprints && !$checkLanguages && !$checkConfig && !$checkSystem) {
|
|
||||||
$this->messages[] = 'Skip configuration timestamp check.';
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate checksum according to the configuration settings.
|
|
||||||
if (!$checkConfig) {
|
|
||||||
// Just check changes in system.yaml files and ignore all the other files.
|
|
||||||
$cc = $checkSystem ? $this->finder->locateConfigFile($this->configLookup, 'system') : [];
|
|
||||||
} else {
|
|
||||||
// Check changes in all configuration files.
|
|
||||||
$cc = $this->finder->locateConfigFiles($this->configLookup, $this->pluginLookup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($checkBlueprints) {
|
|
||||||
$cb = $this->finder->locateBlueprintFiles($this->blueprintLookup, $this->pluginLookup);
|
|
||||||
} else {
|
|
||||||
$cb = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($checkLanguages) {
|
|
||||||
$cl = $this->finder->locateLanguageFiles($this->languagesLookup, $this->pluginLookup);
|
|
||||||
} else {
|
|
||||||
$cl = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->checksum = md5(json_encode([$cc, $cb, $cl]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function autoDetectEnvironmentConfig($items)
|
|
||||||
{
|
|
||||||
$environment = $this->environment;
|
|
||||||
$env_stream = 'user://'.$environment.'/config';
|
|
||||||
|
|
||||||
if (file_exists(USER_DIR.$environment.'/config')) {
|
|
||||||
array_unshift($items['streams']['schemes']['config']['prefixes'][''], $env_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $items;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function loadCompiledBlueprints($blueprints, $plugins, $filename = null)
|
|
||||||
{
|
|
||||||
$checksum = md5(json_encode($blueprints));
|
|
||||||
$filename = $filename
|
|
||||||
? CACHE_DIR . 'compiled/blueprints/' . $filename . '-' . $this->environment . '.php'
|
|
||||||
: CACHE_DIR . 'compiled/blueprints/' . $checksum . '-' . $this->environment . '.php';
|
|
||||||
$file = PhpFile::instance($filename);
|
|
||||||
$cache = $file->exists() ? $file->content() : null;
|
|
||||||
$blueprintFiles = $this->finder->locateBlueprintFiles($blueprints, $plugins);
|
|
||||||
$checksum .= ':'.md5(json_encode($blueprintFiles));
|
|
||||||
$class = get_class($this);
|
|
||||||
|
|
||||||
// Load real file if cache isn't up to date (or is invalid).
|
|
||||||
if (
|
|
||||||
!is_array($cache)
|
|
||||||
|| !isset($cache['checksum'])
|
|
||||||
|| !isset($cache['@class'])
|
|
||||||
|| $cache['checksum'] != $checksum
|
|
||||||
|| $cache['@class'] != $class
|
|
||||||
) {
|
|
||||||
// Attempt to lock the file for writing.
|
|
||||||
$file->lock(false);
|
|
||||||
|
|
||||||
// Load blueprints.
|
|
||||||
$this->blueprints = new Blueprints;
|
|
||||||
foreach ($blueprintFiles as $files) {
|
|
||||||
$this->loadBlueprintFiles($files);
|
|
||||||
}
|
|
||||||
|
|
||||||
$cache = [
|
|
||||||
'@class' => $class,
|
|
||||||
'checksum' => $checksum,
|
|
||||||
'files' => $blueprintFiles,
|
|
||||||
'data' => $this->blueprints->toArray()
|
|
||||||
];
|
|
||||||
// If compiled file wasn't already locked by another process, save it.
|
|
||||||
if ($file->locked() !== false) {
|
|
||||||
$this->messages[] = 'Saving compiled blueprints.';
|
|
||||||
$file->save($cache);
|
|
||||||
$file->unlock();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$this->blueprints = new Blueprints($cache['data']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function loadCompiledConfig($configs, $plugins, $filename = null)
|
|
||||||
{
|
|
||||||
$filename = $filename
|
|
||||||
? CACHE_DIR . 'compiled/config/' . $filename . '-' . $this->environment . '.php'
|
|
||||||
: CACHE_DIR . 'compiled/config/' . $checksum . '-' . $this->environment . '.php';
|
|
||||||
$file = PhpFile::instance($filename);
|
|
||||||
$cache = $file->exists() ? $file->content() : null;
|
|
||||||
$class = get_class($this);
|
|
||||||
$checksum = $this->checksum();
|
|
||||||
|
|
||||||
if (
|
|
||||||
!is_array($cache)
|
|
||||||
|| !isset($cache['checksum'])
|
|
||||||
|| !isset($cache['@class'])
|
|
||||||
|| $cache['@class'] != $class
|
|
||||||
) {
|
|
||||||
$this->messages[] = 'No cached configuration, compiling new configuration..';
|
|
||||||
} else if ($cache['checksum'] !== $checksum) {
|
|
||||||
$this->messages[] = 'Configuration checksum mismatch, reloading configuration..';
|
|
||||||
} else {
|
|
||||||
$this->messages[] = 'Configuration checksum matches, using cached version.';
|
|
||||||
|
|
||||||
$this->items = $cache['data'];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$configFiles = $this->finder->locateConfigFiles($configs, $plugins);
|
|
||||||
|
|
||||||
// Attempt to lock the file for writing.
|
|
||||||
$file->lock(false);
|
|
||||||
|
|
||||||
// Load configuration.
|
|
||||||
foreach ($configFiles as $files) {
|
|
||||||
$this->loadConfigFiles($files);
|
|
||||||
}
|
|
||||||
$cache = [
|
|
||||||
'@class' => $class,
|
|
||||||
'timestamp' => time(),
|
|
||||||
'checksum' => $checksum,
|
|
||||||
'data' => $this->toArray()
|
|
||||||
];
|
|
||||||
|
|
||||||
// If compiled file wasn't already locked by another process, save it.
|
|
||||||
if ($file->locked() !== false) {
|
|
||||||
$this->messages[] = 'Saving compiled configuration.';
|
|
||||||
$file->save($cache);
|
|
||||||
$file->unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->items = $cache['data'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $languages
|
|
||||||
* @param $plugins
|
|
||||||
* @param null $filename
|
|
||||||
*/
|
|
||||||
protected function loadCompiledLanguages($languages, $plugins, $filename = null)
|
|
||||||
{
|
|
||||||
$checksum = md5(json_encode($languages));
|
|
||||||
$filename = $filename
|
|
||||||
? CACHE_DIR . 'compiled/languages/' . $filename . '-' . $this->environment . '.php'
|
|
||||||
: CACHE_DIR . 'compiled/languages/' . $checksum . '-' . $this->environment . '.php';
|
|
||||||
$file = PhpFile::instance($filename);
|
|
||||||
$cache = $file->exists() ? $file->content() : null;
|
|
||||||
$languageFiles = $this->finder->locateLanguageFiles($languages, $plugins);
|
|
||||||
$checksum .= ':' . md5(json_encode($languageFiles));
|
|
||||||
$class = get_class($this);
|
|
||||||
|
|
||||||
// Load real file if cache isn't up to date (or is invalid).
|
|
||||||
if (
|
|
||||||
!is_array($cache)
|
|
||||||
|| !isset($cache['checksum'])
|
|
||||||
|| !isset($cache['@class'])
|
|
||||||
|| $cache['checksum'] != $checksum
|
|
||||||
|| $cache['@class'] != $class
|
|
||||||
) {
|
|
||||||
// Attempt to lock the file for writing.
|
|
||||||
$file->lock(false);
|
|
||||||
|
|
||||||
// Load languages.
|
|
||||||
$this->languages = new Languages;
|
|
||||||
$pluginPaths = str_ireplace(GRAV_ROOT . '/', '', array_reverse($plugins));
|
|
||||||
foreach ($pluginPaths as $path) {
|
|
||||||
if (isset($languageFiles[$path])) {
|
|
||||||
foreach ((array) $languageFiles[$path] as $plugin => $item) {
|
|
||||||
$lang_file = CompiledYamlFile::instance($item['file']);
|
|
||||||
$content = $lang_file->content();
|
|
||||||
$this->languages->mergeRecursive($content);
|
|
||||||
}
|
|
||||||
unset($languageFiles[$path]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($languageFiles as $location) {
|
|
||||||
foreach ($location as $lang => $item) {
|
|
||||||
$lang_file = CompiledYamlFile::instance($item['file']);
|
|
||||||
$content = $lang_file->content();
|
|
||||||
$this->languages->join($lang, $content, '/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$cache = [
|
|
||||||
'@class' => $class,
|
|
||||||
'checksum' => $checksum,
|
|
||||||
'files' => $languageFiles,
|
|
||||||
'data' => $this->languages->toArray()
|
|
||||||
];
|
|
||||||
// If compiled file wasn't already locked by another process, save it.
|
|
||||||
if ($file->locked() !== false) {
|
|
||||||
$this->messages[] = 'Saving compiled languages.';
|
|
||||||
$file->save($cache);
|
|
||||||
$file->unlock();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$this->languages = new Languages($cache['data']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load blueprints.
|
|
||||||
*
|
|
||||||
* @param array $files
|
|
||||||
*/
|
|
||||||
public function loadBlueprintFiles(array $files)
|
|
||||||
{
|
|
||||||
foreach ($files as $name => $item) {
|
|
||||||
$file = CompiledYamlFile::instance($item['file']);
|
|
||||||
$this->blueprints->embed($name, $file->content(), '/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load configuration.
|
|
||||||
*
|
|
||||||
* @param array $files
|
|
||||||
*/
|
|
||||||
public function loadConfigFiles(array $files)
|
|
||||||
{
|
|
||||||
foreach ($files as $name => $item) {
|
|
||||||
$file = CompiledYamlFile::instance($item['file']);
|
|
||||||
$this->join($name, $file->content(), '/');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize resource locator by using the configuration.
|
|
||||||
*
|
|
||||||
* @param UniformResourceLocator $locator
|
|
||||||
*/
|
|
||||||
public function initializeLocator(UniformResourceLocator $locator)
|
|
||||||
{
|
|
||||||
$locator->reset();
|
|
||||||
|
|
||||||
$schemes = (array) $this->get('streams.schemes', []);
|
|
||||||
|
|
||||||
foreach ($schemes as $scheme => $config) {
|
|
||||||
if (isset($config['paths'])) {
|
|
||||||
$locator->addPath($scheme, '', $config['paths']);
|
|
||||||
}
|
|
||||||
if (isset($config['prefixes'])) {
|
|
||||||
foreach ($config['prefixes'] as $prefix => $paths) {
|
|
||||||
$locator->addPath($scheme, $prefix, $paths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get available streams and their types from the configuration.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getStreams()
|
|
||||||
{
|
|
||||||
$schemes = [];
|
|
||||||
foreach ((array) $this->get('streams.schemes') as $scheme => $config) {
|
|
||||||
$type = !empty($config['type']) ? $config['type'] : 'ReadOnlyStream';
|
|
||||||
if ($type[0] != '\\') {
|
|
||||||
$type = '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
$schemes[$scheme] = $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $schemes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLanguages()
|
|
||||||
{
|
|
||||||
return $this->languages;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,186 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Config;
|
|
||||||
|
|
||||||
use Grav\Common\Filesystem\Folder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Configuration Finder class.
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class ConfigFinder
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Get all locations for blueprint files (including plugins).
|
|
||||||
*
|
|
||||||
* @param array $blueprints
|
|
||||||
* @param array $plugins
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function locateBlueprintFiles(array $blueprints, array $plugins)
|
|
||||||
{
|
|
||||||
$list = [];
|
|
||||||
foreach (array_reverse($plugins) as $folder) {
|
|
||||||
$list += $this->detectInFolder($folder, 'blueprints');
|
|
||||||
}
|
|
||||||
foreach (array_reverse($blueprints) as $folder) {
|
|
||||||
$list += $this->detectRecursive($folder);
|
|
||||||
}
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all locations for configuration files (including plugins).
|
|
||||||
*
|
|
||||||
* @param array $configs
|
|
||||||
* @param array $plugins
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function locateConfigFiles(array $configs, array $plugins)
|
|
||||||
{
|
|
||||||
$list = [];
|
|
||||||
foreach (array_reverse($plugins) as $folder) {
|
|
||||||
$list += $this->detectInFolder($folder);
|
|
||||||
}
|
|
||||||
foreach (array_reverse($configs) as $folder) {
|
|
||||||
$list += $this->detectRecursive($folder);
|
|
||||||
}
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function locateLanguageFiles(array $languages, array $plugins)
|
|
||||||
{
|
|
||||||
$list = [];
|
|
||||||
foreach (array_reverse($plugins) as $folder) {
|
|
||||||
$list += $this->detectLanguagesInFolder($folder, 'languages');
|
|
||||||
}
|
|
||||||
foreach (array_reverse($languages) as $folder) {
|
|
||||||
$list += $this->detectRecursive($folder);
|
|
||||||
}
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all locations for a single configuration file.
|
|
||||||
*
|
|
||||||
* @param array $folders Locations to look up from.
|
|
||||||
* @param string $name Filename to be located.
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function locateConfigFile(array $folders, $name)
|
|
||||||
{
|
|
||||||
$filename = "{$name}.yaml";
|
|
||||||
|
|
||||||
$list = [];
|
|
||||||
foreach ($folders as $folder) {
|
|
||||||
$path = trim(Folder::getRelativePath($folder), '/');
|
|
||||||
|
|
||||||
if (is_file("{$folder}/{$filename}")) {
|
|
||||||
$modified = filemtime("{$folder}/{$filename}");
|
|
||||||
} else {
|
|
||||||
$modified = 0;
|
|
||||||
}
|
|
||||||
$list[$path] = [$name => ['file' => "{$path}/{$filename}", 'modified' => $modified]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects all plugins with a configuration file and returns them with last modification time.
|
|
||||||
*
|
|
||||||
* @param string $folder Location to look up from.
|
|
||||||
* @param string $lookup Filename to be located.
|
|
||||||
* @return array
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function detectInFolder($folder, $lookup = null)
|
|
||||||
{
|
|
||||||
$path = trim(Folder::getRelativePath($folder), '/');
|
|
||||||
|
|
||||||
$list = [];
|
|
||||||
|
|
||||||
if (is_dir($folder)) {
|
|
||||||
$iterator = new \FilesystemIterator($folder);
|
|
||||||
|
|
||||||
/** @var \DirectoryIterator $directory */
|
|
||||||
foreach ($iterator as $directory) {
|
|
||||||
if (!$directory->isDir()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$name = $directory->getBasename();
|
|
||||||
$find = ($lookup ?: $name) . '.yaml';
|
|
||||||
$filename = "{$path}/{$name}/$find";
|
|
||||||
|
|
||||||
if (file_exists($filename)) {
|
|
||||||
$list["plugins/{$name}"] = ['file' => $filename, 'modified' => filemtime($filename)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [$path => $list];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function detectLanguagesInFolder($folder, $lookup = null)
|
|
||||||
{
|
|
||||||
$path = trim(Folder::getRelativePath($folder), '/');
|
|
||||||
|
|
||||||
$list = [];
|
|
||||||
|
|
||||||
if (is_dir($folder)) {
|
|
||||||
$iterator = new \FilesystemIterator($folder);
|
|
||||||
|
|
||||||
/** @var \DirectoryIterator $directory */
|
|
||||||
foreach ($iterator as $directory) {
|
|
||||||
if (!$directory->isDir()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$name = $directory->getBasename();
|
|
||||||
$find = ($lookup ?: $name) . '.yaml';
|
|
||||||
$filename = "{$path}/{$name}/$find";
|
|
||||||
|
|
||||||
if (file_exists($filename)) {
|
|
||||||
$list[$name] = ['file' => $filename, 'modified' => filemtime($filename)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [$path => $list];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects all plugins with a configuration file and returns them with last modification time.
|
|
||||||
*
|
|
||||||
* @param string $folder Location to look up from.
|
|
||||||
* @return array
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function detectRecursive($folder)
|
|
||||||
{
|
|
||||||
$path = trim(Folder::getRelativePath($folder), '/');
|
|
||||||
|
|
||||||
if (is_dir($folder)) {
|
|
||||||
// Find all system and user configuration files.
|
|
||||||
$options = [
|
|
||||||
'compare' => 'Filename',
|
|
||||||
'pattern' => '|\.yaml$|',
|
|
||||||
'filters' => [
|
|
||||||
'key' => '|\.yaml$|',
|
|
||||||
'value' => function (\RecursiveDirectoryIterator $file) use ($path) {
|
|
||||||
return ['file' => "{$path}/{$file->getSubPathname()}", 'modified' => $file->getMTime()];
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'key' => 'SubPathname'
|
|
||||||
];
|
|
||||||
|
|
||||||
$list = Folder::all($folder, $options);
|
|
||||||
} else {
|
|
||||||
$list = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [$path => $list];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Config;
|
|
||||||
|
|
||||||
use Grav\Common\Data\Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Languages class contains configuration rules.
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class Languages extends Data
|
|
||||||
{
|
|
||||||
|
|
||||||
public function reformat()
|
|
||||||
{
|
|
||||||
if (isset($this->items['plugins'])) {
|
|
||||||
$this->items = array_merge_recursive($this->items, $this->items['plugins']);
|
|
||||||
unset($this->items['plugins']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function mergeRecursive(array $data)
|
|
||||||
{
|
|
||||||
$this->items = array_merge_recursive($this->items, $data);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,456 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Data;
|
|
||||||
|
|
||||||
use Grav\Common\GravTrait;
|
|
||||||
use RocketTheme\Toolbox\ArrayTraits\Export;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Blueprint handles the inside logic of blueprints.
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class Blueprint
|
|
||||||
{
|
|
||||||
use Export, DataMutatorTrait, GravTrait;
|
|
||||||
|
|
||||||
public $name;
|
|
||||||
|
|
||||||
public $initialized = false;
|
|
||||||
|
|
||||||
protected $items;
|
|
||||||
protected $context;
|
|
||||||
protected $fields;
|
|
||||||
protected $rules = array();
|
|
||||||
protected $nested = array();
|
|
||||||
protected $filter = ['validation' => 1];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $name
|
|
||||||
* @param array $data
|
|
||||||
* @param Blueprints $context
|
|
||||||
*/
|
|
||||||
public function __construct($name, array $data = array(), Blueprints $context = null)
|
|
||||||
{
|
|
||||||
$this->name = $name;
|
|
||||||
$this->items = $data;
|
|
||||||
$this->context = $context;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set filter for inherited properties.
|
|
||||||
*
|
|
||||||
* @param array $filter List of field names to be inherited.
|
|
||||||
*/
|
|
||||||
public function setFilter(array $filter)
|
|
||||||
{
|
|
||||||
$this->filter = array_flip($filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return all form fields.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function fields()
|
|
||||||
{
|
|
||||||
if (!isset($this->fields)) {
|
|
||||||
$this->fields = [];
|
|
||||||
$this->embed('', $this->items);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate data against blueprints.
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @throws \RuntimeException
|
|
||||||
*/
|
|
||||||
public function validate(array $data)
|
|
||||||
{
|
|
||||||
// Initialize data
|
|
||||||
$this->fields();
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->validateArray($data, $this->nested);
|
|
||||||
} catch (\RuntimeException $e) {
|
|
||||||
throw new \RuntimeException(sprintf('<b>Validation failed:</b> %s', $e->getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merge two arrays by using blueprints.
|
|
||||||
*
|
|
||||||
* @param array $data1
|
|
||||||
* @param array $data2
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function mergeData(array $data1, array $data2)
|
|
||||||
{
|
|
||||||
// Initialize data
|
|
||||||
$this->fields();
|
|
||||||
return $this->mergeArrays($data1, $data2, $this->nested);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter data by using blueprints.
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function filter(array $data)
|
|
||||||
{
|
|
||||||
// Initialize data
|
|
||||||
$this->fields();
|
|
||||||
return $this->filterArray($data, $this->nested);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return data fields that do not exist in blueprints.
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @param string $prefix
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function extra(array $data, $prefix = '')
|
|
||||||
{
|
|
||||||
// Initialize data
|
|
||||||
$this->fields();
|
|
||||||
$rules = $this->nested;
|
|
||||||
|
|
||||||
// Drill down to prefix level
|
|
||||||
if (!empty($prefix)) {
|
|
||||||
$parts = explode('.', trim($prefix, '.'));
|
|
||||||
foreach ($parts as $part) {
|
|
||||||
$rules = isset($rules[$part]) ? $rules[$part] : [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->extraArray($data, $rules, $prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extend blueprint with another blueprint.
|
|
||||||
*
|
|
||||||
* @param Blueprint $extends
|
|
||||||
* @param bool $append
|
|
||||||
*/
|
|
||||||
public function extend(Blueprint $extends, $append = false)
|
|
||||||
{
|
|
||||||
$blueprints = $append ? $this->items : $extends->toArray();
|
|
||||||
$appended = $append ? $extends->toArray() : $this->items;
|
|
||||||
|
|
||||||
$bref_stack = array(&$blueprints);
|
|
||||||
$head_stack = array($appended);
|
|
||||||
|
|
||||||
do {
|
|
||||||
end($bref_stack);
|
|
||||||
|
|
||||||
$bref = &$bref_stack[key($bref_stack)];
|
|
||||||
$head = array_pop($head_stack);
|
|
||||||
|
|
||||||
unset($bref_stack[key($bref_stack)]);
|
|
||||||
|
|
||||||
foreach (array_keys($head) as $key) {
|
|
||||||
if (isset($key, $bref[$key]) && is_array($bref[$key]) && is_array($head[$key])) {
|
|
||||||
$bref_stack[] = &$bref[$key];
|
|
||||||
$head_stack[] = $head[$key];
|
|
||||||
} else {
|
|
||||||
$bref = array_merge($bref, array($key => $head[$key]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (count($head_stack));
|
|
||||||
|
|
||||||
$this->items = $blueprints;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert object into an array.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getState()
|
|
||||||
{
|
|
||||||
return ['name' => $this->name, 'items' => $this->items, 'rules' => $this->rules, 'nested' => $this->nested];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Embed an array to the blueprint.
|
|
||||||
*
|
|
||||||
* @param $name
|
|
||||||
* @param array $value
|
|
||||||
* @param string $separator
|
|
||||||
*/
|
|
||||||
public function embed($name, array $value, $separator = '.')
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!isset($value['form']['fields']) || !is_array($value['form']['fields'])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Initialize data
|
|
||||||
$this->fields();
|
|
||||||
$prefix = $name ? strtr($name, $separator, '.') . '.' : '';
|
|
||||||
$params = array_intersect_key($this->filter, $value);
|
|
||||||
$this->parseFormFields($value['form']['fields'], $params, $prefix, $this->fields);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $data
|
|
||||||
* @param array $rules
|
|
||||||
* @throws \RuntimeException
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function validateArray(array $data, array $rules)
|
|
||||||
{
|
|
||||||
$this->checkRequired($data, $rules);
|
|
||||||
|
|
||||||
foreach ($data as $key => $field) {
|
|
||||||
$val = isset($rules[$key]) ? $rules[$key] : null;
|
|
||||||
$rule = is_string($val) ? $this->rules[$val] : null;
|
|
||||||
|
|
||||||
if ($rule) {
|
|
||||||
// Item has been defined in blueprints.
|
|
||||||
Validation::validate($field, $rule);
|
|
||||||
} elseif (is_array($field) && is_array($val)) {
|
|
||||||
// Array has been defined in blueprints.
|
|
||||||
$this->validateArray($field, $val);
|
|
||||||
} elseif (isset($this->items['form']['validation']) && $this->items['form']['validation'] == 'strict') {
|
|
||||||
// Undefined/extra item.
|
|
||||||
throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $data
|
|
||||||
* @param array $rules
|
|
||||||
* @return array
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function filterArray(array $data, array $rules)
|
|
||||||
{
|
|
||||||
$results = array();
|
|
||||||
foreach ($data as $key => $field) {
|
|
||||||
$val = isset($rules[$key]) ? $rules[$key] : null;
|
|
||||||
$rule = is_string($val) ? $this->rules[$val] : null;
|
|
||||||
|
|
||||||
if ($rule) {
|
|
||||||
// Item has been defined in blueprints.
|
|
||||||
if (is_array($field) && count($field) == 1 && reset($field) == '') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$field = Validation::filter($field, $rule);
|
|
||||||
} elseif (is_array($field) && is_array($val)) {
|
|
||||||
// Array has been defined in blueprints.
|
|
||||||
$field = $this->filterArray($field, $val);
|
|
||||||
} elseif (isset($this->items['form']['validation']) && $this->items['form']['validation'] == 'strict') {
|
|
||||||
$field = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($field) && (!is_array($field) || !empty($field))) {
|
|
||||||
$results[$key] = $field;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $data1
|
|
||||||
* @param array $data2
|
|
||||||
* @param array $rules
|
|
||||||
* @return array
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function mergeArrays(array $data1, array $data2, array $rules)
|
|
||||||
{
|
|
||||||
foreach ($data2 as $key => $field) {
|
|
||||||
$val = isset($rules[$key]) ? $rules[$key] : null;
|
|
||||||
$rule = is_string($val) ? $this->rules[$val] : null;
|
|
||||||
|
|
||||||
if (!$rule && array_key_exists($key, $data1) && is_array($field) && is_array($val)) {
|
|
||||||
// Array has been defined in blueprints.
|
|
||||||
$data1[$key] = $this->mergeArrays($data1[$key], $field, $val);
|
|
||||||
} else {
|
|
||||||
// Otherwise just take value from the data2.
|
|
||||||
$data1[$key] = $field;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $data
|
|
||||||
* @param array $rules
|
|
||||||
* @param string $prefix
|
|
||||||
* @return array
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function extraArray(array $data, array $rules, $prefix)
|
|
||||||
{
|
|
||||||
$array = array();
|
|
||||||
foreach ($data as $key => $field) {
|
|
||||||
$val = isset($rules[$key]) ? $rules[$key] : null;
|
|
||||||
$rule = is_string($val) ? $this->rules[$val] : null;
|
|
||||||
|
|
||||||
if ($rule) {
|
|
||||||
// Item has been defined in blueprints.
|
|
||||||
} elseif (is_array($field) && is_array($val)) {
|
|
||||||
// Array has been defined in blueprints.
|
|
||||||
$array += $this->ExtraArray($field, $val, $prefix . $key . '.');
|
|
||||||
} else {
|
|
||||||
// Undefined/extra item.
|
|
||||||
$array[$prefix.$key] = $field;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all field definitions from the blueprints.
|
|
||||||
*
|
|
||||||
* @param array $fields
|
|
||||||
* @param array $params
|
|
||||||
* @param string $prefix
|
|
||||||
* @param array $current
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function parseFormFields(array &$fields, $params, $prefix, array &$current)
|
|
||||||
{
|
|
||||||
// Go though all the fields in current level.
|
|
||||||
foreach ($fields as $key => &$field) {
|
|
||||||
$current[$key] = &$field;
|
|
||||||
// Set name from the array key.
|
|
||||||
$field['name'] = $prefix . $key;
|
|
||||||
$field += $params;
|
|
||||||
|
|
||||||
if (isset($field['fields']) && (!isset($field['type']) || $field['type'] !== 'list')) {
|
|
||||||
// Recursively get all the nested fields.
|
|
||||||
$newParams = array_intersect_key($this->filter, $field);
|
|
||||||
$this->parseFormFields($field['fields'], $newParams, $prefix, $current[$key]['fields']);
|
|
||||||
} else if ($field['type'] !== 'ignore') {
|
|
||||||
// Add rule.
|
|
||||||
$this->rules[$prefix . $key] = &$field;
|
|
||||||
$this->addProperty($prefix . $key);
|
|
||||||
|
|
||||||
foreach ($field as $name => $value) {
|
|
||||||
// Support nested blueprints.
|
|
||||||
if ($this->context && $name == '@import') {
|
|
||||||
$values = (array) $value;
|
|
||||||
if (!isset($field['fields'])) {
|
|
||||||
$field['fields'] = array();
|
|
||||||
}
|
|
||||||
foreach ($values as $bname) {
|
|
||||||
$b = $this->context->get($bname);
|
|
||||||
$field['fields'] = array_merge($field['fields'], $b->fields());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Support for callable data values.
|
|
||||||
elseif (substr($name, 0, 6) == '@data-') {
|
|
||||||
$property = substr($name, 6);
|
|
||||||
if (is_array($value)) {
|
|
||||||
$func = array_shift($value);
|
|
||||||
} else {
|
|
||||||
$func = $value;
|
|
||||||
$value = array();
|
|
||||||
}
|
|
||||||
list($o, $f) = preg_split('/::/', $func);
|
|
||||||
if (!$f && function_exists($o)) {
|
|
||||||
$data = call_user_func_array($o, $value);
|
|
||||||
} elseif ($f && method_exists($o, $f)) {
|
|
||||||
$data = call_user_func_array(array($o, $f), $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If function returns a value,
|
|
||||||
if (isset($data)) {
|
|
||||||
if (isset($field[$property]) && is_array($field[$property]) && is_array($data)) {
|
|
||||||
// Combine field and @data-field together.
|
|
||||||
$field[$property] += $data;
|
|
||||||
} else {
|
|
||||||
// Or create/replace field with @data-field.
|
|
||||||
$field[$property] = $data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
elseif (substr($name, 0, 8) == '@config-') {
|
|
||||||
$property = substr($name, 8);
|
|
||||||
$default = isset($field[$property]) ? $field[$property] : null;
|
|
||||||
$config = self::getGrav()['config']->get($value, $default);
|
|
||||||
|
|
||||||
if (!is_null($config)) {
|
|
||||||
$field[$property] = $config;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize predefined validation rule.
|
|
||||||
if (isset($field['validate']['rule']) && $field['type'] !== 'ignore') {
|
|
||||||
$field['validate'] += $this->getRule($field['validate']['rule']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add property to the definition.
|
|
||||||
*
|
|
||||||
* @param string $path Comma separated path to the property.
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function addProperty($path)
|
|
||||||
{
|
|
||||||
$parts = explode('.', $path);
|
|
||||||
$item = array_pop($parts);
|
|
||||||
|
|
||||||
$nested = &$this->nested;
|
|
||||||
foreach ($parts as $part) {
|
|
||||||
if (!isset($nested[$part])) {
|
|
||||||
$nested[$part] = array();
|
|
||||||
}
|
|
||||||
$nested = &$nested[$part];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($nested[$item])) {
|
|
||||||
$nested[$item] = $path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $rule
|
|
||||||
* @return array
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function getRule($rule)
|
|
||||||
{
|
|
||||||
if (isset($this->items['rules'][$rule]) && is_array($this->items['rules'][$rule])) {
|
|
||||||
return $this->items['rules'][$rule];
|
|
||||||
}
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $data
|
|
||||||
* @param array $fields
|
|
||||||
* @throws \RuntimeException
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
protected function checkRequired(array $data, array $fields)
|
|
||||||
{
|
|
||||||
foreach ($fields as $name => $field) {
|
|
||||||
if (!is_string($field)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$field = $this->rules[$field];
|
|
||||||
if (isset($field['validate']['required'])
|
|
||||||
&& $field['validate']['required'] === true
|
|
||||||
&& empty($data[$name])) {
|
|
||||||
throw new \RuntimeException("Missing required field: {$field['name']}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,145 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Data;
|
|
||||||
|
|
||||||
use Grav\Common\File\CompiledYamlFile;
|
|
||||||
use Grav\Common\GravTrait;
|
|
||||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Blueprints class keeps track on blueprint instances.
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class Blueprints
|
|
||||||
{
|
|
||||||
use GravTrait;
|
|
||||||
|
|
||||||
protected $search;
|
|
||||||
protected $types;
|
|
||||||
protected $instances = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string|array $search Search path.
|
|
||||||
*/
|
|
||||||
public function __construct($search)
|
|
||||||
{
|
|
||||||
$this->search = $search;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get blueprint.
|
|
||||||
*
|
|
||||||
* @param string $type Blueprint type.
|
|
||||||
* @return Blueprint
|
|
||||||
* @throws \RuntimeException
|
|
||||||
*/
|
|
||||||
public function get($type)
|
|
||||||
{
|
|
||||||
if (!isset($this->instances[$type])) {
|
|
||||||
$parents = [];
|
|
||||||
if (is_string($this->search)) {
|
|
||||||
$filename = $this->search . $type . YAML_EXT;
|
|
||||||
|
|
||||||
// Check if search is a stream and resolve the path.
|
|
||||||
if (strpos($filename, '://')) {
|
|
||||||
$grav = static::getGrav();
|
|
||||||
/** @var UniformResourceLocator $locator */
|
|
||||||
$locator = $grav['locator'];
|
|
||||||
$parents = $locator->findResources($filename);
|
|
||||||
$filename = array_shift($parents);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$filename = isset($this->search[$type]) ? $this->search[$type] : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($filename && is_file($filename)) {
|
|
||||||
$file = CompiledYamlFile::instance($filename);
|
|
||||||
$blueprints = $file->content();
|
|
||||||
} else {
|
|
||||||
$blueprints = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$blueprint = new Blueprint($type, $blueprints, $this);
|
|
||||||
|
|
||||||
if (isset($blueprints['@extends'])) {
|
|
||||||
// Extend blueprint by other blueprints.
|
|
||||||
$extends = (array) $blueprints['@extends'];
|
|
||||||
|
|
||||||
if (is_string(key($extends))) {
|
|
||||||
$extends = [ $extends ];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($extends as $extendConfig) {
|
|
||||||
$extendType = !is_string($extendConfig) ? empty($extendConfig['type']) ? false : $extendConfig['type'] : $extendConfig;
|
|
||||||
|
|
||||||
if (!$extendType) {
|
|
||||||
continue;
|
|
||||||
} elseif ($extendType === '@parent') {
|
|
||||||
$parentFile = array_shift($parents);
|
|
||||||
if (!$parentFile || !is_file($parentFile)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$blueprints = CompiledYamlFile::instance($parentFile)->content();
|
|
||||||
$parent = new Blueprint($type.'-parent', $blueprints, $this);
|
|
||||||
$blueprint->extend($parent);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_string($extendConfig) || empty($extendConfig['context'])) {
|
|
||||||
$context = $this;
|
|
||||||
} else {
|
|
||||||
// Load blueprints from external context.
|
|
||||||
$array = explode('://', $extendConfig['context'], 2);
|
|
||||||
$scheme = array_shift($array);
|
|
||||||
$path = array_shift($array);
|
|
||||||
if ($path) {
|
|
||||||
$scheme .= '://';
|
|
||||||
$extendType = $path ? "{$path}/{$extendType}" : $extendType;
|
|
||||||
}
|
|
||||||
$context = new self($scheme);
|
|
||||||
}
|
|
||||||
$blueprint->extend($context->get($extendType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->instances[$type] = $blueprint;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->instances[$type];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all available blueprint types.
|
|
||||||
*
|
|
||||||
* @return array List of type=>name
|
|
||||||
*/
|
|
||||||
public function types()
|
|
||||||
{
|
|
||||||
if ($this->types === null) {
|
|
||||||
$this->types = array();
|
|
||||||
|
|
||||||
// Check if search is a stream.
|
|
||||||
if (strpos($this->search, '://')) {
|
|
||||||
// Stream: use UniformResourceIterator.
|
|
||||||
$grav = static::getGrav();
|
|
||||||
/** @var UniformResourceLocator $locator */
|
|
||||||
$locator = $grav['locator'];
|
|
||||||
$iterator = $locator->getIterator($this->search, null);
|
|
||||||
} else {
|
|
||||||
// Not a stream: use DirectoryIterator.
|
|
||||||
$iterator = new \DirectoryIterator($this->search);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var \DirectoryIterator $file */
|
|
||||||
foreach ($iterator as $file) {
|
|
||||||
if (!$file->isFile() || '.' . $file->getExtension() != YAML_EXT) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$name = $file->getBasename(YAML_EXT);
|
|
||||||
$this->types[$name] = ucfirst(strtr($name, '_', ' '));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $this->types;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,240 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Data;
|
|
||||||
|
|
||||||
use RocketTheme\Toolbox\ArrayTraits\ArrayAccessWithGetters;
|
|
||||||
use RocketTheme\Toolbox\ArrayTraits\Countable;
|
|
||||||
use RocketTheme\Toolbox\ArrayTraits\Export;
|
|
||||||
use RocketTheme\Toolbox\File\File;
|
|
||||||
use RocketTheme\Toolbox\File\FileInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursive data object
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class Data implements DataInterface
|
|
||||||
{
|
|
||||||
use ArrayAccessWithGetters, Countable, Export, DataMutatorTrait;
|
|
||||||
|
|
||||||
protected $gettersVariable = 'items';
|
|
||||||
protected $items;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Blueprints
|
|
||||||
*/
|
|
||||||
protected $blueprints;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var File
|
|
||||||
*/
|
|
||||||
protected $storage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $items
|
|
||||||
* @param Blueprint $blueprints
|
|
||||||
*/
|
|
||||||
public function __construct(array $items = array(), Blueprint $blueprints = null)
|
|
||||||
{
|
|
||||||
$this->items = $items;
|
|
||||||
|
|
||||||
$this->blueprints = $blueprints;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get value by using dot notation for nested arrays/objects.
|
|
||||||
*
|
|
||||||
* @example $value = $data->value('this.is.my.nested.variable');
|
|
||||||
*
|
|
||||||
* @param string $name Dot separated path to the requested value.
|
|
||||||
* @param mixed $default Default value (or null).
|
|
||||||
* @param string $separator Separator, defaults to '.'
|
|
||||||
* @return mixed Value.
|
|
||||||
*/
|
|
||||||
public function value($name, $default = null, $separator = '.')
|
|
||||||
{
|
|
||||||
return $this->get($name, $default, $separator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set default value by using dot notation for nested arrays/objects.
|
|
||||||
*
|
|
||||||
* @example $data->def('this.is.my.nested.variable', 'default');
|
|
||||||
*
|
|
||||||
* @param string $name Dot separated path to the requested value.
|
|
||||||
* @param mixed $default Default value (or null).
|
|
||||||
* @param string $separator Separator, defaults to '.'
|
|
||||||
*/
|
|
||||||
public function def($name, $default = null, $separator = '.')
|
|
||||||
{
|
|
||||||
$this->set($name, $this->get($name, $default, $separator), $separator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Join two values together by using blueprints if available.
|
|
||||||
*
|
|
||||||
* @param string $name Dot separated path to the requested value.
|
|
||||||
* @param mixed $value Value to be joined.
|
|
||||||
* @param string $separator Separator, defaults to '.'
|
|
||||||
*/
|
|
||||||
public function join($name, $value, $separator = '.')
|
|
||||||
{
|
|
||||||
$old = $this->get($name, null, $separator);
|
|
||||||
if ($old === null) {
|
|
||||||
// Variable does not exist yet: just use the incoming value.
|
|
||||||
} elseif ($this->blueprints) {
|
|
||||||
// Blueprints: join values by using blueprints.
|
|
||||||
$value = $this->blueprints->mergeData($old, $value, $name, $separator);
|
|
||||||
} else {
|
|
||||||
// No blueprints: replace existing top level variables with the new ones.
|
|
||||||
$value = array_merge($old, $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->set($name, $value, $separator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Join two values together by using blueprints if available.
|
|
||||||
*
|
|
||||||
* @param string $name Dot separated path to the requested value.
|
|
||||||
* @param mixed $value Value to be joined.
|
|
||||||
* @param string $separator Separator, defaults to '.'
|
|
||||||
*/
|
|
||||||
public function joinDefaults($name, $value, $separator = '.')
|
|
||||||
{
|
|
||||||
$old = $this->get($name, null, $separator);
|
|
||||||
if ($old === null) {
|
|
||||||
// Variable does not exist yet: just use the incoming value.
|
|
||||||
} elseif ($this->blueprints) {
|
|
||||||
// Blueprints: join values by using blueprints.
|
|
||||||
$value = $this->blueprints->mergeData($value, $old, $name, $separator);
|
|
||||||
} else {
|
|
||||||
// No blueprints: replace existing top level variables with the new ones.
|
|
||||||
$value = array_merge($value, $old);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->set($name, $value, $separator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merge two sets of data together.
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function merge(array $data)
|
|
||||||
{
|
|
||||||
if ($this->blueprints) {
|
|
||||||
$this->items = $this->blueprints->mergeData($this->items, $data);
|
|
||||||
} else {
|
|
||||||
$this->items = array_merge($this->items, $data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add default data to the set.
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function setDefaults(array $data)
|
|
||||||
{
|
|
||||||
if ($this->blueprints) {
|
|
||||||
$this->items = $this->blueprints->mergeData($data, $this->items);
|
|
||||||
} else {
|
|
||||||
$this->items = array_merge($data, $this->items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return blueprints.
|
|
||||||
*
|
|
||||||
* @return Blueprint
|
|
||||||
*/
|
|
||||||
public function blueprints()
|
|
||||||
{
|
|
||||||
return $this->blueprints;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate by blueprints.
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function validate()
|
|
||||||
{
|
|
||||||
if ($this->blueprints) {
|
|
||||||
$this->blueprints->validate($this->items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter all items by using blueprints.
|
|
||||||
*/
|
|
||||||
public function filter()
|
|
||||||
{
|
|
||||||
if ($this->blueprints) {
|
|
||||||
$this->items = $this->blueprints->filter($this->items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get extra items which haven't been defined in blueprints.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function extra()
|
|
||||||
{
|
|
||||||
return $this->blueprints ? $this->blueprints->extra($this->items) : array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save data if storage has been defined.
|
|
||||||
*/
|
|
||||||
public function save()
|
|
||||||
{
|
|
||||||
$file = $this->file();
|
|
||||||
if ($file) {
|
|
||||||
$file->save($this->items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the data already exists in the storage.
|
|
||||||
*
|
|
||||||
* NOTE: This method does not check if the data is current.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function exists()
|
|
||||||
{
|
|
||||||
return $this->file()->exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return unmodified data as raw string.
|
|
||||||
*
|
|
||||||
* NOTE: This function only returns data which has been saved to the storage.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function raw()
|
|
||||||
{
|
|
||||||
return $this->file()->raw();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set or get the data storage.
|
|
||||||
*
|
|
||||||
* @param FileInterface $storage Optionally enter a new storage.
|
|
||||||
* @return FileInterface
|
|
||||||
*/
|
|
||||||
public function file(FileInterface $storage = null)
|
|
||||||
{
|
|
||||||
if ($storage) {
|
|
||||||
$this->storage = $storage;
|
|
||||||
}
|
|
||||||
return $this->storage;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Data;
|
|
||||||
|
|
||||||
use RocketTheme\Toolbox\File\FileInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data interface
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
interface DataInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Get value by using dot notation for nested arrays/objects.
|
|
||||||
*
|
|
||||||
* @example $value = $data->value('this.is.my.nested.variable');
|
|
||||||
*
|
|
||||||
* @param string $name Dot separated path to the requested value.
|
|
||||||
* @param mixed $default Default value (or null).
|
|
||||||
* @param string $separator Separator, defaults to '.'
|
|
||||||
* @return mixed Value.
|
|
||||||
*/
|
|
||||||
public function value($name, $default = null, $separator = '.');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merge external data.
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function merge(array $data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return blueprints.
|
|
||||||
*/
|
|
||||||
public function blueprints();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate by blueprints.
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function validate();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter all items by using blueprints.
|
|
||||||
*/
|
|
||||||
public function filter();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get extra items which haven't been defined in blueprints.
|
|
||||||
*/
|
|
||||||
public function extra();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save data into the file.
|
|
||||||
*/
|
|
||||||
public function save();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set or get the data storage.
|
|
||||||
*
|
|
||||||
* @param FileInterface $storage Optionally enter a new storage.
|
|
||||||
* @return FileInterface
|
|
||||||
*/
|
|
||||||
public function file(FileInterface $storage = null);
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Data;
|
|
||||||
|
|
||||||
trait DataMutatorTrait
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get value by using dot notation for nested arrays/objects.
|
|
||||||
*
|
|
||||||
* @example $value = $data->get('this.is.my.nested.variable');
|
|
||||||
*
|
|
||||||
* @param string $name Dot separated path to the requested value.
|
|
||||||
* @param mixed $default Default value (or null).
|
|
||||||
* @param string $separator Separator, defaults to '.'
|
|
||||||
* @return mixed Value.
|
|
||||||
*/
|
|
||||||
public function get($name, $default = null, $separator = '.')
|
|
||||||
{
|
|
||||||
$path = explode($separator, $name);
|
|
||||||
$current = $this->items;
|
|
||||||
foreach ($path as $field) {
|
|
||||||
if (is_object($current) && isset($current->{$field})) {
|
|
||||||
$current = $current->{$field};
|
|
||||||
} elseif (is_array($current) && isset($current[$field])) {
|
|
||||||
$current = $current[$field];
|
|
||||||
} else {
|
|
||||||
return $default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set value by using dot notation for nested arrays/objects.
|
|
||||||
*
|
|
||||||
* @example $value = $data->set('this.is.my.nested.variable', true);
|
|
||||||
*
|
|
||||||
* @param string $name Dot separated path to the requested value.
|
|
||||||
* @param mixed $value New value.
|
|
||||||
* @param string $separator Separator, defaults to '.'
|
|
||||||
*/
|
|
||||||
public function set($name, $value, $separator = '.')
|
|
||||||
{
|
|
||||||
$path = explode($separator, $name);
|
|
||||||
$current = &$this->items;
|
|
||||||
foreach ($path as $field) {
|
|
||||||
if (is_object($current)) {
|
|
||||||
// Handle objects.
|
|
||||||
if (!isset($current->{$field})) {
|
|
||||||
$current->{$field} = array();
|
|
||||||
}
|
|
||||||
$current = &$current->{$field};
|
|
||||||
} else {
|
|
||||||
// Handle arrays and scalars.
|
|
||||||
if (!is_array($current)) {
|
|
||||||
$current = array($field => array());
|
|
||||||
} elseif (!isset($current[$field])) {
|
|
||||||
$current[$field] = array();
|
|
||||||
}
|
|
||||||
$current = &$current[$field];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$current = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,672 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common\Data;
|
|
||||||
use Grav\Common\GravTrait;
|
|
||||||
use Symfony\Component\Yaml\Exception\ParseException;
|
|
||||||
use Symfony\Component\Yaml\Parser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data validation.
|
|
||||||
*
|
|
||||||
* @author RocketTheme
|
|
||||||
* @license MIT
|
|
||||||
*/
|
|
||||||
class Validation
|
|
||||||
{
|
|
||||||
use GravTrait;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate value against a blueprint field definition.
|
|
||||||
*
|
|
||||||
* @param mixed $value
|
|
||||||
* @param array $field
|
|
||||||
* @throws \RuntimeException
|
|
||||||
*/
|
|
||||||
public static function validate($value, array $field)
|
|
||||||
{
|
|
||||||
$validate = isset($field['validate']) ? (array) $field['validate'] : array();
|
|
||||||
|
|
||||||
// If value isn't required, we will stop validation if empty value is given.
|
|
||||||
if (empty($validate['required']) && ($value === null || $value === '')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get language class
|
|
||||||
$language = self::getGrav()['language'];
|
|
||||||
|
|
||||||
// Validate type with fallback type text.
|
|
||||||
$type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type'];
|
|
||||||
$method = 'type'.strtr($type, '-', '_');
|
|
||||||
$name = ucfirst(isset($field['label']) ? $field['label'] : $field['name']);
|
|
||||||
$message = (string) isset($field['validate']['message']) ? $field['validate']['message'] : 'Invalid input in "' . $language->translate($name) . '""';
|
|
||||||
|
|
||||||
if (method_exists(__CLASS__, $method)) {
|
|
||||||
$success = self::$method($value, $validate, $field);
|
|
||||||
} else {
|
|
||||||
$success = self::typeText($value, $validate, $field);
|
|
||||||
}
|
|
||||||
if (!$success) {
|
|
||||||
throw new \RuntimeException($message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check individual rules
|
|
||||||
foreach ($validate as $rule => $params) {
|
|
||||||
$method = 'validate'.strtr($rule, '-', '_');
|
|
||||||
if (method_exists(__CLASS__, $method)) {
|
|
||||||
$success = self::$method($value, $params);
|
|
||||||
|
|
||||||
if (!$success) {
|
|
||||||
throw new \RuntimeException($message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter value against a blueprint field definition.
|
|
||||||
*
|
|
||||||
* @param mixed $value
|
|
||||||
* @param array $field
|
|
||||||
* @return mixed Filtered value.
|
|
||||||
*/
|
|
||||||
public static function filter($value, array $field)
|
|
||||||
{
|
|
||||||
$validate = isset($field['validate']) ? (array) $field['validate'] : array();
|
|
||||||
|
|
||||||
// If value isn't required, we will return null if empty value is given.
|
|
||||||
if (empty($validate['required']) && ($value === null || $value === '')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this is a YAML field, simply parse it and return the value
|
|
||||||
if (isset($field['yaml']) && $field['yaml'] === true) {
|
|
||||||
try {
|
|
||||||
$yaml = new Parser();
|
|
||||||
return $yaml->parse($value);
|
|
||||||
} catch (ParseException $e) {
|
|
||||||
throw new \RuntimeException($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate type with fallback type text.
|
|
||||||
$type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type'];
|
|
||||||
$method = 'filter'.strtr($type, '-', '_');
|
|
||||||
if (method_exists(__CLASS__, $method)) {
|
|
||||||
$value = self::$method($value, $validate, $field);
|
|
||||||
} else {
|
|
||||||
$value = self::filterText($value, $validate, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: text
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeText($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
if (!is_string($value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($params['min']) && strlen($value) < $params['min']) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($params['max']) && strlen($value) > $params['max']) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$min = isset($params['min']) ? $params['min'] : 0;
|
|
||||||
if (isset($params['step']) && (strlen($value) - $min) % $params['step'] == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!isset($params['multiline']) || !$params['multiline']) && preg_match('/\R/um', $value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterText($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return (string) $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterCommaList($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return is_array($value) ? $value : preg_split('/\s*,\s*/', $value, -1, PREG_SPLIT_NO_EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function typeCommaList($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return is_array($value) ? true : self::typeText($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: textarea
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeTextarea($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
if (!isset($params['multiline'])) {
|
|
||||||
$params['multiline'] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::typeText($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: password
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typePassword($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeText($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: hidden
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeHidden($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeText($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom input: checkbox list
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeCheckboxes($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeArray((array) $value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterCheckboxes($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::filterArray($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: checkbox
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeCheckbox($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
$value = (string) $value;
|
|
||||||
|
|
||||||
if (!isset($field['value'])) {
|
|
||||||
$field['value'] = 1;
|
|
||||||
}
|
|
||||||
if ($value && $value != $field['value']) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: radio
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeRadio($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeArray((array) $value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom input: toggle
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeToggle($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeArray((array) $value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: select
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeSelect($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeArray((array) $value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: number
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static function typeNumber($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
if (!is_numeric($value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($params['min']) && $value < $params['min']) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($params['max']) && $value > $params['max']) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$min = isset($params['min']) ? $params['min'] : 0;
|
|
||||||
if (isset($params['step']) && fmod($value - $min, $params['step']) == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterNumber($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return (int) $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterDateTime($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
$format = self::getGrav()['config']->get('system.pages.dateformat.default');
|
|
||||||
if ($format) {
|
|
||||||
$converted = new \DateTime($value);
|
|
||||||
return $converted->format($format);
|
|
||||||
}
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: range
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeRange($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeNumber($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterRange($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::filterNumber($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: color
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeColor($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return preg_match('/^\#[0-9a-fA-F]{3}[0-9a-fA-F]{3}?$/u', $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: email
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeEmail($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeText($value, $params, $field) && filter_var($value, FILTER_VALIDATE_EMAIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: url
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static function typeUrl($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeText($value, $params, $field) && filter_var($value, FILTER_VALIDATE_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: datetime
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeDatetime($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
if ($value instanceof \DateTime) {
|
|
||||||
return true;
|
|
||||||
} elseif (!is_string($value)) {
|
|
||||||
return false;
|
|
||||||
} elseif (!isset($params['format'])) {
|
|
||||||
return false !== strtotime($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
$dateFromFormat = \DateTime::createFromFormat($params['format'], $value);
|
|
||||||
|
|
||||||
return $dateFromFormat && $value === date($params['format'], $dateFromFormat->getTimestamp());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: datetime-local
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeDatetimeLocal($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return self::typeDatetime($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: date
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeDate($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
$params = array($params);
|
|
||||||
if (!isset($params['format'])) {
|
|
||||||
$params['format'] = 'Y-m-d';
|
|
||||||
}
|
|
||||||
return self::typeDatetime($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: time
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeTime($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
$params = array($params);
|
|
||||||
if (!isset($params['format'])) {
|
|
||||||
$params['format'] = 'H:i';
|
|
||||||
}
|
|
||||||
return self::typeDatetime($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: month
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeMonth($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
$params = array($params);
|
|
||||||
if (!isset($params['format'])) {
|
|
||||||
$params['format'] = 'Y-m';
|
|
||||||
}
|
|
||||||
return self::typeDatetime($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTML5 input: week
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeWeek($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
if (!isset($params['format']) && !preg_match('/^\d{4}-W\d{2}$/u', $value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return self::typeDatetime($value, $params, $field);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom input: array
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeArray($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
if (!is_array($value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($field['multiple'])) {
|
|
||||||
if (isset($params['min']) && count($value) < $params['min']) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($params['max']) && count($value) > $params['max']) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$min = isset($params['min']) ? $params['min'] : 0;
|
|
||||||
if (isset($params['step']) && (count($value) - $min) % $params['step'] == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$options = isset($field['options']) ? array_keys($field['options']) : array();
|
|
||||||
$values = isset($field['use']) && $field['use'] == 'keys' ? array_keys($value) : $value;
|
|
||||||
if ($options && array_diff($values, $options)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterArray($value, $params, $field)
|
|
||||||
{
|
|
||||||
$values = (array) $value;
|
|
||||||
$options = isset($field['options']) ? array_keys($field['options']) : array();
|
|
||||||
$multi = isset($field['multiple']) ? $field['multiple'] : false;
|
|
||||||
|
|
||||||
if ($options) {
|
|
||||||
$useKey = isset($field['use']) && $field['use'] == 'keys';
|
|
||||||
foreach ($values as $key => $value) {
|
|
||||||
$values[$key] = $useKey ? (bool) $value : $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($multi) {
|
|
||||||
foreach ($values as $key => $value) {
|
|
||||||
if (is_array($value)) {
|
|
||||||
$value = implode(',', $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
$values[$key] = array_map('trim', explode(',', $value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function typeList($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
if (!is_array($value)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($field['fields'])) {
|
|
||||||
foreach ($value as $key => $item) {
|
|
||||||
foreach ($field['fields'] as $subKey => $subField) {
|
|
||||||
$subKey = trim($subKey, '.');
|
|
||||||
$subValue = isset($item[$subKey]) ? $item[$subKey] : null;
|
|
||||||
self::validate($subValue, $subField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterList($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return (array) $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom input: ignore (will not validate)
|
|
||||||
*
|
|
||||||
* @param mixed $value Value to be validated.
|
|
||||||
* @param array $params Validation parameters.
|
|
||||||
* @param array $field Blueprint for the field.
|
|
||||||
* @return bool True if validation succeeded.
|
|
||||||
*/
|
|
||||||
public static function typeIgnore($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function filterIgnore($value, array $params, array $field)
|
|
||||||
{
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTML5 attributes (min, max and range are handled inside the types)
|
|
||||||
|
|
||||||
public static function validateRequired($value, $params)
|
|
||||||
{
|
|
||||||
if (is_string($value)) {
|
|
||||||
$value = trim($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (bool) $params !== true || !empty($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validatePattern($value, $params)
|
|
||||||
{
|
|
||||||
return (bool) preg_match("`^{$params}$`u", $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Internal types
|
|
||||||
|
|
||||||
public static function validateAlpha($value, $params)
|
|
||||||
{
|
|
||||||
return ctype_alpha($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateAlnum($value, $params)
|
|
||||||
{
|
|
||||||
return ctype_alnum($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function typeBool($value, $params)
|
|
||||||
{
|
|
||||||
return is_bool($value) || $value == 1 || $value == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateBool($value, $params)
|
|
||||||
{
|
|
||||||
return is_bool($value) || $value == 1 || $value == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterBool($value, $params)
|
|
||||||
{
|
|
||||||
return (bool) $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateDigit($value, $params)
|
|
||||||
{
|
|
||||||
return ctype_digit($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateFloat($value, $params)
|
|
||||||
{
|
|
||||||
return is_float(filter_var($value, FILTER_VALIDATE_FLOAT));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterFloat($value, $params)
|
|
||||||
{
|
|
||||||
return (float) $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateHex($value, $params)
|
|
||||||
{
|
|
||||||
return ctype_xdigit($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateInt($value, $params)
|
|
||||||
{
|
|
||||||
return is_numeric($value) && (int) $value == $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function filterInt($value, $params)
|
|
||||||
{
|
|
||||||
return (int) $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateArray($value, $params)
|
|
||||||
{
|
|
||||||
return is_array($value) || ($value instanceof \ArrayAccess
|
|
||||||
&& $value instanceof \Traversable
|
|
||||||
&& $value instanceof \Countable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateJson($value, $params)
|
|
||||||
{
|
|
||||||
return (bool) (json_decode($value));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,121 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Grav\Common;
|
|
||||||
|
|
||||||
use DebugBar\JavascriptRenderer;
|
|
||||||
use DebugBar\StandardDebugBar;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class Debugger
|
|
||||||
* @package Grav\Common
|
|
||||||
*/
|
|
||||||
class Debugger
|
|
||||||
{
|
|
||||||
protected $grav;
|
|
||||||
protected $debugbar;
|
|
||||||
protected $renderer;
|
|
||||||
protected $enabled;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->debugbar = new StandardDebugBar();
|
|
||||||
$this->debugbar['time']->addMeasure('Loading', $this->debugbar['time']->getRequestStartTime(), microtime(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function init()
|
|
||||||
{
|
|
||||||
$this->grav = Grav::instance();
|
|
||||||
|
|
||||||
if ($this->enabled()) {
|
|
||||||
$this->debugbar->addCollector(new \DebugBar\DataCollector\ConfigCollector((array)$this->grav['config']->get('system')));
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function enabled($state = null)
|
|
||||||
{
|
|
||||||
if (isset($state)) {
|
|
||||||
$this->enabled = $state;
|
|
||||||
} else {
|
|
||||||
if (!isset($this->enabled)) {
|
|
||||||
$this->enabled = $this->grav['config']->get('system.debugger.enabled');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $this->enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addAssets()
|
|
||||||
{
|
|
||||||
if ($this->enabled()) {
|
|
||||||
$assets = $this->grav['assets'];
|
|
||||||
|
|
||||||
// Add jquery library
|
|
||||||
$assets->add('jquery', 101);
|
|
||||||
|
|
||||||
$this->renderer = $this->debugbar->getJavascriptRenderer();
|
|
||||||
$this->renderer->setIncludeVendors(false);
|
|
||||||
|
|
||||||
// Get the required CSS files
|
|
||||||
list($css_files, $js_files) = $this->renderer->getAssets(null, JavascriptRenderer::RELATIVE_URL);
|
|
||||||
foreach ($css_files as $css) {
|
|
||||||
$assets->addCss($css);
|
|
||||||
}
|
|
||||||
|
|
||||||
$assets->addCss('/system/assets/debugger.css');
|
|
||||||
|
|
||||||
foreach ($js_files as $js) {
|
|
||||||
$assets->addJs($js);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addCollector($collector)
|
|
||||||
{
|
|
||||||
$this->debugbar->addCollector($collector);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCollector($collector)
|
|
||||||
{
|
|
||||||
return $this->debugbar->getCollector($collector);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
if ($this->enabled()) {
|
|
||||||
echo $this->renderer->render();
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sendDataInHeaders()
|
|
||||||
{
|
|
||||||
$this->debugbar->sendDataInHeaders();
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function startTimer($name, $description = null)
|
|
||||||
{
|
|
||||||
if ($name[0] == '_' || $this->grav['config']->get('system.debugger.enabled')) {
|
|
||||||
$this->debugbar['time']->startMeasure($name, $description);
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stopTimer($name)
|
|
||||||
{
|
|
||||||
if ($name[0] == '_' || $this->grav['config']->get('system.debugger.enabled')) {
|
|
||||||
$this->debugbar['time']->stopMeasure($name);
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function addMessage($message, $label = 'info', $isString = true)
|
|
||||||
{
|
|
||||||
if ($this->enabled()) {
|
|
||||||
$this->debugbar['messages']->addMessage($message, $label, $isString);
|
|
||||||
}
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
|