first commit
This commit is contained in:
1660
wp-content/plugins/mailchimp-for-wp/CHANGELOG.md
Normal file
1660
wp-content/plugins/mailchimp-for-wp/CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
621
wp-content/plugins/mailchimp-for-wp/LICENSE
Normal file
621
wp-content/plugins/mailchimp-for-wp/LICENSE
Normal file
@@ -0,0 +1,621 @@
|
||||
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
|
||||
60
wp-content/plugins/mailchimp-for-wp/README.md
Normal file
60
wp-content/plugins/mailchimp-for-wp/README.md
Normal file
@@ -0,0 +1,60 @@
|
||||
MC4WP: Mailchimp for WordPress
|
||||
======================
|
||||

|
||||

|
||||

|
||||

|
||||
[](https://wordpress.org/support/plugin/mailchimp-for-wp/reviews/)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
|
||||
Here, you can browse the source code of the [MC4WP: Mailchimp for WordPress Plugin](https://wordpress.org/plugins/mailchimp-for-wp/), find and discuss open issues or contribute code to the plugin.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
If you just want to install this plugin on your WordPress site, please download and install the latest version from WordPress.org: [Mailchimp for WordPress plugin on WordPress.org](https://wordpress.org/plugins/mailchimp-for-wp/).
|
||||
|
||||
To install the development version, take the following steps:
|
||||
|
||||
1. Clone the GitHub repository:
|
||||
```
|
||||
git clone https://github.com/ibericode/mailchimp-for-wordpress.git mailchimp-for-wp
|
||||
```
|
||||
|
||||
1. Install Composer dependencies:
|
||||
```sh
|
||||
composer install
|
||||
```
|
||||
|
||||
1. Install NPM dependencies:
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
1. Generate plugin asset files:
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
1. Activate the plugin in your WordPress admin panel.
|
||||
|
||||
Bugs
|
||||
----
|
||||
If you think you've found a bug, [please open an issue here](https://github.com/ibericode/mailchimp-for-wordpress/issues?state=open)!
|
||||
|
||||
Translations
|
||||
-------------
|
||||
You can help [help translate Mailchimp for WordPress](https://translate.wordpress.org/projects/wp-plugins/mailchimp-for-wp/stable/) on WordPress.org.
|
||||
|
||||
Support
|
||||
-------
|
||||
This is a developer's portal for the Mailchimp for WordPress plugin and should not be used for support.
|
||||
Please visit the [Mailchimp for WordPress support forum on WordPress.org](https://wordpress.org/support/plugin/mailchimp-for-wp).
|
||||
|
||||
If you need priority support, [upgrade to Mailchimp for WordPress Premium](https://www.mc4wp.com/).
|
||||
|
||||
Developers
|
||||
----------
|
||||
|
||||
Looking for code snippets? Have a look at the [sample code snippets directory](https://github.com/ibericode/mailchimp-for-wordpress/tree/master/sample-code-snippets) for a collection of modification examples.
|
||||
|
||||
1
wp-content/plugins/mailchimp-for-wp/assets/css/admin.css
Normal file
1
wp-content/plugins/mailchimp-for-wp/assets/css/admin.css
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
.mc4wp-checkbox-__INTEGRATION_SLUG__{clear:both;width:auto;display:block;position:static}.mc4wp-checkbox-__INTEGRATION_SLUG__ input{float:none;vertical-align:middle;-webkit-appearance:checkbox;width:auto;max-width:21px;margin:0 6px 0 0;padding:0;position:static;display:inline-block!important}.mc4wp-checkbox-__INTEGRATION_SLUG__ label{float:none;cursor:pointer;width:auto;margin:0 0 16px;display:block;position:static}
|
||||
@@ -0,0 +1 @@
|
||||
.mc4wp-form input[name^=_mc4wp_honey]{display:none!important}.mc4wp-form-basic{margin:1em 0}.mc4wp-form-basic label,.mc4wp-form-basic input{box-sizing:border-box;cursor:auto;vertical-align:baseline;width:auto;height:auto;line-height:normal;display:block}.mc4wp-form-basic label:after,.mc4wp-form-basic input:after{content:"";clear:both;display:table}.mc4wp-form-basic label{margin-bottom:6px;font-weight:700;display:block}.mc4wp-form-basic input[type=text],.mc4wp-form-basic input[type=email],.mc4wp-form-basic input[type=tel],.mc4wp-form-basic input[type=url],.mc4wp-form-basic input[type=date],.mc4wp-form-basic textarea,.mc4wp-form-basic select{width:100%;max-width:480px;min-height:32px}.mc4wp-form-basic input[type=number]{min-width:40px}.mc4wp-form-basic input[type=checkbox],.mc4wp-form-basic input[type=radio]{border:0;width:13px;height:13px;margin:0 6px 0 0;padding:0;display:inline-block;position:relative}.mc4wp-form-basic input[type=checkbox]{-webkit-appearance:checkbox;-moz-appearance:checkbox;appearance:checkbox}.mc4wp-form-basic input[type=radio]{-webkit-appearance:radio;-moz-appearance:radio;appearance:radio}.mc4wp-form-basic input[type=submit],.mc4wp-form-basic button,.mc4wp-form-basic input[type=button]{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;display:inline-block}.mc4wp-form-basic label>span,.mc4wp-form-basic li>label{font-weight:400}.mc4wp-alert{color:#c09853;clear:both}.mc4wp-success{color:#468847}.mc4wp-notice{color:#3a87ad}.mc4wp-error{color:#cd5c5c}.rtl .mc4wp-form-basic input[type=checkbox],.rtl .mc4wp-form-basic input[type=radio]{margin:0 0 0 6px}
|
||||
File diff suppressed because one or more lines are too long
19
wp-content/plugins/mailchimp-for-wp/assets/img/icon.svg
Normal file
19
wp-content/plugins/mailchimp-for-wp/assets/img/icon.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1">
|
||||
<g
|
||||
fill="#a0a5aa">
|
||||
<path
|
||||
opacity="1"
|
||||
fill="#a0a5aa"
|
||||
fill-opacity="1"
|
||||
stroke="none"
|
||||
d="M 8.0097656 0.052734375 A 8 8 0 0 0 0.009765625 8.0527344 A 8 8 0 0 0 8.0097656 16.052734 A 8 8 0 0 0 16.009766 8.0527344 A 8 8 0 0 0 8.0097656 0.052734375 z M 9.2597656 4.171875 C 9.3205456 4.171875 9.9296146 5.0233822 10.611328 6.0664062 C 11.293041 7.1094313 12.296018 8.5331666 12.841797 9.2285156 L 13.833984 10.492188 L 13.316406 11.041016 C 13.031321 11.342334 12.708299 11.587891 12.599609 11.587891 C 12.253798 11.587891 11.266634 10.490156 10.349609 9.0859375 C 9.8610009 8.3377415 9.4126385 7.7229 9.3515625 7.71875 C 9.2904825 7.71455 9.2402344 8.3477011 9.2402344 9.1269531 L 9.2402344 10.544922 L 8.5839844 10.982422 C 8.2233854 11.223015 7.8735746 11.418294 7.8066406 11.417969 C 7.7397106 11.417644 7.4861075 10.997223 7.2421875 10.482422 C 6.9982675 9.9676199 6.6560079 9.3946444 6.4824219 9.2089844 L 6.1679688 8.8710938 L 6.0664062 9.34375 C 5.7203313 10.974656 5.6693219 11.090791 5.0917969 11.505859 C 4.5805569 11.873288 4.2347982 12.017623 4.1914062 11.882812 C 4.1839062 11.859632 4.1482681 11.574497 4.1113281 11.25 C 3.9708341 10.015897 3.5347399 8.7602861 2.8105469 7.5019531 C 2.5672129 7.0791451 2.5711235 7.0651693 2.9765625 6.8320312 C 3.2046215 6.7008903 3.5466561 6.4845105 3.7363281 6.3515625 C 4.0587811 6.1255455 4.1076376 6.1466348 4.4941406 6.6679688 C 4.8138896 7.0992628 4.9275606 7.166285 4.9941406 6.96875 C 5.0960956 6.666263 6.181165 5.8574219 6.484375 5.8574219 C 6.600668 5.8574219 6.8857635 6.1981904 7.1171875 6.6152344 C 7.3486105 7.0322784 7.5790294 7.3728809 7.6308594 7.3730469 C 7.7759584 7.3735219 7.9383234 5.8938023 7.8339844 5.5195312 C 7.7605544 5.2561423 7.8865035 5.0831575 8.4453125 4.6796875 C 8.8327545 4.3999485 9.1989846 4.171875 9.2597656 4.171875 z "
|
||||
id="path5822" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64"
|
||||
height="64"
|
||||
viewBox="0 0 64 64"
|
||||
version="1.1"
|
||||
id="SVGRoot"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="mc4wp-logo-red-on-white.svg">
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2">
|
||||
<circle
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
id="path5822"
|
||||
cx="32"
|
||||
cy="32"
|
||||
r="32" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:#cc4444;fill-opacity:1;stroke:none;"
|
||||
d="m 16,47.324799 c -0.02985,-0.09271 -0.175159,-1.230558 -0.322927,-2.528543 -0.561978,-4.936413 -2.305204,-9.961206 -5.201976,-14.994537 -0.9733359,-1.691234 -0.9585997,-1.750867 0.663154,-2.683422 0.912236,-0.524562 2.279359,-1.38885 3.038049,-1.920641 1.289813,-0.904069 1.486868,-0.821985 3.032878,1.26335 1.278999,1.725178 1.731406,1.998919 1.997727,1.208779 0.407819,-1.209946 4.748289,-4.450438 5.96113,-4.450438 0.465172,0 1.603153,1.364871 2.528847,3.033047 0.925694,1.668177 1.852705,3.03359 2.060024,3.034253 0.580399,0.0019 1.2257,-5.915967 0.808345,-7.413054 -0.293707,-1.053553 0.21226,-1.748685 2.447515,-3.362568 1.549769,-1.118954 3.016679,-2.034461 3.2598,-2.034461 0.243121,0 2.673101,3.413534 5.399956,7.585632 2.726854,4.172097 6.744105,9.861321 8.927221,12.642719 l 3.969305,5.057088 -2.073345,2.191405 c -1.140339,1.205272 -2.429057,2.191404 -2.863817,2.191404 -1.383243,0 -5.331006,-4.389741 -8.999106,-10.006614 -1.954436,-2.992783 -3.753407,-5.455006 -3.997711,-5.471606 -0.244305,-0.0166 -0.44419,2.520101 -0.44419,5.637112 v 5.667295 l -2.62254,1.749768 c -1.442397,0.962371 -2.841596,1.748706 -3.109332,1.747409 -0.267735,-0.0013 -1.285075,-1.687162 -2.260756,-3.746367 -0.97568,-2.059206 -2.342064,-4.351629 -3.036409,-5.094272 l -1.262444,-1.350262 -0.401863,1.893807 c -1.3843,6.523625 -1.59298,6.985894 -3.90308,8.646166 C 17.549496,47.286963 16.173566,47.864041 16,47.324799 Z"
|
||||
id="path4520"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64"
|
||||
height="64"
|
||||
viewBox="0 0 64 64"
|
||||
version="1.1"
|
||||
id="SVGRoot"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="mc4wp-logo-white-on-red.svg">
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2">
|
||||
<circle
|
||||
style="opacity:1;fill:#cc4444;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||
id="path5822"
|
||||
cx="32"
|
||||
cy="32"
|
||||
r="32" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;"
|
||||
d="m 16,47.324799 c -0.02985,-0.09271 -0.175159,-1.230558 -0.322927,-2.528543 -0.561978,-4.936413 -2.305204,-9.961206 -5.201976,-14.994537 -0.9733359,-1.691234 -0.9585997,-1.750867 0.663154,-2.683422 0.912236,-0.524562 2.279359,-1.38885 3.038049,-1.920641 1.289813,-0.904069 1.486868,-0.821985 3.032878,1.26335 1.278999,1.725178 1.731406,1.998919 1.997727,1.208779 0.407819,-1.209946 4.748289,-4.450438 5.96113,-4.450438 0.465172,0 1.603153,1.364871 2.528847,3.033047 0.925694,1.668177 1.852705,3.03359 2.060024,3.034253 0.580399,0.0019 1.2257,-5.915967 0.808345,-7.413054 -0.293707,-1.053553 0.21226,-1.748685 2.447515,-3.362568 1.549769,-1.118954 3.016679,-2.034461 3.2598,-2.034461 0.243121,0 2.673101,3.413534 5.399956,7.585632 2.726854,4.172097 6.744105,9.861321 8.927221,12.642719 l 3.969305,5.057088 -2.073345,2.191405 c -1.140339,1.205272 -2.429057,2.191404 -2.863817,2.191404 -1.383243,0 -5.331006,-4.389741 -8.999106,-10.006614 -1.954436,-2.992783 -3.753407,-5.455006 -3.997711,-5.471606 -0.244305,-0.0166 -0.44419,2.520101 -0.44419,5.637112 v 5.667295 l -2.62254,1.749768 c -1.442397,0.962371 -2.841596,1.748706 -3.109332,1.747409 -0.267735,-0.0013 -1.285075,-1.687162 -2.260756,-3.746367 -0.97568,-2.059206 -2.342064,-4.351629 -3.036409,-5.094272 l -1.262444,-1.350262 -0.401863,1.893807 c -1.3843,6.523625 -1.59298,6.985894 -3.90308,8.646166 C 17.549496,47.286963 16.173566,47.864041 16,47.324799 Z"
|
||||
id="path4520"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
1
wp-content/plugins/mailchimp-for-wp/assets/js/admin.js
Normal file
1
wp-content/plugins/mailchimp-for-wp/assets/js/admin.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
(()=>{const e=window.wp.i18n.__,{registerBlockType:t}=window.wp.blocks,{SelectControl:i}=window.wp.components,o=window.mc4wp_forms;t("mailchimp-for-wp/form",{title:e("Mailchimp for WordPress Form"),description:e("Block showing a Mailchimp for WordPress sign-up form"),category:"widgets",attributes:{id:{type:"int"}},icon:React.createElement("svg",{width:"16",height:"16",viewBox:"0 0 16 16",version:"1.1"},React.createElement("path",{opacity:"1",fill:"#a0a5aa",fillOpacity:"1",stroke:"none",d:"M 8.0097656 0.052734375 A 8 8 0 0 0 0.009765625 8.0527344 A 8 8 0 0 0 8.0097656 16.052734 A 8 8 0 0 0 16.009766 8.0527344 A 8 8 0 0 0 8.0097656 0.052734375 z M 9.2597656 4.171875 C 9.3205456 4.171875 9.9296146 5.0233822 10.611328 6.0664062 C 11.293041 7.1094313 12.296018 8.5331666 12.841797 9.2285156 L 13.833984 10.492188 L 13.316406 11.041016 C 13.031321 11.342334 12.708299 11.587891 12.599609 11.587891 C 12.253798 11.587891 11.266634 10.490156 10.349609 9.0859375 C 9.8610009 8.3377415 9.4126385 7.7229 9.3515625 7.71875 C 9.2904825 7.71455 9.2402344 8.3477011 9.2402344 9.1269531 L 9.2402344 10.544922 L 8.5839844 10.982422 C 8.2233854 11.223015 7.8735746 11.418294 7.8066406 11.417969 C 7.7397106 11.417644 7.4861075 10.997223 7.2421875 10.482422 C 6.9982675 9.9676199 6.6560079 9.3946444 6.4824219 9.2089844 L 6.1679688 8.8710938 L 6.0664062 9.34375 C 5.7203313 10.974656 5.6693219 11.090791 5.0917969 11.505859 C 4.5805569 11.873288 4.2347982 12.017623 4.1914062 11.882812 C 4.1839062 11.859632 4.1482681 11.574497 4.1113281 11.25 C 3.9708341 10.015897 3.5347399 8.7602861 2.8105469 7.5019531 C 2.5672129 7.0791451 2.5711235 7.0651693 2.9765625 6.8320312 C 3.2046215 6.7008903 3.5466561 6.4845105 3.7363281 6.3515625 C 4.0587811 6.1255455 4.1076376 6.1466348 4.4941406 6.6679688 C 4.8138896 7.0992628 4.9275606 7.166285 4.9941406 6.96875 C 5.0960956 6.666263 6.181165 5.8574219 6.484375 5.8574219 C 6.600668 5.8574219 6.8857635 6.1981904 7.1171875 6.6152344 C 7.3486105 7.0322784 7.5790294 7.3728809 7.6308594 7.3730469 C 7.7759584 7.3735219 7.9383234 5.8938023 7.8339844 5.5195312 C 7.7605544 5.2561423 7.8865035 5.0831575 8.4453125 4.6796875 C 8.8327545 4.3999485 9.1989846 4.171875 9.2597656 4.171875 z "})),supports:{html:!1},edit:function(t){const r=o.map((e=>({label:e.name,value:e.id})));return void 0===t.attributes.id&&o.length>0&&t.setAttributes({id:o[0].id}),React.createElement("div",{style:{backgroundColor:"#f8f9f9",padding:"14px"}},React.createElement(i,{label:e("Mailchimp for WordPress Sign-up Form"),value:t.attributes.id,options:r,onChange:e=>{t.setAttributes({id:e})}}))},save:function(e){return null}})})();
|
||||
@@ -0,0 +1 @@
|
||||
(()=>{var e={1419:e=>{e.exports=function(e){const t=window.pageXOffset||document.documentElement.scrollLeft,o=function(e){const t=document.body,o=document.documentElement,n=e.getBoundingClientRect(),r=o.clientHeight,i=Math.max(t.scrollHeight,t.offsetHeight,o.clientHeight,o.scrollHeight,o.offsetHeight),c=n.bottom-r/2-n.height/2,s=i-r;return Math.min(c+window.pageYOffset,s)}(e);window.scrollTo(t,o)}}},t={};function o(n){var r=t[n];if(void 0!==r)return r.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,o),i.exports}o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";var e=o(1419),t=o.n(e);const n=window.mc4wp_submitted_form,r=window.mc4wp.forms;if(n){const e=document.getElementById(n.element_id);!function(e,o,i,c){const s=Date.now(),d=document.body.clientHeight;i&&e.setData(c),window.scrollY<=10&&n.auto_scroll&&t()(e.element),window.addEventListener("load",(function(){r.trigger("submitted",[e]),i?r.trigger("error",[e,i]):(r.trigger("success",[e,c]),r.trigger(o,[e,c]),"updated_subscriber"===o&&r.trigger("subscribed",[e,c,!0]));const l=Date.now()-s;n.auto_scroll&&l>1e3&&l<2e3&&document.body.clientHeight!==d&&t()(e.element)}))}(r.getByElement(e),n.event,n.errors,n.data)}})()})();
|
||||
1
wp-content/plugins/mailchimp-for-wp/assets/js/forms.js
Normal file
1
wp-content/plugins/mailchimp-for-wp/assets/js/forms.js
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
(()=>{const e=window.mc4wp_vars.ajaxurl,t=window.mc4wp.settings,n=document.getElementById("notice-additional-fields");function i(){const t=[].filter.call(document.querySelectorAll(".mc4wp-list-input"),(e=>e.checked)).map((e=>e.value)).join(","),i=["EMAIL","FNAME","NAME","LNAME"];let l=!1;window.fetch(`${e}?action=mc4wp_get_list_details&ids=${t}`).then((e=>e.json())).then((e=>{e.forEach((e=>{e.merge_fields.forEach((e=>{e.required&&i.indexOf(e.tag)<0&&(l=!0)}))}))})).finally((()=>{n.style.display=l?"":"none"}))}n&&(i(),t.on("selectedLists.change",i))})();
|
||||
83
wp-content/plugins/mailchimp-for-wp/autoload.php
Normal file
83
wp-content/plugins/mailchimp-for-wp/autoload.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/includes/functions.php';
|
||||
require __DIR__ . '/includes/deprecated-functions.php';
|
||||
require __DIR__ . '/includes/forms/functions.php';
|
||||
require __DIR__ . '/includes/forms/admin-functions.php';
|
||||
require __DIR__ . '/includes/integrations/functions.php';
|
||||
|
||||
// require API class manually because Composer's classloader is case-sensitive
|
||||
require __DIR__ . '/includes/api/class-api-v3.php';
|
||||
|
||||
// load other classes dynamically
|
||||
spl_autoload_register(function ($class) {
|
||||
static $classmap = array(
|
||||
'MC4WP_API_Connection_Exception' => __DIR__ . '/includes/api/class-connection-exception.php',
|
||||
'MC4WP_API_Exception' => __DIR__ . '/includes/api/class-exception.php',
|
||||
'MC4WP_API_Resource_Not_Found_Exception' => __DIR__ . '/includes/api/class-resource-not-found-exception.php',
|
||||
'MC4WP_API_V3' => __DIR__ . '/includes/api/class-api-v3.php',
|
||||
'MC4WP_API_V3_Client' => __DIR__ . '/includes/api/class-api-v3-client.php',
|
||||
'MC4WP_Admin' => __DIR__ . '/includes/admin/class-admin.php',
|
||||
'MC4WP_Admin_Ads' => __DIR__ . '/includes/admin/class-ads.php',
|
||||
'MC4WP_Admin_Ajax' => __DIR__ . '/includes/admin/class-admin-ajax.php',
|
||||
'MC4WP_Admin_Messages' => __DIR__ . '/includes/admin/class-admin-messages.php',
|
||||
'MC4WP_Admin_Review_Notice' => __DIR__ . '/includes/admin/class-review-notice.php',
|
||||
'MC4WP_Admin_Texts' => __DIR__ . '/includes/admin/class-admin-texts.php',
|
||||
'MC4WP_Admin_Tools' => __DIR__ . '/includes/admin/class-admin-tools.php',
|
||||
'MC4WP_AffiliateWP_Integration' => __DIR__ . '/integrations/affiliatewp/class-affiliatewp.php',
|
||||
'MC4WP_BuddyPress_Integration' => __DIR__ . '/integrations/buddypress/class-buddypress.php',
|
||||
'MC4WP_Comment_Form_Integration' => __DIR__ . '/integrations/wp-comment-form/class-comment-form.php',
|
||||
'MC4WP_Contact_Form_7_Integration' => __DIR__ . '/integrations/contact-form-7/class-contact-form-7.php',
|
||||
'MC4WP_Container' => __DIR__ . '/includes/class-container.php',
|
||||
'MC4WP_Custom_Integration' => __DIR__ . '/integrations/custom/class-custom.php',
|
||||
'MC4WP_Debug_Log' => __DIR__ . '/includes/class-debug-log.php',
|
||||
'MC4WP_Debug_Log_Reader' => __DIR__ . '/includes/class-debug-log-reader.php',
|
||||
'MC4WP_Dynamic_Content_Tags' => __DIR__ . '/includes/class-dynamic-content-tags.php',
|
||||
'MC4WP_Easy_Digital_Downloads_Integration' => __DIR__ . '/integrations/easy-digital-downloads/class-easy-digital-downloads.php',
|
||||
'MC4WP_Events_Manager_Integration' => __DIR__ . '/integrations/events-manager/class-events-manager.php',
|
||||
'MC4WP_Field_Formatter' => __DIR__ . '/includes/class-field-formatter.php',
|
||||
'MC4WP_Field_Guesser' => __DIR__ . '/includes/class-field-guesser.php',
|
||||
'MC4WP_Form' => __DIR__ . '/includes/forms/class-form.php',
|
||||
'MC4WP_Form_AMP' => __DIR__ . '/includes/forms/class-form-amp.php',
|
||||
'MC4WP_Form_Asset_Manager' => __DIR__ . '/includes/forms/class-asset-manager.php',
|
||||
'MC4WP_Form_Element' => __DIR__ . '/includes/forms/class-form-element.php',
|
||||
'MC4WP_Form_Listener' => __DIR__ . '/includes/forms/class-form-listener.php',
|
||||
'MC4WP_Form_Manager' => __DIR__ . '/includes/forms/class-form-manager.php',
|
||||
'MC4WP_Form_Notice' => __DIR__ . '/includes/forms/class-form-message.php',
|
||||
'MC4WP_Form_Output_Manager' => __DIR__ . '/includes/forms/class-output-manager.php',
|
||||
'MC4WP_Form_Previewer' => __DIR__ . '/includes/forms/class-form-previewer.php',
|
||||
'MC4WP_Form_Tags' => __DIR__ . '/includes/forms/class-form-tags.php',
|
||||
'MC4WP_Form_Widget' => __DIR__ . '/includes/forms/class-widget.php',
|
||||
'MC4WP_Forms_Admin' => __DIR__ . '/includes/forms/class-admin.php',
|
||||
'MC4WP_Give_Integration' => __DIR__ . '/integrations/give/class-give.php',
|
||||
'MC4WP_Gravity_Forms_Field' => __DIR__ . '/integrations/gravity-forms/class-field.php',
|
||||
'MC4WP_Gravity_Forms_Integration' => __DIR__ . '/integrations/gravity-forms/class-gravity-forms.php',
|
||||
'MC4WP_Integration' => __DIR__ . '/includes/integrations/class-integration.php',
|
||||
'MC4WP_Integration_Admin' => __DIR__ . '/includes/integrations/class-admin.php',
|
||||
'MC4WP_Integration_Fixture' => __DIR__ . '/includes/integrations/class-integration-fixture.php',
|
||||
'MC4WP_Integration_Manager' => __DIR__ . '/includes/integrations/class-integration-manager.php',
|
||||
'MC4WP_Integration_Tags' => __DIR__ . '/includes/integrations/class-integration-tags.php',
|
||||
'MC4WP_List_Data_Mapper' => __DIR__ . '/includes/class-list-data-mapper.php',
|
||||
'MC4WP_MailChimp' => __DIR__ . '/includes/class-mailchimp.php',
|
||||
'MC4WP_MailChimp_Subscriber' => __DIR__ . '/includes/class-mailchimp-subscriber.php',
|
||||
'MC4WP_MemberPress_Integration' => __DIR__ . '/integrations/memberpress/class-memberpress.php',
|
||||
'MC4WP_Ninja_Forms_Action' => __DIR__ . '/integrations/ninja-forms/class-action.php',
|
||||
'MC4WP_Ninja_Forms_Field' => __DIR__ . '/integrations/ninja-forms/class-field.php',
|
||||
'MC4WP_Ninja_Forms_Integration' => __DIR__ . '/integrations/ninja-forms/class-ninja-forms.php',
|
||||
'MC4WP_Ninja_Forms_V2_Integration' => __DIR__ . '/integrations/ninja-forms-2/class-ninja-forms.php',
|
||||
'MC4WP_Plugin' => __DIR__ . '/includes/class-plugin.php',
|
||||
'MC4WP_Queue' => __DIR__ . '/includes/class-queue.php',
|
||||
'MC4WP_Queue_Job' => __DIR__ . '/includes/class-queue-job.php',
|
||||
'MC4WP_Registration_Form_Integration' => __DIR__ . '/integrations/wp-registration-form/class-registration-form.php',
|
||||
'MC4WP_Tools' => __DIR__ . '/includes/class-tools.php',
|
||||
'MC4WP_Upgrade_Routines' => __DIR__ . '/includes/admin/class-upgrade-routines.php',
|
||||
'MC4WP_User_Integration' => __DIR__ . '/includes/integrations/class-user-integration.php',
|
||||
'MC4WP_WPForms_Field' => __DIR__ . '/integrations/wpforms/class-field.php',
|
||||
'MC4WP_WPForms_Integration' => __DIR__ . '/integrations/wpforms/class-wpforms.php',
|
||||
'MC4WP_WooCommerce_Integration' => __DIR__ . '/integrations/woocommerce/class-woocommerce.php',
|
||||
);
|
||||
|
||||
if (isset($classmap[$class])) {
|
||||
require $classmap[$class];
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
$email_label = esc_html__('Email address', 'mailchimp-for-wp');
|
||||
$email_placeholder = esc_html__('Your email address', 'mailchimp-for-wp');
|
||||
$signup_button = esc_html__('Sign up', 'mailchimp-for-wp');
|
||||
|
||||
$content = "<p>\n\t<label>{$email_label}: \n";
|
||||
$content .= "\t\t<input type=\"email\" name=\"EMAIL\" placeholder=\"{$email_placeholder}\" required />\n</label>\n</p>\n\n";
|
||||
$content .= "<p>\n\t<input type=\"submit\" value=\"{$signup_button}\" />\n</p>";
|
||||
|
||||
return $content;
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'subscribed' => array(
|
||||
'type' => 'success',
|
||||
'text' => esc_html__('Thank you, your sign-up request was successful! Please check your email inbox to confirm.', 'mailchimp-for-wp'),
|
||||
),
|
||||
'updated' => array(
|
||||
'type' => 'success',
|
||||
'text' => esc_html__('Thank you, your records have been updated!', 'mailchimp-for-wp'),
|
||||
),
|
||||
'unsubscribed' => array(
|
||||
'type' => 'success',
|
||||
'text' => esc_html__('You were successfully unsubscribed.', 'mailchimp-for-wp'),
|
||||
),
|
||||
'not_subscribed' => array(
|
||||
'type' => 'notice',
|
||||
'text' => esc_html__('Given email address is not subscribed.', 'mailchimp-for-wp'),
|
||||
),
|
||||
'error' => array(
|
||||
'type' => 'error',
|
||||
'text' => esc_html__('Oops. Something went wrong. Please try again later.', 'mailchimp-for-wp'),
|
||||
),
|
||||
'invalid_email' => array(
|
||||
'type' => 'error',
|
||||
'text' => esc_html__('Please provide a valid email address.', 'mailchimp-for-wp'),
|
||||
),
|
||||
'already_subscribed' => array(
|
||||
'type' => 'notice',
|
||||
'text' => esc_html__('Given email address is already subscribed, thank you!', 'mailchimp-for-wp'),
|
||||
),
|
||||
'required_field_missing' => array(
|
||||
'type' => 'error',
|
||||
'text' => esc_html__('Please fill in the required fields.', 'mailchimp-for-wp'),
|
||||
),
|
||||
'no_lists_selected' => array(
|
||||
'type' => 'error',
|
||||
'text' => esc_html__('Please select at least one list.', 'mailchimp-for-wp'),
|
||||
),
|
||||
);
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'css' => 0,
|
||||
'double_optin' => 1,
|
||||
'hide_after_success' => 0,
|
||||
'lists' => array(),
|
||||
'redirect' => '',
|
||||
'replace_interests' => 1,
|
||||
'required_fields' => '',
|
||||
'update_existing' => 0,
|
||||
'subscriber_tags' => '',
|
||||
);
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'api_key' => '',
|
||||
'allow_usage_tracking' => 0,
|
||||
'debug_log_level' => 'warning',
|
||||
);
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
class MC4WP_Admin_Ajax
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Admin_Tools
|
||||
*/
|
||||
protected $tools;
|
||||
|
||||
/**
|
||||
* MC4WP_Admin_Ajax constructor.
|
||||
*
|
||||
* @param MC4WP_Admin_Tools $tools
|
||||
*/
|
||||
public function __construct(MC4WP_Admin_Tools $tools)
|
||||
{
|
||||
$this->tools = $tools;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook AJAX actions
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('wp_ajax_mc4wp_renew_mailchimp_lists', array( $this, 'refresh_mailchimp_lists' ));
|
||||
add_action('wp_ajax_mc4wp_get_list_details', array( $this, 'get_list_details' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty lists cache & fetch lists again.
|
||||
*/
|
||||
public function refresh_mailchimp_lists()
|
||||
{
|
||||
if (! $this->tools->is_user_authorized()) {
|
||||
wp_send_json_error();
|
||||
return;
|
||||
}
|
||||
|
||||
check_ajax_referer('mc4wp-ajax');
|
||||
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$success = $mailchimp->refresh_lists();
|
||||
wp_send_json($success);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve details (merge fields and interest categories) for one or multiple lists in Mailchimp
|
||||
* @throws MC4WP_API_Exception
|
||||
*/
|
||||
public function get_list_details()
|
||||
{
|
||||
if (! $this->tools->is_user_authorized()) {
|
||||
wp_send_json_error();
|
||||
return;
|
||||
}
|
||||
|
||||
$list_ids = (array) explode(',', $_GET['ids']);
|
||||
$data = array();
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
foreach ($list_ids as $list_id) {
|
||||
$data[] = (object) array(
|
||||
'id' => $list_id,
|
||||
'merge_fields' => $mailchimp->get_list_merge_fields($list_id),
|
||||
'interest_categories' => $mailchimp->get_list_interest_categories($list_id),
|
||||
'marketing_permissions' => $mailchimp->get_list_marketing_permissions($list_id),
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($_GET['format']) && $_GET['format'] === 'html') {
|
||||
$merge_fields = $data[0]->merge_fields;
|
||||
$interest_categories = $data[0]->interest_categories;
|
||||
$marketing_permissions = $data[0]->marketing_permissions;
|
||||
require MC4WP_PLUGIN_DIR . '/includes/views/parts/lists-overview-details.php';
|
||||
} else {
|
||||
wp_send_json($data);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Admin_Messages
|
||||
*
|
||||
* @ignore
|
||||
* @since 3.0
|
||||
*/
|
||||
class MC4WP_Admin_Messages
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $bag;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $dirty = false;
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('admin_notices', array( $this, 'show' ));
|
||||
register_shutdown_function(array( $this, 'save' ));
|
||||
}
|
||||
|
||||
private function load()
|
||||
{
|
||||
if (is_null($this->bag)) {
|
||||
$this->bag = get_option('mc4wp_flash_messages', array());
|
||||
}
|
||||
}
|
||||
|
||||
// empty flash bag
|
||||
private function reset()
|
||||
{
|
||||
$this->bag = array();
|
||||
$this->dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flash a message (shows on next pageload)
|
||||
*
|
||||
* @param $message
|
||||
* @param string $type
|
||||
*/
|
||||
public function flash($message, $type = 'success')
|
||||
{
|
||||
$this->load();
|
||||
$this->bag[] = array(
|
||||
'text' => $message,
|
||||
'type' => $type,
|
||||
);
|
||||
$this->dirty = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Show queued flash messages
|
||||
*/
|
||||
public function show()
|
||||
{
|
||||
$this->load();
|
||||
|
||||
foreach ($this->bag as $message) {
|
||||
echo sprintf('<div class="notice notice-%s is-dismissible"><p>%s</p></div>', $message['type'], $message['text']);
|
||||
}
|
||||
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save queued messages
|
||||
*
|
||||
* @hooked `shutdown`
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
if ($this->dirty) {
|
||||
update_option('mc4wp_flash_messages', $this->bag, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Admin_Texts
|
||||
*
|
||||
* @ignore
|
||||
* @since 3.0
|
||||
*/
|
||||
class MC4WP_Admin_Texts
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $plugin_file;
|
||||
|
||||
/**
|
||||
* @param string $plugin_file
|
||||
*/
|
||||
public function __construct($plugin_file)
|
||||
{
|
||||
$this->plugin_file = $plugin_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
global $pagenow;
|
||||
|
||||
add_filter('admin_footer_text', array( $this, 'footer_text' ));
|
||||
|
||||
// Hooks for Plugins overview page
|
||||
if ($pagenow === 'plugins.php') {
|
||||
add_filter('plugin_action_links_' . $this->plugin_file, array( $this, 'add_plugin_settings_link' ), 10, 2);
|
||||
add_filter('plugin_row_meta', array( $this, 'add_plugin_meta_links' ), 10, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask for a plugin review in the WP Admin footer, if this is one of the plugin pages.
|
||||
*
|
||||
* @param string $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function footer_text($text)
|
||||
{
|
||||
if (! empty($_GET['page']) && strpos($_GET['page'], 'mailchimp-for-wp') === 0) {
|
||||
$text = sprintf('If you enjoy using <strong>Mailchimp for WordPress</strong>, please <a href="%s" target="_blank">leave us a ★★★★★ plugin review on WordPress.org</a>.', 'https://wordpress.org/support/plugin/mailchimp-for-wp/reviews/#new-post');
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the settings link to the Plugins overview
|
||||
*
|
||||
* @param array $links
|
||||
* @param $file
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_plugin_settings_link($links, $file)
|
||||
{
|
||||
if ($file !== $this->plugin_file) {
|
||||
return $links;
|
||||
}
|
||||
|
||||
$settings_link = sprintf('<a href="%s">%s</a>', admin_url('admin.php?page=mailchimp-for-wp'), esc_html__('Settings', 'mailchimp-for-wp'));
|
||||
array_unshift($links, $settings_link);
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds meta links to the plugin in the WP Admin > Plugins screen
|
||||
*
|
||||
* @param array $links
|
||||
* @param string $file
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_plugin_meta_links($links, $file)
|
||||
{
|
||||
if ($file !== $this->plugin_file) {
|
||||
return $links;
|
||||
}
|
||||
|
||||
$links[] = '<a href="https://www.mc4wp.com/kb/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=plugins-page">' . esc_html__('Documentation', 'mailchimp-for-wp') . '</a>';
|
||||
|
||||
/**
|
||||
* Filters meta links shown on the Plugins overview page
|
||||
*
|
||||
* This takes an array of strings
|
||||
*
|
||||
* @since 3.0
|
||||
* @param array $links
|
||||
* @ignore
|
||||
*/
|
||||
$links = apply_filters('mc4wp_admin_plugin_meta_links', $links);
|
||||
|
||||
return $links;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
class MC4WP_Admin_Tools
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_plugin_page()
|
||||
{
|
||||
if (empty($_GET['page'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$prefix = 'mailchimp-for-wp';
|
||||
$page = ltrim(substr($_GET['page'], strlen($prefix)), '-');
|
||||
return $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $page
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function on_plugin_page($page = null)
|
||||
{
|
||||
// any settings page
|
||||
if (is_null($page)) {
|
||||
return isset($_GET['page']) && strpos($_GET['page'], 'mailchimp-for-wp') === 0;
|
||||
}
|
||||
|
||||
// specific page
|
||||
return $this->get_plugin_page() === $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the logged-in user have the required capability?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_user_authorized()
|
||||
{
|
||||
return current_user_can($this->get_required_capability());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get required capability to access settings page and view dashboard widgets.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_required_capability()
|
||||
{
|
||||
$capability = 'manage_options';
|
||||
|
||||
/**
|
||||
* Filters the required user capability to access the Mailchimp for WordPress' settings pages, view the dashboard widgets.
|
||||
*
|
||||
* Defaults to `manage_options`
|
||||
*
|
||||
* @since 3.0
|
||||
* @param string $capability
|
||||
* @see https://codex.wordpress.org/Roles_and_Capabilities
|
||||
*/
|
||||
$capability = (string) apply_filters('mc4wp_admin_required_capability', $capability);
|
||||
|
||||
return $capability;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,530 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Admin
|
||||
*
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Admin
|
||||
{
|
||||
/**
|
||||
* @var string The relative path to the main plugin file from the plugins dir
|
||||
*/
|
||||
protected $plugin_file;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Admin_Messages
|
||||
*/
|
||||
protected $messages;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Admin_Ads
|
||||
*/
|
||||
protected $ads;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Admin_Tools
|
||||
*/
|
||||
protected $tools;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Admin_Review_Notice
|
||||
*/
|
||||
protected $review_notice;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param MC4WP_Admin_Tools $tools
|
||||
* @param MC4WP_Admin_Messages $messages
|
||||
*/
|
||||
public function __construct(MC4WP_Admin_Tools $tools, MC4WP_Admin_Messages $messages)
|
||||
{
|
||||
$this->tools = $tools;
|
||||
$this->messages = $messages;
|
||||
$this->plugin_file = plugin_basename(MC4WP_PLUGIN_FILE);
|
||||
$this->ads = new MC4WP_Admin_Ads();
|
||||
$this->review_notice = new MC4WP_Admin_Review_Notice($tools);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
|
||||
// Actions used globally throughout WP Admin
|
||||
add_action('admin_menu', array( $this, 'build_menu' ));
|
||||
add_action('admin_init', array( $this, 'initialize' ));
|
||||
|
||||
add_action('current_screen', array( $this, 'customize_admin_texts' ));
|
||||
add_action('wp_dashboard_setup', array( $this, 'register_dashboard_widgets' ));
|
||||
add_action('mc4wp_admin_empty_lists_cache', array( $this, 'renew_lists_cache' ));
|
||||
add_action('mc4wp_admin_empty_debug_log', array( $this, 'empty_debug_log' ));
|
||||
|
||||
add_action('admin_notices', array( $this, 'show_api_key_notice' ));
|
||||
add_action('mc4wp_admin_dismiss_api_key_notice', array( $this, 'dismiss_api_key_notice' ));
|
||||
add_action('admin_enqueue_scripts', array( $this, 'enqueue_assets' ));
|
||||
|
||||
$this->ads->add_hooks();
|
||||
$this->messages->add_hooks();
|
||||
$this->review_notice->add_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes various stuff used in WP Admin
|
||||
*
|
||||
* - Registers settings
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
|
||||
// register settings
|
||||
register_setting('mc4wp_settings', 'mc4wp', array( $this, 'save_general_settings' ));
|
||||
|
||||
// Load upgrader
|
||||
$this->init_upgrade_routines();
|
||||
|
||||
// listen for custom actions
|
||||
$this->listen_for_actions();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Listen for `_mc4wp_action` requests
|
||||
*/
|
||||
public function listen_for_actions()
|
||||
{
|
||||
// do nothing if _mc4wp_action was not in the request parameters
|
||||
if (! isset($_REQUEST['_mc4wp_action'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check if user is authorized
|
||||
if (! $this->tools->is_user_authorized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// verify nonce
|
||||
if (! isset($_REQUEST['_wpnonce']) || false === wp_verify_nonce($_REQUEST['_wpnonce'], '_mc4wp_action')) {
|
||||
wp_nonce_ays('_mc4wp_action');
|
||||
exit;
|
||||
}
|
||||
|
||||
$action = (string) $_REQUEST['_mc4wp_action'];
|
||||
|
||||
/**
|
||||
* Allows you to hook into requests containing `_mc4wp_action` => action name.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$action`, refers to the action name.
|
||||
*
|
||||
* By the time this hook is fired, the user is already authorized. After processing all the registered hooks,
|
||||
* the request is redirected back to the referring URL.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
do_action('mc4wp_admin_' . $action);
|
||||
|
||||
// redirect back to where we came from (to prevent double submit)
|
||||
if (isset($_POST['_redirect_to'])) {
|
||||
$redirect_url = $_POST['_redirect_to'];
|
||||
} elseif (isset($_GET['_redirect_to'])) {
|
||||
$redirect_url = $_GET['_redirect_to'];
|
||||
} else {
|
||||
$redirect_url = remove_query_arg('_mc4wp_action');
|
||||
}
|
||||
|
||||
wp_safe_redirect($redirect_url);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register dashboard widgets
|
||||
*/
|
||||
public function register_dashboard_widgets()
|
||||
{
|
||||
if (! $this->tools->is_user_authorized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup dashboard widget, users are authorized by now.
|
||||
*
|
||||
* Use this hook to register your own dashboard widgets for users with the required capability.
|
||||
*
|
||||
* @since 3.0
|
||||
* @ignore
|
||||
*/
|
||||
do_action('mc4wp_dashboard_setup');
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade routine
|
||||
*/
|
||||
private function init_upgrade_routines()
|
||||
{
|
||||
// upgrade routine for upgrade routine....
|
||||
$previous_version = get_option('mc4wp_lite_version', 0);
|
||||
if ($previous_version) {
|
||||
delete_option('mc4wp_lite_version');
|
||||
update_option('mc4wp_version', $previous_version);
|
||||
}
|
||||
|
||||
$previous_version = get_option('mc4wp_version', 0);
|
||||
|
||||
// Ran upgrade routines before?
|
||||
if (empty($previous_version)) {
|
||||
update_option('mc4wp_version', MC4WP_VERSION);
|
||||
|
||||
// if we have at least one form, we're going to run upgrade routine for v3 => v4 anyway.
|
||||
$posts = get_posts(
|
||||
array(
|
||||
'post_type' => 'mc4wp-form',
|
||||
'posts_per_page' => 1,
|
||||
)
|
||||
);
|
||||
if (empty($posts)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$previous_version = '3.9';
|
||||
}
|
||||
|
||||
// This means we're good!
|
||||
if (version_compare($previous_version, MC4WP_VERSION, '>=')) {
|
||||
return;
|
||||
}
|
||||
|
||||
define('MC4WP_DOING_UPGRADE', true);
|
||||
$upgrade_routines = new MC4WP_Upgrade_Routines($previous_version, MC4WP_VERSION, __DIR__ . '/migrations');
|
||||
$upgrade_routines->run();
|
||||
update_option('mc4wp_version', MC4WP_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renew Mailchimp lists cache
|
||||
*/
|
||||
public function renew_lists_cache()
|
||||
{
|
||||
// try getting new lists to fill cache again
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$lists = $mailchimp->refresh_lists();
|
||||
|
||||
if (! empty($lists)) {
|
||||
$this->messages->flash(esc_html__('Success! The cached configuration for your Mailchimp lists has been renewed.', 'mailchimp-for-wp'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize texts throughout WP Admin
|
||||
*/
|
||||
public function customize_admin_texts()
|
||||
{
|
||||
$texts = new MC4WP_Admin_Texts($this->plugin_file);
|
||||
$texts->add_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the General settings
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
public function save_general_settings(array $settings)
|
||||
{
|
||||
$current = mc4wp_get_options();
|
||||
|
||||
// merge with current settings to allow passing partial arrays to this method
|
||||
$settings = array_merge($current, $settings);
|
||||
|
||||
// Make sure not to use obfuscated key
|
||||
if (strpos($settings['api_key'], '*') !== false) {
|
||||
$settings['api_key'] = $current['api_key'];
|
||||
}
|
||||
|
||||
// Sanitize API key
|
||||
$settings['api_key'] = sanitize_text_field($settings['api_key']);
|
||||
|
||||
// if API key changed, empty Mailchimp cache
|
||||
if ($settings['api_key'] !== $current['api_key']) {
|
||||
delete_transient('mc4wp_mailchimp_lists');
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs right before general settings are saved.
|
||||
*
|
||||
* @param array $settings The updated settings array
|
||||
* @param array $current The old settings array
|
||||
*/
|
||||
do_action('mc4wp_save_settings', $settings, $current);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load scripts and stylesheet on Mailchimp for WP Admin pages
|
||||
*/
|
||||
public function enqueue_assets()
|
||||
{
|
||||
if (! $this->tools->on_plugin_page()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$opts = mc4wp_get_options();
|
||||
$page = $this->tools->get_plugin_page();
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
|
||||
// css
|
||||
wp_register_style('mc4wp-admin', mc4wp_plugin_url('assets/css/admin.css'), array(), MC4WP_VERSION);
|
||||
wp_enqueue_style('mc4wp-admin');
|
||||
|
||||
// js
|
||||
wp_register_script('mc4wp-admin', mc4wp_plugin_url('assets/js/admin.js'), array(), MC4WP_VERSION, true);
|
||||
wp_enqueue_script('mc4wp-admin');
|
||||
$connected = ! empty($opts['api_key']);
|
||||
$mailchimp_lists = $connected ? $mailchimp->get_lists() : array();
|
||||
wp_localize_script(
|
||||
'mc4wp-admin',
|
||||
'mc4wp_vars',
|
||||
array(
|
||||
'ajaxurl' => admin_url('admin-ajax.php'),
|
||||
'nonce' => wp_create_nonce('mc4wp-ajax'),
|
||||
'mailchimp' => array(
|
||||
'api_connected' => $connected,
|
||||
'lists' => $mailchimp_lists,
|
||||
),
|
||||
'countries' => MC4WP_Tools::get_countries(),
|
||||
'i18n' => array(
|
||||
'invalid_api_key' => __('The given value does not look like a valid Mailchimp API key.', 'mailchimp-for-wp'),
|
||||
'pro_only' => __('This is a premium feature. Please upgrade to Mailchimp for WordPress Premium to be able to use it.', 'mailchimp-for-wp'),
|
||||
'renew_mailchimp_lists' => __('Renew Mailchimp lists', 'mailchimp-for-wp'),
|
||||
'fetching_mailchimp_lists' => __('Fetching Mailchimp lists', 'mailchimp-for-wp'),
|
||||
'fetching_mailchimp_lists_done' => __('Done! Mailchimp lists renewed.', 'mailchimp-for-wp'),
|
||||
'fetching_mailchimp_lists_error' => __('Failed to renew your lists. An error occured.', 'mailchimp-for-wp'),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Hook to enqueue your own custom assets on the Mailchimp for WordPress setting pages.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $suffix
|
||||
* @param string $page
|
||||
*/
|
||||
do_action('mc4wp_admin_enqueue_assets', '', $page);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Register the setting pages and their menu items
|
||||
*/
|
||||
public function build_menu()
|
||||
{
|
||||
$required_cap = $this->tools->get_required_capability();
|
||||
|
||||
$menu_items = array(
|
||||
array(
|
||||
'title' => esc_html__('Mailchimp API Settings', 'mailchimp-for-wp'),
|
||||
'text' => 'Mailchimp',
|
||||
'slug' => '',
|
||||
'callback' => array( $this, 'show_generals_setting_page' ),
|
||||
'position' => 0,
|
||||
),
|
||||
array(
|
||||
'title' => esc_html__('Other Settings', 'mailchimp-for-wp'),
|
||||
'text' => esc_html__('Other', 'mailchimp-for-wp'),
|
||||
'slug' => 'other',
|
||||
'callback' => array( $this, 'show_other_setting_page' ),
|
||||
'position' => 90,
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the menu items to appear under the main menu item.
|
||||
*
|
||||
* To add your own item, add an associative array in the following format.
|
||||
*
|
||||
* $menu_items[] = array(
|
||||
* 'title' => 'Page title',
|
||||
* 'text' => 'Menu text',
|
||||
* 'slug' => 'Page slug',
|
||||
* 'callback' => 'my_page_function',
|
||||
* 'position' => 50
|
||||
* );
|
||||
*
|
||||
* @param array $menu_items
|
||||
* @since 3.0
|
||||
*/
|
||||
$menu_items = (array) apply_filters('mc4wp_admin_menu_items', $menu_items);
|
||||
|
||||
// add top menu item
|
||||
$icon = file_get_contents(MC4WP_PLUGIN_DIR . '/assets/img/icon.svg');
|
||||
add_menu_page('Mailchimp for WP', 'MC4WP', $required_cap, 'mailchimp-for-wp', array( $this, 'show_generals_setting_page' ), 'data:image/svg+xml;base64,' . base64_encode($icon), '99.68491');
|
||||
|
||||
// sort submenu items by 'position'
|
||||
usort($menu_items, array( $this, 'sort_menu_items_by_position' ));
|
||||
|
||||
// add sub-menu items
|
||||
foreach ($menu_items as $item) {
|
||||
$this->add_menu_item($item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $item
|
||||
*/
|
||||
public function add_menu_item(array $item)
|
||||
{
|
||||
|
||||
// generate menu slug
|
||||
$slug = 'mailchimp-for-wp';
|
||||
if (! empty($item['slug'])) {
|
||||
$slug .= '-' . $item['slug'];
|
||||
}
|
||||
|
||||
// provide some defaults
|
||||
$parent_slug = ! empty($item['parent_slug']) ? $item['parent_slug'] : 'mailchimp-for-wp';
|
||||
$capability = ! empty($item['capability']) ? $item['capability'] : $this->tools->get_required_capability();
|
||||
|
||||
// register page
|
||||
$hook = add_submenu_page($parent_slug, $item['title'] . ' - Mailchimp for WordPress', $item['text'], $capability, $slug, $item['callback']);
|
||||
|
||||
// register callback for loading this page, if given
|
||||
if (array_key_exists('load_callback', $item)) {
|
||||
add_action('load-' . $hook, $item['load_callback']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the API Settings page
|
||||
*/
|
||||
public function show_generals_setting_page()
|
||||
{
|
||||
$opts = mc4wp_get_options();
|
||||
$api_key = mc4wp_get_api_key();
|
||||
$lists = array();
|
||||
$connected = ! empty($api_key);
|
||||
|
||||
if ($connected) {
|
||||
try {
|
||||
$connected = $this->get_api()->is_connected();
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$lists = $mailchimp->get_lists();
|
||||
} catch (MC4WP_API_Connection_Exception $e) {
|
||||
$message = sprintf('<strong>%s</strong> %s %s ', esc_html__('Error connecting to Mailchimp:', 'mailchimp-for-wp'), $e->getCode(), $e->getMessage());
|
||||
|
||||
if (is_object($e->response_data) && ! empty($e->response_data->ref_no)) {
|
||||
$message .= '<br />' . sprintf(esc_html__('Looks like your server is blocked by Mailchimp\'s firewall. Please contact Mailchimp support and include the following reference number: %s', 'mailchimp-for-wp'), $e->response_data->ref_no);
|
||||
}
|
||||
|
||||
$message .= '<br /><br />' . sprintf('<a href="%s">' . esc_html__('Here\'s some info on solving common connectivity issues.', 'mailchimp-for-wp') . '</a>', 'https://www.mc4wp.com/kb/solving-connectivity-issues/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=settings-notice');
|
||||
|
||||
$this->messages->flash($message, 'error');
|
||||
$connected = false;
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
$message = sprintf('<strong>%s</strong><br /> %s', esc_html__('Mailchimp returned the following error:', 'mailchimp-for-wp'), nl2br((string) $e));
|
||||
$this->messages->flash($message, 'error');
|
||||
$connected = false;
|
||||
}
|
||||
}
|
||||
|
||||
$obfuscated_api_key = mc4wp_obfuscate_string($api_key);
|
||||
require MC4WP_PLUGIN_DIR . '/includes/views/general-settings.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the Other Settings page
|
||||
*/
|
||||
public function show_other_setting_page()
|
||||
{
|
||||
$opts = mc4wp_get_options();
|
||||
$log = $this->get_log();
|
||||
$log_reader = new MC4WP_Debug_Log_Reader($log->file);
|
||||
require MC4WP_PLUGIN_DIR . '/includes/views/other-settings.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $a
|
||||
* @param $b
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function sort_menu_items_by_position($a, $b)
|
||||
{
|
||||
$pos_a = isset($a['position']) ? $a['position'] : 80;
|
||||
$pos_b = isset($b['position']) ? $b['position'] : 90;
|
||||
return $pos_a < $pos_b ? -1 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties the log file
|
||||
*/
|
||||
public function empty_debug_log()
|
||||
{
|
||||
$log = $this->get_log();
|
||||
file_put_contents($log->file, '');
|
||||
|
||||
$this->messages->flash(esc_html__('Log successfully emptied.', 'mailchimp-for-wp'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a notice when API key is not set.
|
||||
*/
|
||||
public function show_api_key_notice()
|
||||
{
|
||||
|
||||
// don't show if on settings page already
|
||||
if ($this->tools->on_plugin_page('')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// only show to user with proper permissions
|
||||
if (! $this->tools->is_user_authorized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't show if dismissed
|
||||
if (get_transient('mc4wp_api_key_notice_dismissed')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't show if api key is set already
|
||||
$api_key = mc4wp_get_api_key();
|
||||
if (! empty($api_key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<div class="notice notice-warning mc4wp-is-dismissible">';
|
||||
echo '<p>', sprintf(wp_kses(__('To get started with Mailchimp for WordPress, please <a href="%s">enter your Mailchimp API key on the settings page of the plugin</a>.', 'mailchimp-for-wp'), array( 'a' => array( 'href' => array() ) )), admin_url('admin.php?page=mailchimp-for-wp')), '</p>';
|
||||
echo '<form method="post"><input type="hidden" name="_mc4wp_action" value="dismiss_api_key_notice" /><button type="submit" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button></form>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses the API key notice for 1 week
|
||||
*/
|
||||
public function dismiss_api_key_notice()
|
||||
{
|
||||
set_transient('mc4wp_api_key_notice_dismissed', 1, 3600 * 24 * 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MC4WP_Debug_Log
|
||||
*/
|
||||
protected function get_log()
|
||||
{
|
||||
return mc4wp('log');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MC4WP_API_V3
|
||||
*/
|
||||
protected function get_api()
|
||||
{
|
||||
return mc4wp('api');
|
||||
}
|
||||
}
|
||||
163
wp-content/plugins/mailchimp-for-wp/includes/admin/class-ads.php
Normal file
163
wp-content/plugins/mailchimp-for-wp/includes/admin/class-ads.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Admin_Ads
|
||||
*
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Admin_Ads
|
||||
{
|
||||
/**
|
||||
* @return bool Adds hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
|
||||
// don't hook if Premium is activated
|
||||
if (defined('MC4WP_PREMIUM_VERSION')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
add_filter('mc4wp_admin_plugin_meta_links', array( $this, 'plugin_meta_links' ));
|
||||
add_action('mc4wp_admin_form_after_behaviour_settings_rows', array( $this, 'after_form_settings_rows' ));
|
||||
add_action('mc4wp_admin_form_after_appearance_settings_rows', array( $this, 'after_form_appearance_settings_rows' ));
|
||||
add_action('mc4wp_admin_sidebar', array( $this, 'admin_sidebar' ));
|
||||
add_action('mc4wp_admin_footer', array( $this, 'admin_footer' ));
|
||||
add_action('mc4wp_admin_other_settings', array( $this, 'ecommerce' ), 90);
|
||||
|
||||
add_filter('mc4wp_admin_menu_items', array( $this, 'add_menu_item' ));
|
||||
|
||||
add_action('mc4wp_admin_after_woocommerce_integration_settings', array( $this, 'ecommerce' ));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function add_menu_item($items)
|
||||
{
|
||||
$items['extensions'] = array(
|
||||
'title' => __('Add-ons', 'mailchimp-for-wp'),
|
||||
'text' => __('Add-ons', 'mailchimp-for-wp'),
|
||||
'slug' => 'extensions',
|
||||
'callback' => array( $this, 'show_extensions_page' ),
|
||||
'position' => 100,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add text row to "Form > Appearance" tab.
|
||||
*/
|
||||
public function after_form_appearance_settings_rows()
|
||||
{
|
||||
echo '<tr>';
|
||||
echo '<td colspan="2">';
|
||||
echo '<p class="description">';
|
||||
echo sprintf(__('Want to customize the style of your form? <a href="%s">Try our Styles Builder</a> & edit the look of your forms with just a few clicks.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=form-settings-link');
|
||||
echo '</p>';
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add text row to "Form > Settings" tab.
|
||||
*/
|
||||
public function after_form_settings_rows()
|
||||
{
|
||||
echo '<tr>';
|
||||
echo '<td colspan="2">';
|
||||
echo '<p class="description">';
|
||||
|
||||
if (rand(1, 2) === 1) {
|
||||
echo sprintf(__('Be notified whenever someone subscribes? <a href="%s">Mailchimp for WordPress Premium</a> allows you to set up email notifications for your forms.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=footer-link');
|
||||
} else {
|
||||
echo sprintf(__('Increased conversions? <a href="%s">Mailchimp for WordPress Premium</a> submits forms without reloading the entire page, resulting in a much better experience for your visitors.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=form-settings-link');
|
||||
}
|
||||
|
||||
echo '</p>';
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $links
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function plugin_meta_links($links)
|
||||
{
|
||||
$links[] = '<a href="https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=plugins-upgrade-link">' . __('Upgrade to Premium', 'mailchimp-for-wp') . '</a>';
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add several texts to admin footer.
|
||||
*/
|
||||
public function admin_footer()
|
||||
{
|
||||
if (isset($_GET['view']) && $_GET['view'] === 'edit-form') {
|
||||
// WPML & Polylang specific message
|
||||
if (defined('ICL_LANGUAGE_CODE')) {
|
||||
echo '<p class="description">' . sprintf(__('Do you want translated forms for all of your languages? <a href="%s">Try Mailchimp for WordPress Premium</a>, which does just that plus more.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=footer-link') . '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
// General "edit form" message
|
||||
echo '<p class="description">' . sprintf(__('Do you want to create more than one form? Our Premium add-on does just that! <a href="%s">Have a look at all Premium benefits</a>.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=footer-link') . '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
// General message
|
||||
echo '<p class="description">' . sprintf(__('Are you enjoying this plugin? The Premium add-on unlocks several powerful features. <a href="%s">Find out about all benefits now</a>.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=footer-link') . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add email opt-in form to sidebar
|
||||
*/
|
||||
public function admin_sidebar()
|
||||
{
|
||||
echo '<style>.mc4wp-premium-box {
|
||||
background: #fff8c5;
|
||||
border: 1px solid #d4a72c66;
|
||||
padding: 1em;
|
||||
}</style>';
|
||||
echo '<div class="mc4wp-box">';
|
||||
echo '<div class="mc4wp-premium-box">';
|
||||
echo '<h3>Mailchimp for WordPress Premium</h3>';
|
||||
echo '<p>';
|
||||
echo 'You are currently using the free version of Mailchimp for WordPress. ';
|
||||
echo '</p>';
|
||||
echo '<p>';
|
||||
echo 'There is a Premium version of this plugin that adds several powerful features. Like multiple and improved sign-up forms, an easier way to visually enhance those forms, advanced e-commerce integration and keeping track of all sign-up attempts in your local WordPress database.';
|
||||
echo '</p>';
|
||||
echo '<p>You can have all those benefits for a small yearly fee. <a href="https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=upgrade-box">Take a look at Mailchimp for WordPress Premium here</a>.</p>';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Show notice about E-Commerce integration in Premium.
|
||||
*/
|
||||
public function ecommerce()
|
||||
{
|
||||
// detect whether WooCommerce is installed & activated.
|
||||
if (! class_exists('WooCommerce')) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<div class="mc4wp-margin-m">';
|
||||
echo '<h3>Advanced WooCommerce integration for Mailchimp</h3>';
|
||||
echo '<p>';
|
||||
echo __('Do you want to track all WooCommerce orders in Mailchimp so you can send emails based on the purchase activity of your subscribers?', 'mailchimp-for-wp');
|
||||
echo '</p>';
|
||||
echo '<p>';
|
||||
echo sprintf(__('<a href="%1$s">Upgrade to Mailchimp for WordPress Premium</a> or <a href="%2$s">read more about Mailchimp\'s E-Commerce features</a>.', 'mailchimp-for-wp') . '</p>', 'https://www.mc4wp.com/premium-features/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=other-settings-link', 'https://www.mc4wp.com/kb/what-is-ecommerce360/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=other-settings-link');
|
||||
echo '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
public function show_extensions_page()
|
||||
{
|
||||
require MC4WP_PLUGIN_DIR . '/includes/views/extensions.php';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Admin_Review_Notice
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Admin_Review_Notice
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Admin_Tools
|
||||
*/
|
||||
protected $tools;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $meta_key_dismissed = '_mc4wp_review_notice_dismissed';
|
||||
|
||||
/**
|
||||
* MC4WP_Admin_Review_Notice constructor.
|
||||
*
|
||||
* @param MC4WP_Admin_Tools $tools
|
||||
*/
|
||||
public function __construct(MC4WP_Admin_Tools $tools)
|
||||
{
|
||||
$this->tools = $tools;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add action & filter hooks.
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('admin_notices', array( $this, 'show' ));
|
||||
add_action('mc4wp_admin_dismiss_review_notice', array( $this, 'dismiss' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set flag in user meta so notice won't be shown.
|
||||
*/
|
||||
public function dismiss()
|
||||
{
|
||||
$user = wp_get_current_user();
|
||||
update_user_meta($user->ID, $this->meta_key_dismissed, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function show()
|
||||
{
|
||||
// only show on Mailchimp for WordPress' pages.
|
||||
if (! $this->tools->on_plugin_page()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// only show if 2 weeks have passed since first use.
|
||||
$two_weeks_in_seconds = ( 60 * 60 * 24 * 14 );
|
||||
if ($this->time_since_first_use() <= $two_weeks_in_seconds) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// only show if user did not dismiss before
|
||||
$user = wp_get_current_user();
|
||||
if (get_user_meta($user->ID, $this->meta_key_dismissed, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
echo '<div class="notice notice-info mc4wp-is-dismissible" id="mc4wp-review-notice">';
|
||||
echo '<p>';
|
||||
echo esc_html__('You\'ve been using Mailchimp for WordPress for some time now; we hope you love it!', 'mailchimp-for-wp'), ' <br />';
|
||||
echo sprintf(wp_kses(__('If you do, please <a href="%s">leave us a 5★ rating on WordPress.org</a>. It would be of great help to us.', 'mailchimp-for-wp'), array( 'a' => array( 'href' => array() ) )), 'https://wordpress.org/support/view/plugin-reviews/mailchimp-for-wp?rate=5#new-post');
|
||||
echo '</p>';
|
||||
echo '<form method="POST" id="mc4wp-dismiss-review-form"><button type="submit" class="notice-dismiss"><span class="screen-reader-text">', esc_html__('Dismiss this notice.', 'mailchimp-for-wp'), '</span></button><input type="hidden" name="_mc4wp_action" value="dismiss_review_notice" />', wp_nonce_field('_mc4wp_action', '_wpnonce', true, false), '</form>';
|
||||
echo '</div>';
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function time_since_first_use()
|
||||
{
|
||||
$options = get_option('mc4wp', array());
|
||||
if (! is_array($options)) {
|
||||
$options = array();
|
||||
}
|
||||
|
||||
// option was never added before, do it now.
|
||||
if (empty($options['first_activated_on'])) {
|
||||
$options['first_activated_on'] = time();
|
||||
update_option('mc4wp', $options);
|
||||
}
|
||||
|
||||
return time() - $options['first_activated_on'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_DB_Upgrader
|
||||
*
|
||||
* This class takes care of loading migration files from the specified migrations directory.
|
||||
* Migration files should only use default WP functions and NOT use code which might not be there in the future.
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Upgrade_Routines
|
||||
{
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $version_from = 0;
|
||||
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
protected $version_to = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $migrations_dir = '';
|
||||
|
||||
/**
|
||||
* @param float $from
|
||||
* @param float $to
|
||||
*/
|
||||
public function __construct($from, $to, $migrations_dir)
|
||||
{
|
||||
$this->version_from = $from;
|
||||
$this->version_to = $to;
|
||||
$this->migrations_dir = $migrations_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the various upgrade routines, all the way up to the latest version
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$migrations = $this->find_migrations();
|
||||
|
||||
// run in sub-function for scope
|
||||
array_map(array( $this, 'run_migration' ), $migrations);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function find_migrations()
|
||||
{
|
||||
$files = glob(rtrim($this->migrations_dir, '/') . '/*.php');
|
||||
$migrations = array();
|
||||
|
||||
// return empty array when glob returns non-array value.
|
||||
if (! is_array($files)) {
|
||||
return $migrations;
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
$migration = basename($file);
|
||||
$parts = explode('-', $migration);
|
||||
$version = $parts[0];
|
||||
|
||||
if (version_compare($this->version_from, $version, '<')) {
|
||||
$migrations[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
return $migrations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include a migration file and runs it.
|
||||
*
|
||||
* @param string $file
|
||||
*/
|
||||
protected function run_migration($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
// get options
|
||||
$form_options = get_option('mc4wp_lite_form', array());
|
||||
|
||||
// bail if there are no previous options
|
||||
if (empty($form_options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// bail if there are Pro forms already
|
||||
$has_forms = get_posts(
|
||||
array(
|
||||
'post_type' => 'mc4wp-form',
|
||||
'post_status' => 'publish',
|
||||
'numberposts' => 1,
|
||||
)
|
||||
);
|
||||
|
||||
// There are forms already, don't continue.
|
||||
if (! empty($has_forms)) {
|
||||
// delete option as it apparently exists.
|
||||
delete_option('mc4wp_lite_form');
|
||||
return;
|
||||
}
|
||||
|
||||
// create post type for form
|
||||
$id = wp_insert_post(
|
||||
array(
|
||||
'post_type' => 'mc4wp-form',
|
||||
'post_status' => 'publish',
|
||||
'post_title' => __('Default sign-up form', 'mailchimp-for-wp'),
|
||||
'post_content' => ( empty($form_options['markup']) ) ? '' : $form_options['markup'],
|
||||
)
|
||||
);
|
||||
|
||||
// set default_form_id
|
||||
update_option('mc4wp_default_form_id', $id);
|
||||
|
||||
// set form settings
|
||||
$setting_keys = array(
|
||||
'css',
|
||||
'custom_theme_color',
|
||||
'double_optin',
|
||||
'update_existing',
|
||||
'replace_interests',
|
||||
'send_welcome',
|
||||
'redirect',
|
||||
'hide_after_success',
|
||||
);
|
||||
|
||||
$settings = array();
|
||||
|
||||
foreach ($setting_keys as $setting_key) {
|
||||
// use isset to account for "0" settings
|
||||
if (isset($form_options[ $setting_key ])) {
|
||||
$settings[ $setting_key ] = $form_options[ $setting_key ];
|
||||
}
|
||||
}
|
||||
|
||||
// get only keys of lists setting
|
||||
if (isset($form_options['lists'])) {
|
||||
$settings['lists'] = array_keys($form_options['lists']);
|
||||
}
|
||||
|
||||
update_post_meta($id, '_mc4wp_settings', $settings);
|
||||
|
||||
// set form message texts
|
||||
$message_keys = array(
|
||||
'text_subscribed',
|
||||
'text_error',
|
||||
'text_invalid_email',
|
||||
'text_already_subscribed',
|
||||
'text_required_field_missing',
|
||||
'text_unsubscribed',
|
||||
'text_not_subscribed',
|
||||
);
|
||||
|
||||
foreach ($message_keys as $message_key) {
|
||||
if (! empty($form_options[ $message_key ])) {
|
||||
update_post_meta($id, $message_key, $form_options[ $message_key ]);
|
||||
}
|
||||
}
|
||||
|
||||
// delete old option
|
||||
delete_option('mc4wp_lite_form');
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
$global_options = (array) get_option('mc4wp_form', array());
|
||||
|
||||
// find all form posts
|
||||
$posts = get_posts(
|
||||
array(
|
||||
'post_type' => 'mc4wp-form',
|
||||
'post_status' => 'publish',
|
||||
'numberposts' => -1,
|
||||
)
|
||||
);
|
||||
|
||||
$css_map = array(
|
||||
'default' => 'basic',
|
||||
'custom' => 'styles-builder',
|
||||
'light' => 'theme-light',
|
||||
'dark' => 'theme-dark',
|
||||
'red' => 'theme-red',
|
||||
'green' => 'theme-green',
|
||||
'blue' => 'theme-blue',
|
||||
'custom-color' => 'theme-custom-color',
|
||||
);
|
||||
|
||||
$stylesheets = array();
|
||||
|
||||
foreach ($posts as $post) {
|
||||
// get form options from post meta directly
|
||||
$options = (array) get_post_meta($post->ID, '_mc4wp_settings', true);
|
||||
|
||||
// store all global options in scoped form settings
|
||||
// do this BEFORE changing css key, so we take that as well.
|
||||
foreach ($global_options as $key => $value) {
|
||||
if (strlen($value) > 0 && ( ! isset($options[ $key ]) || strlen($options[ $key ]) == 0 )) {
|
||||
$options[ $key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// update "css" option value
|
||||
if (isset($options['css']) && isset($css_map[ $options['css'] ])) {
|
||||
$options['css'] = $css_map[ $options['css'] ];
|
||||
}
|
||||
|
||||
// create stylesheets option
|
||||
if (! empty($options['css'])) {
|
||||
$stylesheet = $options['css'];
|
||||
if (strpos($stylesheet, 'theme-') === 0) {
|
||||
$stylesheet = 'themes';
|
||||
}
|
||||
|
||||
if (! in_array($stylesheet, $stylesheets)) {
|
||||
$stylesheets[] = $stylesheet;
|
||||
}
|
||||
}
|
||||
|
||||
update_post_meta($post->ID, '_mc4wp_settings', $options);
|
||||
}
|
||||
|
||||
// update stylesheets option
|
||||
update_option('mc4wp_form_stylesheets', $stylesheets);
|
||||
|
||||
// delete old options
|
||||
delete_option('mc4wp_form');
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
// find all form posts
|
||||
$posts = get_posts(
|
||||
array(
|
||||
'post_type' => 'mc4wp-form',
|
||||
'post_status' => 'publish',
|
||||
'numberposts' => -1,
|
||||
)
|
||||
);
|
||||
|
||||
// set form message texts
|
||||
$message_keys = array(
|
||||
'text_subscribed',
|
||||
'text_error',
|
||||
'text_invalid_email',
|
||||
'text_already_subscribed',
|
||||
'text_required_field_missing',
|
||||
'text_unsubscribed',
|
||||
'text_not_subscribed',
|
||||
);
|
||||
|
||||
foreach ($posts as $post) {
|
||||
$settings = get_post_meta($post->ID, '_mc4wp_settings', true);
|
||||
|
||||
foreach ($message_keys as $key) {
|
||||
if (empty($settings[ $key ])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$message = $settings[ $key ];
|
||||
|
||||
// move message setting over to post meta
|
||||
update_post_meta($post->ID, $key, $message);
|
||||
unset($settings[ $key ]);
|
||||
}
|
||||
|
||||
// update post meta with unset message keys
|
||||
update_post_meta($post->ID, '_mc4wp_settings', $settings);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
// transfer option
|
||||
$options = (array) get_option('mc4wp_lite', array());
|
||||
|
||||
// merge options, with Pro options taking precedence
|
||||
$pro_options = (array) get_option('mc4wp', array());
|
||||
$options = array_merge($options, $pro_options);
|
||||
|
||||
// update options
|
||||
update_option('mc4wp', $options);
|
||||
|
||||
// delete old option
|
||||
delete_option('mc4wp_lite');
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
$old_options = get_option('mc4wp_lite_checkbox', array());
|
||||
$pro_options = get_option('mc4wp_checkbox', array());
|
||||
if (! empty($pro_options)) {
|
||||
$old_options = array_merge($old_options, $pro_options);
|
||||
}
|
||||
|
||||
// do we have to do something?
|
||||
if (empty($old_options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// find activated integrations (show_at_xxx options)
|
||||
$new_options = array();
|
||||
$map = array(
|
||||
'comment_form' => 'wp-comment-form',
|
||||
'registration_form' => 'wp-registration-form',
|
||||
'buddypress_form' => 'buddypress',
|
||||
'bbpres_forms' => 'bbpress',
|
||||
'woocommerce_checkout' => 'woocommerce',
|
||||
'edd_checkout' => 'easy-digital-downloads',
|
||||
);
|
||||
|
||||
$option_keys = array(
|
||||
'label',
|
||||
'precheck',
|
||||
'css',
|
||||
'lists',
|
||||
'double_optin',
|
||||
'update_existing',
|
||||
'replace_interests',
|
||||
'send_welcome',
|
||||
);
|
||||
|
||||
foreach ($map as $old_integration_slug => $new_integration_slug) {
|
||||
// check if integration is enabled using its old slug
|
||||
$show_key = sprintf('show_at_%s', $old_integration_slug);
|
||||
if (empty($old_options[ $show_key ])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'enabled' => 1,
|
||||
);
|
||||
|
||||
foreach ($option_keys as $option_key) {
|
||||
if (isset($old_options[ $option_key ])) {
|
||||
$options[ $option_key ] = $old_options[ $option_key ];
|
||||
}
|
||||
}
|
||||
|
||||
// add to new options
|
||||
$new_options[ $new_integration_slug ] = $options;
|
||||
}
|
||||
|
||||
// save new settings
|
||||
update_option('mc4wp_integrations', $new_options);
|
||||
|
||||
// delete old options
|
||||
delete_option('mc4wp_lite_checkbox');
|
||||
delete_option('mc4wp_checkbox');
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
// move stylebuilders file to bundle
|
||||
$file = (string) get_option('mc4wp_custom_css_file', '');
|
||||
if (empty($file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$uploads = wp_upload_dir();
|
||||
|
||||
// figure out absolute file path
|
||||
$prefix = str_replace('http:', '', $uploads['baseurl']);
|
||||
$relative_path = str_replace($prefix, '', $file);
|
||||
|
||||
// get part before ?
|
||||
if (strpos($relative_path, '?') !== false) {
|
||||
$parts = explode('?', $relative_path);
|
||||
$relative_path = array_shift($parts);
|
||||
}
|
||||
|
||||
// This is the absolute path to the file, he he..
|
||||
$file = $uploads['basedir'] . $relative_path;
|
||||
|
||||
if (file_exists($file)) {
|
||||
// create directory, if necessary
|
||||
$dir = $uploads['basedir'] . '/mc4wp-stylesheets';
|
||||
if (! file_exists($dir)) {
|
||||
@mkdir($dir, 0755);
|
||||
}
|
||||
|
||||
@chmod($dir, 0755);
|
||||
|
||||
// Move file to new location
|
||||
$new_file = $dir . '/bundle.css';
|
||||
$success = rename($file, $new_file);
|
||||
}
|
||||
|
||||
// remove old option
|
||||
delete_option('mc4wp_custom_css_file');
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
$section_widgets = get_option('sidebars_widgets', array());
|
||||
$replaced = false;
|
||||
|
||||
foreach ($section_widgets as $section => $widgets) {
|
||||
// WP has an "array_version" key that is not an array...
|
||||
if (! is_array($widgets)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// loop through widget ID's
|
||||
foreach ($widgets as $key => $widget_id) {
|
||||
// does this widget ID start with "mc4wp_widget"?
|
||||
if (strpos($widget_id, 'mc4wp_widget') === 0) {
|
||||
// replace "mc4wp_widget" with "mc4wp_form_widget"
|
||||
$new_widget_id = str_replace('mc4wp_widget', 'mc4wp_form_widget', $widget_id);
|
||||
$section_widgets[ $section ][ $key ] = $new_widget_id;
|
||||
$replaced = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update option if we made changes
|
||||
if ($replaced) {
|
||||
update_option('sidebars_widgets', $section_widgets);
|
||||
}
|
||||
|
||||
// update widget options
|
||||
$options = get_option('widget_mc4wp_widget', false);
|
||||
if ($options) {
|
||||
update_option('widget_mc4wp_form_widget', $options);
|
||||
|
||||
// delete old option
|
||||
delete_option('widget_mc4wp_widget');
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
$options = get_option('mc4wp_integrations', array());
|
||||
|
||||
if (! empty($options['woocommerce']) && ! empty($options['woocommerce']['position'])) {
|
||||
$options['woocommerce']['position'] = sprintf('checkout_%s', $options['woocommerce']['position']);
|
||||
}
|
||||
|
||||
update_option('mc4wp_integrations', $options);
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @return object
|
||||
*/
|
||||
function _mc4wp_400_find_grouping_for_interest_category($groupings, $interest_category)
|
||||
{
|
||||
foreach ($groupings as $grouping) {
|
||||
// cast to stdClass because of missing class
|
||||
$grouping = (object) (array) $grouping;
|
||||
|
||||
if ($grouping->name === $interest_category->title) {
|
||||
return $grouping;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @return object
|
||||
*/
|
||||
function _mc4wp_400_find_group_for_interest($groups, $interest)
|
||||
{
|
||||
foreach ($groups as $group_id => $group_name) {
|
||||
if ($group_name === $interest->name) {
|
||||
return (object) array(
|
||||
'name' => $group_name,
|
||||
'id' => $group_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// in case the migration is _very_ late to the party
|
||||
if (! class_exists('MC4WP_API_V3')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$options = get_option('mc4wp', array());
|
||||
if (empty($options['api_key'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get current state from transient
|
||||
$lists = get_transient('mc4wp_mailchimp_lists_fallback');
|
||||
if (empty($lists)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@set_time_limit(600);
|
||||
$api_v3 = new MC4WP_API_V3($options['api_key']);
|
||||
$map = array();
|
||||
|
||||
foreach ($lists as $list) {
|
||||
// cast to stdClass because of missing classes
|
||||
$list = (object) (array) $list;
|
||||
|
||||
// no groupings? easy!
|
||||
if (empty($list->groupings)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// fetch (new) interest categories for this list
|
||||
try {
|
||||
$interest_categories = $api_v3->get_list_interest_categories($list->id);
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
foreach ($interest_categories as $interest_category) {
|
||||
// compare interest title with grouping name, if it matches, get new id.
|
||||
$grouping = _mc4wp_400_find_grouping_for_interest_category($list->groupings, $interest_category);
|
||||
if (! $grouping) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
|
||||
try {
|
||||
$interests = $api_v3->get_list_interest_category_interests($list->id, $interest_category->id);
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($interests as $interest) {
|
||||
$group = _mc4wp_400_find_group_for_interest($grouping->groups, $interest);
|
||||
|
||||
if ($group) {
|
||||
$groups[ $group->id ] = $interest->id;
|
||||
$groups[ $group->name ] = $interest->id;
|
||||
}
|
||||
}
|
||||
|
||||
$map[ (string) $grouping->id ] = array(
|
||||
'id' => $interest_category->id,
|
||||
'groups' => $groups,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (! empty($map)) {
|
||||
update_option('mc4wp_groupings_map', $map);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
/** @ignore */
|
||||
function _mc4wp_400_replace_comma_with_pipe($matches)
|
||||
{
|
||||
$old = $matches[1];
|
||||
$new = str_replace(',', '|', $old);
|
||||
return str_replace($old, $new, $matches[0]);
|
||||
}
|
||||
|
||||
// get all forms
|
||||
$posts = get_posts(
|
||||
array(
|
||||
'post_type' => 'mc4wp-form',
|
||||
'numberposts' => -1,
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($posts as $post) {
|
||||
// find hidden field values in form and pass through replace function
|
||||
$old = $post->post_content;
|
||||
$new = preg_replace_callback('/type="hidden" .* value="(.*)"/i', '_mc4wp_400_replace_comma_with_pipe', $old);
|
||||
|
||||
// update post if we replaced something
|
||||
if ($new != $old) {
|
||||
$post->post_content = $new;
|
||||
wp_update_post($post);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
// get old log filename
|
||||
$upload_dir = wp_upload_dir(null, false);
|
||||
$old_filename = trailingslashit($upload_dir['basedir']) . 'mc4wp-debug.log';
|
||||
$new_filename = trailingslashit($upload_dir['basedir']) . 'mc4wp-debug-log.php';
|
||||
|
||||
// check if old default log file exists
|
||||
if (! file_exists($old_filename)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// rename to new file.
|
||||
@rename($old_filename, $new_filename);
|
||||
|
||||
// if success, insert php exit tag as first line
|
||||
if (file_exists($new_filename)) {
|
||||
$handle = fopen($new_filename, 'r+');
|
||||
|
||||
if (is_resource($handle)) {
|
||||
// make sure first line of log file is a PHP tag + exit statement (to prevent direct file access)
|
||||
$line = fgets($handle);
|
||||
$php_exit_string = '<?php exit; ?>';
|
||||
if (strpos($line, $php_exit_string) !== 0) {
|
||||
rewind($handle);
|
||||
fwrite($handle, $php_exit_string . PHP_EOL . $line);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
if (function_exists('mc4wp_refresh_mailchimp_lists')) {
|
||||
mc4wp_refresh_mailchimp_lists();
|
||||
}
|
||||
|
||||
delete_transient('mc4wp_mailchimp_lists_v3');
|
||||
delete_option('mc4wp_mailchimp_lists_v3_fallback');
|
||||
|
||||
wp_schedule_event(strtotime('tomorrow 3 am'), 'daily', 'mc4wp_refresh_mailchimp_lists');
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
wp_clear_scheduled_hook('mc4wp_refresh_mailchimp_lists');
|
||||
|
||||
$time_string = sprintf('tomorrow %d:%d%d am', rand(1, 6), rand(0, 5), rand(0, 9));
|
||||
wp_schedule_event(strtotime($time_string), 'daily', 'mc4wp_refresh_mailchimp_lists');
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
global $wpdb;
|
||||
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'mc4wp_mailchimp_list_%'");
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
// get old filename
|
||||
$upload_dir = wp_upload_dir(null, false);
|
||||
$old_filename = trailingslashit($upload_dir['basedir']) . 'mc4wp-debug-log.php';
|
||||
|
||||
// if old file exists, move it to new location
|
||||
if (is_file($old_filename)) {
|
||||
$new_filename = $upload_dir['basedir'] . '/mailchimp-for-wp/debug-log.php';
|
||||
$dir = dirname($new_filename);
|
||||
if (! is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
rename($old_filename, $new_filename);
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
class MC4WP_API_V3_Client
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $api_key;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $api_url = 'https://api.mailchimp.com/3.0/';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $last_response;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $last_request;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $api_key
|
||||
*/
|
||||
public function __construct($api_key)
|
||||
{
|
||||
$this->api_key = $api_key;
|
||||
|
||||
$dash_position = strpos($api_key, '-');
|
||||
if ($dash_position !== false) {
|
||||
$this->api_url = str_replace('//api.', '//' . substr($api_key, $dash_position + 1) . '.api.', $this->api_url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $resource
|
||||
* @param array $args
|
||||
*
|
||||
* @return mixed
|
||||
* @throws MC4WP_API_Exception
|
||||
*/
|
||||
public function get($resource, array $args = array())
|
||||
{
|
||||
return $this->request('GET', $resource, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resource
|
||||
* @param array $data
|
||||
*
|
||||
* @return mixed
|
||||
* @throws MC4WP_API_Exception
|
||||
*/
|
||||
public function post($resource, array $data)
|
||||
{
|
||||
return $this->request('POST', $resource, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resource
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
* @throws MC4WP_API_Exception
|
||||
*/
|
||||
public function put($resource, array $data)
|
||||
{
|
||||
return $this->request('PUT', $resource, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resource
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
* @throws MC4WP_API_Exception
|
||||
*/
|
||||
public function patch($resource, array $data)
|
||||
{
|
||||
return $this->request('PATCH', $resource, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resource
|
||||
* @return mixed
|
||||
* @throws MC4WP_API_Exception
|
||||
*/
|
||||
public function delete($resource)
|
||||
{
|
||||
return $this->request('DELETE', $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $resource
|
||||
* @param array $data
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws MC4WP_API_Exception
|
||||
*/
|
||||
private function request($method, $resource, array $data = array())
|
||||
{
|
||||
$this->reset();
|
||||
|
||||
// don't bother if no API key was given.
|
||||
if (empty($this->api_key)) {
|
||||
throw new MC4WP_API_Exception('Missing API key', 001);
|
||||
}
|
||||
|
||||
$method = strtoupper(trim($method));
|
||||
$url = $this->api_url . ltrim($resource, '/');
|
||||
$args = array(
|
||||
'method' => $method,
|
||||
'headers' => $this->get_headers(),
|
||||
'timeout' => 20,
|
||||
'sslverify' => apply_filters('mc4wp_use_sslverify', true),
|
||||
);
|
||||
|
||||
if (! empty($data)) {
|
||||
if (in_array($method, array( 'GET', 'DELETE' ), true)) {
|
||||
$url = add_query_arg($data, $url);
|
||||
} else {
|
||||
$args['headers']['Content-Type'] = 'application/json';
|
||||
$args['body'] = json_encode($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the request arguments for all requests generated by this class
|
||||
*
|
||||
* @param array $args
|
||||
*/
|
||||
$args = apply_filters('mc4wp_http_request_args', $args, $url);
|
||||
|
||||
// perform request
|
||||
$response = wp_remote_request($url, $args);
|
||||
|
||||
// store request & response
|
||||
$args['url'] = $url;
|
||||
$this->last_request = $args;
|
||||
$this->last_response = $response;
|
||||
|
||||
// parse response
|
||||
$data = $this->parse_response($response);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_headers()
|
||||
{
|
||||
global $wp_version;
|
||||
|
||||
$headers = array(
|
||||
'Authorization' => sprintf('Basic %s', base64_encode('mc4wp:' . $this->api_key)),
|
||||
'User-Agent' => sprintf('mc4wp/%s; WordPress/%s; %s', MC4WP_VERSION, $wp_version, home_url()),
|
||||
);
|
||||
|
||||
// Copy Accept-Language from browser headers
|
||||
if (! empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
||||
$headers['Accept-Language'] = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|WP_Error $response
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws MC4WP_API_Connection_Exception|MC4WP_API_Resource_Not_Found_Exception|MC4WP_API_Exception
|
||||
*/
|
||||
private function parse_response($response)
|
||||
{
|
||||
if ($response instanceof WP_Error) {
|
||||
throw new MC4WP_API_Connection_Exception($response->get_error_message(), (int) $response->get_error_code(), $this->last_request);
|
||||
}
|
||||
|
||||
// decode response body
|
||||
$code = (int) wp_remote_retrieve_response_code($response);
|
||||
$message = wp_remote_retrieve_response_message($response);
|
||||
$body = wp_remote_retrieve_body($response);
|
||||
|
||||
// set body to "true" in case Mailchimp returned No Content
|
||||
if ($code < 300 && empty($body)) {
|
||||
$body = 'true';
|
||||
}
|
||||
|
||||
$data = json_decode($body);
|
||||
if ($code >= 400) {
|
||||
// check for akamai errors
|
||||
// {"type":"akamai_error_message","title":"akamai_503","status":503,"ref_no":"Reference Number: 00.950e16c3.1498559813.1450dbe2"}
|
||||
if (is_object($data) && isset($data->type) && $data->type === 'akamai_error_message') {
|
||||
throw new MC4WP_API_Connection_Exception($message, $code, $this->last_request, $this->last_response, $data);
|
||||
}
|
||||
|
||||
if ($code === 404) {
|
||||
throw new MC4WP_API_Resource_Not_Found_Exception($message, $code, $this->last_request, $this->last_response, $data);
|
||||
}
|
||||
|
||||
// mailchimp returned an error..
|
||||
throw new MC4WP_API_Exception($message, $code, $this->last_request, $this->last_response, $data);
|
||||
}
|
||||
|
||||
// throw exception if unable to decode response
|
||||
if ($data === null) {
|
||||
throw new MC4WP_API_Exception($message, $code, $this->last_request, $this->last_response);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties all data from previous response
|
||||
*/
|
||||
private function reset()
|
||||
{
|
||||
$this->last_response = null;
|
||||
$this->last_request = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_last_response_body()
|
||||
{
|
||||
return wp_remote_retrieve_body($this->last_response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_last_response_headers()
|
||||
{
|
||||
return wp_remote_retrieve_headers($this->last_response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function get_last_response()
|
||||
{
|
||||
return $this->last_response;
|
||||
}
|
||||
}
|
||||
1376
wp-content/plugins/mailchimp-for-wp/includes/api/class-api-v3.php
Normal file
1376
wp-content/plugins/mailchimp-for-wp/includes/api/class-api-v3.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class MC4WP_API_Connection_Exception extends MC4WP_API_Exception
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_API_Exception
|
||||
*
|
||||
* @property string $title
|
||||
* @property string $detail
|
||||
* @property array $errors
|
||||
*/
|
||||
class MC4WP_API_Exception extends Exception
|
||||
{
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
public $response = array();
|
||||
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
public $request = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $response_data = array();
|
||||
|
||||
/**
|
||||
* MC4WP_API_Exception constructor.
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $code
|
||||
* @param array $request
|
||||
* @param array $response
|
||||
* @param object $data
|
||||
*/
|
||||
public function __construct($message, $code, $request = null, $response = null, $data = null)
|
||||
{
|
||||
parent::__construct($message, $code);
|
||||
|
||||
$this->request = $request;
|
||||
$this->response = $response;
|
||||
|
||||
$this->response_data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backwards compatibility for direct property access.
|
||||
* @param string $property
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($property)
|
||||
{
|
||||
if (in_array($property, array( 'title', 'detail', 'errors' ), true)) {
|
||||
if (! empty($this->response_data) && isset($this->response_data->{$property})) {
|
||||
return $this->response_data->{$property};
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$string = $this->message . '.';
|
||||
|
||||
// add errors from response data returned by Mailchimp
|
||||
if (! empty($this->response_data)) {
|
||||
if (! empty($this->response_data->title) && $this->response_data->title !== $this->getMessage()) {
|
||||
$string .= ' ' . $this->response_data->title . '.';
|
||||
}
|
||||
|
||||
// add detail message
|
||||
if (! empty($this->response_data->detail)) {
|
||||
$string .= ' ' . $this->response_data->detail;
|
||||
}
|
||||
|
||||
// add field specific errors
|
||||
if (! empty($this->response_data->errors) && isset($this->response_data->errors[0]->field)) {
|
||||
// strip off obsolete msg
|
||||
$string = str_replace('For field-specific details, see the \'errors\' array.', '', $string);
|
||||
|
||||
// generate list of field errors
|
||||
$field_errors = array();
|
||||
foreach ($this->response_data->errors as $error) {
|
||||
if (! empty($error->field)) {
|
||||
$field_errors[] = sprintf('- %s : %s', $error->field, $error->message);
|
||||
} else {
|
||||
$field_errors[] = sprintf('- %s', $error->message);
|
||||
}
|
||||
}
|
||||
|
||||
$string .= " \n" . join("\n", $field_errors);
|
||||
}
|
||||
}
|
||||
|
||||
// Add request data
|
||||
if (! empty($this->request) && is_array($this->request)) {
|
||||
$string .= "\n\n" . sprintf("Request: \n%s %s\n", $this->request['method'], $this->request['url']);
|
||||
|
||||
// foreach ( $this->request['headers'] as $key => $value ) {
|
||||
// $string .= sprintf( "%s: %s\n", $key, $value );
|
||||
// }
|
||||
|
||||
if (! empty($this->request['body'])) {
|
||||
$string .= "\n" . $this->request['body'];
|
||||
}
|
||||
}
|
||||
|
||||
// Add response data
|
||||
if (! empty($this->response) && is_array($this->response)) {
|
||||
$response_code = wp_remote_retrieve_response_code($this->response);
|
||||
$response_message = wp_remote_retrieve_response_message($this->response);
|
||||
$response_body = wp_remote_retrieve_body($this->response);
|
||||
$string .= "\n\n" . sprintf("Response: \n%d %s\n%s", $response_code, $response_message, $response_body);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
class MC4WP_API_Resource_Not_Found_Exception extends MC4WP_API_Exception
|
||||
{
|
||||
// Thrown when a requested resource does not exist in Mailchimp
|
||||
}
|
||||
130
wp-content/plugins/mailchimp-for-wp/includes/class-container.php
Normal file
130
wp-content/plugins/mailchimp-for-wp/includes/class-container.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Service_Container
|
||||
*
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Container implements ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $services = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $resolved_services = array();
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return boolean
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return isset($this->services[ $name ]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (! $this->has($name)) {
|
||||
throw new Exception(sprintf('No service named %s was registered.', $name));
|
||||
}
|
||||
|
||||
$service = $this->services[ $name ];
|
||||
|
||||
// is this a resolvable service?
|
||||
if (is_callable($service)) {
|
||||
// resolve service if it's not resolved yet
|
||||
if (! isset($this->resolved_services[ $name ])) {
|
||||
$this->resolved_services[ $name ] = call_user_func($service);
|
||||
}
|
||||
|
||||
return $this->resolved_services[ $name ];
|
||||
}
|
||||
|
||||
return $this->services[ $name ];
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Whether a offset exists
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetexists.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* An offset to check for.
|
||||
* </p>
|
||||
*
|
||||
* @return boolean true on success or false on failure.
|
||||
* </p>
|
||||
* <p>
|
||||
* The return value will be casted to boolean if non-boolean was returned.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->has($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Offset to retrieve
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetget.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* The offset to retrieve.
|
||||
* </p>
|
||||
*
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Offset to set
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetset.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* The offset to assign the value to.
|
||||
* </p>
|
||||
* @param mixed $value <p>
|
||||
* The value to set.
|
||||
* </p>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->services[ $offset ] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Offset to unset
|
||||
* @link http://php.net/manual/en/arrayaccess.offsetunset.php
|
||||
*
|
||||
* @param mixed $offset <p>
|
||||
* The offset to unset.
|
||||
* </p>
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->services[ $offset ]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Debug_Log_Reader
|
||||
*/
|
||||
class MC4WP_Debug_Log_Reader
|
||||
{
|
||||
/**
|
||||
* @var resource|null
|
||||
*/
|
||||
private $handle;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $regex = '/^(\[[\d \-\:]+\]) (\w+\:) (.*)$/S';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private static $html_template = '<span class="time">$1</span> <span class="level">$2</span> <span class="message">$3</span>';
|
||||
|
||||
/**
|
||||
* @var string The log file location.
|
||||
*/
|
||||
private $file;
|
||||
|
||||
/**
|
||||
* MC4WP_Debug_Log_Reader constructor.
|
||||
*
|
||||
* @param $file
|
||||
*/
|
||||
public function __construct($file)
|
||||
{
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return file_get_contents($this->file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets file pointer to $n of lines from the end of file.
|
||||
*
|
||||
* @param int $n
|
||||
*/
|
||||
private function seek_line_from_end($n)
|
||||
{
|
||||
$line_count = 0;
|
||||
|
||||
// get line count
|
||||
while (! feof($this->handle)) {
|
||||
fgets($this->handle);
|
||||
++$line_count;
|
||||
}
|
||||
|
||||
// rewind to beginning
|
||||
rewind($this->handle);
|
||||
|
||||
// calculate target
|
||||
$target = $line_count - $n;
|
||||
$target = $target > 1 ? $target : 1; // always skip first line because oh PHP header
|
||||
$current = 0;
|
||||
|
||||
// keep reading until we're at target
|
||||
while ($current < $target) {
|
||||
fgets($this->handle);
|
||||
++$current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function read()
|
||||
{
|
||||
|
||||
// open file if not yet opened
|
||||
if (! is_resource($this->handle)) {
|
||||
// doesn't exist?
|
||||
if (! file_exists($this->file)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->handle = @fopen($this->file, 'r');
|
||||
|
||||
// unable to read?
|
||||
if (! is_resource($this->handle)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// set pointer to 1000 files from EOF
|
||||
$this->seek_line_from_end(1000);
|
||||
}
|
||||
|
||||
// stop reading once we're at the end
|
||||
if (feof($this->handle)) {
|
||||
fclose($this->handle);
|
||||
$this->handle = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
// read line, up to 8kb
|
||||
$text = fgets($this->handle);
|
||||
|
||||
// strip tags & trim
|
||||
$text = strip_tags($text);
|
||||
$text = trim($text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function read_as_html()
|
||||
{
|
||||
$line = $this->read();
|
||||
|
||||
// null means end of file
|
||||
if (is_null($line)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// empty string means empty line, but not yet eof
|
||||
if (empty($line)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$line = preg_replace(self::$regex, self::$html_template, $line);
|
||||
return $line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads X number of lines.
|
||||
*
|
||||
* If $start is negative, reads from end of log file.
|
||||
*
|
||||
* @param int $start
|
||||
* @param int $number
|
||||
* @return string
|
||||
*/
|
||||
public function lines($start, $number)
|
||||
{
|
||||
$handle = fopen($start, 'r');
|
||||
$lines = '';
|
||||
|
||||
$current_line = 0;
|
||||
while ($current_line < $number) {
|
||||
$lines .= fgets($handle);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
return $lines;
|
||||
}
|
||||
}
|
||||
233
wp-content/plugins/mailchimp-for-wp/includes/class-debug-log.php
Normal file
233
wp-content/plugins/mailchimp-for-wp/includes/class-debug-log.php
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Debug_Log
|
||||
*
|
||||
* Simple logging class which writes to a file, loosely based on PSR-3.
|
||||
*/
|
||||
class MC4WP_Debug_Log
|
||||
{
|
||||
/**
|
||||
* Detailed debug information
|
||||
*/
|
||||
const DEBUG = 100;
|
||||
|
||||
/**
|
||||
* Interesting events
|
||||
*
|
||||
* Examples: Visitor subscribed
|
||||
*/
|
||||
const INFO = 200;
|
||||
|
||||
/**
|
||||
* Exceptional occurrences that are not errors
|
||||
*
|
||||
* Examples: User already subscribed
|
||||
*/
|
||||
const WARNING = 300;
|
||||
|
||||
/**
|
||||
* Runtime errors
|
||||
*/
|
||||
const ERROR = 400;
|
||||
|
||||
/**
|
||||
* Logging levels from syslog protocol defined in RFC 5424
|
||||
*
|
||||
* @var array $levels Logging levels
|
||||
*/
|
||||
protected static $levels = array(
|
||||
self::DEBUG => 'DEBUG',
|
||||
self::INFO => 'INFO',
|
||||
self::WARNING => 'WARNING',
|
||||
self::ERROR => 'ERROR',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string The file to which messages should be written.
|
||||
*/
|
||||
public $file;
|
||||
|
||||
/**
|
||||
* @var int Only write messages with this level or higher
|
||||
*/
|
||||
public $level;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $stream;
|
||||
|
||||
/**
|
||||
* MC4WP_Debug_Log constructor.
|
||||
*
|
||||
* @param string $file
|
||||
* @param mixed $level;
|
||||
*/
|
||||
public function __construct($file, $level = self::DEBUG)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->level = self::to_level($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @return boolean
|
||||
*/
|
||||
public function log($level, $message)
|
||||
{
|
||||
$level = self::to_level($level);
|
||||
|
||||
// only log if message level is higher than log level
|
||||
if ($level < $this->level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// obfuscate email addresses in log message since log might be public.
|
||||
$message = mc4wp_obfuscate_email_addresses((string) $message);
|
||||
|
||||
// first, get rid of everything between "invisible" tags
|
||||
$message = preg_replace('/<(?:style|script|head)>.+?<\/(?:style|script|head)>/is', '', $message);
|
||||
|
||||
// then, strip tags (while retaining content of these tags)
|
||||
$message = strip_tags($message);
|
||||
$message = trim($message);
|
||||
|
||||
/**
|
||||
* Modifies the message that is written to the debug log.
|
||||
* Return an empty string to skip logging this message altogether.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
$message = apply_filters('mc4wp_debug_log_message', $message);
|
||||
if (empty($message)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// generate line
|
||||
$level_name = self::get_level_name($level);
|
||||
$datetime = gmdate('Y-m-d H:i:s', time() + ( get_option('gmt_offset', 0) * HOUR_IN_SECONDS ));
|
||||
$message = sprintf('[%s] %s: %s', $datetime, $level_name, $message) . PHP_EOL;
|
||||
|
||||
// did we open stream yet?
|
||||
if (! is_resource($this->stream)) {
|
||||
// attempt to open stream
|
||||
$this->stream = @fopen($this->file, 'c+');
|
||||
if (! is_resource($this->stream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure first line of log file is a PHP tag + exit statement (to prevent direct file access)
|
||||
$line = fgets($this->stream);
|
||||
$php_exit_string = '<?php exit; ?>';
|
||||
if (strpos($line, $php_exit_string) !== 0) {
|
||||
rewind($this->stream);
|
||||
fwrite($this->stream, $php_exit_string . PHP_EOL . $line);
|
||||
}
|
||||
|
||||
// place pointer at end of file
|
||||
fseek($this->stream, 0, SEEK_END);
|
||||
}
|
||||
|
||||
// lock file while we write, ignore errors (not much we can do)
|
||||
flock($this->stream, LOCK_EX);
|
||||
|
||||
// write the message to the file
|
||||
fwrite($this->stream, $message);
|
||||
|
||||
// unlock file again, but don't close it for remainder of this request
|
||||
flock($this->stream, LOCK_UN);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @return boolean
|
||||
*/
|
||||
public function warning($message)
|
||||
{
|
||||
return $this->log(self::WARNING, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @return boolean
|
||||
*/
|
||||
public function info($message)
|
||||
{
|
||||
return $this->log(self::INFO, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @return boolean
|
||||
*/
|
||||
public function error($message)
|
||||
{
|
||||
return $this->log(self::ERROR, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @return boolean
|
||||
*/
|
||||
public function debug($message)
|
||||
{
|
||||
return $this->log(self::DEBUG, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts PSR-3 levels to local ones if necessary
|
||||
*
|
||||
* @param string|int Level number or name (PSR-3)
|
||||
* @return int
|
||||
*/
|
||||
public static function to_level($level)
|
||||
{
|
||||
if (is_string($level)) {
|
||||
$level = strtoupper($level);
|
||||
if (defined(__CLASS__ . '::' . $level)) {
|
||||
return constant(__CLASS__ . '::' . $level);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('Level "' . $level . '" is not defined, use one of: ' . implode(', ', array_keys(self::$levels)));
|
||||
}
|
||||
|
||||
return $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the logging level.
|
||||
*
|
||||
* @param int $level
|
||||
* @return string
|
||||
*/
|
||||
public static function get_level_name($level)
|
||||
{
|
||||
if (! isset(self::$levels[ $level ])) {
|
||||
throw new InvalidArgumentException('Level "' . $level . '" is not defined, use one of: ' . implode(', ', array_keys(self::$levels)));
|
||||
}
|
||||
|
||||
return self::$levels[ $level ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the log file is writable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function test()
|
||||
{
|
||||
$handle = @fopen($this->file, 'a');
|
||||
$writable = false;
|
||||
|
||||
if (is_resource($handle)) {
|
||||
$writable = true;
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
return $writable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Dynamic_Content_Tags
|
||||
*
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
abstract class MC4WP_Dynamic_Content_Tags
|
||||
{
|
||||
/**
|
||||
* @var string The escape function for replacement values.
|
||||
*/
|
||||
protected $escape_function = null;
|
||||
|
||||
/**
|
||||
* @var array Array of registered dynamic content tags
|
||||
*/
|
||||
protected $tags = array();
|
||||
|
||||
/**
|
||||
* Register template tags
|
||||
*/
|
||||
protected function register()
|
||||
{
|
||||
// Global tags can go here
|
||||
$this->tags['cookie'] = array(
|
||||
'description' => sprintf(__('Data from a cookie.', 'mailchimp-for-wp')),
|
||||
'callback' => array( $this, 'get_cookie' ),
|
||||
'example' => "cookie name='my_cookie' default='Default Value'",
|
||||
);
|
||||
|
||||
$this->tags['email'] = array(
|
||||
'description' => __('The email address of the current visitor (if known).', 'mailchimp-for-wp'),
|
||||
'callback' => array( $this, 'get_email' ),
|
||||
);
|
||||
|
||||
$this->tags['current_url'] = array(
|
||||
'description' => __('The URL of the page.', 'mailchimp-for-wp'),
|
||||
'callback' => 'mc4wp_get_request_url',
|
||||
);
|
||||
|
||||
$this->tags['current_path'] = array(
|
||||
'description' => __('The path of the page.', 'mailchimp-for-wp'),
|
||||
'callback' => 'mc4wp_get_request_path',
|
||||
);
|
||||
|
||||
$this->tags['date'] = array(
|
||||
'description' => sprintf(__('The current date. Example: %s.', 'mailchimp-for-wp'), '<strong>' . gmdate('Y/m/d', time() + ( get_option('gmt_offset') * HOUR_IN_SECONDS )) . '</strong>'),
|
||||
'replacement' => gmdate('Y/m/d', time() + ( get_option('gmt_offset') * HOUR_IN_SECONDS )),
|
||||
);
|
||||
|
||||
$this->tags['time'] = array(
|
||||
'description' => sprintf(__('The current time. Example: %s.', 'mailchimp-for-wp'), '<strong>' . gmdate('H:i:s', time() + ( get_option('gmt_offset') * HOUR_IN_SECONDS )) . '</strong>'),
|
||||
'replacement' => gmdate('H:i:s', time() + ( get_option('gmt_offset') * HOUR_IN_SECONDS )),
|
||||
);
|
||||
|
||||
$this->tags['language'] = array(
|
||||
'description' => sprintf(__('The site\'s language. Example: %s.', 'mailchimp-for-wp'), '<strong>' . get_locale() . '</strong>'),
|
||||
'callback' => 'get_locale',
|
||||
);
|
||||
|
||||
$this->tags['ip'] = array(
|
||||
'description' => sprintf(__('The visitor\'s IP address. Example: %s.', 'mailchimp-for-wp'), '<strong>' . mc4wp_get_request_ip_address() . '</strong>'),
|
||||
'callback' => 'mc4wp_get_request_ip_address',
|
||||
);
|
||||
|
||||
$this->tags['user'] = array(
|
||||
'description' => sprintf(__('The property of the currently logged-in user.', 'mailchimp-for-wp')),
|
||||
'callback' => array( $this, 'get_user_property' ),
|
||||
'example' => "user property='user_email'",
|
||||
);
|
||||
|
||||
$this->tags['post'] = array(
|
||||
'description' => sprintf(__('Property of the current page or post.', 'mailchimp-for-wp')),
|
||||
'callback' => array( $this, 'get_post_property' ),
|
||||
'example' => "post property='ID'",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
if ($this->tags === array()) {
|
||||
$this->register();
|
||||
}
|
||||
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $matches
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function replace_tag(array $matches)
|
||||
{
|
||||
$tags = $this->all();
|
||||
$tag = $matches[1];
|
||||
|
||||
if (isset($tags[ $tag ])) {
|
||||
$config = $tags[ $tag ];
|
||||
$replacement = '';
|
||||
|
||||
if (isset($config['replacement'])) {
|
||||
$replacement = $config['replacement'];
|
||||
} elseif (isset($config['callback'])) {
|
||||
// parse attributes
|
||||
$attributes = array();
|
||||
if (isset($matches[2])) {
|
||||
$attribute_string = $matches[2];
|
||||
$attributes = shortcode_parse_atts($attribute_string);
|
||||
}
|
||||
|
||||
// call function
|
||||
$replacement = call_user_func($config['callback'], $attributes);
|
||||
}
|
||||
|
||||
if (is_callable($this->escape_function)) {
|
||||
$replacement = call_user_func($this->escape_function, $replacement);
|
||||
}
|
||||
|
||||
return $replacement;
|
||||
}
|
||||
|
||||
// default to not replacing it
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string The string containing dynamic content tags.
|
||||
* @param string $escape_function Escape mode for the replacement value. Leave empty for no escaping.
|
||||
* @return string
|
||||
*/
|
||||
protected function replace($string, $escape_function = '')
|
||||
{
|
||||
$this->escape_function = $escape_function;
|
||||
|
||||
// replace strings like this: {tagname attr="value"}
|
||||
$string = preg_replace_callback('/\{(\w+)(\ +(?:(?!\{)[^}\n])+)*\}/', array( $this, 'replace_tag' ), $string);
|
||||
|
||||
// call again to take care of nested variables
|
||||
$string = preg_replace_callback('/\{(\w+)(\ +(?:(?!\{)[^}\n])+)*\}/', array( $this, 'replace_tag' ), $string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function replace_in_html($string)
|
||||
{
|
||||
return $this->replace($string, 'esc_html');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function replace_in_attributes($string)
|
||||
{
|
||||
return $this->replace($string, 'esc_attr');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function replace_in_url($string)
|
||||
{
|
||||
return $this->replace($string, 'urlencode');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data variable from cookie.
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_cookie($args = array())
|
||||
{
|
||||
if (empty($args['name'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$name = $args['name'];
|
||||
$default = isset($args['default']) ? $args['default'] : '';
|
||||
|
||||
if (isset($_COOKIE[ $name ])) {
|
||||
return esc_html(stripslashes($_COOKIE[ $name ]));
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get property of currently logged-in user
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_user_property($args = array())
|
||||
{
|
||||
$property = empty($args['property']) ? 'user_email' : $args['property'];
|
||||
$default = isset($args['default']) ? $args['default'] : '';
|
||||
$user = wp_get_current_user();
|
||||
|
||||
if ($user instanceof WP_User && isset($user->{$property})) {
|
||||
return esc_html($user->{$property});
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get property of viewed post
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_post_property($args = array())
|
||||
{
|
||||
global $post;
|
||||
$property = empty($args['property']) ? 'ID' : $args['property'];
|
||||
$default = isset($args['default']) ? $args['default'] : '';
|
||||
|
||||
if ($post instanceof WP_Post && isset($post->{$property})) {
|
||||
return $post->{$property};
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_email()
|
||||
{
|
||||
if (! empty($_REQUEST['EMAIL'])) {
|
||||
return $_REQUEST['EMAIL'];
|
||||
}
|
||||
|
||||
// then , try logged-in user
|
||||
if (is_user_logged_in()) {
|
||||
$user = wp_get_current_user();
|
||||
return $user->user_email;
|
||||
}
|
||||
|
||||
// TODO: Read from cookie? Or add $_COOKIE support to {data} tag?
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Field_Formatter
|
||||
*
|
||||
* Formats values based on what the Mailchimp API expects or accepts for the given field types.
|
||||
*/
|
||||
class MC4WP_Field_Formatter
|
||||
{
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param object $options
|
||||
* @return array
|
||||
*/
|
||||
public function address($value, $options = null)
|
||||
{
|
||||
// auto-format if this is a string
|
||||
if (is_string($value)) {
|
||||
// addr1, addr2, city, state, zip, country
|
||||
$address_pieces = explode(',', $value);
|
||||
$address_pieces = array_filter($address_pieces);
|
||||
$address_pieces = array_values($address_pieces);
|
||||
|
||||
// try to fill it.... this is a long shot
|
||||
$value = array(
|
||||
'addr1' => $address_pieces[0],
|
||||
'city' => isset($address_pieces[1]) ? $address_pieces[1] : '',
|
||||
'state' => isset($address_pieces[2]) ? $address_pieces[2] : '',
|
||||
'zip' => isset($address_pieces[3]) ? $address_pieces[3] : '',
|
||||
);
|
||||
|
||||
if (! empty($address_pieces[4])) {
|
||||
$value['country'] = $address_pieces[4];
|
||||
}
|
||||
} elseif (is_array($value)) {
|
||||
// merge with array of empty defaults to allow skipping certain fields
|
||||
$default = array_fill_keys(array( 'addr1', 'city', 'state', 'zip' ), '');
|
||||
$value = array_merge($default, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param object $options
|
||||
* @return string
|
||||
*/
|
||||
public function birthday($value, $options = null)
|
||||
{
|
||||
$format = is_object($options) && isset($options->date_format) ? $options->date_format : 'MM/DD';
|
||||
|
||||
if (is_array($value)) {
|
||||
// allow for "day" and "month" fields
|
||||
if (isset($value['month']) && isset($value['day'])) {
|
||||
$value = $value['month'] . '/' . $value['day'];
|
||||
} else {
|
||||
// if other array, just join together
|
||||
$value = join('/', $value);
|
||||
}
|
||||
}
|
||||
|
||||
$value = trim($value);
|
||||
if (empty($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// always use slashes as delimiter, so next part works
|
||||
$value = str_replace(array( '.', '-' ), '/', $value);
|
||||
|
||||
// if format = DD/MM OR if first part is definitely a day value (>12), then flip order
|
||||
// this allows `strtotime` to understand `dd/mm` values
|
||||
$values = explode('/', $value);
|
||||
if ($format === 'DD/MM' || ( $values[0] > 12 && $values[0] <= 31 && isset($values[1]) && $values[1] <= 12 )) {
|
||||
$values = array_reverse($values);
|
||||
$value = join('/', $values);
|
||||
}
|
||||
|
||||
// Mailchimp expects a MM/DD format, regardless of their display preference
|
||||
$value = (string) gmdate('m/d', strtotime($value));
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param object $options
|
||||
* @return string
|
||||
*/
|
||||
public function date($value, $options = null)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
// allow for "year", "month" and "day" keys
|
||||
if (isset($value['year']) && isset($value['month']) && isset($value['day'])) {
|
||||
$value = $value['year'] . '/' . $value['month'] . '/' . $value['day'];
|
||||
} else {
|
||||
// if other array, just join together
|
||||
$value = join('/', $value);
|
||||
}
|
||||
}
|
||||
|
||||
$value = trim($value);
|
||||
if (empty($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Mailchimp expects a Y-m-d format no matter the display preference
|
||||
return (string) gmdate('Y-m-d', strtotime($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param object $options
|
||||
* @return string
|
||||
*/
|
||||
public function language($value, $options = null)
|
||||
{
|
||||
$value = trim($value);
|
||||
|
||||
$exceptions = array(
|
||||
'pt_PT',
|
||||
'es_ES',
|
||||
'fr_CA',
|
||||
);
|
||||
|
||||
if (! in_array($value, $exceptions, true)) {
|
||||
$value = substr($value, 0, 2);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param object $options
|
||||
* @return bool
|
||||
*/
|
||||
public function boolean($value, $options = null)
|
||||
{
|
||||
$falsey = array( 'false', '0' );
|
||||
|
||||
if (in_array($value, $falsey, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// otherwise, just cast.
|
||||
return (bool) $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Field_Guesser
|
||||
*
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Field_Guesser
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fields;
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*/
|
||||
public function __construct(array $fields)
|
||||
{
|
||||
$fields = array_change_key_case($fields, CASE_UPPER);
|
||||
$this->fields = $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data which is namespaced with a given namespace
|
||||
*
|
||||
* @param string $namespace
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function namespaced($namespace = 'mc4wp-')
|
||||
{
|
||||
$prefix = strtoupper($namespace);
|
||||
$return = array();
|
||||
$length = strlen($prefix);
|
||||
|
||||
foreach ($this->fields as $key => $value) {
|
||||
if (strpos($key, $prefix) === 0) {
|
||||
$new_key = substr($key, $length);
|
||||
$return[ $new_key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess values for the following fields
|
||||
* - EMAIL
|
||||
* - NAME
|
||||
* - FNAME
|
||||
* - LNAME
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function guessed()
|
||||
{
|
||||
$guessed = array();
|
||||
|
||||
foreach ($this->fields as $field => $value) {
|
||||
// transform value into array to support 1-level arrays
|
||||
$sub_fields = is_array($value) ? $value : array( $value );
|
||||
|
||||
foreach ($sub_fields as $sub_field_value) {
|
||||
// poor man's urldecode, to get Enfold theme's contact element to work.
|
||||
$sub_field_value = str_replace('%40', '@', $sub_field_value);
|
||||
|
||||
// is this an email value? if so, assume it's the EMAIL field
|
||||
if (empty($guessed['EMAIL']) && is_string($sub_field_value) && is_email($sub_field_value)) {
|
||||
$guessed['EMAIL'] = $sub_field_value;
|
||||
continue 2;
|
||||
}
|
||||
|
||||
// remove special characters from field name
|
||||
$simple_key = str_replace(array( '-', '_', ' ' ), '', $field);
|
||||
|
||||
if (empty($guessed['FNAME']) && $this->string_contains($simple_key, array( 'FIRSTNAME', 'FNAME', 'GIVENNAME', 'FORENAME' ))) {
|
||||
// find first name field
|
||||
$guessed['FNAME'] = $sub_field_value;
|
||||
} elseif (empty($guessed['LNAME']) && $this->string_contains($simple_key, array( 'LASTNAME', 'LNAME', 'SURNAME', 'FAMILYNAME' ))) {
|
||||
// find last name field
|
||||
$guessed['LNAME'] = $sub_field_value;
|
||||
} elseif (empty($guessed['NAME']) && $this->string_contains($simple_key, 'NAME')) {
|
||||
// find name field
|
||||
$guessed['NAME'] = $sub_field_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $guessed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $methods
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function combine(array $methods)
|
||||
{
|
||||
$combined = array();
|
||||
|
||||
foreach ($methods as $method) {
|
||||
if (method_exists($this, $method)) {
|
||||
$combined = array_merge($combined, call_user_func(array( $this, $method )));
|
||||
}
|
||||
}
|
||||
|
||||
return $combined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $haystack
|
||||
* @param string|array $needles
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function string_contains($haystack, $needles)
|
||||
{
|
||||
if (! is_array($needles)) {
|
||||
$needles = array( $needles );
|
||||
}
|
||||
|
||||
foreach ($needles as $needle) {
|
||||
if (strpos($haystack, $needle) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Field_Map
|
||||
*
|
||||
* @access private
|
||||
* @since 4.0
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_List_Data_Mapper
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $data = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $list_ids = array();
|
||||
|
||||
/**
|
||||
* @var MC4WP_Field_Formatter
|
||||
*/
|
||||
private $formatter;
|
||||
|
||||
/**
|
||||
* @var MC4WP_MailChimp
|
||||
*/
|
||||
private $mailchimp;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $list_ids
|
||||
*/
|
||||
public function __construct(array $data, array $list_ids)
|
||||
{
|
||||
$this->data = array_change_key_case($data, CASE_UPPER);
|
||||
if (! isset($this->data['EMAIL'])) {
|
||||
throw new InvalidArgumentException('Data needs at least an EMAIL key.');
|
||||
}
|
||||
|
||||
$this->list_ids = $list_ids;
|
||||
$this->formatter = new MC4WP_Field_Formatter();
|
||||
$this->mailchimp = new MC4WP_MailChimp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MC4WP_MailChimp_Subscriber[]
|
||||
*/
|
||||
public function map()
|
||||
{
|
||||
$map = array();
|
||||
|
||||
foreach ($this->list_ids as $list_id) {
|
||||
$map[ "$list_id" ] = $this->map_list($list_id);
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $list_id
|
||||
* @return MC4WP_MailChimp_Subscriber
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function map_list($list_id)
|
||||
{
|
||||
$subscriber = new MC4WP_MailChimp_Subscriber();
|
||||
$subscriber->email_address = $this->data['EMAIL'];
|
||||
|
||||
// find merge fields
|
||||
$merge_fields = $this->mailchimp->get_list_merge_fields($list_id);
|
||||
foreach ($merge_fields as $merge_field) {
|
||||
// skip EMAIL field as that is handled separately (see above)
|
||||
if ($merge_field->tag === 'EMAIL') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// use empty() here to skip empty field values
|
||||
if (empty($this->data[ $merge_field->tag ])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// format field value
|
||||
$value = $this->data[ $merge_field->tag ];
|
||||
$value = $this->format_merge_field_value($merge_field, $value);
|
||||
|
||||
// add to map
|
||||
$subscriber->merge_fields[ $merge_field->tag ] = $value;
|
||||
}
|
||||
|
||||
// find interest categories
|
||||
if (! empty($this->data['INTERESTS'])) {
|
||||
$interest_categories = $this->mailchimp->get_list_interest_categories($list_id);
|
||||
foreach ($interest_categories as $interest_category) {
|
||||
foreach ($interest_category->interests as $interest_id => $interest_name) {
|
||||
// straight lookup by ID as key with value copy.
|
||||
if (isset($this->data['INTERESTS'][ $interest_id ])) {
|
||||
$subscriber->interests[ $interest_id ] = $this->formatter->boolean($this->data['INTERESTS'][ $interest_id ]);
|
||||
}
|
||||
|
||||
// straight lookup by ID as top-level value
|
||||
if (in_array($interest_id, $this->data['INTERESTS'], false)) {
|
||||
$subscriber->interests[ $interest_id ] = true;
|
||||
}
|
||||
|
||||
// look in array with category ID as key.
|
||||
if (isset($this->data['INTERESTS'][ $interest_category->id ])) {
|
||||
$value = $this->data['INTERESTS'][ $interest_category->id ];
|
||||
$values = is_array($value) ? $value : array_map('trim', explode('|', $value));
|
||||
|
||||
// find by category ID + interest ID
|
||||
if (in_array($interest_id, $values, false)) {
|
||||
$subscriber->interests[ $interest_id ] = true;
|
||||
}
|
||||
|
||||
// find by category ID + interest name
|
||||
if (in_array($interest_name, $values, true)) {
|
||||
$subscriber->interests[ $interest_id ] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add GDPR marketing permissions
|
||||
if (! empty($this->data['MARKETING_PERMISSIONS'])) {
|
||||
$values = $this->data['MARKETING_PERMISSIONS'];
|
||||
$values = is_array($values) ? $values : explode(',', $values);
|
||||
$values = array_map('trim', $values);
|
||||
$marketing_permissions = $this->mailchimp->get_list_marketing_permissions($list_id);
|
||||
foreach ($marketing_permissions as $mp) {
|
||||
if (in_array($mp->marketing_permission_id, $values, true) || in_array($mp->text, $values, true)) {
|
||||
$subscriber->marketing_permissions[] = (object) array(
|
||||
'marketing_permission_id' => $mp->marketing_permission_id,
|
||||
'enabled' => true,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find language
|
||||
/* @see http://kb.mailchimp.com/lists/managing-subscribers/view-and-edit-subscriber-languages?utm_source=mc-api&utm_medium=docs&utm_campaign=apidocs&_ga=1.211519638.2083589671.1469697070 */
|
||||
if (! empty($this->data['MC_LANGUAGE'])) {
|
||||
$subscriber->language = $this->formatter->language($this->data['MC_LANGUAGE']);
|
||||
}
|
||||
|
||||
return $subscriber;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param object $merge_field
|
||||
* @param string $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function format_merge_field_value($merge_field, $value)
|
||||
{
|
||||
$field_type = strtolower($merge_field->type);
|
||||
|
||||
if (method_exists($this->formatter, $field_type)) {
|
||||
$value = call_user_func(array( $this->formatter, $field_type ), $value, $merge_field->options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the value of a field after it is formatted.
|
||||
*
|
||||
* Use this to format a field value according to the field type (in Mailchimp).
|
||||
*
|
||||
* @since 3.0
|
||||
* @param string $value The value
|
||||
* @param string $field_type The type of the field (in Mailchimp)
|
||||
*/
|
||||
$value = apply_filters('mc4wp_format_field_value', $value, $field_type);
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
class MC4WP_MailChimp_Subscriber
|
||||
{
|
||||
/**
|
||||
* @var string Email address for this subscriber.
|
||||
*/
|
||||
public $email_address = '';
|
||||
|
||||
/**
|
||||
* @var array The key of this object’s properties is the ID of the interest in question.
|
||||
*/
|
||||
public $interests = array();
|
||||
|
||||
/**
|
||||
* @var array An individual merge var and value for a member.
|
||||
*/
|
||||
public $merge_fields = array();
|
||||
|
||||
/**
|
||||
* @var string Subscriber’s status.
|
||||
*/
|
||||
public $status = 'pending';
|
||||
|
||||
/**
|
||||
* @var string Type of email this member asked to get (‘html’ or ‘text’).
|
||||
*/
|
||||
public $email_type = 'html';
|
||||
|
||||
/**
|
||||
* @var string IP address the subscriber signed up from.
|
||||
*/
|
||||
public $ip_signup;
|
||||
|
||||
/**
|
||||
* @var string The subscriber's language
|
||||
*/
|
||||
public $language;
|
||||
|
||||
/**
|
||||
* @var boolean VIP status for subscriber.
|
||||
*/
|
||||
public $vip;
|
||||
|
||||
/**
|
||||
* @var array The tags applied to this member.
|
||||
*/
|
||||
public $tags = array();
|
||||
|
||||
/**
|
||||
* @var array The marketing permissions for the subscriber.
|
||||
*/
|
||||
public $marketing_permissions = array();
|
||||
|
||||
/**
|
||||
* Retrieves member data as an array, without null values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array()
|
||||
{
|
||||
$all = get_object_vars($this);
|
||||
$array = array();
|
||||
|
||||
foreach ($all as $key => $value) {
|
||||
// skip null values
|
||||
if ($value === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip empty marketing_permissions property
|
||||
if ($key === 'marketing_permissions' && empty($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// otherwise, add to final array
|
||||
$array[ $key ] = $value;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
579
wp-content/plugins/mailchimp-for-wp/includes/class-mailchimp.php
Normal file
579
wp-content/plugins/mailchimp-for-wp/includes/class-mailchimp.php
Normal file
@@ -0,0 +1,579 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Helper class for dealing with common API requests.
|
||||
*/
|
||||
class MC4WP_MailChimp
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $error_code = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $error_message = '';
|
||||
|
||||
/**
|
||||
*
|
||||
* Sends a subscription request to the Mailchimp API
|
||||
*
|
||||
* @param string $list_id The list id to subscribe to
|
||||
* @param string $email_address The email address to subscribe
|
||||
* @param array $args
|
||||
* @param bool $update_existing Update information if this email is already on list?
|
||||
* @param bool $replace_interests Replace interest groupings, only if update_existing is true.
|
||||
*
|
||||
* @return object
|
||||
* @throws Exception
|
||||
*/
|
||||
public function list_subscribe($list_id, $email_address, array $args = array(), $update_existing = false, $replace_interests = true)
|
||||
{
|
||||
$this->reset_error();
|
||||
$default_args = array(
|
||||
'status' => 'pending',
|
||||
'email_address' => $email_address,
|
||||
);
|
||||
$existing_member_data = null;
|
||||
|
||||
// setup default args
|
||||
$args = array_merge($default_args, $args);
|
||||
$api = $this->get_api();
|
||||
|
||||
// first, check if subscriber is already on the given list
|
||||
try {
|
||||
$existing_member_data = $api->get_list_member($list_id, $email_address);
|
||||
if ($existing_member_data->status === 'subscribed') {
|
||||
// if we're not supposed to update, bail.
|
||||
if (! $update_existing) {
|
||||
$this->error_code = 214;
|
||||
$this->error_message = 'That subscriber already exists.';
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$args['status'] = 'subscribed';
|
||||
|
||||
// this key only exists if list actually has interests
|
||||
if (isset($existing_member_data->interests)) {
|
||||
$existing_interests = (array) $existing_member_data->interests;
|
||||
|
||||
// if replace, assume all existing interests disabled
|
||||
if ($replace_interests) {
|
||||
$existing_interests = array_fill_keys(array_keys($existing_interests), false);
|
||||
}
|
||||
|
||||
$args['interests'] = array_replace($existing_interests, $args['interests']);
|
||||
}
|
||||
} elseif ($args['status'] === 'pending' && $existing_member_data->status === 'pending') {
|
||||
// this ensures that a new double opt-in email is send out
|
||||
$api->update_list_member(
|
||||
$list_id,
|
||||
$email_address,
|
||||
array(
|
||||
'status' => 'unsubscribed',
|
||||
)
|
||||
);
|
||||
}
|
||||
} catch (MC4WP_API_Resource_Not_Found_Exception $e) {
|
||||
// subscriber does not exist (not an issue in this case)
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
// other errors.
|
||||
$this->error_code = $e->getCode();
|
||||
$this->error_message = $e;
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if ($existing_member_data) {
|
||||
$data = $api->update_list_member($list_id, $email_address, $args);
|
||||
$data->was_already_on_list = $existing_member_data->status === 'subscribed';
|
||||
|
||||
if (isset($args['tags']) && is_array($args['tags'])) {
|
||||
$this->list_add_tags_to_subscriber($list_id, $data, $args['tags']);
|
||||
}
|
||||
} else {
|
||||
$data = $api->add_new_list_member($list_id, $args);
|
||||
$data->was_already_on_list = false;
|
||||
}
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
$this->error_code = $e->getCode();
|
||||
$this->error_message = $e;
|
||||
return null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format tags to send to Mailchimp.
|
||||
*
|
||||
* @param $mailchimp_tags array existent user tags
|
||||
* @param $new_tags array new tags to add
|
||||
*
|
||||
* @return array
|
||||
* @since 4.7.9
|
||||
*/
|
||||
private function merge_and_format_member_tags($mailchimp_tags, $new_tags)
|
||||
{
|
||||
$mailchimp_tags = array_map(
|
||||
function ($tag) {
|
||||
return $tag->name;
|
||||
},
|
||||
$mailchimp_tags
|
||||
);
|
||||
|
||||
$tags = array_unique(array_merge($mailchimp_tags, $new_tags), SORT_REGULAR);
|
||||
|
||||
return array_map(
|
||||
function ($tag) {
|
||||
return array(
|
||||
'name' => $tag,
|
||||
'status' => 'active',
|
||||
);
|
||||
},
|
||||
$tags
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post the tags on a list member.
|
||||
*
|
||||
* @param $mailchimp_list_id string The list id to subscribe to
|
||||
* @param $mailchimp_member stdClass mailchimp user informations
|
||||
* @param $new_tags array tags to add to the user
|
||||
*
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
* @since 4.7.9
|
||||
*/
|
||||
private function list_add_tags_to_subscriber($mailchimp_list_id, $mailchimp_member, array $new_tags)
|
||||
{
|
||||
// do nothing if no tags given
|
||||
if (count($new_tags) === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$api = $this->get_api();
|
||||
$data = array(
|
||||
'tags' => $this->merge_and_format_member_tags($mailchimp_member->tags, $new_tags),
|
||||
);
|
||||
|
||||
try {
|
||||
$api->update_list_member_tags($mailchimp_list_id, $mailchimp_member->email_address, $data);
|
||||
} catch (MC4WP_API_Exception $ex) {
|
||||
// fail silently
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the subscriber status to "unsubscribed"
|
||||
*
|
||||
* @param string $list_id
|
||||
* @param string $email_address
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function list_unsubscribe($list_id, $email_address)
|
||||
{
|
||||
$this->reset_error();
|
||||
|
||||
try {
|
||||
$this->get_api()->update_list_member($list_id, $email_address, array( 'status' => 'unsubscribed' ));
|
||||
} catch (MC4WP_API_Resource_Not_Found_Exception $e) {
|
||||
// if email wasn't even on the list: great.
|
||||
return true;
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
$this->error_code = $e->getCode();
|
||||
$this->error_message = $e;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an email address is on a given list with status "subscribed"
|
||||
*
|
||||
* @param string $list_id
|
||||
* @param string $email_address
|
||||
*
|
||||
* @return boolean
|
||||
* @throws Exception
|
||||
*/
|
||||
public function list_has_subscriber($list_id, $email_address)
|
||||
{
|
||||
try {
|
||||
$data = $this->get_api()->get_list_member($list_id, $email_address);
|
||||
} catch (MC4WP_API_Resource_Not_Found_Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! empty($data->id) && $data->status === 'subscribed';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $list_id
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get_list_merge_fields($list_id)
|
||||
{
|
||||
$transient_key = sprintf('mc4wp_list_%s_mf', $list_id);
|
||||
$cached = get_transient($transient_key);
|
||||
if (is_array($cached)) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
$api = $this->get_api();
|
||||
|
||||
try {
|
||||
// fetch list merge fields
|
||||
$merge_fields = $api->get_list_merge_fields(
|
||||
$list_id,
|
||||
array(
|
||||
'count' => 100,
|
||||
'fields' => 'merge_fields.name,merge_fields.tag,merge_fields.type,merge_fields.required,merge_fields.default_value,merge_fields.options,merge_fields.public',
|
||||
)
|
||||
);
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// add EMAIL field
|
||||
array_unshift(
|
||||
$merge_fields,
|
||||
(object) array(
|
||||
'tag' => 'EMAIL',
|
||||
'name' => __('Email address', 'mailchimp-for-wp'),
|
||||
'required' => true,
|
||||
'type' => 'email',
|
||||
'options' => array(),
|
||||
'public' => true,
|
||||
)
|
||||
);
|
||||
|
||||
set_transient($transient_key, $merge_fields, HOUR_IN_SECONDS * 24);
|
||||
|
||||
return $merge_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $list_id
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get_list_interest_categories($list_id)
|
||||
{
|
||||
$transient_key = sprintf('mc4wp_list_%s_ic', $list_id);
|
||||
$cached = get_transient($transient_key);
|
||||
if (is_array($cached)) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
$api = $this->get_api();
|
||||
|
||||
try {
|
||||
// fetch list interest categories
|
||||
$interest_categories = $api->get_list_interest_categories(
|
||||
$list_id,
|
||||
array(
|
||||
'count' => 100,
|
||||
'fields' => 'categories.id,categories.title,categories.type',
|
||||
)
|
||||
);
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ($interest_categories as $interest_category) {
|
||||
$interest_category->interests = array();
|
||||
|
||||
try {
|
||||
// fetch groups for this interest
|
||||
$interests_data = $api->get_list_interest_category_interests(
|
||||
$list_id,
|
||||
$interest_category->id,
|
||||
array(
|
||||
'count' => 100,
|
||||
'fields' => 'interests.id,interests.name',
|
||||
)
|
||||
);
|
||||
foreach ($interests_data as $interest_data) {
|
||||
$interest_category->interests[ (string) $interest_data->id ] = $interest_data->name;
|
||||
}
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
set_transient($transient_key, $interest_categories, HOUR_IN_SECONDS * 24);
|
||||
|
||||
return $interest_categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets marketing permissions from a Mailchimp list.
|
||||
* The list needs to have at least 1 member for this to work.
|
||||
*
|
||||
* @param string $list_id
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get_list_marketing_permissions($list_id)
|
||||
{
|
||||
$transient_key = sprintf('mc4wp_list_%s_mp', $list_id);
|
||||
$cached = get_transient($transient_key);
|
||||
if (is_array($cached)) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
try {
|
||||
$api = $this->get_api();
|
||||
$data = $api->get_list_members(
|
||||
$list_id,
|
||||
array(
|
||||
'fields' => array( 'members.marketing_permissions' ),
|
||||
'count' => 1,
|
||||
)
|
||||
);
|
||||
|
||||
$marketing_permissions = array();
|
||||
if (count($data->members) > 0 && $data->members[0]->marketing_permissions) {
|
||||
foreach ($data->members[0]->marketing_permissions as $mp) {
|
||||
$marketing_permissions[] = (object) array(
|
||||
'marketing_permission_id' => $mp->marketing_permission_id,
|
||||
'text' => $mp->text,
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
return array();
|
||||
}
|
||||
|
||||
set_transient($transient_key, $marketing_permissions, HOUR_IN_SECONDS * 24);
|
||||
return $marketing_permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Mailchimp lists, from cache or remote API.
|
||||
*
|
||||
* @param boolean $skip_cache Whether to force a result by hitting Mailchimp API
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_lists($skip_cache = false)
|
||||
{
|
||||
$cache_key = 'mc4wp_mailchimp_lists';
|
||||
$cached = get_transient($cache_key);
|
||||
|
||||
if (is_array($cached) && ! $skip_cache) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
$lists = $this->fetch_lists();
|
||||
|
||||
/**
|
||||
* Filters the cache time for Mailchimp lists configuration, in seconds. Defaults to 24 hours.
|
||||
*/
|
||||
$cache_ttl = (int) apply_filters('mc4wp_lists_count_cache_time', HOUR_IN_SECONDS * 24);
|
||||
|
||||
// make sure cache ttl is not lower than 60 seconds
|
||||
$cache_ttl = max(60, $cache_ttl);
|
||||
set_transient($cache_key, $lists, $cache_ttl);
|
||||
|
||||
return $lists;
|
||||
}
|
||||
|
||||
private function fetch_lists()
|
||||
{
|
||||
$client = $this->get_api()->get_client();
|
||||
$lists_data = array();
|
||||
$offset = 0;
|
||||
$count = 10;
|
||||
$exceptions_skipped = 0;
|
||||
|
||||
// increase total time limit to 3 minutes
|
||||
@set_time_limit(180);
|
||||
|
||||
// increase HTTP timeout to 30s as MailChimp is super slow to calculate dynamic fields
|
||||
add_filter(
|
||||
'mc4wp_http_request_args',
|
||||
function ($args) {
|
||||
$args['timeout'] = 30;
|
||||
return $args;
|
||||
}
|
||||
);
|
||||
|
||||
// collect all lists in separate HTTP requests
|
||||
do {
|
||||
try {
|
||||
$data = $client->get(
|
||||
'/lists',
|
||||
array(
|
||||
'count' => $count,
|
||||
'offset' => $offset,
|
||||
'fields' => 'total_items,lists.id,lists.name,lists.web_id,lists.stats.member_count,lists.marketing_permissions',
|
||||
)
|
||||
);
|
||||
|
||||
$lists_data = array_merge($lists_data, $data->lists);
|
||||
$offset += $count;
|
||||
} catch (MC4WP_API_Connection_Exception $e) {
|
||||
// ignore timeout errors as this is likely due to mailchimp being slow to calculate the lists.stats.member_count property
|
||||
// keep going so we can at least pull-in all other lists
|
||||
$offset += $count;
|
||||
++$exceptions_skipped;
|
||||
|
||||
// failsafe against infinite loop
|
||||
// bail after 5 skipped exceptions
|
||||
if ($exceptions_skipped >= 5) {
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
} catch (MC4WP_API_Exception $e) {
|
||||
// break on other errors, like "API key missing"etc.
|
||||
break;
|
||||
}
|
||||
} while ($data->total_items >= $offset);
|
||||
|
||||
// key by list ID
|
||||
$lists = array();
|
||||
foreach ($lists_data as $list_data) {
|
||||
$lists["$list_data->id"] = $list_data;
|
||||
}
|
||||
|
||||
return $lists;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $list_id
|
||||
*
|
||||
* @return object|null
|
||||
*/
|
||||
public function get_list($list_id)
|
||||
{
|
||||
$lists = $this->get_lists();
|
||||
|
||||
return isset($lists["$list_id"]) ? $lists["$list_id"] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch lists data from Mailchimp.
|
||||
*/
|
||||
public function refresh_lists()
|
||||
{
|
||||
$lists = $this->get_lists(true);
|
||||
|
||||
foreach ($lists as $list_id => $list) {
|
||||
// delete cached merge fields
|
||||
$transient_key = sprintf('mc4wp_list_%s_mf', $list_id);
|
||||
delete_transient($transient_key);
|
||||
|
||||
// delete cached interest categories
|
||||
$transient_key = sprintf('mc4wp_list_%s_ic', $list_id);
|
||||
delete_transient($transient_key);
|
||||
|
||||
// delete cached marketing permissions
|
||||
$transient_key = sprintf('mc4wp_list_%s_mp', $list_id);
|
||||
delete_transient($transient_key);
|
||||
}
|
||||
|
||||
return ! empty($lists);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns number of subscribers on given lists.
|
||||
*
|
||||
* @param array|string $list_ids Array of list ID's, or single string.
|
||||
*
|
||||
* @return int Total # subscribers for given lists.
|
||||
*/
|
||||
public function get_subscriber_count($list_ids)
|
||||
{
|
||||
// make sure we're getting an array
|
||||
if (! is_array($list_ids)) {
|
||||
$list_ids = array( $list_ids );
|
||||
}
|
||||
|
||||
// if we got an empty array, return 0
|
||||
if (empty($list_ids)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$lists = $this->get_lists();
|
||||
|
||||
// start calculating subscribers count for all given list ID's combined
|
||||
$count = 0;
|
||||
foreach ($list_ids as $list_id) {
|
||||
if (! isset($lists["$list_id"])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$list = $lists["$list_id"];
|
||||
$count += $list->stats->member_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the total subscriber_count for the given List ID's.
|
||||
*
|
||||
* @param string $count
|
||||
* @param array $list_ids
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
return apply_filters('mc4wp_subscriber_count', $count, $list_ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets error properties.
|
||||
*/
|
||||
public function reset_error()
|
||||
{
|
||||
$this->error_message = '';
|
||||
$this->error_code = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function has_error()
|
||||
{
|
||||
return ! empty($this->error_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_error_message()
|
||||
{
|
||||
return $this->error_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_error_code()
|
||||
{
|
||||
return $this->error_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MC4WP_API_V3
|
||||
* @throws Exception
|
||||
*/
|
||||
private function get_api()
|
||||
{
|
||||
return mc4wp('api');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Plugin
|
||||
*
|
||||
* Helper class for easy access to information like the plugin file or plugin directory.
|
||||
* Used in MC4WP Premium.
|
||||
*
|
||||
* @access public
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Plugin
|
||||
{
|
||||
/**
|
||||
* @var string The plugin version.
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* @var string The main plugin file.
|
||||
*/
|
||||
protected $file;
|
||||
|
||||
/**
|
||||
* @param string $file The plugin version.
|
||||
* @param string $version The main plugin file.
|
||||
*/
|
||||
public function __construct($file, $version)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the main plugin file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function file()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin version.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function version()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the directory the plugin lives in.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dir($path = '')
|
||||
{
|
||||
|
||||
// ensure path has leading slash
|
||||
if ('' !== $path) {
|
||||
$path = '/' . ltrim($path, '/');
|
||||
}
|
||||
|
||||
return dirname($this->file) . $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URL to the plugin files.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url($path = '')
|
||||
{
|
||||
return plugins_url($path, $this->file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Queue_Job
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Queue_Job
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $data;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $max_attempts = 1;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $attempts = 0;
|
||||
|
||||
/**
|
||||
* MC4WP_Queue_Job constructor.
|
||||
*
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->id = (string) microtime(true) . rand(1, 10000);
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
||||
198
wp-content/plugins/mailchimp-for-wp/includes/class-queue.php
Normal file
198
wp-content/plugins/mailchimp-for-wp/includes/class-queue.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Queue
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Queue
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Queue_Job[]
|
||||
*/
|
||||
protected $jobs;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $option_name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $dirty = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
const MAX_JOB_COUNT = 1000;
|
||||
|
||||
/**
|
||||
* MC4WP_Ecommerce_Queue constructor.
|
||||
*
|
||||
* @param string $option_name
|
||||
*/
|
||||
public function __construct($option_name)
|
||||
{
|
||||
$this->option_name = $option_name;
|
||||
|
||||
register_shutdown_function(array( $this, 'save' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load jobs from option
|
||||
*/
|
||||
protected function load()
|
||||
{
|
||||
if (! is_null($this->jobs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$jobs = get_option($this->option_name, array());
|
||||
|
||||
if (! is_array($jobs)) {
|
||||
$jobs = array();
|
||||
} else {
|
||||
$valid_jobs = array();
|
||||
|
||||
foreach ($jobs as $i => $obj) {
|
||||
// filter invalid data from array
|
||||
if (! is_object($obj) || empty($obj->data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure each job is instance of MC4WP_Queue_Job
|
||||
if ($obj instanceof MC4WP_Queue_Job) {
|
||||
$job = $obj;
|
||||
} else {
|
||||
$job = new MC4WP_Queue_Job($obj->data);
|
||||
$job->id = $obj->id;
|
||||
}
|
||||
|
||||
$valid_jobs[] = $job;
|
||||
}
|
||||
|
||||
$jobs = $valid_jobs;
|
||||
}
|
||||
|
||||
$this->jobs = $jobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all jobs in the queue
|
||||
*
|
||||
* @return MC4WP_Queue_Job[] Array of jobs
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
$this->load();
|
||||
return $this->jobs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add job to queue
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return boolean
|
||||
*/
|
||||
public function put($data)
|
||||
{
|
||||
$this->load();
|
||||
|
||||
// check if we already have a job with same data
|
||||
foreach ($this->jobs as $job) {
|
||||
if ($job->data === $data) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have more than MAX_JOB_COUNT jobs, remove first job item.
|
||||
// this protects against an ever-growing job list, but also potentially loses jobs if the queue is not processed soon enough.
|
||||
if (count($this->jobs) > self::MAX_JOB_COUNT) {
|
||||
array_shift($this->jobs);
|
||||
}
|
||||
|
||||
// add job to end of jobs array
|
||||
$job = new MC4WP_Queue_Job($data);
|
||||
$this->jobs[] = $job;
|
||||
$this->dirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all jobs in the queue
|
||||
*
|
||||
* @return MC4WP_Queue_Job|false
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
$this->load();
|
||||
|
||||
// do we have jobs?
|
||||
if (count($this->jobs) === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return first element
|
||||
return reset($this->jobs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MC4WP_Queue_Job $job
|
||||
*/
|
||||
public function delete(MC4WP_Queue_Job $job)
|
||||
{
|
||||
$this->load();
|
||||
|
||||
$index = array_search($job, $this->jobs, true);
|
||||
|
||||
// check for "false" here, as 0 is a valid index.
|
||||
if ($index !== false) {
|
||||
unset($this->jobs[ $index ]);
|
||||
$this->jobs = array_values($this->jobs);
|
||||
$this->dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MC4WP_Queue_Job $job
|
||||
*/
|
||||
public function reschedule(MC4WP_Queue_Job $job)
|
||||
{
|
||||
$this->load();
|
||||
|
||||
// delete job from start of queue
|
||||
$this->delete($job);
|
||||
|
||||
// add job to end of queue
|
||||
$this->jobs[] = $job;
|
||||
$this->dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset queue
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->jobs = array();
|
||||
$this->dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the queue
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
if (! $this->dirty || is_null($this->jobs)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$success = update_option($this->option_name, $this->jobs, false);
|
||||
|
||||
if ($success) {
|
||||
$this->dirty = false;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
269
wp-content/plugins/mailchimp-for-wp/includes/class-tools.php
Normal file
269
wp-content/plugins/mailchimp-for-wp/includes/class-tools.php
Normal file
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Tools
|
||||
*
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Tools
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function get_countries()
|
||||
{
|
||||
return array(
|
||||
'AF' => 'Afghanistan',
|
||||
'AX' => 'Aland Islands',
|
||||
'AL' => 'Albania',
|
||||
'DZ' => 'Algeria',
|
||||
'AS' => 'American Samoa',
|
||||
'AD' => 'Andorra',
|
||||
'AO' => 'Angola',
|
||||
'AI' => 'Anguilla',
|
||||
'AQ' => 'Antarctica',
|
||||
'AG' => 'Antigua and Barbuda',
|
||||
'AR' => 'Argentina',
|
||||
'AM' => 'Armenia',
|
||||
'AW' => 'Aruba',
|
||||
'AU' => 'Australia',
|
||||
'AT' => 'Austria',
|
||||
'AZ' => 'Azerbaijan',
|
||||
'BS' => 'Bahamas',
|
||||
'BH' => 'Bahrain',
|
||||
'BD' => 'Bangladesh',
|
||||
'BB' => 'Barbados',
|
||||
'BY' => 'Belarus',
|
||||
'BE' => 'Belgium',
|
||||
'BZ' => 'Belize',
|
||||
'BJ' => 'Benin',
|
||||
'BM' => 'Bermuda',
|
||||
'BT' => 'Bhutan',
|
||||
'BO' => 'Bolivia',
|
||||
'BQ' => 'Bonaire, Saint Eustatius and Saba',
|
||||
'BA' => 'Bosnia and Herzegovina',
|
||||
'BW' => 'Botswana',
|
||||
'BV' => 'Bouvet Island',
|
||||
'BR' => 'Brazil',
|
||||
'IO' => 'British Indian Ocean Territory',
|
||||
'VG' => 'British Virgin Islands',
|
||||
'BN' => 'Brunei',
|
||||
'BG' => 'Bulgaria',
|
||||
'BF' => 'Burkina Faso',
|
||||
'BI' => 'Burundi',
|
||||
'KH' => 'Cambodia',
|
||||
'CM' => 'Cameroon',
|
||||
'CA' => 'Canada',
|
||||
'CV' => 'Cape Verde',
|
||||
'KY' => 'Cayman Islands',
|
||||
'CF' => 'Central African Republic',
|
||||
'TD' => 'Chad',
|
||||
'CL' => 'Chile',
|
||||
'CN' => 'China',
|
||||
'CX' => 'Christmas Island',
|
||||
'CC' => 'Cocos Islands',
|
||||
'CO' => 'Colombia',
|
||||
'KM' => 'Comoros',
|
||||
'CK' => 'Cook Islands',
|
||||
'CR' => 'Costa Rica',
|
||||
'HR' => 'Croatia',
|
||||
'CU' => 'Cuba',
|
||||
'CW' => 'Curacao',
|
||||
'CY' => 'Cyprus',
|
||||
'CZ' => 'Czech Republic',
|
||||
'CD' => 'Democratic Republic of the Congo',
|
||||
'DK' => 'Denmark',
|
||||
'DJ' => 'Djibouti',
|
||||
'DM' => 'Dominica',
|
||||
'DO' => 'Dominican Republic',
|
||||
'TL' => 'East Timor',
|
||||
'EC' => 'Ecuador',
|
||||
'EG' => 'Egypt',
|
||||
'SV' => 'El Salvador',
|
||||
'GQ' => 'Equatorial Guinea',
|
||||
'ER' => 'Eritrea',
|
||||
'EE' => 'Estonia',
|
||||
'ET' => 'Ethiopia',
|
||||
'FK' => 'Falkland Islands',
|
||||
'FO' => 'Faroe Islands',
|
||||
'FJ' => 'Fiji',
|
||||
'FI' => 'Finland',
|
||||
'FR' => 'France',
|
||||
'GF' => 'French Guiana',
|
||||
'PF' => 'French Polynesia',
|
||||
'TF' => 'French Southern Territories',
|
||||
'GA' => 'Gabon',
|
||||
'GM' => 'Gambia',
|
||||
'GE' => 'Georgia',
|
||||
'DE' => 'Germany',
|
||||
'GH' => 'Ghana',
|
||||
'GI' => 'Gibraltar',
|
||||
'GR' => 'Greece',
|
||||
'GL' => 'Greenland',
|
||||
'GD' => 'Grenada',
|
||||
'GP' => 'Guadeloupe',
|
||||
'GU' => 'Guam',
|
||||
'GT' => 'Guatemala',
|
||||
'GG' => 'Guernsey',
|
||||
'GN' => 'Guinea',
|
||||
'GW' => 'Guinea-Bissau',
|
||||
'GY' => 'Guyana',
|
||||
'HT' => 'Haiti',
|
||||
'HM' => 'Heard Island and McDonald Islands',
|
||||
'HN' => 'Honduras',
|
||||
'HK' => 'Hong Kong',
|
||||
'HU' => 'Hungary',
|
||||
'IS' => 'Iceland',
|
||||
'IN' => 'India',
|
||||
'ID' => 'Indonesia',
|
||||
'IR' => 'Iran',
|
||||
'IQ' => 'Iraq',
|
||||
'IE' => 'Ireland',
|
||||
'IM' => 'Isle of Man',
|
||||
'IL' => 'Israel',
|
||||
'IT' => 'Italy',
|
||||
'CI' => 'Ivory Coast',
|
||||
'JM' => 'Jamaica',
|
||||
'JP' => 'Japan',
|
||||
'JE' => 'Jersey',
|
||||
'JO' => 'Jordan',
|
||||
'KZ' => 'Kazakhstan',
|
||||
'KE' => 'Kenya',
|
||||
'KI' => 'Kiribati',
|
||||
'XK' => 'Kosovo',
|
||||
'KW' => 'Kuwait',
|
||||
'KG' => 'Kyrgyzstan',
|
||||
'LA' => 'Laos',
|
||||
'LV' => 'Latvia',
|
||||
'LB' => 'Lebanon',
|
||||
'LS' => 'Lesotho',
|
||||
'LR' => 'Liberia',
|
||||
'LY' => 'Libya',
|
||||
'LI' => 'Liechtenstein',
|
||||
'LT' => 'Lithuania',
|
||||
'LU' => 'Luxembourg',
|
||||
'MO' => 'Macao',
|
||||
'MK' => 'Macedonia',
|
||||
'MG' => 'Madagascar',
|
||||
'MW' => 'Malawi',
|
||||
'MY' => 'Malaysia',
|
||||
'MV' => 'Maldives',
|
||||
'ML' => 'Mali',
|
||||
'MT' => 'Malta',
|
||||
'MH' => 'Marshall Islands',
|
||||
'MQ' => 'Martinique',
|
||||
'MR' => 'Mauritania',
|
||||
'MU' => 'Mauritius',
|
||||
'YT' => 'Mayotte',
|
||||
'MX' => 'Mexico',
|
||||
'FM' => 'Micronesia',
|
||||
'MD' => 'Moldova',
|
||||
'MC' => 'Monaco',
|
||||
'MN' => 'Mongolia',
|
||||
'ME' => 'Montenegro',
|
||||
'MS' => 'Montserrat',
|
||||
'MA' => 'Morocco',
|
||||
'MZ' => 'Mozambique',
|
||||
'MM' => 'Myanmar',
|
||||
'NA' => 'Namibia',
|
||||
'NR' => 'Nauru',
|
||||
'NP' => 'Nepal',
|
||||
'NL' => 'Netherlands',
|
||||
'NC' => 'New Caledonia',
|
||||
'NZ' => 'New Zealand',
|
||||
'NI' => 'Nicaragua',
|
||||
'NE' => 'Niger',
|
||||
'NG' => 'Nigeria',
|
||||
'NU' => 'Niue',
|
||||
'NF' => 'Norfolk Island',
|
||||
'KP' => 'North Korea',
|
||||
'MP' => 'Northern Mariana Islands',
|
||||
'NO' => 'Norway',
|
||||
'OM' => 'Oman',
|
||||
'PK' => 'Pakistan',
|
||||
'PW' => 'Palau',
|
||||
'PS' => 'Palestinian Territory',
|
||||
'PA' => 'Panama',
|
||||
'PG' => 'Papua New Guinea',
|
||||
'PY' => 'Paraguay',
|
||||
'PE' => 'Peru',
|
||||
'PH' => 'Philippines',
|
||||
'PN' => 'Pitcairn',
|
||||
'PL' => 'Poland',
|
||||
'PT' => 'Portugal',
|
||||
'PR' => 'Puerto Rico',
|
||||
'QA' => 'Qatar',
|
||||
'CG' => 'Republic of the Congo',
|
||||
'RE' => 'Reunion',
|
||||
'RO' => 'Romania',
|
||||
'RU' => 'Russia',
|
||||
'RW' => 'Rwanda',
|
||||
'BL' => 'Saint Barthelemy',
|
||||
'SH' => 'Saint Helena',
|
||||
'KN' => 'Saint Kitts and Nevis',
|
||||
'LC' => 'Saint Lucia',
|
||||
'MF' => 'Saint Martin',
|
||||
'PM' => 'Saint Pierre and Miquelon',
|
||||
'VC' => 'Saint Vincent and the Grenadines',
|
||||
'WS' => 'Samoa',
|
||||
'SM' => 'San Marino',
|
||||
'ST' => 'Sao Tome and Principe',
|
||||
'SA' => 'Saudi Arabia',
|
||||
'SN' => 'Senegal',
|
||||
'RS' => 'Serbia',
|
||||
'SC' => 'Seychelles',
|
||||
'SL' => 'Sierra Leone',
|
||||
'SG' => 'Singapore',
|
||||
'SX' => 'Sint Maarten',
|
||||
'SK' => 'Slovakia',
|
||||
'SI' => 'Slovenia',
|
||||
'SB' => 'Solomon Islands',
|
||||
'SO' => 'Somalia',
|
||||
'ZA' => 'South Africa',
|
||||
'GS' => 'South Georgia and the South Sandwich Islands',
|
||||
'KR' => 'South Korea',
|
||||
'SS' => 'South Sudan',
|
||||
'ES' => 'Spain',
|
||||
'LK' => 'Sri Lanka',
|
||||
'SD' => 'Sudan',
|
||||
'SR' => 'Suriname',
|
||||
'SJ' => 'Svalbard and Jan Mayen',
|
||||
'SZ' => 'Swaziland',
|
||||
'SE' => 'Sweden',
|
||||
'CH' => 'Switzerland',
|
||||
'SY' => 'Syria',
|
||||
'TW' => 'Taiwan',
|
||||
'TJ' => 'Tajikistan',
|
||||
'TZ' => 'Tanzania',
|
||||
'TH' => 'Thailand',
|
||||
'TG' => 'Togo',
|
||||
'TK' => 'Tokelau',
|
||||
'TO' => 'Tonga',
|
||||
'TT' => 'Trinidad and Tobago',
|
||||
'TN' => 'Tunisia',
|
||||
'TR' => 'Turkey',
|
||||
'TM' => 'Turkmenistan',
|
||||
'TC' => 'Turks and Caicos Islands',
|
||||
'TV' => 'Tuvalu',
|
||||
'VI' => 'U.S. Virgin Islands',
|
||||
'UG' => 'Uganda',
|
||||
'UA' => 'Ukraine',
|
||||
'AE' => 'United Arab Emirates',
|
||||
'GB' => 'United Kingdom',
|
||||
'US' => 'United States',
|
||||
'UM' => 'United States Minor Outlying Islands',
|
||||
'UY' => 'Uruguay',
|
||||
'UZ' => 'Uzbekistan',
|
||||
'VU' => 'Vanuatu',
|
||||
'VA' => 'Vatican',
|
||||
'VE' => 'Venezuela',
|
||||
'VN' => 'Vietnam',
|
||||
'WF' => 'Wallis and Futuna',
|
||||
'EH' => 'Western Sahara',
|
||||
'YE' => 'Yemen',
|
||||
'ZM' => 'Zambia',
|
||||
'ZW' => 'Zimbabwe',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
add_action('mc4wp_refresh_mailchimp_lists', 'mc4wp_refresh_mailchimp_lists');
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
add_filter('mc4wp_form_data', 'mc4wp_add_name_data', 60);
|
||||
add_filter('mc4wp_integration_data', 'mc4wp_add_name_data', 60);
|
||||
|
||||
add_filter('mctb_data', '_mc4wp_update_groupings_data', PHP_INT_MAX);
|
||||
add_filter('mc4wp_form_data', '_mc4wp_update_groupings_data', PHP_INT_MAX);
|
||||
add_filter('mc4wp_integration_data', '_mc4wp_update_groupings_data', PHP_INT_MAX);
|
||||
add_filter('mailchimp_sync_user_data', '_mc4wp_update_groupings_data', PHP_INT_MAX);
|
||||
add_filter('mc4wp_use_sslverify', '_mc4wp_use_sslverify', 1);
|
||||
|
||||
mc4wp_apply_deprecated_filters('mc4wp_merge_vars', 'mc4wp_form_data');
|
||||
mc4wp_apply_deprecated_filters('mc4wp_form_merge_vars', 'mc4wp_form_data');
|
||||
mc4wp_apply_deprecated_filters('mc4wp_integration_merge_vars', 'mc4wp_integration_data');
|
||||
@@ -0,0 +1 @@
|
||||
<?php
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Gets the absolute url to edit a form
|
||||
*
|
||||
* @param int $form_id ID of the form
|
||||
* @param string $tab Tab identifier to open
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_get_edit_form_url($form_id, $tab = '')
|
||||
{
|
||||
$url = admin_url(sprintf('admin.php?page=mailchimp-for-wp-forms&view=edit-form&form_id=%d', $form_id));
|
||||
|
||||
if (! empty($tab)) {
|
||||
$url .= sprintf('&tab=%s', $tab);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get absolute URL to create a new form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_get_add_form_url()
|
||||
{
|
||||
$url = admin_url('admin.php?page=mailchimp-for-wp-forms&view=add-form');
|
||||
return $url;
|
||||
}
|
||||
@@ -0,0 +1,491 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Forms_Admin
|
||||
*
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Forms_Admin
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Admin_Messages
|
||||
*/
|
||||
protected $messages;
|
||||
|
||||
/**
|
||||
* @param MC4WP_Admin_Messages $messages
|
||||
*/
|
||||
public function __construct(MC4WP_Admin_Messages $messages)
|
||||
{
|
||||
$this->messages = $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('register_shortcode_ui', array( $this, 'register_shortcake_ui' ));
|
||||
add_action('mc4wp_save_form', array( $this, 'update_form_stylesheets' ));
|
||||
add_action('mc4wp_admin_edit_form', array( $this, 'process_save_form' ));
|
||||
add_action('mc4wp_admin_add_form', array( $this, 'process_add_form' ));
|
||||
add_filter('mc4wp_admin_menu_items', array( $this, 'add_menu_item' ), 5);
|
||||
add_action('mc4wp_admin_show_forms_page-edit-form', array( $this, 'show_edit_page' ));
|
||||
add_action('mc4wp_admin_show_forms_page-add-form', array( $this, 'show_add_page' ));
|
||||
add_action('mc4wp_admin_enqueue_assets', array( $this, 'enqueue_assets' ), 10, 2);
|
||||
|
||||
add_action('enqueue_block_editor_assets', array( $this, 'enqueue_gutenberg_assets' ));
|
||||
}
|
||||
|
||||
|
||||
public function enqueue_gutenberg_assets()
|
||||
{
|
||||
wp_enqueue_script('mc4wp-form-block', mc4wp_plugin_url('assets/js/forms-block.js'), array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-components' ));
|
||||
|
||||
$forms = mc4wp_get_forms();
|
||||
$data = array();
|
||||
foreach ($forms as $form) {
|
||||
$data[] = array(
|
||||
'name' => $form->name,
|
||||
'id' => $form->ID,
|
||||
);
|
||||
}
|
||||
wp_localize_script('mc4wp-form-block', 'mc4wp_forms', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $suffix
|
||||
* @param string $page
|
||||
*/
|
||||
public function enqueue_assets($suffix, $page = '')
|
||||
{
|
||||
if ($page !== 'forms' || empty($_GET['view']) || $_GET['view'] !== 'edit-form') {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_register_script('mc4wp-forms-admin', mc4wp_plugin_url('assets/js/forms-admin.js'), array( 'mc4wp-admin' ), MC4WP_VERSION, true);
|
||||
wp_enqueue_script('mc4wp-forms-admin');
|
||||
wp_localize_script(
|
||||
'mc4wp-forms-admin',
|
||||
'mc4wp_forms_i18n',
|
||||
array(
|
||||
'addToForm' => __('Add to form', 'mailchimp-for-wp'),
|
||||
'agreeToTerms' => __('I have read and agree to the terms & conditions', 'mailchimp-for-wp'),
|
||||
'agreeToTermsShort' => __('Agree to terms', 'mailchimp-for-wp'),
|
||||
'agreeToTermsLink' => __('Link to your terms & conditions page', 'mailchimp-for-wp'),
|
||||
'city' => __('City', 'mailchimp-for-wp'),
|
||||
'checkboxes' => __('Checkboxes', 'mailchimp-for-wp'),
|
||||
'choices' => __('Choices', 'mailchimp-for-wp'),
|
||||
'choiceType' => __('Choice type', 'mailchimp-for-wp'),
|
||||
'chooseField' => __('Choose a field to add to the form', 'mailchimp-for-wp'),
|
||||
'close' => __('Close', 'mailchimp-for-wp'),
|
||||
'country' => __('Country', 'mailchimp-for-wp'),
|
||||
'dropdown' => __('Dropdown', 'mailchimp-for-wp'),
|
||||
'emailAddress' => __('Email address', 'mailchimp-for-wp'),
|
||||
'fieldType' => __('Field type', 'mailchimp-for-wp'),
|
||||
'fieldLabel' => __('Field label', 'mailchimp-for-wp'),
|
||||
'formAction' => __('Form action', 'mailchimp-for-wp'),
|
||||
'formActionDescription' => __('This field will allow your visitors to choose whether they would like to subscribe or unsubscribe', 'mailchimp-for-wp'),
|
||||
'formFields' => __('Form fields', 'mailchimp-for-wp'),
|
||||
'forceRequired' => __('This field is marked as required in Mailchimp.', 'mailchimp-for-wp'),
|
||||
'initialValue' => __('Initial value', 'mailchimp-for-wp'),
|
||||
'interestCategories' => __('Interest categories', 'mailchimp-for-wp'),
|
||||
'isFieldRequired' => __('Is this field required?', 'mailchimp-for-wp'),
|
||||
'listChoice' => __('List choice', 'mailchimp-for-wp'),
|
||||
'listChoiceDescription' => __('This field will allow your visitors to choose a list to subscribe to.', 'mailchimp-for-wp'),
|
||||
'listFields' => __('List fields', 'mailchimp-for-wp'),
|
||||
'min' => __('Min', 'mailchimp-for-wp'),
|
||||
'max' => __('Max', 'mailchimp-for-wp'),
|
||||
'noAvailableFields' => __('No available fields. Did you select a Mailchimp list in the form settings?', 'mailchimp-for-wp'),
|
||||
'optional' => __('Optional', 'mailchimp-for-wp'),
|
||||
'placeholder' => __('Placeholder', 'mailchimp-for-wp'),
|
||||
'placeholderHelp' => __('Text to show when field has no value.', 'mailchimp-for-wp'),
|
||||
'preselect' => __('Preselect', 'mailchimp-for-wp'),
|
||||
'remove' => __('Remove', 'mailchimp-for-wp'),
|
||||
'radioButtons' => __('Radio buttons', 'mailchimp-for-wp'),
|
||||
'streetAddress' => __('Street Address', 'mailchimp-for-wp'),
|
||||
'state' => __('State', 'mailchimp-for-wp'),
|
||||
'subscribe' => __('Subscribe', 'mailchimp-for-wp'),
|
||||
'submitButton' => __('Submit button', 'mailchimp-for-wp'),
|
||||
'wrapInParagraphTags' => __('Wrap in paragraph tags?', 'mailchimp-for-wp'),
|
||||
'value' => __('Value', 'mailchimp-for-wp'),
|
||||
'valueHelp' => __('Text to prefill this field with.', 'mailchimp-for-wp'),
|
||||
'zip' => __('ZIP', 'mailchimp-for-wp'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $items
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function add_menu_item($items)
|
||||
{
|
||||
$items['forms'] = array(
|
||||
'title' => esc_html__('Forms', 'mailchimp-for-wp'),
|
||||
'text' => esc_html__('Form', 'mailchimp-for-wp'),
|
||||
'slug' => 'forms',
|
||||
'callback' => array( $this, 'show_forms_page' ),
|
||||
'load_callback' => array( $this, 'redirect_to_form_action' ),
|
||||
'position' => 10,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on the "add form" form
|
||||
*/
|
||||
public function process_add_form()
|
||||
{
|
||||
$form_data = $_POST['mc4wp_form'];
|
||||
$form_content = include MC4WP_PLUGIN_DIR . '/config/default-form-content.php';
|
||||
|
||||
// Fix for MultiSite stripping KSES for roles other than administrator
|
||||
remove_all_filters('content_save_pre');
|
||||
|
||||
$form_id = wp_insert_post(
|
||||
array(
|
||||
'post_type' => 'mc4wp-form',
|
||||
'post_status' => 'publish',
|
||||
'post_title' => $form_data['name'],
|
||||
'post_content' => $form_content,
|
||||
)
|
||||
);
|
||||
|
||||
// if settings were passed, save those too.
|
||||
if (isset($form_data['settings'])) {
|
||||
update_post_meta($form_id, '_mc4wp_settings', $form_data['settings']);
|
||||
}
|
||||
|
||||
// set default form ID
|
||||
$this->set_default_form_id($form_id);
|
||||
|
||||
$this->messages->flash(esc_html__('Form saved.', 'mailchimp-for-wp'));
|
||||
$edit_form_url = mc4wp_get_edit_form_url($form_id);
|
||||
wp_redirect($edit_form_url);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a form to the database
|
||||
* @param int $form_id
|
||||
* @param array $data
|
||||
* @return int
|
||||
*/
|
||||
private function save_form($form_id, array $data)
|
||||
{
|
||||
$keys = array(
|
||||
'settings' => array(),
|
||||
'messages' => array(),
|
||||
'name' => '',
|
||||
'content' => '',
|
||||
);
|
||||
$data = array_merge($keys, $data);
|
||||
$data = $this->sanitize_form_data($data);
|
||||
|
||||
$post_data = array(
|
||||
'ID' => $form_id,
|
||||
'post_type' => 'mc4wp-form',
|
||||
'post_status' => ! empty($data['status']) ? $data['status'] : 'publish',
|
||||
'post_title' => $data['name'],
|
||||
'post_content' => $data['content'],
|
||||
);
|
||||
|
||||
// Fix for MultiSite stripping KSES for roles other than administrator
|
||||
remove_all_filters('content_save_pre');
|
||||
wp_insert_post($post_data);
|
||||
|
||||
// merge new settings with current settings to allow passing partial data
|
||||
$current_settings = get_post_meta($form_id, '_mc4wp_settings', true);
|
||||
if (is_array($current_settings)) {
|
||||
$data['settings'] = array_merge($current_settings, $data['settings']);
|
||||
}
|
||||
update_post_meta($form_id, '_mc4wp_settings', $data['settings']);
|
||||
|
||||
// save form messages in individual meta keys
|
||||
foreach ($data['messages'] as $key => $message) {
|
||||
update_post_meta($form_id, 'text_' . $key, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs right after a form is updated.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $form_id
|
||||
*/
|
||||
do_action('mc4wp_save_form', $form_id);
|
||||
|
||||
return $form_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function sanitize_form_data(array $data)
|
||||
{
|
||||
$raw_data = $data;
|
||||
|
||||
// strip <form> tags from content
|
||||
$data['content'] = preg_replace('/<\/?form(.|\s)*?>/i', '', $data['content']);
|
||||
|
||||
// replace lowercased name="name" to prevent 404
|
||||
$data['content'] = str_ireplace(' name=\"name\"', ' name=\"NAME\"', $data['content']);
|
||||
|
||||
// sanitize text fields
|
||||
$data['settings']['redirect'] = sanitize_text_field($data['settings']['redirect']);
|
||||
|
||||
// strip tags from messages
|
||||
foreach ($data['messages'] as $key => $message) {
|
||||
$data['messages'][ $key ] = strip_tags($message, '<strong><b><br><a><script><u><em><i><span><img>');
|
||||
}
|
||||
|
||||
// make sure lists is an array
|
||||
if (! isset($data['settings']['lists'])) {
|
||||
$data['settings']['lists'] = array();
|
||||
}
|
||||
|
||||
$data['settings']['lists'] = array_filter((array) $data['settings']['lists']);
|
||||
|
||||
// if current user can not post unfiltered HTML, run HTML through whitelist using wp_kses
|
||||
if (! current_user_can('unfiltered_html')) {
|
||||
$data['content'] = mc4wp_kses($data['content']);
|
||||
foreach ($data['messages'] as $key => $message) {
|
||||
$data['messages'][ $key ] = mc4wp_kses($data['messages'][ $key ]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the form data just before it is saved.
|
||||
*
|
||||
* @param array $data Sanitized array of form data.
|
||||
* @param array $raw_data Raw array of form data.
|
||||
*
|
||||
* @since 3.0.8
|
||||
* @ignore
|
||||
*/
|
||||
$data = (array) apply_filters('mc4wp_form_sanitized_data', $data, $raw_data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a form
|
||||
*/
|
||||
public function process_save_form()
|
||||
{
|
||||
// save global settings (if submitted)
|
||||
if (isset($_POST['mc4wp']) && is_array($_POST['mc4wp'])) {
|
||||
$options = get_option('mc4wp', array());
|
||||
$posted = $_POST['mc4wp'];
|
||||
foreach ($posted as $key => $value) {
|
||||
$options[ $key ] = trim($value);
|
||||
}
|
||||
update_option('mc4wp', $options);
|
||||
}
|
||||
|
||||
// update form, settings and messages
|
||||
$form_id = (int) $_POST['mc4wp_form_id'];
|
||||
$form_data = $_POST['mc4wp_form'];
|
||||
$this->save_form($form_id, $form_data);
|
||||
$this->set_default_form_id($form_id);
|
||||
$this->messages->flash(esc_html__('Form saved.', 'mailchimp-for-wp'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $form_id
|
||||
*/
|
||||
private function set_default_form_id($form_id)
|
||||
{
|
||||
$default_form_id = get_option('mc4wp_default_form_id', 0);
|
||||
|
||||
if (empty($default_form_id)) {
|
||||
update_option('mc4wp_default_form_id', $form_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes through each form and aggregates array of stylesheet slugs to load.
|
||||
*
|
||||
* @hooked `mc4wp_save_form`
|
||||
*/
|
||||
public function update_form_stylesheets()
|
||||
{
|
||||
$stylesheets = array();
|
||||
|
||||
$forms = mc4wp_get_forms();
|
||||
foreach ($forms as $form) {
|
||||
$stylesheet = $form->get_stylesheet();
|
||||
|
||||
if (! empty($stylesheet) && ! in_array($stylesheet, $stylesheets, true)) {
|
||||
$stylesheets[] = $stylesheet;
|
||||
}
|
||||
}
|
||||
|
||||
update_option('mc4wp_form_stylesheets', $stylesheets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to correct form action
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
public function redirect_to_form_action()
|
||||
{
|
||||
if (! empty($_GET['view'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// try default form first
|
||||
$default_form = mc4wp_get_form();
|
||||
$redirect_url = mc4wp_get_edit_form_url($default_form->ID);
|
||||
} catch (Exception $e) {
|
||||
// no default form, query first available form and go there
|
||||
$forms = mc4wp_get_forms(
|
||||
array(
|
||||
'posts_per_page' => 1,
|
||||
'orderby' => 'ID',
|
||||
'order' => 'ASC',
|
||||
)
|
||||
);
|
||||
|
||||
if (count($forms) > 0) {
|
||||
// take first form and use it to go to the "edit form" screen
|
||||
$form = array_shift($forms);
|
||||
$redirect_url = mc4wp_get_edit_form_url($form->ID);
|
||||
} else {
|
||||
// we don't have a form yet, go to "add new" screen
|
||||
$redirect_url = mc4wp_get_add_form_url();
|
||||
}
|
||||
}
|
||||
|
||||
if (headers_sent()) {
|
||||
echo sprintf('<meta http-equiv="refresh" content="0;url=%s" />', $redirect_url);
|
||||
} else {
|
||||
wp_redirect($redirect_url);
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the Forms Settings page
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function show_forms_page()
|
||||
{
|
||||
$view = ! empty($_GET['view']) ? $_GET['view'] : '';
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
do_action('mc4wp_admin_show_forms_page', $view);
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
do_action('mc4wp_admin_show_forms_page-' . $view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the "Edit Form" page
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function show_edit_page()
|
||||
{
|
||||
$form_id = ( ! empty($_GET['form_id']) ) ? (int) $_GET['form_id'] : 0;
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$lists = $mailchimp->get_lists();
|
||||
|
||||
try {
|
||||
$form = mc4wp_get_form($form_id);
|
||||
} catch (Exception $e) {
|
||||
echo '<h2>', esc_html__('Form not found.', 'mailchimp-for-wp'), '</h2>';
|
||||
echo '<p>', $e->getMessage(), '</p>';
|
||||
echo '<p><a href="javascript:history.go(-1);"> ‹ ', esc_html__('Go back', 'mailchimp-for-wp'), '</a></p>';
|
||||
return;
|
||||
}
|
||||
|
||||
$opts = $form->settings;
|
||||
$active_tab = ( isset($_GET['tab']) ) ? $_GET['tab'] : 'fields';
|
||||
|
||||
$form_preview_url = add_query_arg(
|
||||
array(
|
||||
'mc4wp_preview_form' => $form_id,
|
||||
),
|
||||
site_url('/', 'admin')
|
||||
);
|
||||
|
||||
require __DIR__ . '/views/edit-form.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the "Add Form" page
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function show_add_page()
|
||||
{
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$lists = $mailchimp->get_lists();
|
||||
$number_of_lists = count($lists);
|
||||
require __DIR__ . '/views/add-form.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL for a tab on the current page.
|
||||
*
|
||||
* @since 3.0
|
||||
* @internal
|
||||
* @param $tab
|
||||
* @return string
|
||||
*/
|
||||
public function tab_url($tab)
|
||||
{
|
||||
return add_query_arg(array( 'tab' => $tab ), remove_query_arg('tab'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers UI for when shortcake is activated
|
||||
*/
|
||||
public function register_shortcake_ui()
|
||||
{
|
||||
$assets = new MC4WP_Form_Asset_Manager();
|
||||
$assets->load_stylesheets();
|
||||
|
||||
$forms = mc4wp_get_forms();
|
||||
$options = array();
|
||||
foreach ($forms as $form) {
|
||||
$options[ $form->ID ] = $form->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register UI for your shortcode
|
||||
*
|
||||
* @param string $shortcode_tag
|
||||
* @param array $ui_args
|
||||
*/
|
||||
shortcode_ui_register_for_shortcode(
|
||||
'mc4wp_form',
|
||||
array(
|
||||
'label' => esc_html__('Mailchimp Sign-Up Form', 'mailchimp-for-wp'),
|
||||
'listItemImage' => 'dashicons-feedback',
|
||||
'attrs' => array(
|
||||
array(
|
||||
'label' => esc_html__('Select the form to show', 'mailchimp-for-wp'),
|
||||
'attr' => 'id',
|
||||
'type' => 'select',
|
||||
'options' => $options,
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class takes care of all form assets related functionality
|
||||
*
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Form_Asset_Manager
|
||||
{
|
||||
/**
|
||||
* @var bool Flag to determine whether scripts should be enqueued.
|
||||
*/
|
||||
private $load_scripts = false;
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('init', array( $this, 'register_scripts' ));
|
||||
add_action('wp_enqueue_scripts', array( $this, 'load_stylesheets' ));
|
||||
add_action('wp_footer', array( $this, 'load_scripts' ));
|
||||
add_action('mc4wp_output_form', array( $this, 'before_output_form' ));
|
||||
add_action('script_loader_tag', array( $this, 'add_defer_attribute' ), 10, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register scripts to be enqueued later.
|
||||
*/
|
||||
public function register_scripts()
|
||||
{
|
||||
wp_register_script('mc4wp-forms-api', mc4wp_plugin_url('assets/js/forms.js'), array(), MC4WP_VERSION, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stylesheet
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_registered_stylesheet($stylesheet)
|
||||
{
|
||||
$stylesheets = $this->get_registered_stylesheets();
|
||||
return in_array($stylesheet, $stylesheets, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_registered_stylesheets()
|
||||
{
|
||||
return array(
|
||||
'basic',
|
||||
'themes',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stylesheet
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_stylesheet_url($stylesheet)
|
||||
{
|
||||
return mc4wp_plugin_url('assets/css/form-' . $stylesheet . '.css');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of stylesheet handles which should be enqueued.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_active_stylesheets()
|
||||
{
|
||||
$stylesheets = (array) get_option('mc4wp_form_stylesheets', array());
|
||||
|
||||
/**
|
||||
* Filters the stylesheets to be loaded
|
||||
*
|
||||
* Should be an array of stylesheet handles previously registered using `wp_register_style`.
|
||||
* Each value is prefixed with `mc4wp-form-` to get the handle.
|
||||
*
|
||||
* Return an empty array if you want to disable the loading of all stylesheets.
|
||||
*
|
||||
* @since 3.0
|
||||
* @param array $stylesheets Array of valid stylesheet handles
|
||||
*/
|
||||
$stylesheets = (array) apply_filters('mc4wp_form_stylesheets', $stylesheets);
|
||||
return $stylesheets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the various stylesheets
|
||||
*/
|
||||
public function load_stylesheets()
|
||||
{
|
||||
$stylesheets = $this->get_active_stylesheets();
|
||||
|
||||
foreach ($stylesheets as $stylesheet) {
|
||||
if (! $this->is_registered_stylesheet($stylesheet)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$handle = 'mc4wp-form-' . $stylesheet;
|
||||
$url = $this->get_stylesheet_url($stylesheet);
|
||||
wp_enqueue_style($handle, $url, array(), MC4WP_VERSION);
|
||||
add_editor_style($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
do_action('mc4wp_load_form_stylesheets', $stylesheets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data object for client-side use for after a form is submitted over HTTP POST (not AJAX).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_submitted_form_data()
|
||||
{
|
||||
$submitted_form = mc4wp_get_submitted_form();
|
||||
if (! $submitted_form instanceof MC4WP_Form) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = array(
|
||||
'id' => $submitted_form->ID,
|
||||
'event' => $submitted_form->last_event,
|
||||
'data' => $submitted_form->get_data(),
|
||||
'element_id' => $submitted_form->config['element_id'],
|
||||
'auto_scroll' => true,
|
||||
);
|
||||
|
||||
if ($submitted_form->has_errors()) {
|
||||
$data['errors'] = $submitted_form->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the `auto_scroll` setting for when a form is submitted.
|
||||
* Set to false to disable scrolling to form.
|
||||
*
|
||||
* @param boolean $auto_scroll
|
||||
* @since 3.0
|
||||
*/
|
||||
$data['auto_scroll'] = apply_filters('mc4wp_form_auto_scroll', $data['auto_scroll']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load JavaScript files
|
||||
*/
|
||||
public function before_output_form()
|
||||
{
|
||||
$load_scripts = apply_filters('mc4wp_load_form_scripts', true);
|
||||
if (! $load_scripts) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->print_dummy_javascript();
|
||||
$this->load_scripts = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints dummy JavaScript which allows people to call `mc4wp.forms.on()` before the JS is loaded.
|
||||
*/
|
||||
public function print_dummy_javascript()
|
||||
{
|
||||
echo '<script>';
|
||||
include __DIR__ . '/views/js/dummy-api.js';
|
||||
echo '</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the inline JavaScript that is used to enhance forms
|
||||
*/
|
||||
public function load_scripts()
|
||||
{
|
||||
$load_scripts = apply_filters('mc4wp_load_form_scripts', $this->load_scripts);
|
||||
if (! $load_scripts) {
|
||||
return;
|
||||
}
|
||||
|
||||
// load general client-side form API
|
||||
wp_enqueue_script('mc4wp-forms-api');
|
||||
|
||||
// maybe load JS file for when a form was submitted over HTTP POST
|
||||
$submitted_form_data = $this->get_submitted_form_data();
|
||||
if ($submitted_form_data !== null) {
|
||||
wp_enqueue_script('mc4wp-forms-submitted', mc4wp_plugin_url('assets/js/forms-submitted.js'), array( 'mc4wp-forms-api' ), MC4WP_VERSION, true);
|
||||
wp_localize_script('mc4wp-forms-submitted', 'mc4wp_submitted_form', $submitted_form_data);
|
||||
}
|
||||
|
||||
// print inline scripts
|
||||
echo '<script>';
|
||||
echo '(function() {';
|
||||
include __DIR__ . '/views/js/url-fields.js';
|
||||
echo '})();';
|
||||
echo '</script>';
|
||||
|
||||
/** @ignore */
|
||||
do_action('mc4wp_load_form_scripts');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `defer` attribute to all form-related `<script>` elements so they do not block page rendering.
|
||||
*
|
||||
* @param string $tag
|
||||
* @param string $handle
|
||||
* @return string
|
||||
*/
|
||||
public function add_defer_attribute($tag, $handle)
|
||||
{
|
||||
if (! in_array($handle, array( 'mc4wp-forms-api', 'mc4wp-forms-submitted' ), true) || stripos($tag, ' defer') !== false) {
|
||||
return $tag;
|
||||
}
|
||||
|
||||
return str_replace(' src=', ' defer src=', $tag);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Form_AMP
|
||||
*/
|
||||
class MC4WP_Form_AMP
|
||||
{
|
||||
/**
|
||||
* Hook!
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_filter('mc4wp_form_content', array( $this, 'add_response_templates' ), 10, 2);
|
||||
add_filter('mc4wp_form_element_attributes', array( $this, 'add_amp_request' ));
|
||||
add_filter('mc4wp_load_form_scripts', array( $this, 'suppress_scripts' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add AMP templates for submit/success/error.
|
||||
*
|
||||
* @param string $content The form content.
|
||||
* @param MC4WP_Form $form The form object.
|
||||
* @return string Modified $content.
|
||||
*/
|
||||
public function add_response_templates($content, $form)
|
||||
{
|
||||
if (! function_exists('amp_is_request') || ! amp_is_request()) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div submitting>
|
||||
<template type="amp-mustache">
|
||||
<?php echo esc_html__('Submitting...', 'mailchimp-for-wp'); ?>
|
||||
</template>
|
||||
</div>
|
||||
<div submit-success>
|
||||
<template type="amp-mustache">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$form->get_message('subscribed'),
|
||||
array(
|
||||
'a' => array(),
|
||||
'strong' => array(),
|
||||
'em' => array(),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</template>
|
||||
</div>
|
||||
<div submit-error>
|
||||
<template type="amp-mustache">
|
||||
{{message}}
|
||||
</template>
|
||||
</div>
|
||||
<?php
|
||||
$content .= ob_get_clean();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'action-xhr' to AMP forms.
|
||||
*
|
||||
* @param array $attributes Key-Value pairs of attributes output on form.
|
||||
* @return array Modified $attributes.
|
||||
*/
|
||||
public function add_amp_request($attributes)
|
||||
{
|
||||
if (function_exists('amp_is_request') && amp_is_request()) {
|
||||
$attributes['action-xhr'] = get_rest_url(null, 'mc4wp/v1/form');
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppress form scripts on AMP pages.
|
||||
*
|
||||
* @param bool $load_scripts Whether scripts should be loaded.
|
||||
* @return bool Modified $load_scripts.
|
||||
*/
|
||||
public function suppress_scripts($load_scripts)
|
||||
{
|
||||
if (function_exists('amp_is_request') && amp_is_request()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $load_scripts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Form_Element
|
||||
*
|
||||
* @since 3.0
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Form_Element
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $ID;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Form
|
||||
*/
|
||||
public $form;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
* Can be used to set element-specific config settings. Accepts the following keys.
|
||||
*
|
||||
* - lists: Customized number of Mailchimp list ID's to subscribe to.
|
||||
* - email_type: The email type
|
||||
*/
|
||||
public $config = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $is_submitted = false;
|
||||
|
||||
/**
|
||||
* @param MC4WP_Form $form
|
||||
* @param string $id
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct(MC4WP_Form $form, $id, array $config = array())
|
||||
{
|
||||
$this->form = $form;
|
||||
$this->ID = $id;
|
||||
$this->config = $config;
|
||||
|
||||
$this->is_submitted = $this->form->is_submitted
|
||||
&& $this->form->config['element_id'] === $this->ID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_visible_fields()
|
||||
{
|
||||
$content = $this->form->content;
|
||||
$form = $this->form;
|
||||
$element = $this;
|
||||
|
||||
/**
|
||||
* Filters the HTML for the form fields.
|
||||
*
|
||||
* Use this filter to add custom HTML to a form programmatically
|
||||
*
|
||||
* @param string $content
|
||||
* @param MC4WP_Form $form
|
||||
* @param MC4WP_Form_Element $element
|
||||
* @since 2.0
|
||||
*/
|
||||
$visible_fields = (string) apply_filters('mc4wp_form_content', $content, $form, $element);
|
||||
|
||||
return $visible_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_hidden_fields()
|
||||
{
|
||||
|
||||
// hidden fields
|
||||
$hidden_fields = '<label style="display: none !important;">' . __('Leave this field empty if you\'re human:', 'mailchimp-for-wp') . ' ' . '<input type="text" name="_mc4wp_honeypot" value="" tabindex="-1" autocomplete="off" /></label>';
|
||||
$hidden_fields .= '<input type="hidden" name="_mc4wp_timestamp" value="' . time() . '" />';
|
||||
$hidden_fields .= '<input type="hidden" name="_mc4wp_form_id" value="' . esc_attr($this->form->ID) . '" />';
|
||||
$hidden_fields .= '<input type="hidden" name="_mc4wp_form_element_id" value="' . esc_attr($this->ID) . '" />';
|
||||
|
||||
// was "lists" parameter passed in shortcode arguments?
|
||||
if (! empty($this->config['lists'])) {
|
||||
$lists_string = is_array($this->config['lists']) ? join(',', $this->config['lists']) : $this->config['lists'];
|
||||
$hidden_fields .= '<input type="hidden" name="_mc4wp_lists" value="' . esc_attr($lists_string) . '" />';
|
||||
}
|
||||
|
||||
// was "lists" parameter passed in shortcode arguments?
|
||||
if (! empty($this->config['email_type'])) {
|
||||
$hidden_fields .= '<input type="hidden" name="_mc4wp_email_type" value="' . esc_attr($this->config['email_type']) . '" />';
|
||||
}
|
||||
|
||||
return (string) $hidden_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML string for a notice, including wrapper element.
|
||||
*
|
||||
* @param MC4WP_Form_Notice $notice
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_notice_html(MC4WP_Form_Notice $notice)
|
||||
{
|
||||
if ($notice->text === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$html = sprintf('<div class="mc4wp-alert mc4wp-%s" role="alert"><p>%s</p></div>', esc_attr($notice->type), $notice->text);
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the form response string
|
||||
*
|
||||
* @param boolean $force_show
|
||||
* @return string
|
||||
*/
|
||||
public function get_response_html($force_show = false)
|
||||
{
|
||||
$html = '';
|
||||
$form = $this->form;
|
||||
|
||||
if ($this->is_submitted || $force_show) {
|
||||
foreach ($this->form->notices as $notice) {
|
||||
$html .= $this->get_notice_html($notice);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the form response HTML
|
||||
*
|
||||
* Use this to add your own HTML to the form response. The form instance is passed to the callback function.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $html The complete HTML string of the response, excluding the wrapper element.
|
||||
* @param MC4WP_Form $form The form object
|
||||
*/
|
||||
$html = (string) apply_filters('mc4wp_form_response_html', $html, $form);
|
||||
|
||||
// wrap entire response in div, regardless of a form was submitted
|
||||
$html = '<div class="mc4wp-response">' . $html . '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_response_position()
|
||||
{
|
||||
$position = 'after';
|
||||
$form = $this->form;
|
||||
|
||||
// check if content contains {response} tag
|
||||
if (stripos($this->form->content, '{response}') !== false) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the position for the form response.
|
||||
*
|
||||
* Valid values are "before" and "after". Will have no effect if `{response}` is used in the form content.
|
||||
*
|
||||
* @param string $position
|
||||
* @param MC4WP_Form $form
|
||||
* @since 2.0
|
||||
*/
|
||||
$response_position = (string) apply_filters('mc4wp_form_response_position', $position, $form);
|
||||
|
||||
return $response_position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML to be added _before_ the HTML of the form fields.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_html_before_fields()
|
||||
{
|
||||
$html = '';
|
||||
$form = $this->form;
|
||||
|
||||
/**
|
||||
* Filters the HTML before the form fields.
|
||||
*
|
||||
* @param string $html
|
||||
* @param MC4WP_Form $form
|
||||
* @ignore
|
||||
*/
|
||||
$html = (string) apply_filters('mc4wp_form_before_fields', $html, $form);
|
||||
|
||||
if ($this->get_response_position() === 'before') {
|
||||
$html = $html . $this->get_response_html();
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML to be added _after_ the HTML of the form fields.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_html_after_fields()
|
||||
{
|
||||
$html = '';
|
||||
$form = $this->form;
|
||||
|
||||
/**
|
||||
* Filters the HTML after the form fields.
|
||||
*
|
||||
* @param string $html
|
||||
* @param MC4WP_Form $form
|
||||
* @ignore
|
||||
*/
|
||||
$html = (string) apply_filters('mc4wp_form_after_fields', $html, $form);
|
||||
|
||||
if ($this->get_response_position() === 'after') {
|
||||
$html = $this->get_response_html() . $html;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all HTMl attributes for the form element
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_form_element_attributes()
|
||||
{
|
||||
$form = $this;
|
||||
$form_action_attribute = null;
|
||||
|
||||
$attributes = array(
|
||||
'id' => $this->ID,
|
||||
'class' => $this->get_css_classes(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the `action` attribute of the `<form>` element.
|
||||
*
|
||||
* Defaults to `null`, which means no `action` attribute will be printed.
|
||||
*
|
||||
* @param string $form_action_attribute
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$form_action_attribute = apply_filters('mc4wp_form_action', $form_action_attribute, $form);
|
||||
if (is_string($form_action_attribute)) {
|
||||
$attributes['action'] = $form_action_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters all attributes to be added to the `<form>` element
|
||||
*
|
||||
* @param array $attributes Key-value pairs of attributes.
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$attributes = (array) apply_filters('mc4wp_form_element_attributes', $attributes, $form);
|
||||
|
||||
// hardcoded attributes, can not be changed.
|
||||
$attributes['method'] = 'post';
|
||||
$attributes['data-id'] = $this->form->ID;
|
||||
$attributes['data-name'] = $this->form->name;
|
||||
|
||||
// build string of key="value" from array
|
||||
$string = '';
|
||||
foreach ($attributes as $name => $value) {
|
||||
$string .= sprintf('%s="%s" ', $name, esc_attr($value));
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $config Use this to override the configuration for this form element
|
||||
* @return string
|
||||
*/
|
||||
public function generate_html(array $config = null)
|
||||
{
|
||||
if ($config) {
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
// return empty string if form is in trash
|
||||
if ($this->form->status !== 'publish') {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Start building content string
|
||||
$opening_html = '<!-- Mailchimp for WordPress v' . MC4WP_VERSION . ' - https://wordpress.org/plugins/mailchimp-for-wp/ -->';
|
||||
$opening_html .= '<form ' . $this->get_form_element_attributes() . '>';
|
||||
$before_fields = $this->get_html_before_fields();
|
||||
$fields = '';
|
||||
$after_fields = $this->get_html_after_fields();
|
||||
$closing_html = '</form><!-- / Mailchimp for WordPress Plugin -->';
|
||||
|
||||
if (
|
||||
! $this->is_submitted
|
||||
|| ! $this->form->settings['hide_after_success']
|
||||
|| $this->form->has_errors()
|
||||
) {
|
||||
// add HTML for fields + wrapper element.
|
||||
$fields = '<div class="mc4wp-form-fields">' .
|
||||
$this->get_visible_fields() .
|
||||
'</div>' .
|
||||
$this->get_hidden_fields();
|
||||
}
|
||||
|
||||
// concatenate everything
|
||||
$output = $opening_html .
|
||||
$before_fields .
|
||||
$fields .
|
||||
$after_fields .
|
||||
$closing_html;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a space separated list of CSS classes for this form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_css_classes()
|
||||
{
|
||||
$classes = array();
|
||||
$form = $this->form;
|
||||
|
||||
$classes[] = 'mc4wp-form';
|
||||
$classes[] = 'mc4wp-form-' . $form->ID;
|
||||
|
||||
// Add form classes if this specific form element was submitted
|
||||
if ($this->is_submitted) {
|
||||
$classes[] = 'mc4wp-form-submitted';
|
||||
|
||||
if (! $form->has_errors()) {
|
||||
$classes[] = 'mc4wp-form-success';
|
||||
} else {
|
||||
$classes[] = 'mc4wp-form-error';
|
||||
}
|
||||
}
|
||||
|
||||
// add class for CSS targeting in custom stylesheets
|
||||
if (! empty($form->settings['css'])) {
|
||||
if (strpos($form->settings['css'], 'theme-') === 0) {
|
||||
$classes[] = 'mc4wp-form-theme';
|
||||
}
|
||||
|
||||
$classes[] = 'mc4wp-form-' . $form->settings['css'];
|
||||
}
|
||||
|
||||
// add classes from config array
|
||||
if (! empty($this->config['element_class'])) {
|
||||
$classes = array_merge($classes, explode(' ', $this->config['element_class']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters `class` attributes for the `<form>` element.
|
||||
*
|
||||
* @param array $classes
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$classes = apply_filters('mc4wp_form_css_classes', $classes, $form);
|
||||
|
||||
return implode(' ', $classes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Form_Listener
|
||||
*
|
||||
* @since 3.0
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Form_Listener
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Form The submitted form instance
|
||||
*/
|
||||
public $submitted_form;
|
||||
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('init', array( $this, 'listen' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for submitted forms
|
||||
* @return bool
|
||||
*/
|
||||
public function listen()
|
||||
{
|
||||
if (empty($_POST['_mc4wp_form_id'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get form instance
|
||||
try {
|
||||
$form_id = (int) $_POST['_mc4wp_form_id'];
|
||||
$form = mc4wp_get_form($form_id);
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// sanitize request data
|
||||
$request_data = $_POST;
|
||||
$request_data = mc4wp_sanitize_deep($request_data);
|
||||
$request_data = stripslashes_deep($request_data);
|
||||
|
||||
// bind request to form & validate
|
||||
$form->handle_request($request_data);
|
||||
$form->validate();
|
||||
|
||||
// store submitted form
|
||||
$this->submitted_form = $form;
|
||||
|
||||
// did form have errors?
|
||||
if (! $form->has_errors()) {
|
||||
switch ($form->get_action()) {
|
||||
case 'subscribe':
|
||||
$this->process_subscribe_form($form);
|
||||
break;
|
||||
|
||||
case 'unsubscribe':
|
||||
$this->process_unsubscribe_form($form);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
foreach ($form->errors as $error_code) {
|
||||
$form->add_notice($form->get_message($error_code), 'error');
|
||||
}
|
||||
|
||||
$this->get_log()->info(sprintf('Form %d > Submitted with errors: %s', $form->ID, join(', ', $form->errors)));
|
||||
}
|
||||
|
||||
$this->respond($form);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a subscribe form.
|
||||
*
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
public function process_subscribe_form(MC4WP_Form $form)
|
||||
{
|
||||
$result = false;
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$email_type = $form->get_email_type();
|
||||
$data = $form->get_data();
|
||||
$ip_address = mc4wp_get_request_ip_address();
|
||||
|
||||
/** @var MC4WP_MailChimp_Subscriber $subscriber */
|
||||
$subscriber = null;
|
||||
|
||||
// create a map of all lists with list-specific data
|
||||
$mapper = new MC4WP_List_Data_Mapper($data, $form->get_lists());
|
||||
|
||||
/** @var MC4WP_MailChimp_Subscriber[] $map */
|
||||
$map = $mapper->map();
|
||||
|
||||
// loop through lists
|
||||
foreach ($map as $list_id => $subscriber) {
|
||||
$subscriber->status = $form->settings['double_optin'] ? 'pending' : 'subscribed';
|
||||
$subscriber->email_type = $email_type;
|
||||
$subscriber->ip_signup = $ip_address;
|
||||
$subscriber->tags = $form->get_subscriber_tags();
|
||||
|
||||
/**
|
||||
* Filters subscriber data before it is sent to Mailchimp. Fires for both form & integration requests.
|
||||
*
|
||||
* @param MC4WP_MailChimp_Subscriber $subscriber
|
||||
* @param string $list_id ID of the Mailchimp list this subscriber will be added/updated in
|
||||
*/
|
||||
$subscriber = apply_filters('mc4wp_subscriber_data', $subscriber, $list_id);
|
||||
if (! $subscriber instanceof MC4WP_MailChimp_Subscriber) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters subscriber data before it is sent to Mailchimp. Only fires for form requests.
|
||||
*
|
||||
* @param MC4WP_MailChimp_Subscriber $subscriber
|
||||
* @param string $list_id ID of the Mailchimp list this subscriber will be added/updated in
|
||||
*/
|
||||
$subscriber = apply_filters('mc4wp_form_subscriber_data', $subscriber, $list_id);
|
||||
if (! $subscriber instanceof MC4WP_MailChimp_Subscriber) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// send a subscribe request to Mailchimp for each list
|
||||
$result = $mailchimp->list_subscribe($list_id, $subscriber->email_address, $subscriber->to_array(), $form->settings['update_existing'], $form->settings['replace_interests']);
|
||||
}
|
||||
|
||||
$log = $this->get_log();
|
||||
|
||||
// do stuff on failure
|
||||
if (! is_object($result) || empty($result->id)) {
|
||||
$error_code = $mailchimp->get_error_code();
|
||||
$error_message = $mailchimp->get_error_message();
|
||||
|
||||
if ((int) $mailchimp->get_error_code() === 214) {
|
||||
$form->add_error('already_subscribed');
|
||||
$form->add_notice($form->messages['already_subscribed'], 'notice');
|
||||
$log->warning(sprintf('Form %d > %s is already subscribed to the selected list(s)', $form->ID, $data['EMAIL']));
|
||||
} else {
|
||||
$form->add_error($error_code);
|
||||
$form->add_notice($form->messages['error'], 'error');
|
||||
$log->error(sprintf('Form %d > Mailchimp API error: %s %s', $form->ID, $error_code, $error_message));
|
||||
|
||||
/**
|
||||
* Fire action hook so API errors can be hooked into.
|
||||
*
|
||||
* @param MC4WP_Form $form
|
||||
* @param string $error_message
|
||||
*/
|
||||
do_action('mc4wp_form_api_error', $form, $error_message);
|
||||
}
|
||||
|
||||
// bail
|
||||
return;
|
||||
}
|
||||
|
||||
// Success! Did we update or newly subscribe?
|
||||
if ($result->status === 'subscribed' && $result->was_already_on_list) {
|
||||
$form->last_event = 'updated_subscriber';
|
||||
$form->add_notice($form->messages['updated'], 'success');
|
||||
$log->info(sprintf('Form %d > Successfully updated %s', $form->ID, $data['EMAIL']));
|
||||
|
||||
/**
|
||||
* Fires right after a form was used to update an existing subscriber.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Form $form Instance of the submitted form
|
||||
* @param string $email
|
||||
* @param array $data
|
||||
*/
|
||||
do_action('mc4wp_form_updated_subscriber', $form, $subscriber->email_address, $data);
|
||||
} else {
|
||||
$form->last_event = 'subscribed';
|
||||
$form->add_notice($form->messages['subscribed'], 'success');
|
||||
$log->info(sprintf('Form %d > Successfully subscribed %s', $form->ID, $data['EMAIL']));
|
||||
|
||||
/**
|
||||
* Fires right after a form was used to add a new subscriber.
|
||||
*
|
||||
* @since 4.8.13
|
||||
*
|
||||
* @param MC4WP_Form $form Instance of the submitted form
|
||||
* @param string $email
|
||||
* @param array $data
|
||||
*/
|
||||
do_action('mc4wp_form_added_subscriber', $form, $subscriber->email_address, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires right after a form was used to add a new subscriber (or update an existing one).
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Form $form Instance of the submitted form
|
||||
* @param string $email
|
||||
* @param array $data
|
||||
* @param MC4WP_MailChimp_Subscriber[] $subscriber
|
||||
*/
|
||||
do_action('mc4wp_form_subscribed', $form, $subscriber->email_address, $data, $map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
public function process_unsubscribe_form(MC4WP_Form $form)
|
||||
{
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$log = $this->get_log();
|
||||
$result = null;
|
||||
$data = $form->get_data();
|
||||
|
||||
// unsubscribe from each list
|
||||
foreach ($form->get_lists() as $list_id) {
|
||||
$result = $mailchimp->list_unsubscribe($list_id, $data['EMAIL']);
|
||||
}
|
||||
|
||||
if (! $result) {
|
||||
$form->add_notice($form->messages['error'], 'error');
|
||||
$log->error(sprintf('Form %d > Mailchimp API error: %s', $form->ID, $mailchimp->get_error_message()));
|
||||
|
||||
// bail
|
||||
return;
|
||||
}
|
||||
|
||||
// Success! Unsubscribed.
|
||||
$form->last_event = 'unsubscribed';
|
||||
$form->add_notice($form->messages['unsubscribed'], 'notice');
|
||||
$log->info(sprintf('Form %d > Successfully unsubscribed %s', $form->ID, $data['EMAIL']));
|
||||
|
||||
/**
|
||||
* Fires right after a form was used to unsubscribe.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Form $form Instance of the submitted form.
|
||||
* @param string $email
|
||||
*/
|
||||
do_action('mc4wp_form_unsubscribed', $form, $data['EMAIL']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
public function respond(MC4WP_Form $form)
|
||||
{
|
||||
$success = ! $form->has_errors();
|
||||
|
||||
if ($success) {
|
||||
|
||||
/**
|
||||
* Fires right after a form is submitted without any errors (success).
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Form $form Instance of the submitted form
|
||||
*/
|
||||
do_action('mc4wp_form_success', $form);
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Fires right after a form is submitted with errors.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Form $form The submitted form instance.
|
||||
*/
|
||||
do_action('mc4wp_form_error', $form);
|
||||
|
||||
// fire a dedicated event for each error
|
||||
foreach ($form->errors as $error) {
|
||||
|
||||
/**
|
||||
* Fires right after a form was submitted with errors.
|
||||
*
|
||||
* The dynamic portion of the hook, `$error`, refers to the error that occurred.
|
||||
*
|
||||
* Default errors give us the following possible hooks:
|
||||
*
|
||||
* - mc4wp_form_error_error General errors
|
||||
* - mc4wp_form_error_spam
|
||||
* - mc4wp_form_error_invalid_email Invalid email address
|
||||
* - mc4wp_form_error_already_subscribed Email is already on selected list(s)
|
||||
* - mc4wp_form_error_required_field_missing One or more required fields are missing
|
||||
* - mc4wp_form_error_no_lists_selected No Mailchimp lists were selected
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Form $form The form instance of the submitted form.
|
||||
*/
|
||||
do_action('mc4wp_form_error_' . $error, $form);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires right before responding to the form request.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Form $form Instance of the submitted form.
|
||||
*/
|
||||
do_action('mc4wp_form_respond', $form);
|
||||
|
||||
// do stuff on success (if form was submitted over plain HTTP, not for AJAX or REST requests)
|
||||
if ($success && ! $this->request_wants_json()) {
|
||||
$redirect_url = $form->get_redirect_url();
|
||||
if (! empty($redirect_url)) {
|
||||
wp_redirect($redirect_url);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function request_wants_json()
|
||||
{
|
||||
if (isset($_SERVER['HTTP_ACCEPT']) && false !== strpos($_SERVER['HTTP_ACCEPT'], 'application/json')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MC4WP_API_V3
|
||||
*/
|
||||
protected function get_api()
|
||||
{
|
||||
return mc4wp('api');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MC4WP_Debug_Log
|
||||
*/
|
||||
protected function get_log()
|
||||
{
|
||||
return mc4wp('log');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class takes care of all form related functionality
|
||||
*
|
||||
* Do not interact with this class directly, use `mc4wp_form` functions tagged with @access public instead.
|
||||
*
|
||||
* @class MC4WP_Form_Manager
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Form_Manager
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Form_Output_Manager
|
||||
*/
|
||||
protected $output_manager;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Form_Listener
|
||||
*/
|
||||
protected $listener;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Form_Tags
|
||||
*/
|
||||
protected $tags;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Form_Previewer
|
||||
*/
|
||||
protected $previewer;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Form_Asset_Manager
|
||||
*/
|
||||
protected $assets;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Form_AMP
|
||||
*/
|
||||
protected $amp_compatibility;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->output_manager = new MC4WP_Form_Output_Manager();
|
||||
$this->tags = new MC4WP_Form_Tags();
|
||||
$this->listener = new MC4WP_Form_Listener();
|
||||
$this->previewer = new MC4WP_Form_Previewer();
|
||||
$this->assets = new MC4WP_Form_Asset_Manager();
|
||||
$this->amp_compatibility = new MC4WP_Form_AMP();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook!
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('init', array( $this, 'initialize' ));
|
||||
add_action('widgets_init', array( $this, 'register_widget' ));
|
||||
add_action('rest_api_init', array( $this, 'register_endpoint' ));
|
||||
|
||||
$this->listener->add_hooks();
|
||||
$this->output_manager->add_hooks();
|
||||
$this->assets->add_hooks();
|
||||
$this->tags->add_hooks();
|
||||
$this->previewer->add_hooks();
|
||||
$this->amp_compatibility->add_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$this->register_post_type();
|
||||
$this->register_block_type();
|
||||
}
|
||||
|
||||
private function register_block_type()
|
||||
{
|
||||
// Bail if register_block_type does not exist (available since WP 5.0)
|
||||
if (! function_exists('register_block_type')) {
|
||||
return;
|
||||
}
|
||||
|
||||
register_block_type(
|
||||
'mailchimp-for-wp/form',
|
||||
array(
|
||||
'render_callback' => array( $this->output_manager, 'shortcode' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register post type "mc4wp-form"
|
||||
*/
|
||||
private function register_post_type()
|
||||
{
|
||||
// register post type
|
||||
register_post_type(
|
||||
'mc4wp-form',
|
||||
array(
|
||||
'labels' => array(
|
||||
'name' => 'Mailchimp Sign-up Forms',
|
||||
'singular_name' => 'Sign-up Form',
|
||||
),
|
||||
'public' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register our Form widget
|
||||
*/
|
||||
public function register_widget()
|
||||
{
|
||||
register_widget('MC4WP_Form_Widget');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an API endpoint for handling a form.
|
||||
*/
|
||||
public function register_endpoint()
|
||||
{
|
||||
register_rest_route(
|
||||
'mc4wp/v1',
|
||||
'/form',
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
'permission_callback' => '__return_true',
|
||||
'callback' => array( $this, 'handle_endpoint' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process requests to the form endpoint.
|
||||
*
|
||||
* A listener checks every request for a form submit, so we just need to fetch the listener and get its status.
|
||||
*/
|
||||
public function handle_endpoint()
|
||||
{
|
||||
$form = mc4wp_get_submitted_form();
|
||||
if (! $form instanceof MC4WP_Form) {
|
||||
return new WP_Error(
|
||||
'not_found',
|
||||
esc_html__('Resource does not exist.', 'mailchimp-for-wp'),
|
||||
array(
|
||||
'status' => 404,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($form->has_errors()) {
|
||||
$message_key = $form->errors[0];
|
||||
$message = $form->get_message($message_key);
|
||||
return new WP_Error(
|
||||
$message_key,
|
||||
$message,
|
||||
array(
|
||||
'status' => 400,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return new WP_REST_Response(true, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $form_id
|
||||
* @param array $config
|
||||
* @param bool $echo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output_form($form_id, $config = array(), $echo = true)
|
||||
{
|
||||
return $this->output_manager->output_form($form_id, $config, $echo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently submitted form
|
||||
*
|
||||
* @return MC4WP_Form|null
|
||||
*/
|
||||
public function get_submitted_form()
|
||||
{
|
||||
if ($this->listener->submitted_form instanceof MC4WP_Form) {
|
||||
return $this->listener->submitted_form;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all tags
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_tags()
|
||||
{
|
||||
return $this->tags->all();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Form_Notice
|
||||
*
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Form_Notice
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'error';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $text;
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @param string $type
|
||||
*/
|
||||
public function __construct($text, $type = 'error')
|
||||
{
|
||||
$this->text = $text;
|
||||
|
||||
if (! empty($type)) {
|
||||
$this->type = $type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
class MC4WP_Form_Previewer
|
||||
{
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('parse_request', array( $this, 'listen' ));
|
||||
}
|
||||
|
||||
public function listen()
|
||||
{
|
||||
if (empty($_GET['mc4wp_preview_form'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! current_user_can('edit_posts')) {
|
||||
return;
|
||||
}
|
||||
|
||||
show_admin_bar(false);
|
||||
add_filter('pre_handle_404', '__return_true');
|
||||
remove_all_actions('template_redirect');
|
||||
add_action('template_redirect', array( $this, 'load_preview' ));
|
||||
}
|
||||
|
||||
public function load_preview()
|
||||
{
|
||||
// clear output, some plugin or hooked code might have thrown errors by now.
|
||||
if (ob_get_level() > 0) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
$form_id = (int) $_GET['mc4wp_preview_form'];
|
||||
status_header(200);
|
||||
|
||||
require __DIR__ . '/views/preview.php';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Form_Tags
|
||||
*
|
||||
* @access private
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Form_Tags extends MC4WP_Dynamic_Content_Tags
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Form
|
||||
*/
|
||||
protected $form;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Form_Element
|
||||
*/
|
||||
protected $form_element;
|
||||
|
||||
public function add_hooks()
|
||||
{
|
||||
add_filter('mc4wp_form_response_html', array( $this, 'replace_in_form_response' ), 10, 2);
|
||||
add_filter('mc4wp_form_content', array( $this, 'replace_in_form_content' ), 10, 3);
|
||||
add_filter('mc4wp_form_redirect_url', array( $this, 'replace_in_form_redirect_url' ), 10, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register template tags
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
parent::register();
|
||||
|
||||
$this->tags['response'] = array(
|
||||
'description' => __('Replaced with the form response (error or success messages).', 'mailchimp-for-wp'),
|
||||
'callback' => array( $this, 'get_form_response' ),
|
||||
);
|
||||
|
||||
$this->tags['data'] = array(
|
||||
'description' => sprintf(__('Data from the URL or a submitted form.', 'mailchimp-for-wp')),
|
||||
'callback' => array( $this, 'get_data' ),
|
||||
'example' => "data key='UTM_SOURCE' default='Default Source'",
|
||||
);
|
||||
|
||||
$this->tags['subscriber_count'] = array(
|
||||
'description' => __('Replaced with the number of subscribers on the selected list(s)', 'mailchimp-for-wp'),
|
||||
'callback' => array( $this, 'get_subscriber_count' ),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function replace_in_form_content($string, MC4WP_Form $form, MC4WP_Form_Element $element = null)
|
||||
{
|
||||
$this->form = $form;
|
||||
$this->form_element = $element;
|
||||
|
||||
$string = $this->replace($string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function replace_in_form_response($string, MC4WP_Form $form)
|
||||
{
|
||||
$this->form = $form;
|
||||
|
||||
$string = $this->replace($string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
public function replace_in_form_redirect_url($string, MC4WP_Form $form)
|
||||
{
|
||||
$this->form = $form;
|
||||
$string = $this->replace_in_url($string);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of subscribers on the selected lists (for the form context)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_subscriber_count()
|
||||
{
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$count = $mailchimp->get_subscriber_count($this->form->get_lists());
|
||||
return number_format($count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the form response
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_form_response()
|
||||
{
|
||||
if ($this->form_element instanceof MC4WP_Form_Element) {
|
||||
return $this->form_element->get_response_html();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets data value from GET or POST variables.
|
||||
*
|
||||
* @param array $args
|
||||
* @return string
|
||||
*/
|
||||
public function get_data(array $args = array())
|
||||
{
|
||||
if (empty($args['key'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$default = isset($args['default']) ? $args['default'] : '';
|
||||
$key = $args['key'];
|
||||
|
||||
$data = array_merge($_GET, $_POST);
|
||||
$value = isset($data[ $key ]) ? $data[ $key ] : $default;
|
||||
|
||||
// turn array into readable value
|
||||
if (is_array($value)) {
|
||||
$value = array_filter($value);
|
||||
$value = join(', ', $value);
|
||||
}
|
||||
|
||||
return esc_html($value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,776 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Form
|
||||
*
|
||||
* Represents a Form object.
|
||||
*
|
||||
* To get a form instance, use `mc4wp_get_form( $id );` where `$id` is the post ID.
|
||||
*
|
||||
* @access public
|
||||
* @since 3.0
|
||||
*/
|
||||
class MC4WP_Form
|
||||
{
|
||||
/**
|
||||
* @var array Array of instantiated form objects.
|
||||
*/
|
||||
public static $instances = array();
|
||||
|
||||
/**
|
||||
* @param int $post_id
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function throw_not_found_exception($post_id)
|
||||
{
|
||||
$message = sprintf(__('There is no form with ID %d, perhaps it was deleted?', 'mailchimp-for-wp'), $post_id);
|
||||
throw new Exception($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a shared form instance.
|
||||
*
|
||||
* @param WP_Post|int $post Post instance or post ID.
|
||||
* @return MC4WP_Form
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function get_instance($post = 0)
|
||||
{
|
||||
if ($post instanceof WP_Post) {
|
||||
$post_id = $post->ID;
|
||||
} else {
|
||||
$post_id = (int) $post;
|
||||
|
||||
if ($post_id === 0) {
|
||||
$post_id = (int) get_option('mc4wp_default_form_id', 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ($post_id === 0) {
|
||||
self::throw_not_found_exception($post_id);
|
||||
}
|
||||
|
||||
if (isset(self::$instances[ $post_id ])) {
|
||||
return self::$instances[ $post_id ];
|
||||
}
|
||||
|
||||
// get post object if we don't have it by now
|
||||
if (! $post instanceof WP_Post) {
|
||||
$post = get_post($post_id);
|
||||
}
|
||||
|
||||
// check post object
|
||||
if (! $post instanceof WP_Post || $post->post_type !== 'mc4wp-form') {
|
||||
self::throw_not_found_exception($post_id);
|
||||
}
|
||||
|
||||
// get all post meta in single call for performance
|
||||
$post_meta = (array) get_post_meta($post_id);
|
||||
$form = new MC4WP_Form($post_id, $post, $post_meta);
|
||||
|
||||
// store instance
|
||||
self::$instances[ $post_id ] = $form;
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var int The form ID, matches the underlying post its ID
|
||||
*/
|
||||
public $ID = 0;
|
||||
|
||||
/**
|
||||
* @var string The form name
|
||||
*/
|
||||
public $name = 'Default Form';
|
||||
|
||||
/**
|
||||
* @var string The form HTML content
|
||||
*/
|
||||
public $content = '';
|
||||
|
||||
/**
|
||||
* @var array Array of settings
|
||||
*/
|
||||
public $settings = array();
|
||||
|
||||
/**
|
||||
* @var array Array of messages
|
||||
*/
|
||||
public $messages = array();
|
||||
|
||||
/**
|
||||
* @var array Array of notices to be shown when this form is rendered
|
||||
*/
|
||||
public $notices = array();
|
||||
|
||||
/**
|
||||
* @var array Array of error codes
|
||||
*/
|
||||
public $errors = array();
|
||||
|
||||
/**
|
||||
* @var bool Was this form submitted?
|
||||
*/
|
||||
public $is_submitted = false;
|
||||
|
||||
/**
|
||||
* @var array Array of the data that was submitted, in name => value pairs.
|
||||
*
|
||||
* Keys in this array are uppercased and keys starting with _ are stripped.
|
||||
*/
|
||||
private $data = array();
|
||||
|
||||
/**
|
||||
* @var array Array of the raw form data that was submitted.
|
||||
*/
|
||||
public $raw_data = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $config = array(
|
||||
'action' => 'subscribe',
|
||||
'lists' => array(),
|
||||
'email_type' => '',
|
||||
'element_id' => '',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $last_event = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $status;
|
||||
|
||||
/**
|
||||
* @param int $id The post ID
|
||||
* @param WP_Post $post
|
||||
* @param array $post_meta
|
||||
*/
|
||||
public function __construct($id, WP_Post $post, array $post_meta = array())
|
||||
{
|
||||
$this->ID = (int) $id;
|
||||
$this->name = $post->post_title;
|
||||
$this->content = $post->post_content;
|
||||
$this->status = $post->post_status;
|
||||
$this->settings = $this->load_settings($post_meta);
|
||||
$this->messages = $this->load_messages($post_meta);
|
||||
|
||||
// update config from settings
|
||||
$this->config['lists'] = $this->settings['lists'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
$method_name = sprintf('get_%s', $name);
|
||||
if (method_exists($this, $method_name)) {
|
||||
return $this->$method_name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the form response string
|
||||
*
|
||||
* This does not take the submitted form element into account.
|
||||
*
|
||||
* @see MC4WP_Form_Element::get_response_html()
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_response_html()
|
||||
{
|
||||
return $this->get_element()->get_response_html(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $element_id
|
||||
* @param array $config
|
||||
* @return MC4WP_Form_element
|
||||
*/
|
||||
public function get_element($element_id = 'mc4wp-form', array $config = array())
|
||||
{
|
||||
return new MC4WP_Form_Element($this, $element_id, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML string for this form.
|
||||
*
|
||||
* If you want to output a form, use `mc4wp_show_form` instead as it.
|
||||
*
|
||||
* @param string $element_id
|
||||
* @param array $config
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_html($element_id = 'mc4wp-form', array $config = array())
|
||||
{
|
||||
$element = $this->get_element($element_id, $config);
|
||||
$html = $element->generate_html();
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $post_meta
|
||||
* @return array
|
||||
*/
|
||||
protected function load_settings(array $post_meta = array())
|
||||
{
|
||||
$form = $this;
|
||||
$default_settings = include MC4WP_PLUGIN_DIR . '/config/default-form-settings.php';
|
||||
|
||||
// start with defaults
|
||||
$settings = $default_settings;
|
||||
|
||||
// get custom settings from meta
|
||||
if (! empty($post_meta['_mc4wp_settings'])) {
|
||||
$meta = $post_meta['_mc4wp_settings'][0];
|
||||
$meta = (array) maybe_unserialize($meta);
|
||||
|
||||
// ensure lists is an array
|
||||
if (empty($meta['lists'])) {
|
||||
$meta['lists'] = array();
|
||||
}
|
||||
|
||||
// merge with current settings (defaults)
|
||||
$settings = array_merge($settings, $meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the form settings
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $settings
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$settings = (array) apply_filters('mc4wp_form_settings', $settings, $form);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $post_meta
|
||||
* @return array
|
||||
*/
|
||||
protected function load_messages(array $post_meta = array())
|
||||
{
|
||||
$form = $this;
|
||||
|
||||
// get default messages
|
||||
$default_messages = include MC4WP_PLUGIN_DIR . '/config/default-form-messages.php';
|
||||
|
||||
// start with default messages
|
||||
$messages = $default_messages;
|
||||
|
||||
/**
|
||||
* Filters the form messages
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $registered_messages
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$messages = (array) apply_filters('mc4wp_form_messages', $messages, $form);
|
||||
|
||||
// for backwards compatiblity, grab text of each message (if is array)
|
||||
foreach ($messages as $key => $message) {
|
||||
if (is_array($message) && isset($message['text'])) {
|
||||
$messages[ $key ] = $message['text'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($messages as $key => $message_text) {
|
||||
// overwrite default text with text in form meta.
|
||||
if (isset($post_meta[ 'text_' . $key ][0])) {
|
||||
$message_text = $post_meta[ 'text_' . $key ][0];
|
||||
}
|
||||
|
||||
$messages[ $key ] = $message_text;
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this form has a field of the given type?
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_field_type($type)
|
||||
{
|
||||
return in_array(strtolower($type), $this->get_field_types(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of field types which are present in this form.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_field_types()
|
||||
{
|
||||
preg_match_all('/type=\"(\w+)?\"/', strtolower($this->content), $result);
|
||||
$field_types = $result[1];
|
||||
return $field_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add notice to this form when it is rendered
|
||||
* @param string $text
|
||||
* @param string $type
|
||||
*/
|
||||
public function add_notice($text, $type = 'notice')
|
||||
{
|
||||
$this->notices[] = new MC4WP_Form_Notice($text, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output this form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return mc4wp_show_form($this->ID, array(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "redirect to url after success" setting for this form
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_redirect_url()
|
||||
{
|
||||
$form = $this;
|
||||
$url = trim($this->settings['redirect']);
|
||||
|
||||
/**
|
||||
* Filters the redirect URL setting
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $url
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$url = (string) apply_filters('mc4wp_form_redirect_url', $url, $form);
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this form valid?
|
||||
*
|
||||
* Will always return true if the form is not yet submitted. Otherwise, it will run validation and store any errors.
|
||||
* This method should be called before `get_errors()`
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
if (! $this->is_submitted) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$form = $this;
|
||||
$errors = array();
|
||||
|
||||
if (empty($this->config['lists'])) {
|
||||
$errors[] = 'no_lists_selected';
|
||||
}
|
||||
|
||||
if (! isset($this->raw_data['_mc4wp_timestamp']) || $this->raw_data['_mc4wp_timestamp'] > ( time() - 2 )) {
|
||||
$errors[] = 'spam';
|
||||
} elseif (! isset($this->raw_data['_mc4wp_honeypot']) || ! empty($this->raw_data['_mc4wp_honeypot'])) {
|
||||
$errors[] = 'spam';
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
// validate email field
|
||||
if (empty($this->data['EMAIL']) || ! is_email($this->data['EMAIL'])) {
|
||||
$errors[] = 'invalid_email';
|
||||
}
|
||||
|
||||
// validate other required fields
|
||||
foreach ($this->get_required_fields() as $field) {
|
||||
$value = mc4wp_array_get($this->data, $field);
|
||||
|
||||
// check for empty string or array here instead of empty() since we want to allow for "0" values.
|
||||
if ($value === '' || $value === array()) {
|
||||
$errors[] = 'required_field_missing';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters whether this form has errors. Runs only when a form is submitted.
|
||||
* Expects an array of message keys with an error type (string).
|
||||
*
|
||||
* Beware: all non-string values added to this array will be filtered out.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $errors
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$errors = (array) apply_filters('mc4wp_form_errors', $errors, $form);
|
||||
|
||||
// filter out all non-string values
|
||||
$errors = array_filter($errors, 'is_string');
|
||||
|
||||
// set property on self
|
||||
$this->errors = $errors;
|
||||
|
||||
// return whether we have errors
|
||||
return ! $this->has_errors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request. Should be called before calling validate() method.
|
||||
*
|
||||
* @see MC4WP_Form::validate
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function handle_request(array $data)
|
||||
{
|
||||
$this->is_submitted = true;
|
||||
$this->raw_data = $data;
|
||||
$this->data = $this->parse_request_data($data);
|
||||
$this->last_event = '';
|
||||
|
||||
// update form configuration from given data
|
||||
$config = array();
|
||||
$map = array(
|
||||
'_mc4wp_lists' => 'lists',
|
||||
'_mc4wp_action' => 'action',
|
||||
'_mc4wp_form_element_id' => 'element_id',
|
||||
'_mc4wp_email_type' => 'email_type',
|
||||
);
|
||||
|
||||
// use isset here to allow empty lists (which should show a notice)
|
||||
foreach ($map as $param_key => $config_key) {
|
||||
if (isset($this->raw_data[ $param_key ])) {
|
||||
$value = $this->raw_data[ $param_key ];
|
||||
if (is_array($value)) {
|
||||
$value = array_filter($value);
|
||||
}
|
||||
|
||||
$config[ $config_key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($config)) {
|
||||
$this->set_config($config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a request for data which should be binded to `$data` property.
|
||||
*
|
||||
* This does the following on all post data.
|
||||
*
|
||||
* - Removes fields starting with an underscore.
|
||||
* - Remove fields which are set to be ignored.
|
||||
* - Uppercase all field names
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parse_request_data(array $data)
|
||||
{
|
||||
$form = $this;
|
||||
$filtered = array();
|
||||
$ignored_field_names = array();
|
||||
|
||||
/**
|
||||
* Filters field names which should be ignored when showing data.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $ignored_field_names Array of ignored field names
|
||||
* @param MC4WP_Form $form The form instance.
|
||||
*/
|
||||
$ignored_field_names = apply_filters('mc4wp_form_ignored_field_names', $ignored_field_names, $form);
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
// skip fields in ignored field names
|
||||
if ($key[0] === '_' || in_array($key, $ignored_field_names, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// uppercase key
|
||||
$key = strtoupper($key);
|
||||
|
||||
// filter empty array values
|
||||
if (is_array($value)) {
|
||||
$value = array_filter($value);
|
||||
}
|
||||
|
||||
$filtered[ $key ] = $value;
|
||||
}
|
||||
|
||||
return $filtered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update configuration for this form
|
||||
*
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
public function set_config(array $config)
|
||||
{
|
||||
$this->config = array_merge($this->config, $config);
|
||||
|
||||
// make sure lists is an array
|
||||
if (! is_array($this->config['lists'])) {
|
||||
$this->config['lists'] = array_map('trim', explode(',', $this->config['lists']));
|
||||
}
|
||||
|
||||
// make sure action is valid
|
||||
if (! in_array($this->config['action'], array( 'subscribe', 'unsubscribe' ), true)) {
|
||||
$this->config['action'] = 'subscribe';
|
||||
}
|
||||
|
||||
// email_type should be a valid value
|
||||
if (! in_array($this->config['email_type'], array( 'html', 'text' ), true)) {
|
||||
$this->config['email_type'] = '';
|
||||
}
|
||||
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ID's of Mailchimp lists this form subscribes to
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_lists()
|
||||
{
|
||||
$lists = $this->config['lists'];
|
||||
$form = $this;
|
||||
|
||||
/**
|
||||
* Filters Mailchimp lists new subscribers should be added to.
|
||||
*
|
||||
* @param array $lists
|
||||
*/
|
||||
$lists = (array) apply_filters('mc4wp_lists', $lists);
|
||||
|
||||
/**
|
||||
* Filters Mailchimp lists new subscribers coming from this form should be added to.
|
||||
*
|
||||
* @param array $lists
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$lists = (array) apply_filters('mc4wp_form_lists', $lists, $form);
|
||||
|
||||
// filter out empty array elements
|
||||
$lists = array_filter($lists);
|
||||
|
||||
return $lists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this form have errors?
|
||||
*
|
||||
* Should always evaluate to false when form has not been submitted.
|
||||
*
|
||||
* @see `mc4wp_form_errors` filter.
|
||||
* @return bool
|
||||
*/
|
||||
public function has_errors()
|
||||
{
|
||||
return count($this->errors) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an error to this form
|
||||
*
|
||||
* @param string $error_code
|
||||
*/
|
||||
public function add_error($error_code)
|
||||
{
|
||||
// only add each error once
|
||||
if (! in_array($error_code, $this->errors, true)) {
|
||||
$this->errors[] = $error_code;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form action
|
||||
*
|
||||
* Valid return values are "subscribe" and "unsubscribe"
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_action()
|
||||
{
|
||||
return $this->config['action'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_data()
|
||||
{
|
||||
$data = $this->data;
|
||||
$form = $this;
|
||||
|
||||
/**
|
||||
* Filters the form data.
|
||||
*
|
||||
* @param array $data
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$data = apply_filters('mc4wp_form_data', $data, $form);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_raw_data()
|
||||
{
|
||||
return $this->raw_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of name attributes for the required fields in this form.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_required_fields()
|
||||
{
|
||||
$form = $this;
|
||||
|
||||
// explode required fields (generated in JS) to an array (uppercased)
|
||||
$required_fields_string = strtoupper($this->settings['required_fields']);
|
||||
|
||||
// remove array-formatted fields
|
||||
// workaround for #261 (https://github.com/ibericode/mailchimp-for-wordpress/issues/261)
|
||||
$required_fields_string = preg_replace('/\[\w+\]/', '', $required_fields_string);
|
||||
|
||||
// turn into an array
|
||||
$required_fields = explode(',', $required_fields_string);
|
||||
|
||||
// EMAIL is not a required field as it has its own validation rules
|
||||
$required_fields = array_diff($required_fields, array( 'EMAIL' ));
|
||||
|
||||
// filter duplicate & empty values
|
||||
$required_fields = array_unique($required_fields);
|
||||
$required_fields = array_filter($required_fields);
|
||||
|
||||
// fix uppercased subkeys, see https://github.com/ibericode/mailchimp-for-wordpress/issues/516
|
||||
foreach ($required_fields as $key => $value) {
|
||||
$pos = strpos($value, '.');
|
||||
if ($pos > 0) {
|
||||
$required_fields[ $key ] = substr($value, 0, $pos) . strtolower(substr($value, $pos));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the required fields for a form
|
||||
*
|
||||
* By default, this holds the following fields.
|
||||
*
|
||||
* - All fields which are required for the selected Mailchimp lists
|
||||
* - All fields in the form with a `required` attribute.
|
||||
*
|
||||
* @param array $required_fields
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
$required_fields = (array) apply_filters('mc4wp_form_required_fields', $required_fields, $form);
|
||||
|
||||
return $required_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "email_type" setting for new Mailchimp subscribers added by this form.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_email_type()
|
||||
{
|
||||
$email_type = $this->config['email_type'];
|
||||
|
||||
if (empty($email_type)) {
|
||||
$email_type = mc4wp_get_email_type();
|
||||
}
|
||||
|
||||
return $email_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filename of the stylesheet to load for this form.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_stylesheet()
|
||||
{
|
||||
$stylesheet = $this->settings['css'];
|
||||
|
||||
if (empty($stylesheet)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// form themes live in the same stylesheet
|
||||
if (strpos($stylesheet, 'theme-') !== false) {
|
||||
$stylesheet = 'themes';
|
||||
}
|
||||
|
||||
return $stylesheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function get_message($key)
|
||||
{
|
||||
$message = isset($this->messages[ $key ]) ? $this->messages[ $key ] : $this->messages['error'];
|
||||
|
||||
if ($key === 'no_lists_selected' && current_user_can('manage_options')) {
|
||||
$message .= sprintf(' (<a href="%s">%s</a>)', mc4wp_get_edit_form_url($this->ID, 'settings'), 'edit form settings');
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
* @return array
|
||||
*/
|
||||
public function get_subscriber_tags()
|
||||
{
|
||||
if (empty($this->settings['subscriber_tags'])) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$tags = explode(',', $this->settings['subscriber_tags']);
|
||||
$tags = array_map('trim', $tags);
|
||||
|
||||
// remove empty tag values
|
||||
foreach ($tags as $i => $tag) {
|
||||
if ($tag === '') {
|
||||
unset($tags[ $i ]);
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($tags);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Form_Output_Manager
|
||||
*
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Form_Output_Manager
|
||||
{
|
||||
/**
|
||||
* @var int The # of forms outputted
|
||||
*/
|
||||
public $count = 0;
|
||||
|
||||
/**
|
||||
* @const string
|
||||
*/
|
||||
const SHORTCODE = 'mc4wp_form';
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
// enable shortcodes in form content
|
||||
add_filter('mc4wp_form_content', 'do_shortcode');
|
||||
add_action('init', array( $this, 'register_shortcode' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the [mc4wp_form] shortcode
|
||||
*/
|
||||
public function register_shortcode()
|
||||
{
|
||||
add_shortcode(self::SHORTCODE, array( $this, 'shortcode' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attributes
|
||||
* @param string $content
|
||||
* @return string
|
||||
*/
|
||||
public function shortcode($attributes = array(), $content = '')
|
||||
{
|
||||
$default_attributes = array(
|
||||
'id' => '',
|
||||
'lists' => '',
|
||||
'email_type' => '',
|
||||
'element_id' => '',
|
||||
'element_class' => '',
|
||||
);
|
||||
|
||||
$attributes = shortcode_atts(
|
||||
$default_attributes,
|
||||
$attributes,
|
||||
self::SHORTCODE
|
||||
);
|
||||
|
||||
$config = array(
|
||||
'element_id' => $attributes['element_id'],
|
||||
'lists' => $attributes['lists'],
|
||||
'email_type' => $attributes['email_type'],
|
||||
'element_class' => $attributes['element_class'],
|
||||
);
|
||||
|
||||
return $this->output_form($attributes['id'], $config, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param array $config
|
||||
* @param bool $echo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output_form($id = 0, $config = array(), $echo = true)
|
||||
{
|
||||
try {
|
||||
$form = mc4wp_get_form($id);
|
||||
} catch (Exception $e) {
|
||||
if (current_user_can('manage_options')) {
|
||||
return sprintf('<strong>Mailchimp for WordPress error:</strong> %s', $e->getMessage());
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
++$this->count;
|
||||
|
||||
// set a default element_id if none is given
|
||||
if (empty($config['element_id'])) {
|
||||
$config['element_id'] = 'mc4wp-form-' . $this->count;
|
||||
}
|
||||
|
||||
$form_html = $form->get_html($config['element_id'], $config);
|
||||
|
||||
try {
|
||||
// start new output buffer
|
||||
ob_start();
|
||||
|
||||
/**
|
||||
* Runs just before a form element is outputted.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Form $form
|
||||
*/
|
||||
do_action('mc4wp_output_form', $form);
|
||||
|
||||
// output the form (in output buffer)
|
||||
echo $form_html;
|
||||
|
||||
// grab all contents in current output buffer & then clean + end it.
|
||||
$html = ob_get_clean();
|
||||
} catch (Error $e) {
|
||||
$html = $form_html;
|
||||
}
|
||||
|
||||
// echo content if necessary
|
||||
if ($echo) {
|
||||
echo $html;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
/**
|
||||
* Adds MC4WP_Widget widget.
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Form_Widget extends WP_Widget
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $default_instance_settings = array(
|
||||
'title' => '',
|
||||
'form_id' => '',
|
||||
);
|
||||
|
||||
/**
|
||||
* Register widget with WordPress.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
// translate default widget title
|
||||
$this->default_instance_settings['title'] = __('Newsletter', 'mailchimp-for-wp');
|
||||
|
||||
parent::__construct(
|
||||
'mc4wp_form_widget', // Base ID
|
||||
__('Mailchimp Sign-Up Form', 'mailchimp-for-wp'), // Name
|
||||
array(
|
||||
'description' => __('Displays your Mailchimp for WordPress sign-up form', 'mailchimp-for-wp'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Front-end display of widget.
|
||||
*
|
||||
* @see WP_Widget::widget()
|
||||
*
|
||||
* @param array $args Widget arguments.
|
||||
* @param array $instance_settings Saved values from database.
|
||||
*/
|
||||
public function widget($args, $instance_settings)
|
||||
{
|
||||
|
||||
// ensure $instance_settings is an array
|
||||
if (! is_array($instance_settings)) {
|
||||
$instance_settings = array();
|
||||
}
|
||||
|
||||
$instance_settings = array_merge($this->default_instance_settings, $instance_settings);
|
||||
$title = apply_filters('widget_title', $instance_settings['title'], $instance_settings, $this->id_base);
|
||||
|
||||
echo $args['before_widget'];
|
||||
|
||||
if (! empty($title)) {
|
||||
echo $args['before_title'] . $title . $args['after_title'];
|
||||
}
|
||||
|
||||
mc4wp_show_form($instance_settings['form_id']);
|
||||
|
||||
echo $args['after_widget'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Back-end widget form.
|
||||
*
|
||||
* @see WP_Widget::form()
|
||||
*
|
||||
* @param array $settings Previously saved values from database.
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public function form($settings)
|
||||
{
|
||||
$settings = array_merge($this->default_instance_settings, (array) $settings); ?>
|
||||
<p>
|
||||
<label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:', 'mailchimp-for-wp'); ?></label>
|
||||
<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($settings['title']); ?>" />
|
||||
</p>
|
||||
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Runs right after the widget settings form is outputted
|
||||
*
|
||||
* @param array $settings
|
||||
* @param MC4WP_Form_Widget $this
|
||||
* @ignore
|
||||
*/
|
||||
do_action('mc4wp_form_widget_form', $settings, $this);
|
||||
?>
|
||||
|
||||
<p class="description">
|
||||
<?php printf(__('You can edit your sign-up form in the <a href="%s">Mailchimp for WordPress form settings</a>.', 'mailchimp-for-wp'), admin_url('admin.php?page=mailchimp-for-wp-forms')); ?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates widget form values as they are saved.
|
||||
*
|
||||
* @see WP_Widget::update()
|
||||
*
|
||||
* @param array $new_settings Values just sent to be saved.
|
||||
* @param array $old_settings Previously saved values from database.
|
||||
*
|
||||
* @return array Updated safe values to be saved.
|
||||
*/
|
||||
public function update($new_settings, $old_settings)
|
||||
{
|
||||
if (! empty($new_settings['title'])) {
|
||||
$new_settings['title'] = sanitize_text_field($new_settings['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the widget settings before they are saved.
|
||||
*
|
||||
* @param array $new_settings
|
||||
* @param array $old_settings
|
||||
* @param MC4WP_Form_Widget $widget
|
||||
* @ignore
|
||||
*/
|
||||
$new_settings = apply_filters('mc4wp_form_widget_update_settings', $new_settings, $old_settings, $this);
|
||||
|
||||
return $new_settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Returns a Form instance
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param int|WP_Post $form_id.
|
||||
*
|
||||
* @return MC4WP_Form
|
||||
*/
|
||||
function mc4wp_get_form($form_id = 0)
|
||||
{
|
||||
return MC4WP_Form::get_instance($form_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of Form instances
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array $args Array of parameters
|
||||
*
|
||||
* @return MC4WP_Form[]
|
||||
*/
|
||||
function mc4wp_get_forms(array $args = array())
|
||||
{
|
||||
// parse function arguments
|
||||
$default_args = array(
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'ignore_sticky_posts' => true,
|
||||
'no_found_rows' => true,
|
||||
);
|
||||
$args = array_merge($default_args, $args);
|
||||
|
||||
// set post_type here so it can't be overwritten using function arguments
|
||||
$args['post_type'] = 'mc4wp-form';
|
||||
|
||||
$q = new WP_Query();
|
||||
$posts = $q->query($args);
|
||||
$forms = array();
|
||||
foreach ($posts as $post) {
|
||||
try {
|
||||
$form = mc4wp_get_form($post);
|
||||
} catch (Exception $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$forms[] = $form;
|
||||
}
|
||||
return $forms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Echoes the given form
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param int $form_id
|
||||
* @param array $config
|
||||
* @param bool $echo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_show_form($form_id = 0, $config = array(), $echo = true)
|
||||
{
|
||||
/** @var MC4WP_Form_Manager $forms */
|
||||
$forms = mc4wp('forms');
|
||||
return $forms->output_form($form_id, $config, $echo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets an instance of the submitted form, if any.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return MC4WP_Form|null
|
||||
*/
|
||||
function mc4wp_get_submitted_form()
|
||||
{
|
||||
return mc4wp('forms')->get_submitted_form();
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php defined('ABSPATH') or exit; ?>
|
||||
<div id="mc4wp-admin" class="wrap mc4wp-settings">
|
||||
|
||||
<div class="mc4wp-row">
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content mc4wp-col">
|
||||
|
||||
<h1 class="mc4wp-page-title">
|
||||
<?php echo esc_html__('Add new form', 'mailchimp-for-wp'); ?>
|
||||
</h1>
|
||||
|
||||
<h2 style="display: none;"></h2><?php // fake h2 for admin notices ?>
|
||||
|
||||
<div style="max-width: 480px;">
|
||||
|
||||
<!-- Wrap entire page in <form> -->
|
||||
<form method="post">
|
||||
|
||||
<input type="hidden" name="_mc4wp_action" value="add_form" />
|
||||
<?php wp_nonce_field('_mc4wp_action', '_wpnonce'); ?>
|
||||
|
||||
<div class="mc4wp-margin-s">
|
||||
<h3>
|
||||
<label>
|
||||
<?php echo esc_html__('What is the name of this form?', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
</h3>
|
||||
<input type="text" name="mc4wp_form[name]" class="widefat" value="" spellcheck="true" autocomplete="off" placeholder="<?php echo esc_attr__('Enter your form title..', 'mailchimp-for-wp'); ?>">
|
||||
</div>
|
||||
|
||||
<div class="mc4wp-margin-s">
|
||||
|
||||
<h3>
|
||||
<label>
|
||||
<?php echo esc_html__('To which Mailchimp lists should this form subscribe?', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
</h3>
|
||||
|
||||
<?php
|
||||
if (! empty($lists)) {
|
||||
?>
|
||||
<ul id="mc4wp-lists">
|
||||
<?php
|
||||
foreach ($lists as $list) {
|
||||
?>
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox" name="mc4wp_form[settings][lists][<?php echo esc_attr($list->id); ?>]" value="<?php echo esc_attr($list->id); ?>" <?php checked($number_of_lists, 1); ?> >
|
||||
<?php echo esc_html($list->name); ?>
|
||||
</label>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<p class="mc4wp-notice">
|
||||
<?php echo sprintf(wp_kses(__('No lists found. Did you <a href="%s">connect with Mailchimp</a>?', 'mailchimp-for-wp'), array( 'a' => array( 'href' => array() ) )), admin_url('admin.php?page=mailchimp-for-wp')); ?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php submit_button(esc_html__('Add new form', 'mailchimp-for-wp')); ?>
|
||||
|
||||
|
||||
</form><!-- Entire page form wrap -->
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<?php require MC4WP_PLUGIN_DIR . '/includes/views/parts/admin-footer.php'; ?>
|
||||
|
||||
</div><!-- / Main content -->
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="mc4wp-sidebar mc4wp-col">
|
||||
<?php require MC4WP_PLUGIN_DIR . '/includes/views/parts/admin-sidebar.php'; ?>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php defined('ABSPATH') or exit;
|
||||
|
||||
$tabs = array(
|
||||
'fields' => esc_html__('Fields', 'mailchimp-for-wp'),
|
||||
'messages' => esc_html__('Messages', 'mailchimp-for-wp'),
|
||||
'settings' => esc_html__('Settings', 'mailchimp-for-wp'),
|
||||
'appearance' => esc_html__('Appearance', 'mailchimp-for-wp'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the setting tabs on the "edit form" screen.
|
||||
*
|
||||
* @param array $tabs
|
||||
* @ignore
|
||||
*/
|
||||
$tabs = apply_filters('mc4wp_admin_edit_form_tabs', $tabs);
|
||||
|
||||
?>
|
||||
<div id="mc4wp-admin" class="wrap mc4wp-settings">
|
||||
|
||||
<p class="mc4wp-breadcrumbs">
|
||||
<span class="prefix"><?php echo esc_html__('You are here: ', 'mailchimp-for-wp'); ?></span>
|
||||
<a href="<?php echo esc_url(admin_url('admin.php?page=mailchimp-for-wp')); ?>">Mailchimp for WordPress</a> ›
|
||||
<a href="<?php echo esc_url(admin_url('admin.php?page=mailchimp-for-wp-forms')); ?>"><?php echo esc_html__('Forms', 'mailchimp-for-wp'); ?></a>
|
||||
›
|
||||
<span class="current-crumb"><strong><?php echo esc_html__('Form', 'mailchimp-for-wp'); ?> <?php echo $form_id; ?>
|
||||
| <?php echo esc_html($form->name); ?></strong></span>
|
||||
</p>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div>
|
||||
|
||||
<h1 class="mc4wp-page-title">
|
||||
<?php echo esc_html__('Edit Form', 'mailchimp-for-wp'); ?>
|
||||
|
||||
<!-- Form actions -->
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
do_action('mc4wp_admin_edit_form_after_title');
|
||||
?>
|
||||
</h1>
|
||||
|
||||
<h2 style="display: none;"></h2><?php // fake h2 for admin notices ?>
|
||||
|
||||
<!-- Wrap entire page in <form> -->
|
||||
<form method="post">
|
||||
<?php // default submit button to prevent opening preview ?>
|
||||
<input type="submit" style="display: none;" />
|
||||
<input type="hidden" name="_mc4wp_action" value="edit_form"/>
|
||||
<?php wp_nonce_field('_mc4wp_action', '_wpnonce'); ?>
|
||||
<input type="hidden" name="mc4wp_form_id" value="<?php echo esc_attr($form->ID); ?>"/>
|
||||
|
||||
<div id="titlediv" class="mc4wp-margin-s">
|
||||
<div id="titlewrap">
|
||||
<label class="screen-reader-text"
|
||||
for="title"><?php echo esc_html__('Enter form title here', 'mailchimp-for-wp'); ?></label>
|
||||
<input type="text" name="mc4wp_form[name]" size="30"
|
||||
value="<?php echo esc_attr($form->name); ?>" id="title" spellcheck="true"
|
||||
autocomplete="off"
|
||||
placeholder="<?php echo esc_html__('Enter the title of your sign-up form', 'mailchimp-for-wp'); ?>"
|
||||
style="line-height: initial;">
|
||||
</div>
|
||||
<div>
|
||||
<?php echo sprintf(esc_html__('Use the shortcode %s to display this form inside a post, page or text widget.', 'mailchimp-for-wp'), '<input type="text" onfocus="this.select();" readonly="readonly" value="' . esc_attr(sprintf('[mc4wp_form id=%d]', $form->ID)) . '" size="' . ( strlen($form->ID) + 15 ) . '">'); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<h2 class="nav-tab-wrapper" id="mc4wp-tabs-nav">
|
||||
<?php
|
||||
foreach ($tabs as $tab => $name) {
|
||||
$class = ( $active_tab === $tab ) ? 'nav-tab-active' : '';
|
||||
echo sprintf('<a class="nav-tab nav-tab-%s %s" data-tab="%s" href="%s">%s</a>', $tab, $class, $tab, esc_attr($this->tab_url($tab)), $name);
|
||||
}
|
||||
?>
|
||||
</h2>
|
||||
|
||||
<div id="mc4wp-tabs">
|
||||
|
||||
<?php
|
||||
|
||||
foreach ($tabs as $tab => $name) :
|
||||
$class = ( $active_tab === $tab ) ? 'mc4wp-tab-active' : '';
|
||||
|
||||
// start of .tab
|
||||
echo sprintf('<div class="mc4wp-tab %s" id="mc4wp-tab-%s">', $class, $tab);
|
||||
|
||||
/**
|
||||
* Runs when outputting a tab section on the "edit form" screen
|
||||
*
|
||||
* @param string $tab
|
||||
* @ignore
|
||||
*/
|
||||
do_action('mc4wp_admin_edit_form_output_' . $tab . '_tab', $opts, $form);
|
||||
|
||||
$tab_file = __DIR__ . '/tabs/form-' . $tab . '.php';
|
||||
if (file_exists($tab_file)) {
|
||||
include $tab_file;
|
||||
}
|
||||
|
||||
// end of .tab
|
||||
echo '</div>';
|
||||
endforeach; // foreach tabs
|
||||
?>
|
||||
|
||||
</div><!-- / tabs -->
|
||||
</div>
|
||||
|
||||
</form><!-- Entire page form wrap -->
|
||||
|
||||
<?php require MC4WP_PLUGIN_DIR . '/includes/views/parts/admin-footer.php'; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
(function() {
|
||||
window.mc4wp = window.mc4wp || {
|
||||
listeners: [],
|
||||
forms: {
|
||||
on: function(evt, cb) {
|
||||
window.mc4wp.listeners.push(
|
||||
{
|
||||
event : evt,
|
||||
callback: cb
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,11 @@
|
||||
function maybePrefixUrlField () {
|
||||
const value = this.value.trim()
|
||||
if (value !== '' && value.indexOf('http') !== 0) {
|
||||
this.value = 'http://' + value
|
||||
}
|
||||
}
|
||||
|
||||
const urlFields = document.querySelectorAll('.mc4wp-form input[type="url"]')
|
||||
for (let j = 0; j < urlFields.length; j++) {
|
||||
urlFields[j].addEventListener('blur', maybePrefixUrlField)
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php defined('ABSPATH') or exit; ?>
|
||||
|
||||
<div class="mc4wp-admin">
|
||||
<h2><?php echo esc_html__('Add more fields', 'mailchimp-for-wp'); ?></h2>
|
||||
|
||||
<div>
|
||||
|
||||
<p>
|
||||
<?php echo esc_html__('To add more fields to your form, you will need to create those fields in Mailchimp first.', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
|
||||
<p><strong><?php echo esc_html__("Here's how:", 'mailchimp-for-wp'); ?></strong></p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<p>
|
||||
<?php echo esc_html__('Log in to your Mailchimp account.', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
<?php echo esc_html__('Add list fields to any of your selected lists.', 'mailchimp-for-wp'); ?>
|
||||
<?php echo esc_html__('Clicking the following links will take you to the right screen.', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
<ul class="children lists--only-selected">
|
||||
<?php
|
||||
foreach ($lists as $list) {
|
||||
?>
|
||||
<li data-list-id="<?php echo $list->id; ?>" style="display: <?php echo in_array($list->id, $opts['lists']) ? '' : 'none'; ?>">
|
||||
<a href="https://admin.mailchimp.com/lists/settings/merge-tags?id=<?php echo $list->web_id; ?>">
|
||||
<span class="screen-reader-text"><?php echo esc_html__('Edit list fields for', 'mailchimp-for-wp'); ?> </span>
|
||||
<?php echo $list->name; ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
<?php echo esc_html__('Click the following button to have Mailchimp for WordPress pick up on your changes.', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a class="button button-primary" href="
|
||||
<?php
|
||||
echo esc_attr(
|
||||
add_query_arg(
|
||||
array(
|
||||
'_mc4wp_action' => 'empty_lists_cache',
|
||||
'_wpnonce' => wp_create_nonce('_mc4wp_action'),
|
||||
)
|
||||
)
|
||||
);
|
||||
?>
|
||||
">
|
||||
<?php echo esc_html__('Renew Mailchimp lists', 'mailchimp-for-wp'); ?>
|
||||
</a>
|
||||
</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
$tags = mc4wp('forms')->get_tags();
|
||||
?>
|
||||
<h2><?php echo esc_html__('Add dynamic form variable', 'mailchimp-for-wp'); ?></h2>
|
||||
<p>
|
||||
<?php echo sprintf(wp_kses(__('The following list of variables can be used to <a href="%s">add some dynamic content to your form or success and error messages</a>.', 'mailchimp-for-wp'), array( 'a' => array( 'href' => array() ) )), 'https://www.mc4wp.com/kb/using-variables-in-your-form-or-messages/') . ' ' . __('This allows you to personalise your form or response messages.', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
<table class="widefat striped">
|
||||
<?php
|
||||
foreach ($tags as $tag => $config) {
|
||||
$tag = ! empty($config['example']) ? $config['example'] : $tag;
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" class="widefat" value="<?php echo esc_attr(sprintf('{%s}', $tag)); ?>" readonly="readonly" onfocus="this.select();" />
|
||||
<p class="description" style="margin-bottom:0;"><?php echo strip_tags($config['description'], '<strong><b><em><i><a><code>'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
// fake post to prevent notices in wp_enqueue_scripts call
|
||||
$GLOBALS['post'] = new \WP_Post((object) array( 'filter' => 'raw' ));
|
||||
|
||||
// render simple page with form in it.
|
||||
?><!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Mailchimp for WordPress Form Preview</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="robots" content="noindex" />
|
||||
<link type="text/css" rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" />
|
||||
<?php
|
||||
wp_enqueue_scripts();
|
||||
wp_print_styles();
|
||||
wp_print_head_scripts();
|
||||
|
||||
if (function_exists('wp_custom_css_cb')) {
|
||||
wp_custom_css_cb();
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
body{
|
||||
background: white;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* hide all other elements */
|
||||
body::before,
|
||||
body::after,
|
||||
body > *:not(#form-preview) {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
#form-preview {
|
||||
display: block !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="page-template-default page ">
|
||||
<div id="form-preview" class="page type-page status-publish hentry post post-content">
|
||||
<?php mc4wp_show_form($form_id); ?>
|
||||
</div>
|
||||
<?php wp_footer(); ?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
$theme = wp_get_theme();
|
||||
$css_options = array(
|
||||
'0' => sprintf(esc_html__('Inherit from %s theme', 'mailchimp-for-wp'), $theme->Name),
|
||||
'basic' => esc_html__('Basic', 'mailchimp-for-wp'),
|
||||
esc_html__('Form Themes', 'mailchimp-for-wp') => array(
|
||||
'theme-light' => esc_html__('Light Theme', 'mailchimp-for-wp'),
|
||||
'theme-dark' => esc_html__('Dark Theme', 'mailchimp-for-wp'),
|
||||
'theme-red' => esc_html__('Red Theme', 'mailchimp-for-wp'),
|
||||
'theme-green' => esc_html__('Green Theme', 'mailchimp-for-wp'),
|
||||
'theme-blue' => esc_html__('Blue Theme', 'mailchimp-for-wp'),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the <option>'s in the "CSS Stylesheet" <select> box.
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
$css_options = apply_filters('mc4wp_admin_form_css_options', $css_options);
|
||||
|
||||
?>
|
||||
|
||||
<h2><?php echo esc_html__('Form Appearance', 'mailchimp-for-wp'); ?></h2>
|
||||
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_load_stylesheet_select"><?php echo esc_html__('Form Style', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td class="nowrap valigntop">
|
||||
<select name="mc4wp_form[settings][css]" id="mc4wp_load_stylesheet_select">
|
||||
|
||||
<?php
|
||||
foreach ($css_options as $key => $option) {
|
||||
if (is_array($option)) {
|
||||
$label = $key;
|
||||
$options = $option;
|
||||
printf('<optgroup label="%s">', $label);
|
||||
foreach ($options as $key => $option) {
|
||||
printf('<option value="%s" %s>%s</option>', $key, selected($opts['css'], $key, false), $option);
|
||||
}
|
||||
print( '</optgroup>' );
|
||||
} else {
|
||||
printf('<option value="%s" %s>%s</option>', $key, selected($opts['css'], $key, false), $option);
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<p class="description">
|
||||
<?php echo esc_html__('If you want to load some default CSS styles, select "basic formatting styles" or choose one of the color themes', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
/** @ignore */
|
||||
|
||||
do_action('mc4wp_admin_form_after_appearance_settings_rows', $opts, $form);
|
||||
?>
|
||||
|
||||
</table>
|
||||
|
||||
<?php submit_button(); ?>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php add_thickbox(); ?>
|
||||
|
||||
<div class="alignright">
|
||||
<a href="#TB_inline?width=0&height=550&inlineId=mc4wp-form-variables" class="thickbox button-secondary">
|
||||
<span class="dashicons dashicons-info"></span>
|
||||
<?php echo esc_html__('Form variables', 'mailchimp-for-wp'); ?>
|
||||
</a>
|
||||
<a href="#TB_inline?width=600&height=400&inlineId=mc4wp-add-field-help" class="thickbox button-secondary">
|
||||
<span class="dashicons dashicons-editor-help"></span>
|
||||
<?php echo esc_html__('Add more fields', 'mailchimp-for-wp'); ?>
|
||||
</a>
|
||||
</div>
|
||||
<h2><?php echo esc_html__('Form Fields', 'mailchimp-for-wp'); ?></h2>
|
||||
|
||||
<!-- Placeholder for the field wizard -->
|
||||
<div id="mc4wp-field-wizard"></div>
|
||||
|
||||
<div class="mc4wp-form-markup-wrap">
|
||||
<div class="mc4wp-form-editor-wrap">
|
||||
<h4 style="margin: 0"><?php echo esc_html__('Form code', 'mailchimp-for-wp'); ?> <span style="visibility: hidden;" class="dashicons dashicons-editor-help"></span></h4>
|
||||
<!-- Textarea for the actual form content HTML -->
|
||||
<textarea class="widefat" cols="160" rows="20" id="mc4wp-form-content" name="mc4wp_form[content]" placeholder="<?php echo esc_attr__('Enter the HTML code for your form fields..', 'mailchimp-for-wp'); ?>" autocomplete="false" autocorrect="false" autocapitalize="false" spellcheck="false"><?php echo htmlspecialchars($form->content, ENT_QUOTES, get_option('blog_charset')); ?></textarea>
|
||||
</div>
|
||||
<div class="mc4wp-form-preview-wrap">
|
||||
<h4 style="margin: 0;">
|
||||
<?php echo esc_html__('Form preview', 'mailchimp-for-wp'); ?>
|
||||
<span class="dashicons dashicons-editor-help" title="<?php echo esc_attr__('The form may look slightly different than this when shown in a post, page or widget area.', 'mailchimp-for-wp'); ?>"></span>
|
||||
</h4>
|
||||
<iframe id="mc4wp-form-preview" src="<?php echo esc_attr($form_preview_url); ?>"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- This field is updated by JavaScript as the form content changes -->
|
||||
<input type="hidden" id="required-fields" name="mc4wp_form[settings][required_fields]" value="<?php echo esc_attr($form->settings['required_fields']); ?>" />
|
||||
|
||||
<?php submit_button(); ?>
|
||||
|
||||
<p class="mc4wp-form-usage"><?php printf(esc_html__('Use the shortcode %s to display this form inside a post, page or text widget.', 'mailchimp-for-wp'), '<input type="text" onfocus="this.select();" readonly="readonly" value="' . esc_attr(sprintf('[mc4wp_form id=%d]', $form->ID)) . '" size="' . ( strlen($form->ID) + 15 ) . '">'); ?></p>
|
||||
|
||||
|
||||
<?php // Content for Thickboxes ?>
|
||||
<div id="mc4wp-form-variables" style="display: none;">
|
||||
<?php require __DIR__ . '/../parts/dynamic-content-tags.php'; ?>
|
||||
</div>
|
||||
|
||||
<div id="mc4wp-add-field-help" style="display: none;">
|
||||
<?php require __DIR__ . '/../parts/add-fields-help.php'; ?>
|
||||
</div>
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php defined('ABSPATH') or exit;
|
||||
|
||||
/** @var MC4WP_Form $form */
|
||||
?>
|
||||
|
||||
<h2><?php echo esc_html__('Form Messages', 'mailchimp-for-wp'); ?></h2>
|
||||
|
||||
<table class="form-table mc4wp-form-messages">
|
||||
|
||||
<?php
|
||||
|
||||
/** @ignore */
|
||||
|
||||
do_action('mc4wp_admin_form_before_messages_settings_rows', $opts, $form);
|
||||
?>
|
||||
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_subscribed"><?php echo esc_html__('Successfully subscribed', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_form_subscribed" name="mc4wp_form[messages][subscribed]" value="<?php echo esc_attr($form->messages['subscribed']); ?>" />
|
||||
<p class="description"><?php echo esc_html__('The text that shows when an email address is successfully subscribed to the selected list(s).', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_invalid_email"><?php echo esc_html__('Invalid email address', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_form_invalid_email" name="mc4wp_form[messages][invalid_email]" value="<?php echo esc_attr($form->messages['invalid_email']); ?>" required />
|
||||
<p class="description"><?php echo esc_html__('The text that shows when an invalid email address is given.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_required_field_missing"><?php echo esc_html__('Required field missing', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_form_required_field_missing" name="mc4wp_form[messages][required_field_missing]" value="<?php echo esc_attr($form->messages['required_field_missing']); ?>" required />
|
||||
<p class="description"><?php echo esc_html__('The text that shows when a required field for the selected list(s) is missing.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_already_subscribed"><?php echo esc_html__('Already subscribed', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_form_already_subscribed" name="mc4wp_form[messages][already_subscribed]" value="<?php echo esc_attr($form->messages['already_subscribed']); ?>" required />
|
||||
<p class="description"><?php echo esc_html__('The text that shows when the given email is already subscribed to the selected list(s).', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_error"><?php echo esc_html__('General error', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_form_error" name="mc4wp_form[messages][error]" value="<?php echo esc_attr($form->messages['error']); ?>" required />
|
||||
<p class="description"><?php echo esc_html__('The text that shows when a general error occured.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_unsubscribed"><?php echo esc_html__('Unsubscribed', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_form_unsubscribed" name="mc4wp_form[messages][unsubscribed]" value="<?php echo esc_attr($form->messages['unsubscribed']); ?>" required />
|
||||
<p class="description"><?php echo esc_html__('When using the unsubscribe method, this is the text that shows when the given email address is successfully unsubscribed from the selected list(s).', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_not_subscribed"><?php echo esc_html__('Not subscribed', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_form_not_subscribed" name="mc4wp_form[messages][not_subscribed]" value="<?php echo esc_attr($form->messages['not_subscribed']); ?>" required />
|
||||
<p class="description"><?php echo esc_html__('When using the unsubscribe method, this is the text that shows when the given email address is not on the selected list(s).', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_no_lists_selected"><?php echo esc_html__('No list selected', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_form_no_lists_selected" name="mc4wp_form[messages][no_lists_selected]" value="<?php echo esc_attr($form->messages['no_lists_selected']); ?>" required />
|
||||
<p class="description"><?php echo esc_html__('When offering a list choice, this is the text that shows when no lists were selected.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
$config = array(
|
||||
'element' => 'mc4wp_form[settings][update_existing]',
|
||||
'value' => 1,
|
||||
);
|
||||
?>
|
||||
<tr valign="top" data-showif="<?php echo esc_attr(json_encode($config)); ?>">
|
||||
<th scope="row"><label for="mc4wp_form_updated"><?php echo esc_html__('Updated', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_form_updated" name="mc4wp_form[messages][updated]" value="<?php echo esc_attr($form->messages['updated']); ?>" />
|
||||
<p class="description"><?php echo esc_html__('The text that shows when an existing subscriber is updated.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
/** @ignore */
|
||||
do_action('mc4wp_admin_form_after_messages_settings_rows', array(), $form);
|
||||
?>
|
||||
|
||||
<tr valign="top">
|
||||
<th></th>
|
||||
<td>
|
||||
<p class="description"><?php echo sprintf(esc_html__('HTML tags like %s are allowed in the message fields.', 'mailchimp-for-wp'), '<code>' . esc_html('<strong><em><a>') . '</code>'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<?php submit_button(); ?>
|
||||
@@ -0,0 +1,169 @@
|
||||
<h2><?php echo esc_html__('Form Settings', 'mailchimp-for-wp'); ?></h2>
|
||||
|
||||
<div class="mc4wp-margin-m"></div>
|
||||
|
||||
<h3><?php echo esc_html__('Mailchimp specific settings', 'mailchimp-for-wp'); ?></h3>
|
||||
|
||||
<table class="form-table" style="table-layout: fixed;">
|
||||
|
||||
<?php
|
||||
|
||||
/** @ignore */
|
||||
|
||||
do_action('mc4wp_admin_form_before_mailchimp_settings_rows', $opts, $form);
|
||||
?>
|
||||
|
||||
<tr valign="top">
|
||||
<th scope="row" style="width: 250px;"><?php echo esc_html__('Lists this form subscribes to', 'mailchimp-for-wp'); ?></th>
|
||||
<?php
|
||||
// loop through lists
|
||||
if (empty($lists)) {
|
||||
?>
|
||||
<td colspan="2"><?php echo sprintf(wp_kses(__('No lists found, <a href="%s">are you connected to Mailchimp</a>?', 'mailchimp-for-wp'), array( 'a' => array( 'href' => array() ) )), admin_url('admin.php?page=mailchimp-for-wp')); ?></td>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<td >
|
||||
|
||||
<ul id="mc4wp-lists" style="margin-bottom: 20px; max-height: 300px; overflow-y: auto;">
|
||||
<?php
|
||||
foreach ($lists as $list) {
|
||||
?>
|
||||
<li>
|
||||
<label>
|
||||
<input class="mc4wp-list-input" type="checkbox" name="mc4wp_form[settings][lists][]" value="<?php echo esc_attr($list->id); ?>" <?php checked(in_array($list->id, $opts['lists']), true); ?>> <?php echo esc_html($list->name); ?>
|
||||
</label>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
<p class="description"><?php echo esc_html__('Select the list(s) to which people who submit this form should be subscribed.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php echo esc_html__('Use double opt-in?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_form[settings][double_optin]" value="1" <?php checked($opts['double_optin'], 1); ?> />‏
|
||||
<?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_form[settings][double_optin]" value="0" <?php checked($opts['double_optin'], 0); ?> onclick="return confirm('<?php echo esc_attr__('Are you sure you want to disable double opt-in?', 'mailchimp-for-wp'); ?>');" />‏
|
||||
<?php echo esc_html__('No', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<p class="description"><?php echo esc_html__('We strongly suggest keeping double opt-in enabled. Disabling double opt-in may affect your GDPR compliance.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php echo esc_html__('Update existing subscribers?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_form[settings][update_existing]" value="1" <?php checked($opts['update_existing'], 1); ?> />‏
|
||||
<?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_form[settings][update_existing]" value="0" <?php checked($opts['update_existing'], 0); ?> />‏
|
||||
<?php echo esc_html__('No', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<p class="description"><?php echo esc_html__('Select "yes" if you want to update existing subscribers with the data that is sent.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
$config = array(
|
||||
'element' => 'mc4wp_form[settings][update_existing]',
|
||||
'value' => 1,
|
||||
);
|
||||
?>
|
||||
<tr valign="top" data-showif="<?php echo esc_attr(json_encode($config)); ?>">
|
||||
<th scope="row"><?php echo esc_html__('Replace interest groups?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_form[settings][replace_interests]" value="1" <?php checked($opts['replace_interests'], 1); ?> />‏
|
||||
<?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_form[settings][replace_interests]" value="0" <?php checked($opts['replace_interests'], 0); ?> />‏
|
||||
<?php echo esc_html__('No', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php echo esc_html__('Select "no" if you want to add the selected interests to any previously selected interests when updating a subscriber.', 'mailchimp-for-wp'); ?>
|
||||
<?php echo sprintf(' <a href="%s" target="_blank">' . esc_html__('What does this do?', 'mailchimp-for-wp') . '</a>', 'https://www.mc4wp.com/kb/what-does-replace-groupings-mean/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=settings-page'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_subscriber_tags"><?php echo esc_html__('Subscriber tags', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" name="mc4wp_form[settings][subscriber_tags]" id="mc4wp_form_subscriber_tags" placeholder="<?php echo esc_attr__('Example: My tag, another tag', 'mailchimp-for-wp'); ?>" value="<?php echo esc_attr($opts['subscriber_tags']); ?>" />
|
||||
<p class="description">
|
||||
<?php echo esc_html__('The listed tags will be applied to all subscribers added or updated by this form.', 'mailchimp-for-wp'); ?>
|
||||
<?php echo esc_html__('Separate multiple values with a comma.', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
/** @ignore */
|
||||
do_action('mc4wp_admin_form_after_mailchimp_settings_rows', $opts, $form);
|
||||
?>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="mc4wp-margin-m"></div>
|
||||
|
||||
<h3><?php echo esc_html__('Form behaviour', 'mailchimp-for-wp'); ?></h3>
|
||||
|
||||
<table class="form-table" style="table-layout: fixed;">
|
||||
|
||||
<?php
|
||||
/** @ignore */
|
||||
do_action('mc4wp_admin_form_before_behaviour_settings_rows', $opts, $form);
|
||||
?>
|
||||
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php echo esc_html__('Hide form after a successful sign-up?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_form[settings][hide_after_success]" value="1" <?php checked($opts['hide_after_success'], 1); ?> />‏
|
||||
<?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_form[settings][hide_after_success]" value="0" <?php checked($opts['hide_after_success'], 0); ?> />‏
|
||||
<?php echo esc_html__('No', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php echo esc_html__('Select "yes" to hide the form fields after a successful sign-up.', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="mc4wp_form_redirect"><?php echo esc_html__('Redirect to URL after successful sign-ups', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" name="mc4wp_form[settings][redirect]" id="mc4wp_form_redirect" placeholder="<?php echo sprintf(esc_attr__('Example: %s', 'mailchimp-for-wp'), esc_attr(site_url('/thank-you/'))); ?>" value="<?php echo esc_attr($opts['redirect']); ?>" />
|
||||
<p class="description">
|
||||
<?php echo wp_kses(__('Leave empty or enter <code>0</code> for no redirect. Otherwise, use complete (absolute) URLs, including <code>http://</code>.', 'mailchimp-for-wp'), array( 'code' => array() )); ?>
|
||||
</p>
|
||||
<p class="description">
|
||||
<?php echo esc_html__('Your "subscribed" message will not show when redirecting to another page, so make sure to let your visitors know they were successfully subscribed.', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
/** @ignore */
|
||||
do_action('mc4wp_admin_form_after_behaviour_settings_rows', $opts, $form);
|
||||
?>
|
||||
|
||||
</table>
|
||||
|
||||
<?php submit_button(); ?>
|
||||
626
wp-content/plugins/mailchimp-for-wp/includes/functions.php
Normal file
626
wp-content/plugins/mailchimp-for-wp/includes/functions.php
Normal file
@@ -0,0 +1,626 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Get a service by its name
|
||||
*
|
||||
* _Example:_
|
||||
*
|
||||
* $forms = mc4wp('forms');
|
||||
* $api = mc4wp('api');
|
||||
*
|
||||
* When no service parameter is given, the entire container will be returned.
|
||||
*
|
||||
* @ignore
|
||||
* @access private
|
||||
*
|
||||
* @param null|string $service (optional)
|
||||
* @return mixed
|
||||
*
|
||||
* @throws Exception when service is not found
|
||||
*/
|
||||
function mc4wp($service = null)
|
||||
{
|
||||
static $mc4wp = null;
|
||||
if (null === $mc4wp) {
|
||||
$mc4wp = new MC4WP_Container();
|
||||
}
|
||||
|
||||
if (null !== $service) {
|
||||
return $mc4wp->get($service);
|
||||
}
|
||||
|
||||
return $mc4wp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Mailchimp for WP options from the database
|
||||
* Uses default values to prevent undefined index notices.
|
||||
*
|
||||
* @since 1.0
|
||||
* @access public
|
||||
* @static array $options
|
||||
* @return array
|
||||
*/
|
||||
function mc4wp_get_options()
|
||||
{
|
||||
$defaults = require MC4WP_PLUGIN_DIR . '/config/default-settings.php';
|
||||
$options = (array) get_option('mc4wp', array());
|
||||
$options = array_merge($defaults, $options);
|
||||
|
||||
/**
|
||||
* Filters the Mailchimp for WordPress settings (general).
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
return apply_filters('mc4wp_settings', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function mc4wp_get_settings()
|
||||
{
|
||||
return mc4wp_get_options();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.2.6
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_get_api_key()
|
||||
{
|
||||
// try to get from constant
|
||||
if (defined('MC4WP_API_KEY') && constant('MC4WP_API_KEY') !== '') {
|
||||
return MC4WP_API_KEY;
|
||||
}
|
||||
|
||||
// get from options
|
||||
$opts = mc4wp_get_options();
|
||||
return $opts['api_key'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Mailchimp for WP API class (v3) and injects it with the API key
|
||||
*
|
||||
* @since 4.0
|
||||
* @access public
|
||||
*
|
||||
* @return MC4WP_API_V3
|
||||
*/
|
||||
function mc4wp_get_api_v3()
|
||||
{
|
||||
$api_key = mc4wp_get_api_key();
|
||||
return new MC4WP_API_V3($api_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the Debug Log
|
||||
*
|
||||
* @return MC4WP_Debug_Log
|
||||
*/
|
||||
function mc4wp_get_debug_log()
|
||||
{
|
||||
$opts = mc4wp_get_options();
|
||||
|
||||
// get default log file location
|
||||
$upload_dir = wp_upload_dir(null, false);
|
||||
$file = $upload_dir['basedir'] . '/mailchimp-for-wp/debug-log.php';
|
||||
$default_file = $file;
|
||||
|
||||
/**
|
||||
* Filters the log file to write to.
|
||||
*
|
||||
* @param string $file The log file location. Default: /wp-content/uploads/mailchimp-for-wp/mc4wp-debug.log
|
||||
*/
|
||||
$file = apply_filters('mc4wp_debug_log_file', $file);
|
||||
|
||||
if ($file === $default_file) {
|
||||
$dir = dirname($file);
|
||||
if (! is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
if (! is_file($dir . '/.htaccess')) {
|
||||
$lines = array(
|
||||
'<IfModule !authz_core_module>',
|
||||
'Order deny,allow',
|
||||
'Deny from all',
|
||||
'</IfModule>',
|
||||
'<IfModule authz_core_module>',
|
||||
'Require all denied',
|
||||
'</IfModule>',
|
||||
);
|
||||
file_put_contents($dir . '/.htaccess', join(PHP_EOL, $lines));
|
||||
}
|
||||
|
||||
if (! is_file($dir . '/index.html')) {
|
||||
file_put_contents($dir . '/index.html', '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the minimum level to log messages.
|
||||
*
|
||||
* @see MC4WP_Debug_Log
|
||||
*
|
||||
* @param string|int $level The minimum level of messages which should be logged.
|
||||
*/
|
||||
$level = apply_filters('mc4wp_debug_log_level', $opts['debug_log_level']);
|
||||
|
||||
return new MC4WP_Debug_Log($file, $level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL to a file inside the plugin directory
|
||||
*
|
||||
* @since 4.8.3
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_plugin_url($path)
|
||||
{
|
||||
static $base = null;
|
||||
if ($base === null) {
|
||||
$base = plugins_url('/', MC4WP_PLUGIN_FILE);
|
||||
}
|
||||
|
||||
return $base . $path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get current URL (full)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_get_request_url()
|
||||
{
|
||||
global $wp;
|
||||
|
||||
// get requested url from global $wp object
|
||||
$site_request_uri = $wp->request;
|
||||
|
||||
// fix for IIS servers using index.php in the URL
|
||||
if (false !== stripos($_SERVER['REQUEST_URI'], '/index.php/' . $site_request_uri)) {
|
||||
$site_request_uri = 'index.php/' . $site_request_uri;
|
||||
}
|
||||
|
||||
// concatenate request url to home url
|
||||
$url = home_url($site_request_uri);
|
||||
$url = trailingslashit($url);
|
||||
|
||||
return esc_url($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current URL path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_get_request_path()
|
||||
{
|
||||
return $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IP address for client making current request
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function mc4wp_get_request_ip_address()
|
||||
{
|
||||
if (isset($_SERVER['X-Forwarded-For'])) {
|
||||
$ip_address = $_SERVER['X-Forwarded-For'];
|
||||
} elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
$ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
$ip_address = $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
if (isset($ip_address)) {
|
||||
if (! is_array($ip_address)) {
|
||||
$ip_address = explode(',', $ip_address);
|
||||
}
|
||||
|
||||
// use first IP in list
|
||||
$ip_address = trim($ip_address[0]);
|
||||
|
||||
// if IP address is not valid, simply return null
|
||||
if (! filter_var($ip_address, FILTER_VALIDATE_IP)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $ip_address;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips all HTML tags from all values in a mixed variable, then trims the result.
|
||||
*
|
||||
* @access public
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function mc4wp_sanitize_deep($value)
|
||||
{
|
||||
if (is_scalar($value)) {
|
||||
// strip all HTML tags & whitespace
|
||||
$value = trim(strip_tags($value));
|
||||
|
||||
// convert & back to &
|
||||
$value = html_entity_decode($value, ENT_NOQUOTES);
|
||||
} elseif (is_array($value)) {
|
||||
$value = array_map('mc4wp_sanitize_deep', $value);
|
||||
} elseif (is_object($value)) {
|
||||
$vars = get_object_vars($value);
|
||||
foreach ($vars as $key => $data) {
|
||||
$value->{$key} = mc4wp_sanitize_deep($data);
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 4.0
|
||||
* @ignore
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
function _mc4wp_update_groupings_data($data = array())
|
||||
{
|
||||
|
||||
// data still has old "GROUPINGS" key?
|
||||
if (empty($data['GROUPINGS'])) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
// prepare new key
|
||||
if (! isset($data['INTERESTS'])) {
|
||||
$data['INTERESTS'] = array();
|
||||
}
|
||||
|
||||
$map = get_option('mc4wp_groupings_map', array());
|
||||
|
||||
foreach ($data['GROUPINGS'] as $grouping_id => $groups) {
|
||||
// for compatibility with expanded grouping arrays
|
||||
$grouping_key = $grouping_id;
|
||||
if (is_array($groups) && isset($groups['id']) && isset($groups['groups'])) {
|
||||
$grouping_id = $groups['id'];
|
||||
$groups = $groups['groups'];
|
||||
}
|
||||
|
||||
// do we have transfer data for this grouping id?
|
||||
if (! isset($map[ $grouping_id ])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we get a string, explode on delimiter(s)
|
||||
if (is_string($groups)) {
|
||||
// for BC with 3.x: explode on comma's
|
||||
$groups = join('|', explode(',', $groups));
|
||||
|
||||
// explode on current delimiter
|
||||
$groups = explode('|', $groups);
|
||||
}
|
||||
|
||||
// loop through groups and find interest ID
|
||||
$migrated = 0;
|
||||
foreach ($groups as $key => $group_name_or_id) {
|
||||
// do we know the new interest ID?
|
||||
if (empty($map[ $grouping_id ]['groups'][ $group_name_or_id ])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$interest_id = $map[ $grouping_id ]['groups'][ $group_name_or_id ];
|
||||
|
||||
// add to interests data
|
||||
if (! in_array($interest_id, $data['INTERESTS'], false)) {
|
||||
++$migrated;
|
||||
$data['INTERESTS'][] = $interest_id;
|
||||
}
|
||||
}
|
||||
|
||||
// remove old grouping ID if we migrated all groups.
|
||||
if ($migrated === count($groups)) {
|
||||
unset($data['GROUPINGS'][ $grouping_key ]);
|
||||
}
|
||||
}
|
||||
|
||||
// if everything went well, this is now empty & moved to new INTERESTS key.
|
||||
if (empty($data['GROUPINGS'])) {
|
||||
unset($data['GROUPINGS']);
|
||||
}
|
||||
|
||||
// is this empty? just unset it then.
|
||||
if (empty($data['INTERESTS'])) {
|
||||
unset($data['INTERESTS']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guesses merge vars based on given data & current request.
|
||||
*
|
||||
* @since 3.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function mc4wp_add_name_data($data)
|
||||
{
|
||||
|
||||
// Guess first and last name
|
||||
if (! empty($data['NAME']) && empty($data['FNAME']) && empty($data['LNAME'])) {
|
||||
$data['NAME'] = trim($data['NAME']);
|
||||
$strpos = strpos($data['NAME'], ' ');
|
||||
|
||||
if ($strpos !== false) {
|
||||
$data['FNAME'] = trim(substr($data['NAME'], 0, $strpos));
|
||||
$data['LNAME'] = trim(substr($data['NAME'], $strpos));
|
||||
} else {
|
||||
$data['FNAME'] = $data['NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
// Set name value
|
||||
if (empty($data['NAME']) && ! empty($data['FNAME']) && ! empty($data['LNAME'])) {
|
||||
$data['NAME'] = sprintf('%s %s', $data['FNAME'], $data['LNAME']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the "email type" for new subscribers.
|
||||
*
|
||||
* Possible return values are either "html" or "text"
|
||||
*
|
||||
* @access public
|
||||
* @since 3.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_get_email_type()
|
||||
{
|
||||
$email_type = 'html';
|
||||
|
||||
/**
|
||||
* Filters the email type preference for this new subscriber.
|
||||
*
|
||||
* @param string $email_type
|
||||
*/
|
||||
$email_type = (string) apply_filters('mc4wp_email_type', $email_type);
|
||||
|
||||
return $email_type;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ignore
|
||||
* @return bool
|
||||
*/
|
||||
function _mc4wp_use_sslverify()
|
||||
{
|
||||
|
||||
// Disable for all transports other than CURL
|
||||
if (! function_exists('curl_version')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$curl = curl_version();
|
||||
|
||||
// Disable if OpenSSL is not installed
|
||||
if (empty($curl['ssl_version'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disable if on WP 4.4, see https://core.trac.wordpress.org/ticket/34935
|
||||
if ($GLOBALS['wp_version'] === '4.4') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will replace the first half of a string with "*" characters.
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_obfuscate_string($string)
|
||||
{
|
||||
$length = strlen($string);
|
||||
$obfuscated_length = ceil($length / 2);
|
||||
$string = str_repeat('*', $obfuscated_length) . substr($string, $obfuscated_length);
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @ignore
|
||||
*/
|
||||
function _mc4wp_obfuscate_email_addresses_callback($m)
|
||||
{
|
||||
$one = $m[1] . str_repeat('*', strlen($m[2]));
|
||||
$two = $m[3] . str_repeat('*', strlen($m[4]));
|
||||
$three = $m[5];
|
||||
return sprintf('%s@%s.%s', $one, $two, $three);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obfuscates email addresses in a string.
|
||||
*
|
||||
* @param $string String possibly containing email address
|
||||
* @return string
|
||||
*/
|
||||
function mc4wp_obfuscate_email_addresses($string)
|
||||
{
|
||||
return preg_replace_callback('/([\w\.]{1,4})([\w\.]*)\@(\w{1,2})(\w*)\.(\w+)/', '_mc4wp_obfuscate_email_addresses_callback', $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes Mailchimp lists. This can take a while if the connected Mailchimp account has many lists.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function mc4wp_refresh_mailchimp_lists()
|
||||
{
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$mailchimp->refresh_lists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element from array, allows for dot notation eg: "foo.bar"
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
function mc4wp_array_get($array, $key, $default = null)
|
||||
{
|
||||
if (is_null($key)) {
|
||||
return $array;
|
||||
}
|
||||
|
||||
if (isset($array[ $key ])) {
|
||||
return $array[ $key ];
|
||||
}
|
||||
|
||||
foreach (explode('.', $key) as $segment) {
|
||||
if (! is_array($array) || ! array_key_exists($segment, $array)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$array = $array[ $segment ];
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters string and strips out all HTML tags and attributes, except what's in our whitelist.
|
||||
*
|
||||
* @param string $string The string to apply KSES whitelist on
|
||||
* @return string
|
||||
* @since 4.8.8
|
||||
*/
|
||||
function mc4wp_kses($string)
|
||||
{
|
||||
$always_allowed_attr = array_fill_keys(
|
||||
array(
|
||||
'aria-describedby',
|
||||
'aria-details',
|
||||
'aria-label',
|
||||
'aria-labelledby',
|
||||
'aria-hidden',
|
||||
'class',
|
||||
'id',
|
||||
'style',
|
||||
'title',
|
||||
'role',
|
||||
'data-*',
|
||||
'tabindex',
|
||||
),
|
||||
true
|
||||
);
|
||||
$input_allowed_attr = array_merge(
|
||||
$always_allowed_attr,
|
||||
array_fill_keys(
|
||||
array(
|
||||
'type',
|
||||
'required',
|
||||
'placeholder',
|
||||
'value',
|
||||
'name',
|
||||
'step',
|
||||
'min',
|
||||
'max',
|
||||
'checked',
|
||||
'width',
|
||||
'autocomplete',
|
||||
'autofocus',
|
||||
'minlength',
|
||||
'maxlength',
|
||||
'size',
|
||||
'pattern',
|
||||
'disabled',
|
||||
'readonly',
|
||||
),
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
$allowed = array(
|
||||
'p' => $always_allowed_attr,
|
||||
'label' => array_merge($always_allowed_attr, array( 'for' => true )),
|
||||
'input' => $input_allowed_attr,
|
||||
'button' => $input_allowed_attr,
|
||||
'fieldset' => $always_allowed_attr,
|
||||
'legend' => $always_allowed_attr,
|
||||
'ul' => $always_allowed_attr,
|
||||
'ol' => $always_allowed_attr,
|
||||
'li' => $always_allowed_attr,
|
||||
'select' => array_merge($input_allowed_attr, array( 'multiple' => true )),
|
||||
'option' => array_merge($input_allowed_attr, array( 'selected' => true )),
|
||||
'optgroup' => array(
|
||||
'disabled' => true,
|
||||
'label' => true,
|
||||
),
|
||||
'textarea' => array_merge(
|
||||
$input_allowed_attr,
|
||||
array(
|
||||
'rows' => true,
|
||||
'cols' => true,
|
||||
)
|
||||
),
|
||||
'div' => $always_allowed_attr,
|
||||
'strong' => $always_allowed_attr,
|
||||
'b' => $always_allowed_attr,
|
||||
'i' => $always_allowed_attr,
|
||||
'br' => array(),
|
||||
'em' => $always_allowed_attr,
|
||||
'span' => $always_allowed_attr,
|
||||
'a' => array_merge($always_allowed_attr, array( 'href' => true )),
|
||||
'img' => array_merge(
|
||||
$always_allowed_attr,
|
||||
array(
|
||||
'src' => true,
|
||||
'alt' => true,
|
||||
'width' => true,
|
||||
'height' => true,
|
||||
'srcset' => true,
|
||||
'sizes' => true,
|
||||
'referrerpolicy' => true,
|
||||
)
|
||||
),
|
||||
'u' => $always_allowed_attr,
|
||||
);
|
||||
|
||||
return wp_kses($string, $allowed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for safely deprecating a changed filter hook.
|
||||
*
|
||||
* @param string $old_hook
|
||||
* @param string $new_hook
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function mc4wp_apply_deprecated_filters($old_hook, $new_hook)
|
||||
{
|
||||
add_filter($new_hook, function ($value, $a = null, $b = null, $c = null) use ($new_hook, $old_hook) {
|
||||
return apply_filters_deprecated($old_hook, array( $value, $a, $b, $c ), '4.9.0', $new_hook);
|
||||
}, 10, 3);
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Integration_Admin
|
||||
*
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Integration_Admin
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Integration_Manager
|
||||
*/
|
||||
protected $integrations;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Admin_Messages
|
||||
*/
|
||||
protected $messages;
|
||||
|
||||
/**
|
||||
* @param MC4WP_Integration_Manager $integrations
|
||||
* @param MC4WP_Admin_Messages $messages
|
||||
*/
|
||||
public function __construct(MC4WP_Integration_Manager $integrations, MC4WP_Admin_Messages $messages)
|
||||
{
|
||||
$this->integrations = $integrations;
|
||||
$this->messages = $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('admin_init', array( $this, 'register_setting' ));
|
||||
add_action('mc4wp_admin_enqueue_assets', array( $this, 'enqueue_assets' ), 10, 2);
|
||||
add_filter('mc4wp_admin_menu_items', array( $this, 'add_menu_item' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register settings
|
||||
*/
|
||||
public function register_setting()
|
||||
{
|
||||
register_setting('mc4wp_integrations_settings', 'mc4wp_integrations', array( $this, 'save_integration_settings' ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue assets
|
||||
*
|
||||
* @param string $suffix
|
||||
* @param string $page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_assets($suffix, $page)
|
||||
{
|
||||
// only load on integrations pages
|
||||
if ($page !== 'integrations') {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_register_script('mc4wp-integrations-admin', mc4wp_plugin_url('assets/js/integrations-admin.js'), array( 'mc4wp-admin' ), MC4WP_VERSION, true);
|
||||
wp_enqueue_script('mc4wp-integrations-admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_menu_item($items)
|
||||
{
|
||||
$items[] = array(
|
||||
'title' => esc_html__('Integrations', 'mailchimp-for-wp'),
|
||||
'text' => esc_html__('Integrations', 'mailchimp-for-wp'),
|
||||
'slug' => 'integrations',
|
||||
'callback' => array( $this, 'show_integrations_page' ),
|
||||
'position' => 20,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $new_settings
|
||||
* @return array
|
||||
*/
|
||||
public function save_integration_settings(array $new_settings)
|
||||
{
|
||||
$integrations = $this->integrations->get_all();
|
||||
$current_settings = (array) get_option('mc4wp_integrations', array());
|
||||
$settings = array();
|
||||
|
||||
foreach ($integrations as $slug => $integration) {
|
||||
$settings[ $slug ] = $this->parse_integration_settings($slug, $current_settings, $new_settings);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0
|
||||
* @param string $slug
|
||||
* @param array $current
|
||||
* @param array $new
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parse_integration_settings($slug, $current, $new)
|
||||
{
|
||||
$settings = array();
|
||||
|
||||
// start with current settings
|
||||
if (! empty($current[ $slug ])) {
|
||||
$settings = $current[ $slug ];
|
||||
}
|
||||
|
||||
// if no new settings were given, return current settings.
|
||||
if (empty($new[ $slug ])) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
// merge new settings with currents (to allow passing partial setting arrays)
|
||||
$settings = array_merge($settings, $new[ $slug ]);
|
||||
|
||||
// sanitize settings
|
||||
$settings = $this->sanitize_integration_settings($settings);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
protected function sanitize_integration_settings($settings)
|
||||
{
|
||||
|
||||
// filter null values from lists setting
|
||||
if (! empty($settings['lists'])) {
|
||||
$settings['lists'] = array_filter($settings['lists']);
|
||||
} else {
|
||||
$settings['lists'] = array();
|
||||
}
|
||||
|
||||
$settings['label'] = strip_tags($settings['label'], '<strong><b><br><a><script><u><em><i><span><img>');
|
||||
if (! current_user_can('unfiltered_html')) {
|
||||
$settings['label'] = mc4wp_kses($settings['label']);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the Integration Settings page
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function show_integrations_page()
|
||||
{
|
||||
if (! empty($_GET['integration'])) {
|
||||
$this->show_integration_settings_page($_GET['integration']);
|
||||
return;
|
||||
}
|
||||
|
||||
// get all installed & enabled integrations
|
||||
$enabled_integrations = $this->integrations->get_enabled_integrations();
|
||||
|
||||
// get all integrations but remove enabled integrations from the resulting array
|
||||
$integrations = $this->integrations->get_all();
|
||||
|
||||
require __DIR__ . '/views/integrations.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function show_integration_settings_page($slug)
|
||||
{
|
||||
try {
|
||||
$integration = $this->integrations->get($slug);
|
||||
} catch (Exception $e) {
|
||||
echo sprintf('<h3>Integration not found.</h3><p>No integration with slug <strong>%s</strong> was found.</p>', esc_html($slug));
|
||||
return;
|
||||
}
|
||||
|
||||
$opts = $integration->options;
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$lists = $mailchimp->get_lists();
|
||||
|
||||
require __DIR__ . '/views/integration-settings.php';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Integration_Fixture
|
||||
*
|
||||
* @since 3.0
|
||||
* @ignore
|
||||
*/
|
||||
class MC4WP_Integration_Fixture
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $slug;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $class;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $enabled;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $enabled_by_default;
|
||||
|
||||
/**
|
||||
* @var MC4WP_Integration
|
||||
*/
|
||||
public $instance;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $options;
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
* @param string $class
|
||||
* @param bool $enabled_by_default
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($slug, $class, $enabled_by_default, array $options)
|
||||
{
|
||||
$this->slug = $slug;
|
||||
$this->class = $class;
|
||||
$this->enabled_by_default = $enabled_by_default;
|
||||
$this->enabled = $enabled_by_default;
|
||||
$this->options = $options;
|
||||
|
||||
if (! empty($options['enabled'])) {
|
||||
$this->enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual instance
|
||||
*
|
||||
* @return MC4WP_Integration
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
if (! $this->instance instanceof MC4WP_Integration) {
|
||||
$this->instance = new $this->class($this->slug, $this->options);
|
||||
}
|
||||
|
||||
return $this->instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tunnel everything to MC4WP_Integration class
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return MC4WP_Integration
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
return call_user_func_array(array( $this->load(), $name ), $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->load()->$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->slug;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Integration_Manager
|
||||
*
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Integration_Manager
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Integration_Fixture[]
|
||||
*/
|
||||
protected $integrations = array();
|
||||
|
||||
/**
|
||||
* @var MC4WP_Integration_Tags
|
||||
*/
|
||||
protected $tags;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->tags = new MC4WP_Integration_Tags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_action('after_setup_theme', array( $this, 'initialize' ));
|
||||
|
||||
$this->tags->add_hooks();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
/*** @var MC4WP_Integration_Fixture $integration */
|
||||
$enabled_integrations = $this->get_enabled_integrations();
|
||||
|
||||
foreach ($enabled_integrations as $integration) {
|
||||
$integration->load()->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an integration instance
|
||||
*
|
||||
* @return MC4WP_Integration_Fixture[]
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get_all()
|
||||
{
|
||||
return $this->integrations;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an integration instance
|
||||
*
|
||||
* @param string $slug
|
||||
* @return MC4WP_Integration
|
||||
* @throws Exception
|
||||
*/
|
||||
public function get($slug)
|
||||
{
|
||||
if (! isset($this->integrations[ $slug ])) {
|
||||
throw new Exception(sprintf('No integration with slug %s has been registered.', $slug));
|
||||
}
|
||||
|
||||
return $this->integrations[ $slug ]->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new integration class
|
||||
*
|
||||
* @param string $slug
|
||||
* @param string $class
|
||||
* @param bool $enabled
|
||||
*/
|
||||
public function register_integration($slug, $class, $enabled = false)
|
||||
{
|
||||
$raw_options = $this->get_integration_options($slug);
|
||||
$this->integrations[ $slug ] = new MC4WP_Integration_Fixture($slug, $class, $enabled, $raw_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deregister an integration class
|
||||
*
|
||||
* @param string $slug
|
||||
*/
|
||||
public function deregister_integration($slug)
|
||||
{
|
||||
if (isset($this->integrations[ $slug ])) {
|
||||
unset($this->integrations[ $slug ]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a certain integration is enabled (in the settings)
|
||||
*
|
||||
* This is decoupled from the integration class itself as checking an array is way "cheaper" than instantiating an object
|
||||
*
|
||||
* @param MC4WP_Integration_Fixture $integration
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled(MC4WP_Integration_Fixture $integration)
|
||||
{
|
||||
return $integration->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MC4WP_Integration $integration
|
||||
* @return bool
|
||||
*/
|
||||
public function is_installed($integration)
|
||||
{
|
||||
return $integration->is_installed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the integrations which are enabled
|
||||
*
|
||||
* - Some integrations are always enabled because they need manual work
|
||||
* - Other integrations can be enabled in the settings page
|
||||
* - Only returns installed integrations
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_enabled_integrations()
|
||||
{
|
||||
// get all enabled integrations
|
||||
$enabled_integrations = array_filter($this->integrations, array( $this, 'is_enabled' ));
|
||||
|
||||
// remove duplicate values, for whatever reason..
|
||||
$enabled_integrations = array_unique($enabled_integrations);
|
||||
|
||||
// filter out integrations which are not installed
|
||||
$installed_enabled_integrations = array_filter($enabled_integrations, array( $this, 'is_installed' ));
|
||||
|
||||
return $installed_enabled_integrations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all integration options in a keyed array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function load_options()
|
||||
{
|
||||
$options = (array) get_option('mc4wp_integrations', array());
|
||||
|
||||
/**
|
||||
* Filters global integration options
|
||||
*
|
||||
* This array holds ALL integration settings
|
||||
*
|
||||
* @since 3.0
|
||||
* @param array $options
|
||||
* @ignore
|
||||
*/
|
||||
return (array) apply_filters('mc4wp_integration_options', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw options for an integration
|
||||
*
|
||||
* @param $slug
|
||||
* @return array
|
||||
*/
|
||||
public function get_integration_options($slug)
|
||||
{
|
||||
static $options;
|
||||
if ($options === null) {
|
||||
$options = $this->load_options();
|
||||
}
|
||||
|
||||
return isset($options[ $slug ]) ? $options[ $slug ] : array();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Integration_Tags
|
||||
*
|
||||
* @ignore
|
||||
* @access private
|
||||
*/
|
||||
class MC4WP_Integration_Tags extends MC4WP_Dynamic_Content_Tags
|
||||
{
|
||||
/**
|
||||
* @var MC4WP_Integration
|
||||
*/
|
||||
protected $integration;
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function add_hooks()
|
||||
{
|
||||
add_filter('mc4wp_integration_checkbox_label', array( $this, 'replace_in_checkbox_label' ), 10, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register template tags for integrations
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
parent::register();
|
||||
|
||||
$this->tags['subscriber_count'] = array(
|
||||
'description' => __('Replaced with the number of subscribers on the selected list(s)', 'mailchimp-for-wp'),
|
||||
'callback' => array( $this, 'get_subscriber_count' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hooked `mc4wp_integration_checkbox_label`
|
||||
* @param string $string
|
||||
* @param MC4WP_Integration $integration
|
||||
* @return string
|
||||
*/
|
||||
public function replace_in_checkbox_label($string, MC4WP_Integration $integration)
|
||||
{
|
||||
$this->integration = $integration;
|
||||
$string = $this->replace($string, 'esc_html');
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of subscribers on the selected lists (for the form context)
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_subscriber_count()
|
||||
{
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$list_ids = $this->integration->get_lists();
|
||||
$count = $mailchimp->get_subscriber_count($list_ids);
|
||||
return number_format($count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,590 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class MC4WP_Integration
|
||||
*
|
||||
* Base class for all integrations.
|
||||
*
|
||||
* Extend this class and implement the `add_hooks` method to get a settings page.
|
||||
*
|
||||
* @access public
|
||||
* @since 3.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class MC4WP_Integration
|
||||
{
|
||||
/**
|
||||
* @var string Name of this integration.
|
||||
*/
|
||||
public $name = '';
|
||||
|
||||
/**
|
||||
* @var string Description
|
||||
*/
|
||||
public $description = '';
|
||||
|
||||
/**
|
||||
* @var string Slug, used as an unique identifier for this integration.
|
||||
*/
|
||||
public $slug = '';
|
||||
|
||||
/**
|
||||
* @var array Array of settings
|
||||
*/
|
||||
public $options = array();
|
||||
|
||||
/**
|
||||
* @var string Name attribute for the checkbox element. Will be created from slug if empty.
|
||||
*/
|
||||
protected $checkbox_name = '';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $checkbox_classes = array();
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public $wrapper_classes = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $slug
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($slug, array $options)
|
||||
{
|
||||
$this->slug = $slug;
|
||||
$this->options = $this->parse_options($options);
|
||||
|
||||
// if checkbox name is not set, set a good custom value
|
||||
if ($this->checkbox_name === '') {
|
||||
$this->checkbox_name = '_mc4wp_subscribe_' . $this->slug;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of default options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_default_options()
|
||||
{
|
||||
return array(
|
||||
'css' => 0,
|
||||
'double_optin' => 1,
|
||||
'enabled' => 0,
|
||||
'implicit' => 0,
|
||||
'label' => __('Sign me up for the newsletter!', 'mailchimp-for-wp'),
|
||||
'lists' => array(),
|
||||
'precheck' => 0,
|
||||
'replace_interests' => 0,
|
||||
'update_existing' => 0,
|
||||
'wrap_p' => 1,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parse_options(array $options)
|
||||
{
|
||||
$slug = $this->slug;
|
||||
|
||||
$default_options = $this->get_default_options();
|
||||
$options = array_merge($default_options, $options);
|
||||
|
||||
/**
|
||||
* Filters options for a specific integration
|
||||
*
|
||||
* The dynamic portion of the hook, `$slug`, refers to the slug of the ingration.
|
||||
*
|
||||
* @param array $integration_options
|
||||
*/
|
||||
return (array) apply_filters('mc4wp_integration_' . $slug . '_options', $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the integration
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$this->add_required_hooks();
|
||||
$this->add_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the required hooks for core functionality, like adding checkbox reset CSS.
|
||||
*/
|
||||
protected function add_required_hooks()
|
||||
{
|
||||
if ($this->options['css'] && ! $this->options['implicit']) {
|
||||
add_action('wp_head', array( $this, 'print_css_reset' ));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Was integration triggered?
|
||||
*
|
||||
* Will always return true when integration is implicit. Otherwise, will check value of checkbox.
|
||||
*
|
||||
* @param int $object_id Useful when overriding method. (optional)
|
||||
* @return bool
|
||||
*/
|
||||
public function triggered($object_id = null)
|
||||
{
|
||||
return $this->options['implicit'] || $this->checkbox_was_checked();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the hooks which are specific to this integration
|
||||
*/
|
||||
abstract protected function add_hooks();
|
||||
|
||||
/**
|
||||
* Print CSS reset
|
||||
*
|
||||
* @hooked `wp_head`
|
||||
*/
|
||||
public function print_css_reset()
|
||||
{
|
||||
$css = file_get_contents(MC4WP_PLUGIN_DIR . '/assets/css/checkbox-reset.css');
|
||||
|
||||
// replace selector by integration specific selector so the css affects just this checkbox
|
||||
$css = str_ireplace('__INTEGRATION_SLUG__', $this->slug, $css);
|
||||
|
||||
printf('<style>%s</style>', $css);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text for the label element
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_label_text()
|
||||
{
|
||||
$integration = $this;
|
||||
$label = $this->options['label'];
|
||||
|
||||
if (empty($label)) {
|
||||
$default_options = $this->get_default_options();
|
||||
$label = $default_options['label'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the checkbox label
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $label
|
||||
* @param MC4WP_Integration $integration
|
||||
* @ignore
|
||||
*/
|
||||
$label = (string) apply_filters('mc4wp_integration_checkbox_label', $label, $integration);
|
||||
return $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was the integration checkbox checked?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function checkbox_was_checked()
|
||||
{
|
||||
$data = $this->get_data();
|
||||
return isset($data[ $this->checkbox_name ]) && (int) $data[ $this->checkbox_name ] === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string of attributes for the HTML element wrapping the checkbox + label
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_wrapper_attributes()
|
||||
{
|
||||
$html_attrs = array(
|
||||
'class' => sprintf('mc4wp-checkbox mc4wp-checkbox-%s %s', $this->slug, join(' ', $this->wrapper_classes)),
|
||||
);
|
||||
return $this->array_to_attr_string($html_attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string of attributes for the checkbox element.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_checkbox_attributes()
|
||||
{
|
||||
$integration = $this;
|
||||
$slug = $this->slug;
|
||||
|
||||
$attributes = array();
|
||||
|
||||
if ($this->options['precheck']) {
|
||||
$attributes['checked'] = 'checked';
|
||||
}
|
||||
|
||||
if (! empty($this->checkbox_classes)) {
|
||||
$attributes['class'] = join(' ', $this->checkbox_classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the attributes array.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param MC4WP_Integration $integration
|
||||
* @ignore
|
||||
*/
|
||||
$attributes = (array) apply_filters('mc4wp_integration_checkbox_attributes', $attributes, $integration);
|
||||
|
||||
/**
|
||||
* Filters the attributes array.
|
||||
*
|
||||
* The dynamic portion of the hook, `$slug`, refers to the slug for this integration.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param MC4WP_Integration $integration
|
||||
* @ignore
|
||||
*/
|
||||
$attributes = (array) apply_filters('mc4wp_integration_' . $slug . '_checkbox_attributes', $attributes, $integration);
|
||||
|
||||
return $this->array_to_attr_string($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a checkbox
|
||||
*/
|
||||
public function output_checkbox()
|
||||
{
|
||||
echo $this->get_checkbox_html();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML string for the checkbox row (incl. wrapper, label, etc.)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_checkbox_html()
|
||||
{
|
||||
$show_checkbox = empty($this->options['implicit']);
|
||||
$integration_slug = $this->slug;
|
||||
|
||||
/**
|
||||
* Filters whether to show the sign-up checkbox for this integration.
|
||||
*
|
||||
* @param bool $show_checkbox
|
||||
* @param string $integration_slug
|
||||
*/
|
||||
$show_checkbox = (bool) apply_filters('mc4wp_integration_show_checkbox', $show_checkbox, $integration_slug);
|
||||
if (! $show_checkbox) {
|
||||
return '';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
|
||||
echo sprintf('<!-- Mailchimp for WordPress v%s - https://www.mc4wp.com/ -->', MC4WP_VERSION);
|
||||
|
||||
/** @ignore */
|
||||
do_action('mc4wp_integration_before_checkbox_wrapper', $this);
|
||||
|
||||
/** @ignore */
|
||||
do_action('mc4wp_integration_' . $this->slug . '_before_checkbox_wrapper', $this);
|
||||
|
||||
$wrapper_tag = $this->options['wrap_p'] ? 'p' : 'span';
|
||||
$wrapper_attrs = $this->get_wrapper_attributes();
|
||||
|
||||
// Hidden field to make sure "0" is sent to server
|
||||
echo sprintf('<input type="hidden" name="%s" value="0" />', esc_attr($this->checkbox_name));
|
||||
echo sprintf('<%s %s>', $wrapper_tag, $wrapper_attrs);
|
||||
echo '<label>';
|
||||
echo sprintf('<input type="checkbox" name="%s" value="1" %s />', esc_attr($this->checkbox_name), $this->get_checkbox_attributes());
|
||||
echo sprintf('<span>%s</span>', $this->get_label_text());
|
||||
echo '</label>';
|
||||
echo sprintf('</%s>', $wrapper_tag);
|
||||
|
||||
/** @ignore */
|
||||
do_action('mc4wp_integration_after_checkbox_wrapper', $this);
|
||||
|
||||
/** @ignore */
|
||||
do_action('mc4wp_integration_' . $this->slug . '_after_checkbox_wrapper', $this);
|
||||
echo '<!-- / Mailchimp for WordPress -->';
|
||||
|
||||
$html = ob_get_clean();
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected Mailchimp lists
|
||||
*
|
||||
* @return array Array of List ID's
|
||||
*/
|
||||
public function get_lists()
|
||||
{
|
||||
$data = $this->get_data();
|
||||
$integration = $this;
|
||||
$slug = $this->slug;
|
||||
|
||||
// get checkbox lists options
|
||||
$lists = $this->options['lists'];
|
||||
|
||||
// get lists from request, if set.
|
||||
if (! empty($data['_mc4wp_lists'])) {
|
||||
$lists = $data['_mc4wp_lists'];
|
||||
|
||||
// ensure lists is an array
|
||||
if (! is_array($lists)) {
|
||||
$lists = explode(',', $lists);
|
||||
$lists = array_map('trim', $lists);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow plugins to filter final lists value. This filter is documented elsewhere.
|
||||
*
|
||||
* @since 2.0
|
||||
* @see MC4WP_Form::get_lists
|
||||
* @ignore
|
||||
*/
|
||||
$lists = (array) apply_filters('mc4wp_lists', $lists);
|
||||
|
||||
/**
|
||||
* Filters the Mailchimp lists this integration should subscribe to
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $lists
|
||||
* @param MC4WP_Integration $integration
|
||||
*/
|
||||
$lists = (array) apply_filters('mc4wp_integration_lists', $lists, $integration);
|
||||
|
||||
/**
|
||||
* Filters the Mailchimp lists a specific integration should subscribe to
|
||||
*
|
||||
* The dynamic portion of the hook, `$slug`, refers to the slug of the integration.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $lists
|
||||
* @param MC4WP_Integration $integration
|
||||
*/
|
||||
$lists = (array) apply_filters('mc4wp_integration_' . $slug . '_lists', $lists, $integration);
|
||||
|
||||
return $lists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a subscription request
|
||||
*
|
||||
* @param array $data
|
||||
* @param int $related_object_id
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function subscribe(array $data, $related_object_id = 0)
|
||||
{
|
||||
$integration = $this;
|
||||
$slug = $this->slug;
|
||||
$mailchimp = new MC4WP_MailChimp();
|
||||
$log = $this->get_log();
|
||||
$list_ids = $this->get_lists();
|
||||
|
||||
/** @var MC4WP_MailChimp_Subscriber $subscriber */
|
||||
$subscriber = null;
|
||||
$result = false;
|
||||
|
||||
// validate lists
|
||||
if (empty($list_ids)) {
|
||||
$log->warning(sprintf('%s > No Mailchimp lists were selected', $this->name));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters data for integration requests.
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
$data = apply_filters('mc4wp_integration_data', $data);
|
||||
|
||||
/**
|
||||
* Filters data for a specific integration request.
|
||||
*
|
||||
* The dynamic portion of the hook, `$slug`, refers to the integration slug.
|
||||
*
|
||||
* @param array $data
|
||||
* @param int $related_object_id
|
||||
*/
|
||||
$data = apply_filters("mc4wp_integration_{$slug}_data", $data, $related_object_id);
|
||||
|
||||
$email_type = mc4wp_get_email_type();
|
||||
|
||||
$mapper = new MC4WP_List_Data_Mapper($data, $list_ids);
|
||||
|
||||
/** @var MC4WP_MailChimp_Subscriber[] $map */
|
||||
$map = $mapper->map();
|
||||
|
||||
foreach ($map as $list_id => $subscriber) {
|
||||
$subscriber->status = $this->options['double_optin'] ? 'pending' : 'subscribed';
|
||||
$subscriber->email_type = $email_type;
|
||||
$subscriber->ip_signup = mc4wp_get_request_ip_address();
|
||||
|
||||
/** @ignore (documented elsewhere) */
|
||||
$subscriber = apply_filters('mc4wp_subscriber_data', $subscriber);
|
||||
if (! $subscriber instanceof MC4WP_MailChimp_Subscriber) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters subscriber data before it is sent to Mailchimp. Only fires for integration requests.
|
||||
*
|
||||
* @param MC4WP_MailChimp_Subscriber $subscriber
|
||||
*/
|
||||
$subscriber = apply_filters('mc4wp_integration_subscriber_data', $subscriber);
|
||||
if (! $subscriber instanceof MC4WP_MailChimp_Subscriber) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters subscriber data before it is sent to Mailchimp. Only fires for integration requests.
|
||||
*
|
||||
* The dynamic portion of the hook, `$slug`, refers to the integration slug.
|
||||
*
|
||||
* @param MC4WP_MailChimp_Subscriber $subscriber
|
||||
* @param int $related_object_id
|
||||
*/
|
||||
$subscriber = apply_filters("mc4wp_integration_{$slug}_subscriber_data", $subscriber, $related_object_id);
|
||||
if (! $subscriber instanceof MC4WP_MailChimp_Subscriber) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result = $mailchimp->list_subscribe($list_id, $subscriber->email_address, $subscriber->to_array(), $this->options['update_existing'], $this->options['replace_interests']);
|
||||
}
|
||||
|
||||
// if result failed, show error message
|
||||
if (! $result) {
|
||||
// log error
|
||||
if ((int) $mailchimp->get_error_code() === 214) {
|
||||
$log->warning(sprintf('%s > %s is already subscribed to the selected list(s)', $this->name, $subscriber->email_address));
|
||||
} else {
|
||||
$log->error(sprintf('%s > Mailchimp API Error: %s', $this->name, $mailchimp->get_error_message()));
|
||||
}
|
||||
|
||||
// bail
|
||||
return false;
|
||||
}
|
||||
|
||||
$log->info(sprintf('%s > Successfully subscribed %s', $this->name, $subscriber->email_address));
|
||||
|
||||
/**
|
||||
* Runs right after someone is subscribed using an integration
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Integration $integration
|
||||
* @param string $email_address
|
||||
* @param array $merge_vars
|
||||
* @param MC4WP_MailChimp_Subscriber[] $subscriber_data
|
||||
* @param int $related_object_id
|
||||
*/
|
||||
do_action('mc4wp_integration_subscribed', $integration, $subscriber->email_address, $subscriber->merge_fields, $map, $related_object_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are the required dependencies for this integration installed?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_installed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Which UI elements should we show on the settings page for this integration?
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_ui_elements()
|
||||
{
|
||||
return array_keys($this->options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does integration have the given UI element?
|
||||
*
|
||||
* @param string $element
|
||||
* @return bool
|
||||
*/
|
||||
public function has_ui_element($element)
|
||||
{
|
||||
$elements = $this->get_ui_elements();
|
||||
return in_array($element, $elements, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string to the admin settings page for this object (if any)
|
||||
*
|
||||
* @param int $object_id
|
||||
* @return string
|
||||
*/
|
||||
public function get_object_link($object_id)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data for this integration request
|
||||
*
|
||||
* By default, this will return a combination of all $_GET and $_POST parameters.
|
||||
* Override this method if you need data from somewhere else.
|
||||
*
|
||||
* This data should contain the value of the checkbox (required)
|
||||
* and the lists to which should be subscribed (optional)
|
||||
*
|
||||
* @see MC4WP_Integration::$checkbox_name
|
||||
* @see MC4WP_Integration::get_lists
|
||||
* @see MC4WP_Integration::checkbox_was_checked
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_data()
|
||||
{
|
||||
return array_merge((array) $_GET, (array) $_POST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array to an attribute string (foo="bar" bar="foo") with escaped values.
|
||||
*
|
||||
* @param array $attrs
|
||||
* @return string
|
||||
*/
|
||||
protected function array_to_attr_string(array $attrs)
|
||||
{
|
||||
$str = '';
|
||||
foreach ($attrs as $key => $value) {
|
||||
$str .= sprintf('%s="%s" ', $key, esc_attr($value));
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MC4WP_Debug_Log
|
||||
*/
|
||||
protected function get_log()
|
||||
{
|
||||
return mc4wp('log');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MC4WP_API_V3
|
||||
*/
|
||||
protected function get_api()
|
||||
{
|
||||
return mc4wp('api');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
defined('ABSPATH') or exit;
|
||||
|
||||
/**
|
||||
* Class MC4WP_User_Integration
|
||||
*
|
||||
* @access public
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class MC4WP_User_Integration extends MC4WP_Integration
|
||||
{
|
||||
/**
|
||||
* @param WP_User $user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function user_merge_vars(WP_User $user)
|
||||
{
|
||||
|
||||
// start with user_login as name, since that's always known
|
||||
$data = array(
|
||||
'EMAIL' => $user->user_email,
|
||||
'NAME' => $user->user_login,
|
||||
);
|
||||
|
||||
if ('' !== $user->first_name) {
|
||||
$data['NAME'] = $user->first_name;
|
||||
$data['FNAME'] = $user->first_name;
|
||||
}
|
||||
|
||||
if ('' !== $user->last_name) {
|
||||
$data['LNAME'] = $user->last_name;
|
||||
}
|
||||
|
||||
if ('' !== $user->first_name && '' !== $user->last_name) {
|
||||
$data['NAME'] = sprintf('%s %s', $user->first_name, $user->last_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @use mc4wp_integration_user_data
|
||||
* @since 3.0
|
||||
* @deprecated 4.0
|
||||
* @ignore
|
||||
*/
|
||||
$data = (array) apply_filters('mc4wp_user_merge_vars', $data, $user);
|
||||
|
||||
/**
|
||||
* Filters the data for user-related integrations
|
||||
* @since 4.2
|
||||
* @param array $data
|
||||
* @param WP_User $user
|
||||
*/
|
||||
$data = (array) apply_filters('mc4wp_integration_user_data', $data, $user);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Gets an array of all registered integrations
|
||||
*
|
||||
* @since 3.0
|
||||
* @access public
|
||||
*
|
||||
* @return MC4WP_Integration[]
|
||||
*/
|
||||
function mc4wp_get_integrations()
|
||||
{
|
||||
return mc4wp('integrations')->get_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of a registered integration class
|
||||
*
|
||||
* @since 3.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $slug
|
||||
*
|
||||
* @return MC4WP_Integration
|
||||
*/
|
||||
function mc4wp_get_integration($slug)
|
||||
{
|
||||
return mc4wp('integrations')->get($slug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new integration with Mailchimp for WordPress
|
||||
*
|
||||
* @since 3.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $slug
|
||||
* @param string $class
|
||||
*
|
||||
* @param bool $always_enabled
|
||||
*/
|
||||
function mc4wp_register_integration($slug, $class, $always_enabled = false)
|
||||
{
|
||||
return mc4wp('integrations')->register_integration($slug, $class, $always_enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deregister a previously registered integration with Mailchimp for WordPress
|
||||
*
|
||||
* @since 3.0
|
||||
* @access public
|
||||
* @param string $slug
|
||||
*/
|
||||
function mc4wp_deregister_integration($slug)
|
||||
{
|
||||
mc4wp('integrations')->deregister_integration($slug);
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
<?php defined('ABSPATH') or exit;
|
||||
/** @var MC4WP_Integration $integration */
|
||||
/** @var array $opts */
|
||||
?>
|
||||
<div id="mc4wp-admin" class="wrap mc4wp-settings">
|
||||
|
||||
<p class="mc4wp-breadcrumbs">
|
||||
<span class="prefix"><?php echo esc_html__('You are here: ', 'mailchimp-for-wp'); ?></span>
|
||||
<a href="<?php echo esc_url(admin_url('admin.php?page=mailchimp-for-wp')); ?>">Mailchimp for WordPress</a> ›
|
||||
<a href="<?php echo esc_url(admin_url('admin.php?page=mailchimp-for-wp-integrations')); ?>"><?php echo esc_html__('Integrations', 'mailchimp-for-wp'); ?></a> ›
|
||||
<span class="current-crumb"><strong><?php echo esc_html($integration->name); ?></strong></span>
|
||||
</p>
|
||||
|
||||
<div class="mc4wp-row">
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="main-content mc4wp-col">
|
||||
|
||||
<h1 class="mc4wp-page-title">
|
||||
<?php printf(esc_html__('%s integration', 'mailchimp-for-wp'), esc_html($integration->name)); ?>
|
||||
</h1>
|
||||
|
||||
<h2 style="display: none;"></h2>
|
||||
<?php settings_errors(); ?>
|
||||
|
||||
<div id="notice-additional-fields" class="notice notice-warning" style="display: none;">
|
||||
<p><?php echo esc_html__('The selected Mailchimp lists require non-default fields, which may prevent this integration from working.', 'mailchimp-for-wp'); ?></p>
|
||||
<p><?php echo sprintf(wp_kses(__('Please ensure you <a href="%1$s">configure the plugin to send all required fields</a> or <a href="%2$s">log into your Mailchimp account</a> and make sure only the email & name fields are marked as required fields for the selected list(s).', 'mailchimp-for-wp'), array( 'a' => array( 'href' => array() ) )), 'https://www.mc4wp.com/kb/send-additional-fields-from-integrations/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=integrations-page', 'https://admin.mailchimp.com/lists/'); ?></p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<?php echo esc_html($integration->description); ?>
|
||||
</p>
|
||||
|
||||
<!-- Settings form -->
|
||||
<form method="post" action="<?php echo admin_url('options.php'); ?>">
|
||||
<?php settings_fields('mc4wp_integrations_settings'); ?>
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runs just before integration settings are outputted in admin.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param MC4WP_Integration $integration
|
||||
* @param array $opts
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
do_action('mc4wp_admin_before_integration_settings', $integration, $opts);
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
do_action('mc4wp_admin_before_' . $integration->slug . '_integration_settings', $integration, $opts);
|
||||
?>
|
||||
|
||||
<table class="form-table">
|
||||
|
||||
<?php
|
||||
if ($integration->has_ui_element('enabled')) {
|
||||
?>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php echo esc_html__('Enabled?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap integration-toggles-wrap">
|
||||
<label><input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][enabled]" value="1" <?php checked($opts['enabled'], 1); ?> /> <?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?></label>
|
||||
<label><input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][enabled]" value="0" <?php checked($opts['enabled'], 0); ?> /> <?php echo esc_html__('No', 'mailchimp-for-wp'); ?></label>
|
||||
<p class="description"><?php echo sprintf(esc_html__('Enable the %s integration? This will add a sign-up checkbox to the form.', 'mailchimp-for-wp'), $integration->name); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
$config = array(
|
||||
'element' => 'mc4wp_integrations[' . $integration->slug . '][enabled]',
|
||||
'value' => '1',
|
||||
'hide' => false,
|
||||
);
|
||||
?>
|
||||
<tbody class="integration-toggled-settings" data-showif="<?php echo esc_attr(json_encode($config)); ?>">
|
||||
|
||||
<?php
|
||||
if ($integration->has_ui_element('implicit')) {
|
||||
?>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php echo esc_html__('Implicit?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label><input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][implicit]" value="1" <?php checked($opts['implicit'], 1); ?> /> <?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?></label>
|
||||
<label><input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][implicit]" value="0" <?php checked($opts['implicit'], 0); ?> /> <?php echo esc_html__('No', 'mailchimp-for-wp'); ?> <?php echo '<em>', esc_html__('(recommended)', 'mailchimp-for-wp'), '</em>'; ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php
|
||||
echo esc_html__('Select "yes" if you want to subscribe people without asking them explicitly.', 'mailchimp-for-wp');
|
||||
echo '<br />';
|
||||
|
||||
echo sprintf(
|
||||
wp_kses(
|
||||
__('<strong>Warning: </strong> enabling this may affect your <a href="%s">GDPR compliance</a>.', 'mailchimp-for-wp'),
|
||||
array(
|
||||
'a' => array( 'href' => array() ),
|
||||
'strong' => array(),
|
||||
)
|
||||
),
|
||||
'https://www.mc4wp.com/kb/gdpr-compliance/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=integrations-page'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
if ($integration->has_ui_element('lists')) {
|
||||
?>
|
||||
<?php // hidden input to make sure a value is sent to the server when no checkboxes were selected ?>
|
||||
<input type="hidden" name="mc4wp_integrations[<?php echo $integration->slug; ?>][lists][]" value="" />
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php echo esc_html__('Mailchimp Lists', 'mailchimp-for-wp'); ?></th>
|
||||
<?php
|
||||
if (! empty($lists)) {
|
||||
echo '<td>';
|
||||
echo '<ul style="margin-bottom: 20px; max-height: 300px; overflow-y: auto;">';
|
||||
foreach ($lists as $list) {
|
||||
echo '<li><label>';
|
||||
echo sprintf('<input type="checkbox" name="mc4wp_integrations[%s][lists][]" value="%s" class="mc4wp-list-input" %s> ', $integration->slug, $list->id, checked(in_array($list->id, $opts['lists'], true), true, false));
|
||||
echo esc_html($list->name);
|
||||
echo '</label></li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
|
||||
echo '<p class="description">';
|
||||
echo esc_html__('Select the list(s) to which people who check the checkbox should be subscribed.', 'mailchimp-for-wp');
|
||||
echo '</p>';
|
||||
echo '</td>';
|
||||
} else {
|
||||
echo '<td>', sprintf(wp_kses(__('No lists found, <a href="%s">are you connected to Mailchimp</a>?', 'mailchimp-for-wp'), array( 'a' => array( 'href' => array() ) )), esc_url(admin_url('admin.php?page=mailchimp-for-wp'))), '</td>';
|
||||
}
|
||||
?>
|
||||
</tr>
|
||||
<?php
|
||||
} // end if UI has lists
|
||||
?>
|
||||
|
||||
<?php
|
||||
if ($integration->has_ui_element('label')) {
|
||||
$config = array(
|
||||
'element' => 'mc4wp_integrations[' . $integration->slug . '][implicit]',
|
||||
'value' => 0,
|
||||
);
|
||||
?>
|
||||
<tr valign="top" data-showif="<?php echo esc_attr(json_encode($config)); ?>">
|
||||
<th scope="row"><label for="mc4wp_checkbox_label"><?php echo esc_html__('Checkbox label text', 'mailchimp-for-wp'); ?></label></th>
|
||||
<td>
|
||||
<input type="text" class="widefat" id="mc4wp_checkbox_label" name="mc4wp_integrations[<?php echo $integration->slug; ?>][label]" value="<?php echo esc_attr($opts['label']); ?>" required />
|
||||
<p class="description"><?php printf(esc_html__('HTML tags like %s are allowed in the label text.', 'mailchimp-for-wp'), '<code>' . esc_html('<strong><em><a>') . '</code>'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} // end if UI label
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
if ($integration->has_ui_element('precheck')) {
|
||||
$config = array(
|
||||
'element' => 'mc4wp_integrations[' . $integration->slug . '][implicit]',
|
||||
'value' => 0,
|
||||
);
|
||||
?>
|
||||
<tr valign="top" data-showif="<?php echo esc_attr(json_encode($config)); ?>">
|
||||
<th scope="row"><?php echo esc_html__('Pre-check the checkbox?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label><input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][precheck]" value="1" <?php checked($opts['precheck'], 1); ?> /> <?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?></label>
|
||||
<label><input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][precheck]" value="0" <?php checked($opts['precheck'], 0); ?> /> <?php echo esc_html__('No', 'mailchimp-for-wp'); ?> <?php echo '<em>' . __('(recommended)', 'mailchimp-for-wp') . '</em>'; ?></label>
|
||||
<p class="description">
|
||||
<?php
|
||||
echo esc_html__('Select "yes" if the checkbox should be pre-checked.', 'mailchimp-for-wp');
|
||||
echo '<br />';
|
||||
echo sprintf(
|
||||
wp_kses(
|
||||
__('<strong>Warning: </strong> enabling this may affect your <a href="%s">GDPR compliance</a>.', 'mailchimp-for-wp'),
|
||||
array(
|
||||
'a' => array( 'href' => array() ),
|
||||
'strong' => array(),
|
||||
)
|
||||
),
|
||||
'https://www.mc4wp.com/kb/gdpr-compliance/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=integrations-page'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</td>
|
||||
<?php
|
||||
} // end if UI precheck
|
||||
?>
|
||||
|
||||
<?php
|
||||
if ($integration->has_ui_element('css')) {
|
||||
$config = array(
|
||||
'element' => 'mc4wp_integrations[' . $integration->slug . '][implicit]',
|
||||
'value' => 0,
|
||||
);
|
||||
?>
|
||||
<tr valign="top" data-showif="<?php echo esc_attr(json_encode($config)); ?>">
|
||||
<th scope="row"><?php echo esc_html__('Load some default CSS?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label><input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][css]" value="1" <?php checked($opts['css'], 1); ?> />‏ <?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?></label>
|
||||
<label><input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][css]" value="0" <?php checked($opts['css'], 0); ?> />‏ <?php echo esc_html__('No', 'mailchimp-for-wp'); ?></label>
|
||||
<p class="description"><?php echo esc_html__('Select "yes" if the checkbox appears in a weird place.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} // end if UI css
|
||||
?>
|
||||
|
||||
<?php
|
||||
if ($integration->has_ui_element('double_optin')) {
|
||||
?>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php echo esc_html__('Double opt-in?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][double_optin]" value="1" <?php checked($opts['double_optin'], 1); ?> />‏
|
||||
<?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" id="mc4wp_checkbox_double_optin_0" name="mc4wp_integrations[<?php echo $integration->slug; ?>][double_optin]" value="0" <?php checked($opts['double_optin'], 0); ?> />‏
|
||||
<?php echo esc_html__('No', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php echo esc_html__('Select "yes" if you want people to confirm their email address before being subscribed (recommended)', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} // end if UI double_optin
|
||||
?>
|
||||
|
||||
<?php
|
||||
if ($integration->has_ui_element('update_existing')) {
|
||||
?>
|
||||
<tr valign="top">
|
||||
<th scope="row"><?php echo esc_html__('Update existing subscribers?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][update_existing]" value="1" <?php checked($opts['update_existing'], 1); ?> />‏
|
||||
<?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][update_existing]" value="0" <?php checked($opts['update_existing'], 0); ?> />‏
|
||||
<?php echo esc_html__('No', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<p class="description"><?php echo esc_html__('Select "yes" if you want to update existing subscribers with the data that is sent.', 'mailchimp-for-wp'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} // end if UI update_existing
|
||||
?>
|
||||
|
||||
<?php
|
||||
if ($integration->has_ui_element('replace_interests')) {
|
||||
$config = array(
|
||||
'element' => 'mc4wp_integrations[' . $integration->slug . '][update_existing]',
|
||||
'value' => 1,
|
||||
);
|
||||
?>
|
||||
<tr valign="top" data-showif="<?php echo esc_attr(json_encode($config)); ?>">
|
||||
<th scope="row"><?php echo esc_html__('Replace interest groups?', 'mailchimp-for-wp'); ?></th>
|
||||
<td class="nowrap">
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][replace_interests]" value="1" <?php checked($opts['replace_interests'], 1); ?> />‏
|
||||
<?php echo esc_html__('Yes', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="mc4wp_integrations[<?php echo $integration->slug; ?>][replace_interests]" value="0" <?php checked($opts['replace_interests'], 0); ?> />‏
|
||||
<?php echo esc_html__('No', 'mailchimp-for-wp'); ?>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php echo esc_html__('Select "no" if you want to add the selected interests to any previously selected interests when updating a subscriber.', 'mailchimp-for-wp'); ?>
|
||||
<?php echo sprintf('<a href="%s" target="_blank">' . esc_html__('What does this do?', 'mailchimp-for-wp') . '</a>', 'https://www.mc4wp.com/kb/what-does-replace-groupings-mean/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=integrations-page'); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} // end if UI replace_interests
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runs right after integration settings are outputted (before the submit button).
|
||||
*
|
||||
* @param MC4WP_Integration $integration
|
||||
* @param array $opts
|
||||
* @ignore
|
||||
*/
|
||||
do_action('mc4wp_admin_after_integration_settings', $integration, $opts);
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
do_action('mc4wp_admin_after_' . $integration->slug . '_integration_settings', $integration, $opts);
|
||||
?>
|
||||
|
||||
<?php
|
||||
if (count($integration->get_ui_elements()) > 0) {
|
||||
submit_button();
|
||||
}
|
||||
?>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="mc4wp-sidebar mc4wp-col">
|
||||
<?php require MC4WP_PLUGIN_DIR . '/includes/views/parts/admin-sidebar.php'; ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php defined('ABSPATH') or exit;
|
||||
/** @var MC4WP_Integration_Fixture[] $enabled_integrations */
|
||||
/** @var MC4WP_Integration_Fixture[] $available_integrations */
|
||||
/** @var MC4WP_Integration_Fixture $integration */
|
||||
function _mc4wp_integrations_table_row($integration)
|
||||
{
|
||||
?>
|
||||
<tr style="
|
||||
<?php
|
||||
if (! $integration->is_installed()) {
|
||||
echo 'opacity: 0.6;';
|
||||
}
|
||||
?>
|
||||
">
|
||||
|
||||
<!-- Integration Name -->
|
||||
<td>
|
||||
|
||||
<?php
|
||||
if ($integration->is_installed()) {
|
||||
echo sprintf('<strong><a href="%s" title="%s">%s</a></strong>', esc_attr(add_query_arg(array( 'integration' => $integration->slug ))), esc_html__('Configure this integration', 'mailchimp-for-wp'), $integration->name);
|
||||
} else {
|
||||
echo $integration->name;
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
</td>
|
||||
<td class="desc">
|
||||
<?php
|
||||
echo esc_html($integration->description);
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
if ($integration->enabled && $integration->is_installed()) {
|
||||
echo '<span class="mc4wp-status positive">', esc_html__('Active', 'mailchimp-for-wp'), '</span>';
|
||||
} elseif ($integration->is_installed()) {
|
||||
echo '<span class="mc4wp-status neutral">', esc_html__('Inactive', 'mailchimp-for-wp'), '</span>';
|
||||
} else {
|
||||
echo '<span>', esc_html__('Not installed', 'mailchimp-for-wp'), '</span>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a table with integrations
|
||||
*
|
||||
* @param $integrations
|
||||
* @ignore
|
||||
*/
|
||||
function _mc4wp_integrations_table($integrations)
|
||||
{
|
||||
?>
|
||||
<table class="mc4wp-table widefat striped">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo esc_html__('Name', 'mailchimp-for-wp'); ?></th>
|
||||
<th><?php echo esc_html__('Description', 'mailchimp-for-wp'); ?></th>
|
||||
<th><?php echo esc_html__('Status', 'mailchimp-for-wp'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<?php
|
||||
// active & enabled integrations first
|
||||
foreach ($integrations as $integration) {
|
||||
if ($integration->is_installed() && $integration->enabled) {
|
||||
_mc4wp_integrations_table_row($integration);
|
||||
}
|
||||
}
|
||||
|
||||
// active & disabled integrations next
|
||||
foreach ($integrations as $integration) {
|
||||
if ($integration->is_installed() && ! $integration->enabled) {
|
||||
_mc4wp_integrations_table_row($integration);
|
||||
}
|
||||
}
|
||||
|
||||
// rest
|
||||
foreach ($integrations as $integration) {
|
||||
if (! $integration->is_installed()) {
|
||||
_mc4wp_integrations_table_row($integration);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<div id="mc4wp-admin" class="wrap mc4wp-settings">
|
||||
|
||||
<p class="mc4wp-breadcrumbs">
|
||||
<span class="prefix"><?php echo esc_html__('You are here: ', 'mailchimp-for-wp'); ?></span>
|
||||
<a href="<?php echo admin_url('admin.php?page=mailchimp-for-wp'); ?>">Mailchimp for WordPress</a> ›
|
||||
<span class="current-crumb"><strong><?php echo esc_html__('Integrations', 'mailchimp-for-wp'); ?></strong></span>
|
||||
</p>
|
||||
|
||||
<div class="mc4wp-row">
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="mc4wp-col mc4wp-col-4">
|
||||
|
||||
<h1 class="mc4wp-page-title">Mailchimp for WordPress: <?php echo esc_html__('Integrations', 'mailchimp-for-wp'); ?></h1>
|
||||
|
||||
<h2 style="display: none;"></h2>
|
||||
<?php settings_errors(); ?>
|
||||
|
||||
<p>
|
||||
<?php echo esc_html__('The table below shows all available integrations.', 'mailchimp-for-wp'); ?>
|
||||
<?php echo esc_html__('Click on the name of an integration to edit all settings specific to that integration.', 'mailchimp-for-wp'); ?>
|
||||
</p>
|
||||
|
||||
<form action="<?php echo admin_url('options.php'); ?>" method="post">
|
||||
|
||||
<?php settings_fields('mc4wp_integrations_settings'); ?>
|
||||
|
||||
<h3><?php echo esc_html__('Integrations', 'mailchimp-for-wp'); ?></h3>
|
||||
<?php _mc4wp_integrations_table($integrations); ?>
|
||||
|
||||
<p><?php echo esc_html__('Greyed out integrations will become available after installing & activating the corresponding plugin.', 'mailchimp-for-wp'); ?></p>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="mc4wp-sidebar mc4wp-col">
|
||||
<?php require MC4WP_PLUGIN_DIR . '/includes/views/parts/admin-sidebar.php'; ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user