open videos on popup overlay
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
|
||||
Libraries 7.x-2.3, 2016-05-12
|
||||
-----------------------------
|
||||
#1884246 by BR0kEN, tstoeckler et al: Allow downloading libraries via Drush.
|
||||
by tstoeckler: Allow detecting all libraries by calling libraries_detect().
|
||||
by tstoeckler: Prevent LibrariesWebTestBase from being displayed in the UI.
|
||||
#819610 by tstoeckler: Add tests for the Libraries UI.
|
||||
#1884246 by BR0kEN, tstoeckler: Show the provider in drush libraries-list
|
||||
#819610 by Pol, tstoeckler: Show the provider in the UI.
|
||||
#2634732 by Rob Holmes, tstoeckler: Sort libraries by title in the UI.
|
||||
#2585395 by robinsonsarah01: Allow object methods as version callbacks.
|
||||
#819610 by tstoeckler, Pol: Provide a status report for library information.
|
||||
#2352251 by netw3rker: Fix incorrect hook name in libraries.api.php.
|
||||
#2352237 by netw3rker, tstoeckler: Allow clearing the libraries cache from Drush.
|
||||
#2193969 by tstoeckler: Avoid warnings for stale library caches.
|
||||
#2287529 by drupalshrek, tstoeckler: Update installation link in README.txt.
|
||||
|
||||
Libraries 7.x-2.2, 2014-02-09
|
||||
-----------------------------
|
||||
#2046919 by tstoeckler: Clarify 'version' docs.
|
||||
#1946110 by munroe_richard: Allow uppercase letters as library machine names.
|
||||
#1953260 by tstoeckler: Improve documentation of libraries_get_version().
|
||||
#1855918 by tstoeckler: Make integration file loading backwards-compatible.
|
||||
#1876124 by tstoeckler: Fix integration files for themes.
|
||||
#1876124 by tstoeckler: Add tests for theme-provided library information.
|
||||
#1876124 by tstoeckler: Prepare for adding a test theme.
|
||||
#1876124 by tstoeckler | whastings, fubhy: Fix hook_libraries_info() for themes.
|
||||
#2015721 by tstoeckler, CaptainHook: Protect against files overriding local variables.
|
||||
#2046919 by tstoeckler: Improve documentation around 'version callback'.
|
||||
#1844272 by tstoeckler, jweowu: Fix typos in libraries.api.php.
|
||||
#1938638 by tstoeckler: Prevent weird PHP notice on update.
|
||||
#1329388 by RobLoach, tstoeckler: Clear static caches in libraries_flush_caches().
|
||||
#1855918 by rbayliss: Load integration files after library files.
|
||||
#1938638 by Pol: Fix typo in libraries.api.php.
|
||||
|
||||
Libraries 7.x-2.1, 2013-03-09
|
||||
-----------------------------
|
||||
#1937446 by Pol, tstoeckler: Add a 'pre-dependencies-load' callback group.
|
||||
#1775668 by tstoeckler: Fix bogus assertion message in assertLibraryFiles().
|
||||
#1773640 by tstoeckler: Use drupal_get_path() to find the profile directory.
|
||||
#1565426 by tstoeckler: Invoke hook_libraries_info() in enabled themes.
|
||||
|
||||
Libraries 7.x-2.0, 2012-07-29
|
||||
-----------------------------
|
||||
#1606018 by chemical: Tests fail if the module is downloaded from Drupal.org.
|
||||
#1386250 by tstoeckler: Clarify module and library installation in README.txt.
|
||||
#1578618 by iamEAP: Fixed Fatal cache flush failure on major version upgrades.
|
||||
#1449346 by tstoeckler, sun: Clean-up libraries.test
|
||||
|
||||
Libraries 7.x-2.0-alpha2, 2011-12-15
|
||||
------------------------------------
|
||||
#1299076 by tstoeckler: Improve testing of JS, CSS, and PHP files.
|
||||
#1347214 by rfay: Improve update function 7200.
|
||||
#1323530 by tstoeckler: Document libraries_get_version() pattern matching.
|
||||
#1325524 by sun, Rob Loach, tstoeckler: Statically cache libraries_detect().
|
||||
#1321372 by Rob Loach: Provide a 'post-load' callback group.
|
||||
#1205854 by tstoeckler, sun: Test library caching.
|
||||
|
||||
Libraries 7.x-2.0-alpha1, 2011-10-01
|
||||
------------------------------------
|
||||
#1268342 by tstoeckler: Clean up drush libraries-list command.
|
||||
#962214 by tstoeckler, sun: Add support for library dependencies.
|
||||
#1224838 by sun, mjpa: Fix library path not being prepended to JS/CSS files.
|
||||
#1023258 by tstoeckler: Make 'files' consistently keyed by filename.
|
||||
#958162 by sun, tstoeckler: Add pre-detect callback group.
|
||||
#958162 by sun, tstoeckler: Make tests debuggable and provide libraries_info_defaults().
|
||||
#961476 by tstoeckler: Changed libraries_get_path() to return FALSE by default.
|
||||
#958162 by tstoeckler, sun, good_man: Allow to apply callbacks to libraries.
|
||||
#1125904 by tstoeckler, boombatower: Fix drush libraries-list.
|
||||
#1050076 by tstoeckler: Re-utilize libraries_detect() and remove libraries_detect_library().
|
||||
#466090 by tstoeckler: Add update function.
|
||||
#466090 by tstoeckler: Allow cache to be flushed.
|
||||
#466090 by tstoeckler, sun: Cache library information.
|
||||
#1064008 by tstoeckler, bfroehle: Fix outdated API examples in libraries.api.php.
|
||||
#1028744 by tstoeckler: Code clean-up.
|
||||
#1023322 by tstoeckler, sun: Fixed libraries shouldn't be loaded multiple times.
|
||||
#1024080 by hswong3i, tstoeckler: Fixed installation profile retrieval.
|
||||
#995988 by good_man: Wrong default install profile.
|
||||
#975498 by Gábor Hojtsy: Update JS/CSS-loading to new drupal_add_js/css() API.
|
||||
#958162 by tsteoeckler, sun: Consistent variable naming.
|
||||
#924130 by aaronbauman: Fixed libraries_get_path() should use drupal_static().
|
||||
#958162 by tstoeckler, sun: Code clean-up, tests revamp, more robust loading.
|
||||
#919632 by tstoeckler, sun: Allow library information to be stored in info files.
|
||||
by sun: Fixed testbot breaks upon directory name/info file name mismatch.
|
||||
#864376 by tstoeckler, sun: Code-cleanup, allow hard-coded 'version'.
|
||||
#939174 by sun, tstoeckler: Rename example.info to libraries_example.info.
|
||||
by sun: Fixed testbot breaks upon .info file without .module file.
|
||||
#542940 by tstoeckler, sun: Add libraries-list command.
|
||||
#919632 by tstoeckler: Add example library info file for testing purposes.
|
||||
#719896 by tstoeckler, sun: Documentation clean-up and tests improvement.
|
||||
#542940 by sun: Added initial Drush integration file.
|
||||
#719896 by tstoeckler, sun: Improved library detection and library loading.
|
||||
#855050 by Gábor Hojtsy: Avoid call-time pass by reference in libraries_detect().
|
||||
#719896 by tstoeckler, sun: Added starting point for hook_libraries_info().
|
||||
|
||||
|
||||
Libraries 7.x-1.x, xxxx-xx-xx
|
||||
-----------------------------
|
||||
|
||||
Libraries 7.x-1.0, 2010-01-27
|
||||
-----------------------------
|
||||
#743522 by sun: Ported to D7.
|
||||
|
||||
|
||||
Libraries 6.x-1.x, xxxx-xx-xx
|
||||
-----------------------------
|
||||
|
||||
Libraries 6.x-1.0, 2010-01-27
|
||||
-----------------------------
|
||||
#1028744 by tstoeckler: Code clean-up.
|
||||
#496732 by tstoeckler, robphillips: Allow placing libraries in root directory.
|
||||
|
||||
Libraries 6.x-1.0-alpha1, 2009-12-30
|
||||
------------------------------------
|
||||
#480440 by markus_petrux: Fixed base_path() not applied to default library path.
|
||||
#320562 by sun: Added basic functions.
|
||||
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) 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
|
||||
this service 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 make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. 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.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE 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.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
-- SUMMARY --
|
||||
|
||||
Libraries API provides external library handling for Drupal modules.
|
||||
|
||||
For a full description visit the project page:
|
||||
http://drupal.org/project/libraries
|
||||
Bug reports, feature suggestions and latest developments:
|
||||
http://drupal.org/project/issues/libraries
|
||||
|
||||
|
||||
-- REQUIREMENTS --
|
||||
|
||||
* None.
|
||||
|
||||
|
||||
-- INSTALLATION --
|
||||
|
||||
* Install as usual, see
|
||||
https://www.drupal.org/documentation/install/modules-themes/modules-7 for
|
||||
further information. Note that installing external libraries is separate from
|
||||
installing this module and should happen in the sites/all/libraries directory.
|
||||
See http://drupal.org/node/1440066 for more information.
|
||||
|
||||
|
||||
-- CONTACT --
|
||||
|
||||
Current maintainers:
|
||||
* Daniel F. Kudwien (sun) - http://drupal.org/user/54136
|
||||
* Tobias Stöckler (tstoeckler) - http://drupal.org/user/107158
|
||||
|
||||
|
||||
This project has been sponsored by:
|
||||
* UNLEASHED MIND
|
||||
Specialized in consulting and planning of Drupal powered sites, UNLEASHED
|
||||
MIND offers installation, development, theming, customization, and hosting
|
||||
to get you started. Visit http://www.unleashedmind.com for more information.
|
||||
|
||||
@@ -0,0 +1,547 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides administrative page and form callbacks for Libraries module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Form generation callback for the libraries overview table.
|
||||
*
|
||||
* This is a form instead of a page to allow easier extending in contributed
|
||||
* modules.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param array $form_state
|
||||
* A keyed array containing the current state of the form.
|
||||
*
|
||||
* @return array
|
||||
* The form array for the overview form.
|
||||
*/
|
||||
function libraries_admin_overview(array $form, array &$form_state) {
|
||||
$header = array(t('Name'), t('Status'), t('Installed version'), t('Provider'), t('Links'));
|
||||
$rows = array();
|
||||
|
||||
$libraries = libraries_detect();
|
||||
uasort($libraries, 'libraries_admin_sort_title');
|
||||
|
||||
foreach ($libraries as $machine_name => $library) {
|
||||
$actions = array();
|
||||
|
||||
if ($library['vendor url']) {
|
||||
$actions[] = l('Homepage', $library['vendor url']);
|
||||
}
|
||||
if ($library['download url']) {
|
||||
$actions[] = l('Download', $library['download url']);
|
||||
}
|
||||
|
||||
$rows[] = array(
|
||||
'data' => array(
|
||||
l($library['name'], 'admin/reports/libraries/' . $machine_name),
|
||||
($library['installed'] ? t('OK') : drupal_ucfirst($library['error'])),
|
||||
(isset($library['version']) ? $library['version'] : ''),
|
||||
libraries_admin_get_provider_with_type($library),
|
||||
implode(' | ', $actions),
|
||||
),
|
||||
'class' => ($library['installed'] ? array('ok') : array('error')),
|
||||
);
|
||||
}
|
||||
|
||||
$form['libraries']['list'] = array(
|
||||
'#theme' => 'table',
|
||||
'#header' => $header,
|
||||
'#rows' => $rows,
|
||||
'#empty' => t('There are currently no libraries installed'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form generation callback for the status overview for a single library.
|
||||
*
|
||||
* This is a form instead of a page to allow easier extending in contributed
|
||||
* modules.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param array $form_state
|
||||
* A keyed array containing the current state of the form.
|
||||
* @param array $library
|
||||
* A library information array.
|
||||
*
|
||||
* @return array|null
|
||||
* The form array for the status form or NULL if the library was not found.
|
||||
*
|
||||
* @todo Add some var_export($library)-style output
|
||||
*/
|
||||
function libraries_admin_library_status_form(array $form, array &$form_state, $library) {
|
||||
drupal_set_title(t('Status report for library %library', array('%library' => $library['name'])), PASS_THROUGH);
|
||||
|
||||
if ($library['installed']) {
|
||||
drupal_set_message(t('The %name library is installed correctly.', array('%name' => $library['name'])));
|
||||
$form['status'] = libraries_admin_status_table($library);
|
||||
}
|
||||
else {
|
||||
drupal_set_message($library['error message'], 'error');
|
||||
switch ($library['error']) {
|
||||
case 'not found':
|
||||
$form['instructions'] = libraries_admin_instructions_missing($library);
|
||||
break;
|
||||
|
||||
case 'not detected':
|
||||
$form['instructions'] = libraries_admin_instructions_undetected($library);;
|
||||
break;
|
||||
|
||||
case 'not supported':
|
||||
$form['instructions'] = libraries_admin_instructions_unsupported($library);
|
||||
break;
|
||||
|
||||
case 'missing dependency':
|
||||
$form['instructions']['instruction']['#markup'] = t('There a missing dependency in your configuration that prevent this library to work properly.') . '<br>';
|
||||
break;
|
||||
|
||||
case 'incompatible dependency':
|
||||
$form['instructions']['instruction']['#markup'] = t('There an incompatible dependency in your configuration that prevent this library to work properly.') . '<br>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays a table of status information about a library.
|
||||
*
|
||||
* @param array $library
|
||||
* A library information array.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array containing a table with status information.
|
||||
*/
|
||||
function libraries_admin_status_table(array $library) {
|
||||
$header = array(array(
|
||||
// @todo The title implies that other type of information is displayed, as
|
||||
// well, but this is currently not the case.
|
||||
// @todo Use CSS instead of a <strong> element.
|
||||
'data' => '<strong>' . t('General information') . '</strong>',
|
||||
'colspan' => 2,
|
||||
'class' => 'table-heading',
|
||||
'no_striping' => TRUE,
|
||||
));
|
||||
|
||||
$rows = array();
|
||||
// @todo Use CSS instead of <strong> elements.
|
||||
$rows['name'] = array('<strong>' . t('Name') . '</strong>', check_plain($library['name']));
|
||||
$rows['machine_name'] = array('<strong>' . t('Machine name') . '</strong>', check_plain($library['machine name']));
|
||||
if ($library['vendor url']) {
|
||||
$rows['vendor_url'] = array('<strong>' . t('Vendor URL') . '</strong>', l($library['vendor url'], $library['vendor url']));
|
||||
}
|
||||
if ($library['download url']) {
|
||||
$rows['download_url'] = array('<strong>' . t('Download URL') . '</strong>', l($library['download url'], $library['download url']));
|
||||
}
|
||||
$rows['provider'] = array('<strong>' . t('Provider') . '</strong>', libraries_admin_get_provider_with_type($library));
|
||||
$rows['library_path'] = array('<strong>' . t('Library path') . '</strong>', $library['library path']);
|
||||
$rows['version'] = array('<strong>' . t('Version') . '</strong>', $library['version']);
|
||||
if (!empty($library['variants'])) {
|
||||
$rows['variants'] = array('<strong>' . t('Variants') . '</strong>', implode(', ', array_keys($library['variants'])));
|
||||
}
|
||||
|
||||
return array(
|
||||
'#theme' => 'table',
|
||||
'#header' => $header,
|
||||
'#rows' => $rows,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns instructions for dealing with a missing library.
|
||||
*
|
||||
* @param array $library
|
||||
* A library information array.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array containing the instructions.
|
||||
*/
|
||||
function libraries_admin_instructions_missing(array $library) {
|
||||
$build = array();
|
||||
|
||||
$build['instruction']['#markup'] = t('Follow these steps to install the library:');
|
||||
|
||||
$items = array();
|
||||
// 1. Download the library.
|
||||
// If no supported versions are specified, the latest version is
|
||||
// recommended.
|
||||
if (empty($library['versions'])) {
|
||||
$items[] = t('Download the latest version of the library <a href="@download-url">here</a>.', array(
|
||||
'@download-url' => $library['download url'],
|
||||
));
|
||||
}
|
||||
// Otherwise, the latest supported version is recommended.
|
||||
else {
|
||||
$versions = array_keys($library['versions']);
|
||||
usort($versions, 'version_compare');
|
||||
$versions = array_reverse($versions);
|
||||
$version = $versions[0];
|
||||
$items[] = t('Download version %version of the library <a href="@download-url">here</a>.', array(
|
||||
'%version' => $version,
|
||||
'@download-url' => $library['download url'],
|
||||
));
|
||||
}
|
||||
// 2. Unpack it.
|
||||
$items[] = t('If the library is an archive, i.e. if the file ending is for example <em>.tar.gz</em> or <em>.zip</em>, unpack it.');
|
||||
// 3. Create the libraries folder.
|
||||
$items[] = t('In the %library-directory directory of your Drupal installation create a %library directory.', array(
|
||||
'%library-directory' => 'sites/all/libraries',
|
||||
'%library' => $library['machine name'],
|
||||
));
|
||||
// 4. Upload it.
|
||||
// If the library has variant-independent files, give the user the
|
||||
// location of an example file to check his filesystem against.
|
||||
if ($directory_layout = libraries_admin_directory_layout($library)) {
|
||||
$items[] = t('Upload the whole library (which can consist of multiple directories) into the newly created %library-path directory. The following files and directories should be contained in that directory: !directory-layout', array(
|
||||
'%library-path' => 'sites/all/libraries/' . $library['machine name'],
|
||||
'!directory-layout' => drupal_render($directory_layout),
|
||||
));
|
||||
}
|
||||
else {
|
||||
$items[] = t('Upload the whole library (which can consist of multiple directories) into the newly created %library-path directory.', array(
|
||||
'%library-path' => 'sites/all/libraries/' . $library['machine name'],
|
||||
));
|
||||
}
|
||||
// 5. Reload.
|
||||
$items[] = t('<a href="">Reload</a> the page. If successful, you should see status information about this library.');
|
||||
|
||||
$build['steps'] = array(
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $items,
|
||||
'#type' => 'ol'
|
||||
);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns instructions for dealing with an undetected library.
|
||||
*
|
||||
* @param array $library
|
||||
* A library information array.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array containing the instructions.
|
||||
*/
|
||||
function libraries_admin_instructions_undetected($library) {
|
||||
$build = array();
|
||||
// Re-check location.
|
||||
// @todo Avoid usage of <br> elements.
|
||||
$build['instruction']['#markup'] = t('Check that the whole library is located at %library-path.', array(
|
||||
'%library-path' => $library['library path'],
|
||||
)) . '<br>';
|
||||
// If the library has variant-independent files, give the user the
|
||||
// exact location of the files to check against.
|
||||
// @todo It should be possible to display even variant-specific files
|
||||
// in case the variant is installed, but libraries_detect() does not
|
||||
// detect variants if the library version cannot be detected.
|
||||
if ($directory_layout = libraries_admin_directory_layout($library)) {
|
||||
$build['directory_layout'] = $directory_layout;
|
||||
$build['directory_layout']['#prefix'] = t('The following files and directories should be contained in that directory:');
|
||||
}
|
||||
|
||||
// If the library is placed correctly the library information is
|
||||
// incorrect.
|
||||
// This switch could be avoided by using $library['info type'], but that would
|
||||
// hinder properly translating these strings.
|
||||
$build['reload']['#markup'] = t('If you have moved any files, <a href="">reload</a> the page. If successful, you should see status information about this library.') . '<br>';
|
||||
$build['notice']['#markup'] = t('If the files are placed correctly and the version can still not be detected, the library information is incorrect.') . '<br>';
|
||||
|
||||
$provider = libraries_admin_get_provider($library);
|
||||
switch ($library['info type']) {
|
||||
case 'module':
|
||||
$build['contact']['#markup'] = t('Contact the maintainer of the %module module to correct this.', array(
|
||||
'%module' => $provider,
|
||||
)) . '<br>';
|
||||
break;
|
||||
|
||||
case 'theme':
|
||||
$build['contact']['#markup'] = t('Contact the maintainer of the %theme theme to correct this.', array(
|
||||
'%theme' => $provider,
|
||||
)) . '<br>';
|
||||
break;
|
||||
|
||||
case 'info file':
|
||||
$build['contact']['#markup'] = t('Contact the maintainer of the %info-file info file to correct this.', array(
|
||||
'%info-file' => $provider,
|
||||
)) . '<br>';
|
||||
break;
|
||||
}
|
||||
return $build;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns instructions for dealing with an unsupported library.
|
||||
*
|
||||
* @param array $library
|
||||
* A library information array.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array containing the instructions.
|
||||
*/
|
||||
function libraries_admin_instructions_unsupported($library) {
|
||||
$build = array();
|
||||
$items = array();
|
||||
|
||||
// Either download a different version of the library...
|
||||
$versions = array_keys($library['versions']);
|
||||
usort($versions, 'version_compare');
|
||||
$versions = array_reverse($versions);
|
||||
$version = $versions[0];
|
||||
$build['instruction']['#markup'] = t('Please install version %version of the library by following the following steps:',
|
||||
array(
|
||||
'%version' => $version,
|
||||
));
|
||||
// 1. Delete the old library.
|
||||
$items[] = t('Delete the entire contents of the %library-path directory.',
|
||||
array(
|
||||
'%library-path' => $library['library path'],
|
||||
));
|
||||
// 2. Download the new library.
|
||||
$items[] = t('Download version %version of the library <a href="@download-url">here</a>.',
|
||||
array(
|
||||
'%version' => $version,
|
||||
'@download-url' => $library['download url'],
|
||||
));
|
||||
// 3. Unpack it.
|
||||
$items[] = t('If the library is an archive, i.e. if the file ending is for example <em>.tar.gz</em> or <em>.zip</em>, unpack it.');
|
||||
// 4. Upload the new library.
|
||||
// If the library has variant-independent files, give the user the
|
||||
// location of an example file to check his filesystem against.
|
||||
if ($directory_layout = libraries_admin_directory_layout($library)) {
|
||||
$items[] = t('Upload the new files into the %library-path directory. The following files and directories should be contained in that directory: !directory-layout',
|
||||
array(
|
||||
'%library-path' => $library['library path'],
|
||||
'!directory-layout' => drupal_render($directory_layout),
|
||||
));
|
||||
}
|
||||
else {
|
||||
$items[] = t('Upload the new files into the %library-path directory.',
|
||||
array(
|
||||
'%library-path' => $library['library path'],
|
||||
));
|
||||
}
|
||||
// 5. Reload.
|
||||
$items[] = t('<a href="">Reload</a> the page. If successful, you should see status information about this library.');
|
||||
$build['steps'] = array(
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $items,
|
||||
'#type' => 'ol',
|
||||
);
|
||||
// ...or contact the maintainer of the library information.
|
||||
$provider = libraries_admin_get_provider($library);
|
||||
switch ($library['info type']) {
|
||||
case 'module':
|
||||
$build['contact']['#markup'] = t('If you are bound to version @version of the library, ask the maintainer of the %module module to provide support for it.', array(
|
||||
'@version' => $library['version'],
|
||||
'%module' => $provider,
|
||||
)) . '<br>';
|
||||
break;
|
||||
|
||||
case 'theme':
|
||||
$build['contact']['#markup'] = t('If you are bound to version @version of the library, ask the maintainer of the %theme theme to provide support for it.', array(
|
||||
'@version' => $library['version'],
|
||||
'%theme' => $provider,
|
||||
)) . '<br>';
|
||||
break;
|
||||
|
||||
case 'info file':
|
||||
$build['contact']['#markup'] = t('If you are bound to version @version of the library, ask the maintainer of the %info-file info file to provide support for it.', array(
|
||||
'@version' => $library['version'],
|
||||
'%info-file' => $provider,
|
||||
)) . '<br>';
|
||||
break;
|
||||
}
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory layout of the library, if possible.
|
||||
*
|
||||
* The result of this function can help users to verify that they have uploaded
|
||||
* the library to the correct location.
|
||||
*
|
||||
* @param array $library
|
||||
* A library information array.
|
||||
*
|
||||
* @return array|false
|
||||
* A renderable array containing the directory layout of the library or FALSE
|
||||
* if a directory layout could not be generated.
|
||||
*/
|
||||
function libraries_admin_directory_layout(array $library) {
|
||||
$build = array(
|
||||
'#theme' => 'item_list',
|
||||
'#type' => 'ul',
|
||||
'#items' => array(),
|
||||
);
|
||||
|
||||
$items = &$build['#items'];
|
||||
if ($library['path']) {
|
||||
$items = &libraries_admin_path_to_tree($items, $library['path']);
|
||||
}
|
||||
foreach (array('js', 'css', 'php') as $type) {
|
||||
if (!empty($library['files'][$type])) {
|
||||
$files = array_keys($library['files'][$type]);
|
||||
foreach ($files as $file) {
|
||||
// Skip JavaScript settings.
|
||||
if (is_int($file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$children = &$items;
|
||||
libraries_admin_path_to_tree($children, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $build['#items'] ? $build : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a file path into a tree structure for use in an item list.
|
||||
*
|
||||
* For example, the path 'foo/bar/baz' will be converted into the tree structure
|
||||
* represented by the following list:
|
||||
* - foo
|
||||
* - bar
|
||||
* - baz
|
||||
*
|
||||
* The $items array that is modified by reference or returned (see below) can
|
||||
* be used as the 'items' variable for theme_item_list().
|
||||
*
|
||||
* This function modifies passed-in $items array, so that multiple paths can
|
||||
* be placed into the same tree structure easily.
|
||||
*
|
||||
* @code
|
||||
* $items = array();
|
||||
* foreach ($paths as $path) {
|
||||
* libraries_admin_path_to_tree($items, $path);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* It also returns the last item by reference, so that it can also be used to
|
||||
* traverse into a sub-structure and add further children there.
|
||||
*
|
||||
* @code
|
||||
* $items = array();
|
||||
* $children = &libraries_admin_path_to_tree($items, $path);
|
||||
* foreach ($sub_paths as $sub_path) {
|
||||
* libraries_admin_path_to_tree($children, $sub_path);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @param array $items
|
||||
* @param string $path
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function &libraries_admin_path_to_tree(array &$items, $path) {
|
||||
$part = strtok($path, '/');
|
||||
while ($part) {
|
||||
if (!isset($items[$part])) {
|
||||
$items[$part] = array(
|
||||
'data' => $part,
|
||||
'children' => array(),
|
||||
);
|
||||
}
|
||||
$items = &$items[$part]['children'];
|
||||
$part = strtok('/');
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts libraries by name.
|
||||
*
|
||||
* This function can be used as a callback for usort() or uasort().
|
||||
*
|
||||
* @param array $a
|
||||
* The first library information array.
|
||||
* @param array $b
|
||||
* The second library information array.
|
||||
*
|
||||
* @return int
|
||||
* Returns -1 if $a is considered smaller than $b, 1 if $a considered greater
|
||||
* than $b and 0 if $a and $b are considered equal.
|
||||
*
|
||||
* @see strnatcasecmp()
|
||||
* @see usort()
|
||||
* @see uasort()
|
||||
*/
|
||||
function libraries_admin_sort_title(array $a, array $b) {
|
||||
return strnatcasecmp($a['name'], $b['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the library's provider.
|
||||
*
|
||||
* The provider can be a module, a theme, or an info file.
|
||||
*
|
||||
* @param array $library
|
||||
* A library information array.
|
||||
*
|
||||
* @return string
|
||||
* The provider.
|
||||
*/
|
||||
function libraries_admin_get_provider($library) {
|
||||
$provider = '';
|
||||
|
||||
switch ($library['info type']) {
|
||||
case 'module':
|
||||
case 'theme':
|
||||
$info = system_get_info($library['info type'], $library[$library['info type']]);
|
||||
$provider = $info['name'];
|
||||
break;
|
||||
|
||||
case 'info file':
|
||||
$provider = basename($library['info file']);
|
||||
break;
|
||||
}
|
||||
|
||||
return $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the library's provider and provider type.
|
||||
*
|
||||
* The provider type is either 'module', 'theme', or 'info file'.
|
||||
*
|
||||
* @param array $library
|
||||
* A library information array.
|
||||
*
|
||||
* @return string
|
||||
* The provider and provider type.
|
||||
*/
|
||||
function libraries_admin_get_provider_with_type($library) {
|
||||
$provider = libraries_admin_get_provider($library);
|
||||
$provider_with_type = '';
|
||||
|
||||
// This switch could be avoided by using $library['info type'], but that would
|
||||
// hinder properly translating these strings.
|
||||
switch ($library['info type']) {
|
||||
case 'module':
|
||||
$provider_with_type = t('%module module', array('%module' => $provider));
|
||||
break;
|
||||
|
||||
case 'theme':
|
||||
$provider_with_type = t('%theme theme', array('%theme' => $provider));
|
||||
break;
|
||||
|
||||
case 'info file':
|
||||
$provider_with_type = t('%info-file info file', array('%info-file' => $provider));
|
||||
break;
|
||||
}
|
||||
|
||||
return $provider_with_type;
|
||||
}
|
||||
@@ -0,0 +1,484 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Documents API functions for Libraries module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return information about external libraries.
|
||||
*
|
||||
* @return
|
||||
* An associative array whose keys are internal names of libraries and whose
|
||||
* values are describing each library. Each key is the directory name below
|
||||
* the 'libraries' directory, in which the library may be found. Each value is
|
||||
* an associative array containing:
|
||||
* - name: The official, human-readable name of the library.
|
||||
* - vendor url: The URL of the homepage of the library.
|
||||
* - download url: The URL of a web page on which the library can be obtained.
|
||||
* - download file url: (optional) The URL where the latest version of the
|
||||
* library can be downloaded. In case such a static URL exists the library
|
||||
* can be downloaded automatically via Drush. Run
|
||||
* 'drush help libraries-download' in the command-line for more information.
|
||||
* - path: (optional) A relative path from the directory of the library to the
|
||||
* actual library. Only required if the extracted download package contains
|
||||
* the actual library files in a sub-directory.
|
||||
* - library path: (optional) The absolute path to the library directory. This
|
||||
* should not be declared normally, as it is automatically detected, to
|
||||
* allow for multiple possible library locations. A valid use-case is an
|
||||
* external library, in which case the full URL to the library should be
|
||||
* specified here.
|
||||
* - version: (optional) The version of the library. This should not be
|
||||
* declared normally, as it is automatically detected (see 'version
|
||||
* callback' below) to allow for version changes of libraries without code
|
||||
* changes of implementing modules and to support different versions of a
|
||||
* library simultaneously (though only one version can be installed per
|
||||
* site). A valid use-case is an external library whose version cannot be
|
||||
* determined programmatically. Either 'version' or 'version callback' (or
|
||||
* 'version arguments' in case libraries_get_version() is being used as a
|
||||
* version callback) must be declared.
|
||||
* - version callback: (optional) The name of a function that detects and
|
||||
* returns the full version string of the library. The first argument is
|
||||
* always $library, an array containing all library information as described
|
||||
* here. There are two ways to declare the version callback's additional
|
||||
* arguments, either as a single $options parameter or as multiple
|
||||
* parameters, which correspond to the two ways to specify the argument
|
||||
* values (see 'version arguments'). Defaults to libraries_get_version().
|
||||
* Unless 'version' is declared or libraries_get_version() is being used as
|
||||
* a version callback, 'version callback' must be declared. In the latter
|
||||
* case, however, 'version arguments' must be declared in the specified way.
|
||||
* - version arguments: (optional) A list of arguments to pass to the version
|
||||
* callback. Version arguments can be declared either as an associative
|
||||
* array whose keys are the argument names or as an indexed array without
|
||||
* specifying keys. If declared as an associative array, the arguments get
|
||||
* passed to the version callback as a single $options parameter whose keys
|
||||
* are the argument names (i.e. $options is identical to the specified
|
||||
* array). If declared as an indexed array, the array values get passed to
|
||||
* the version callback as separate arguments in the order they were
|
||||
* declared. The default version callback libraries_get_version() expects a
|
||||
* single, associative array with named keys:
|
||||
* - file: The filename to parse for the version, relative to the path
|
||||
* speficied as the 'library path' property (see above). For example:
|
||||
* 'docs/changelog.txt'.
|
||||
* - pattern: A string containing a regular expression (PCRE) to match the
|
||||
* library version. For example: '@version\s+([0-9a-zA-Z\.-]+)@'. Note
|
||||
* that the returned version is not the match of the entire pattern (i.e.
|
||||
* '@version 1.2.3' in the above example) but the match of the first
|
||||
* sub-pattern (i.e. '1.2.3' in the above example).
|
||||
* - lines: (optional) The maximum number of lines to search the pattern in.
|
||||
* Defaults to 20.
|
||||
* - cols: (optional) The maximum number of characters per line to take into
|
||||
* account. Defaults to 200. In case of minified or compressed files, this
|
||||
* prevents reading the entire file into memory.
|
||||
* Defaults to an empty array. 'version arguments' must be specified unless
|
||||
* 'version' is declared or the specified 'version callback' does not
|
||||
* require any arguments. The latter might be the case with a
|
||||
* library-specific version callback, for example.
|
||||
* - files: An associative array of library files to load. Supported keys are:
|
||||
* - js: A list of JavaScript files to load, using the same syntax as Drupal
|
||||
* core's hook_library().
|
||||
* - css: A list of CSS files to load, using the same syntax as Drupal
|
||||
* core's hook_library().
|
||||
* - php: A list of PHP files to load.
|
||||
* - dependencies: An array of libraries this library depends on. Similar to
|
||||
* declaring module dependencies, the dependency declaration may contain
|
||||
* information on the supported version. Examples of supported declarations:
|
||||
* @code
|
||||
* $libraries['dependencies'] = array(
|
||||
* // Load the 'example' library, regardless of the version available:
|
||||
* 'example',
|
||||
* // Only load the 'example' library, if version 1.2 is available:
|
||||
* 'example (1.2)',
|
||||
* // Only load a version later than 1.3-beta2 of the 'example' library:
|
||||
* 'example (>1.3-beta2)'
|
||||
* // Only load a version equal to or later than 1.3-beta3:
|
||||
* 'example (>=1.3-beta3)',
|
||||
* // Only load a version earlier than 1.5:
|
||||
* 'example (<1.5)',
|
||||
* // Only load a version equal to or earlier than 1.4:
|
||||
* 'example (<=1.4)',
|
||||
* // Combinations of the above are allowed as well:
|
||||
* 'example (>=1.3-beta2, <1.5)',
|
||||
* );
|
||||
* @endcode
|
||||
* - variants: (optional) An associative array of available library variants.
|
||||
* For example, the top-level 'files' property may refer to a default
|
||||
* variant that is compressed. If the library also ships with a minified and
|
||||
* uncompressed/source variant, those can be defined here. Each key should
|
||||
* describe the variant type, e.g. 'minified' or 'source'. Each value is an
|
||||
* associative array of top-level properties that are entirely overridden by
|
||||
* the variant, most often just 'files'. Additionally, each variant can
|
||||
* contain following properties:
|
||||
* - variant callback: (optional) The name of a function that detects the
|
||||
* variant and returns TRUE or FALSE, depending on whether the variant is
|
||||
* available or not. The first argument is always $library, an array
|
||||
* containing all library information as described here. The second
|
||||
* argument is always a string containing the variant name. There are two
|
||||
* ways to declare the variant callback's additional arguments, either as a
|
||||
* single $options parameter or as multiple parameters, which correspond
|
||||
* to the two ways to specify the argument values (see 'variant
|
||||
* arguments'). If omitted, the variant is expected to always be
|
||||
* available.
|
||||
* - variant arguments: A list of arguments to pass to the variant callback.
|
||||
* Variant arguments can be declared either as an associative array whose
|
||||
* keys are the argument names or as an indexed array without specifying
|
||||
* keys. If declared as an associative array, the arguments get passed to
|
||||
* the variant callback as a single $options parameter whose keys are the
|
||||
* argument names (i.e. $options is identical to the specified array). If
|
||||
* declared as an indexed array, the array values get passed to the
|
||||
* variant callback as separate arguments in the order they were declared.
|
||||
* Variants can be version-specific (see 'versions').
|
||||
* - versions: (optional) An associative array of supported library versions.
|
||||
* Naturally, libraries evolve over time and so do their APIs. In case a
|
||||
* library changes between versions, different 'files' may need to be
|
||||
* loaded, different 'variants' may become available, or Drupal modules need
|
||||
* to load different integration files adapted to the new version. Each key
|
||||
* is a version *string* (PHP does not support floats as keys). Each value
|
||||
* is an associative array of top-level properties that are entirely
|
||||
* overridden by the version.
|
||||
* - integration files: (optional) An associative array whose keys are module
|
||||
* names and whose values are sets of files to load for the module, using
|
||||
* the same notion as the top-level 'files' property. Each specified file
|
||||
* should contain the path to the file relative to the module it belongs to.
|
||||
* - callbacks: An associative array whose keys are callback groups and whose
|
||||
* values are arrays of callbacks to apply to the library in that group.
|
||||
* Each callback receives the following arguments:
|
||||
* - $library: An array of library information belonging to the top-level
|
||||
* library, a specific version, a specific variant or a specific variant
|
||||
* of a specific version. Because library information such as the 'files'
|
||||
* property (see above) can be declared in all these different locations
|
||||
* of the library array, but a callback may have to act on all these
|
||||
* different parts of the library, it is called recursively for each
|
||||
* library with a certain part of the libraries array passed as $library
|
||||
* each time.
|
||||
* - $version: If the $library array belongs to a certain version (see
|
||||
* above), a string containing the version. This argument may be empty, so
|
||||
* NULL should be specified as the default value.
|
||||
* - $variant: If the $library array belongs to a certain variant (see
|
||||
* above), a string containing the variant name. This argument may be
|
||||
* empty, so NULL should be specified as the default value.
|
||||
* Valid callback groups are:
|
||||
* - info: Callbacks registered in this group are applied after the library
|
||||
* information has been retrieved via hook_libraries_info() or info files.
|
||||
* At this point the following additional information is available:
|
||||
* - $library['info type']: How the library information was obtained. Can
|
||||
* be 'info file', 'module', or 'theme', depending on whether the
|
||||
* library information was obtained from an info file, an enabled module
|
||||
* or an enabled theme, respectively.
|
||||
* Additionally, one of the following three keys is available, depending
|
||||
* on the value of $library['info type'].
|
||||
* - $library['info file']: In case the library information was obtained
|
||||
* from an info file, the URI of the info file.
|
||||
* - $library['module']: In case the library was obtained from an enabled
|
||||
* module, the name of the providing module.
|
||||
* - $library['theme']: In case the library was obtained from an enabled
|
||||
* theme, the name of the providing theme.
|
||||
* - pre-detect: Callbacks registered in this group are applied after the
|
||||
* library path has been determined and before the version callback is
|
||||
* invoked. At this point the following additional information is
|
||||
* available:
|
||||
* - $library['library path']: The path on the file system to the library.
|
||||
* - post-detect: Callbacks registered in this group are applied after the
|
||||
* library has been successfully detected. At this point the library
|
||||
* contains the version-specific information, if specified, and following
|
||||
* additional information is available:
|
||||
* - $library['installed']: A boolean indicating whether the library is
|
||||
* installed or not.
|
||||
* - $library['version']: If it could be detected, a string containing the
|
||||
* version of the library.
|
||||
* - $library['variants'][$variant]['installed']: For each specified
|
||||
* variant, a boolean indicating whether the variant is installed or
|
||||
* not.
|
||||
* Note that in this group the 'versions' property is no longer available.
|
||||
* - pre-dependencies-load: Callbacks registered in this group are applied
|
||||
* directly before the library's dependencies are loaded. At this point
|
||||
* the library contains variant-specific information, if specified. Note
|
||||
* that in this group the 'variants' property is no longer available.
|
||||
* - pre-load: Callbacks registered in this group are applied directly after
|
||||
* the library's dependencies are loaded and before the library itself is
|
||||
* loaded.
|
||||
* - post-load: Callbacks registered in this group are applied directly
|
||||
* after this library is loaded. At this point, the library contains a
|
||||
* 'loaded' key, which contains the number of files that were loaded.
|
||||
* Additional top-level properties can be registered as needed.
|
||||
*
|
||||
* @see hook_library()
|
||||
*/
|
||||
function hook_libraries_info() {
|
||||
// The following is a full explanation of all properties. See below for more
|
||||
// concrete example implementations.
|
||||
|
||||
// This array key lets Libraries API search for 'sites/all/libraries/example'
|
||||
// directory, which should contain the entire, original extracted library.
|
||||
$libraries['example'] = array(
|
||||
// Only used in administrative UI of Libraries API.
|
||||
'name' => 'Example library',
|
||||
'vendor url' => 'http://example.com',
|
||||
'download url' => 'http://example.com/download',
|
||||
// It is important that this URL does not include the actual version to
|
||||
// download. Not all libraries provide such a static URL.
|
||||
'download file url' => 'http://example.com/latest.tar.gz',
|
||||
// Optional: If, after extraction, the actual library files are contained in
|
||||
// 'sites/all/libraries/example/lib', specify the relative path here.
|
||||
'path' => 'lib',
|
||||
// Optional: Define a custom version detection callback, if required.
|
||||
'version callback' => 'mymodule_get_version',
|
||||
// Specify arguments for the version callback. By default,
|
||||
// libraries_get_version() takes a named argument array:
|
||||
'version arguments' => array(
|
||||
'file' => 'docs/CHANGELOG.txt',
|
||||
'pattern' => '@version\s+([0-9a-zA-Z\.-]+)@',
|
||||
'lines' => 5,
|
||||
'cols' => 20,
|
||||
),
|
||||
// Default list of files of the library to load. Important: Only specify
|
||||
// third-party files belonging to the library here, not integration files of
|
||||
// your module.
|
||||
'files' => array(
|
||||
// 'js' and 'css' follow the syntax of hook_library(), but file paths are
|
||||
// relative to the library path.
|
||||
'js' => array(
|
||||
'exlib.js',
|
||||
'gadgets/foo.js',
|
||||
),
|
||||
'css' => array(
|
||||
'lib_style.css',
|
||||
'skin/example.css',
|
||||
),
|
||||
// For PHP libraries, specify include files here, still relative to the
|
||||
// library path.
|
||||
'php' => array(
|
||||
'exlib.php',
|
||||
'exlib.inc',
|
||||
),
|
||||
),
|
||||
// Optional: Specify alternative variants of the library, if available.
|
||||
'variants' => array(
|
||||
// All properties defined for 'minified' override top-level properties.
|
||||
'minified' => array(
|
||||
'files' => array(
|
||||
'js' => array(
|
||||
'exlib.min.js',
|
||||
'gadgets/foo.min.js',
|
||||
),
|
||||
'css' => array(
|
||||
'lib_style.css',
|
||||
'skin/example.css',
|
||||
),
|
||||
),
|
||||
'variant callback' => 'mymodule_check_variant',
|
||||
'variant arguments' => array(
|
||||
'variant' => 'minified',
|
||||
),
|
||||
),
|
||||
),
|
||||
// Optional, but usually required: Override top-level properties for later
|
||||
// versions of the library. The properties of the minimum version that is
|
||||
// matched override the top-level properties. Note:
|
||||
// - When registering 'versions', it usually does not make sense to register
|
||||
// 'files', 'variants', and 'integration files' on the top-level, as most
|
||||
// of those likely need to be different per version and there are no
|
||||
// defaults.
|
||||
// - The array keys have to be strings, as PHP does not support floats for
|
||||
// array keys.
|
||||
'versions' => array(
|
||||
'2' => array(
|
||||
'files' => array(
|
||||
'js' => array('exlib.js'),
|
||||
'css' => array('exlib_style.css'),
|
||||
),
|
||||
),
|
||||
'3.0' => array(
|
||||
'files' => array(
|
||||
'js' => array('exlib.js'),
|
||||
'css' => array('lib_style.css'),
|
||||
),
|
||||
),
|
||||
'3.2' => array(
|
||||
'files' => array(
|
||||
'js' => array(
|
||||
'exlib.js',
|
||||
'gadgets/foo.js',
|
||||
),
|
||||
'css' => array(
|
||||
'lib_style.css',
|
||||
'skin/example.css',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Optional: Register files to auto-load for your module. All files must be
|
||||
// keyed by module, and follow the syntax of the 'files' property.
|
||||
'integration files' => array(
|
||||
'mymodule' => array(
|
||||
'js' => array('ex_lib.inc'),
|
||||
),
|
||||
),
|
||||
// Optionally register callbacks to apply to the library during different
|
||||
// stages of its lifetime ('callback groups').
|
||||
'callbacks' => array(
|
||||
// Used to alter the info associated with the library.
|
||||
'info' => array(
|
||||
'mymodule_example_libraries_info_callback',
|
||||
),
|
||||
// Called before detecting the given library.
|
||||
'pre-detect' => array(
|
||||
'mymodule_example_libraries_predetect_callback',
|
||||
),
|
||||
// Called after detecting the library.
|
||||
'post-detect' => array(
|
||||
'mymodule_example_libraries_postdetect_callback',
|
||||
),
|
||||
// Called before the library's dependencies are loaded.
|
||||
'pre-dependencies-load' => array(
|
||||
'mymodule_example_libraries_pre_dependencies_load_callback',
|
||||
),
|
||||
// Called before the library is loaded.
|
||||
'pre-load' => array(
|
||||
'mymodule_example_libraries_preload_callback',
|
||||
),
|
||||
// Called after the library is loaded.
|
||||
'post-load' => array(
|
||||
'mymodule_example_libraries_postload_callback',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// A very simple library. No changing APIs (hence, no versions), no variants.
|
||||
// Expected to be extracted into 'sites/all/libraries/simple'.
|
||||
$libraries['simple'] = array(
|
||||
'name' => 'Simple library',
|
||||
'vendor url' => 'http://example.com/simple',
|
||||
'download url' => 'http://example.com/simple',
|
||||
// The download file URL can also point to a single file (instead of an
|
||||
// archive).
|
||||
'download file url' => 'http://example.com/latest/simple.js',
|
||||
'version arguments' => array(
|
||||
'file' => 'readme.txt',
|
||||
// Best practice: Document the actual version strings for later reference.
|
||||
// 1.x: Version 1.0
|
||||
'pattern' => '/Version (\d+)/',
|
||||
'lines' => 5,
|
||||
),
|
||||
'files' => array(
|
||||
'js' => array('simple.js'),
|
||||
),
|
||||
);
|
||||
|
||||
// A library that (naturally) evolves over time with API changes.
|
||||
$libraries['tinymce'] = array(
|
||||
'name' => 'TinyMCE',
|
||||
'vendor url' => 'http://tinymce.moxiecode.com',
|
||||
'download url' => 'http://tinymce.moxiecode.com/download.php',
|
||||
'path' => 'jscripts/tiny_mce',
|
||||
// The regular expression catches two parts (the major and the minor
|
||||
// version), which libraries_get_version() doesn't allow.
|
||||
'version callback' => 'tinymce_get_version',
|
||||
'version arguments' => array(
|
||||
// It can be easier to parse the first characters of a minified file
|
||||
// instead of doing a multi-line pattern matching in a source file. See
|
||||
// 'lines' and 'cols' below.
|
||||
'file' => 'jscripts/tiny_mce/tiny_mce.js',
|
||||
// Best practice: Document the actual version strings for later reference.
|
||||
// 2.x: this.majorVersion="2";this.minorVersion="1.3"
|
||||
// 3.x: majorVersion:'3',minorVersion:'2.0.1'
|
||||
'pattern' => '@majorVersion[=:]["\'](\d).+?minorVersion[=:]["\']([\d\.]+)@',
|
||||
'lines' => 1,
|
||||
'cols' => 100,
|
||||
),
|
||||
'versions' => array(
|
||||
'2.1' => array(
|
||||
'files' => array(
|
||||
'js' => array('tiny_mce.js'),
|
||||
),
|
||||
'variants' => array(
|
||||
'source' => array(
|
||||
'files' => array(
|
||||
'js' => array('tiny_mce_src.js'),
|
||||
),
|
||||
),
|
||||
),
|
||||
'integration files' => array(
|
||||
'wysiwyg' => array(
|
||||
'js' => array('editors/js/tinymce-2.js'),
|
||||
'css' => array('editors/js/tinymce-2.css'),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Definition used if 3.1 or above is detected.
|
||||
'3.1' => array(
|
||||
// Does not support JS aggregation.
|
||||
'files' => array(
|
||||
'js' => array(
|
||||
'tiny_mce.js' => array('preprocess' => FALSE),
|
||||
),
|
||||
),
|
||||
'variants' => array(
|
||||
// New variant leveraging jQuery. Not stable yet; therefore not the
|
||||
// default variant.
|
||||
'jquery' => array(
|
||||
'files' => array(
|
||||
'js' => array(
|
||||
'tiny_mce_jquery.js' => array('preprocess' => FALSE),
|
||||
),
|
||||
),
|
||||
),
|
||||
'source' => array(
|
||||
'files' => array(
|
||||
'js' => array(
|
||||
'tiny_mce_src.js' => array('preprocess' => FALSE),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'integration files' => array(
|
||||
'wysiwyg' => array(
|
||||
'js' => array('editors/js/tinymce-3.js'),
|
||||
'css' => array('editors/js/tinymce-3.css'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $libraries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter the library information before detection and caching takes place.
|
||||
*
|
||||
* The library definitions are passed by reference. A common use-case is adding
|
||||
* a module's integration files to the library array, so that the files are
|
||||
* loaded whenever the library is. As noted above, it is important to declare
|
||||
* integration files inside of an array, whose key is the module name.
|
||||
*
|
||||
* @see hook_libraries_info()
|
||||
*/
|
||||
function hook_libraries_info_alter(&$libraries) {
|
||||
$files = array(
|
||||
'php' => array('example_module.php_spellchecker.inc'),
|
||||
);
|
||||
$libraries['php_spellchecker']['integration files']['example_module'] = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify paths to look for library info files.
|
||||
*
|
||||
* Libraries API looks in the following directories for library info files by
|
||||
* default:
|
||||
* - libraries
|
||||
* - profiles/$profile/libraries
|
||||
* - sites/all/libraries
|
||||
* - sites/$site/libraries
|
||||
* This hook allows you to specify additional locations to look for library info
|
||||
* files. This should only be used for modules that declare many libraries.
|
||||
* Modules that only implement a few libraries should implement
|
||||
* hook_libraries_info().
|
||||
*
|
||||
* @return
|
||||
* An array of paths.
|
||||
*/
|
||||
function hook_libraries_info_file_paths() {
|
||||
// Taken from the Libraries test module, which needs to specify the path to
|
||||
// the test library.
|
||||
return array(drupal_get_path('module', 'libraries_test') . '/example');
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Drush integration for Libraries API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_drush_command().
|
||||
*/
|
||||
function libraries_drush_command() {
|
||||
$items = array();
|
||||
|
||||
$items['libraries-list'] = array(
|
||||
'description' => dt('Show a list of registered libraries.'),
|
||||
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
|
||||
'aliases' => array('lls', 'lib-list'),
|
||||
);
|
||||
|
||||
$items['libraries-download'] = array(
|
||||
'description' => dt('Download library files of registered libraries.'),
|
||||
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
|
||||
'aliases' => array('ldl', 'lib-download'),
|
||||
'arguments' => array(
|
||||
'libraries' => 'A comma delimited list of library machine names.',
|
||||
),
|
||||
'required-arguments' => TRUE,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_drush_cache_clear().
|
||||
*
|
||||
* @see drush_cache_clear_types()
|
||||
*/
|
||||
function libraries_drush_cache_clear(array &$types) {
|
||||
$types['libraries'] = 'libraries_drush_invalidate_cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the library cache.
|
||||
*/
|
||||
function libraries_drush_invalidate_cache() {
|
||||
// @see drupal_flush_all_caches()
|
||||
foreach (libraries_flush_caches() as $table) {
|
||||
cache_clear_all('*', $table, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Command callback. Show a list of registered libraries.
|
||||
*/
|
||||
function drush_libraries_list() {
|
||||
$libraries = libraries_detect();
|
||||
ksort($libraries);
|
||||
|
||||
if (empty($libraries)) {
|
||||
drush_print('There are no registered libraries.');
|
||||
}
|
||||
else {
|
||||
module_load_include('inc', 'libraries', 'libraries.admin');
|
||||
|
||||
$rows = array();
|
||||
// drush_print_table() automatically treats the first row as the header, if
|
||||
// $header is TRUE.
|
||||
$rows[] = array(
|
||||
dt('Name'),
|
||||
dt('Status'),
|
||||
dt('Version'),
|
||||
dt('Variants'),
|
||||
dt('Dependencies'),
|
||||
dt('Provider'),
|
||||
);
|
||||
foreach ($libraries as $name => $library) {
|
||||
// Only list installed variants.
|
||||
$variants = array();
|
||||
foreach ($library['variants'] as $variant_name => $variant) {
|
||||
if ($variant['installed']) {
|
||||
$variants[] = $variant_name;
|
||||
}
|
||||
}
|
||||
|
||||
$rows[] = array(
|
||||
$name,
|
||||
$library['installed'] ? dt('OK') : drupal_ucfirst($library['error']),
|
||||
($library['installed'] && $library['version']) ? '-' : $library['version'],
|
||||
$variants ? implode(', ', $variants) : '-',
|
||||
$library['dependencies'] ? implode(', ', $library['dependencies']) : '-',
|
||||
libraries_admin_get_provider($library),
|
||||
);
|
||||
}
|
||||
|
||||
// Make the possible values for the 'Status' column and the 'Version' header
|
||||
// wrap nicely.
|
||||
$widths = array(0, 12, 7, 0, 0, 0);
|
||||
drush_print_table($rows, TRUE, $widths);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Command callback. Downloads a library.
|
||||
*
|
||||
* Only libraries that provide a download file URL can be downloaded.
|
||||
*
|
||||
* @see hook_libraries_info()
|
||||
* @see drush_pm_download()
|
||||
*/
|
||||
function drush_libraries_download() {
|
||||
drush_command_include('pm-download');
|
||||
|
||||
$libraries = libraries_info();
|
||||
|
||||
// @todo Consider supporting downloading all downloadable libraries.
|
||||
// @todo Consider offering a selection if no library is specified.
|
||||
foreach (pm_parse_arguments(func_get_args(), FALSE) as $machine_name) {
|
||||
if (!isset($libraries[$machine_name])) {
|
||||
$message = dt("The !library library is not registered with Libraries API.\n", array('!library' => $machine_name));
|
||||
$message .= dt("Provide an info file for it or implement hook_libraries_info().\n");
|
||||
$message .= dt("See hook_libraries_info() for more information.\n");
|
||||
drush_set_error('DRUSH_LIBRARY_UKNOWN', $message);
|
||||
continue;
|
||||
}
|
||||
$library = $libraries[$machine_name];
|
||||
|
||||
if (empty($library['download file url'])) {
|
||||
$message = dt("The !library library cannot be downloaded.\n", array('!library' => $machine_name));
|
||||
$message .= dt("Libraries need to specify a download file URL to support being downloaded via Drush.\n");
|
||||
$message .= dt("See hook_libraries_info() for more information.\n");
|
||||
drush_set_error('DRUSH_LIBRARY_NOT_DOWNLOADABLE', $message);
|
||||
continue;
|
||||
}
|
||||
$download_url = $library['download file url'];
|
||||
|
||||
drush_log(dt('Downloading library !name ...', array('!name' => $machine_name)));
|
||||
|
||||
// @see package_handler_download_project() in wget.inc
|
||||
// It cannot be used directly because it will always try to extract the
|
||||
// archive which fails when downloading a single file.
|
||||
// @todo Modify upstream to be able to use
|
||||
// package_handler_download_project() directly.
|
||||
// Prepare download path. On Windows file name cannot contain '?'.
|
||||
// See http://drupal.org/node/1782444
|
||||
$filename = str_replace('?', '_', basename($download_url));
|
||||
$download_path = drush_tempdir() . '/' . $filename;
|
||||
|
||||
// Download the tarball.
|
||||
// Never cache the downloaded file. The downloading relies on the fact that
|
||||
// different versions of the library are available under the same URL as new
|
||||
// versions are released.
|
||||
$download_path = drush_download_file($download_url, $download_path, 0);
|
||||
if ($download_path || drush_get_context('DRUSH_SIMULATE')) {
|
||||
drush_log(dt('Downloading !filename was successful.', array('!filename' => $filename)));
|
||||
}
|
||||
else {
|
||||
drush_set_error('DRUSH_PM_DOWNLOAD_FAILED', dt('Unable to download !project to !path from !url.', array('!project' => $machine_name, '!path' => $download_path, '!url' => $download_url)));
|
||||
drush_log(dt('Error downloading !name', array('!name' => $machine_name)), 'error');
|
||||
continue;
|
||||
}
|
||||
|
||||
// @todo Suport MD5 file hashing.
|
||||
|
||||
// Extract the tarball in place and return the full path to the untarred directory.
|
||||
$download_base = dirname($download_path);
|
||||
if (drush_file_is_tarball($download_path)) {
|
||||
if (!$tar_file_list = drush_tarball_extract($download_path, $download_base, TRUE)) {
|
||||
// An error has been logged.
|
||||
return FALSE;
|
||||
}
|
||||
$tar_directory = drush_trim_path($tar_file_list[0]);
|
||||
$download_path = $download_base . '/' . $tar_directory;
|
||||
}
|
||||
else {
|
||||
$download_path = $download_base;
|
||||
}
|
||||
|
||||
// Determine the install location for the project. User provided
|
||||
// --destination has preference.
|
||||
$destination = drush_get_option('destination');
|
||||
if (!empty($destination)) {
|
||||
if (!file_exists($destination)) {
|
||||
drush_mkdir($destination);
|
||||
}
|
||||
$install_location = realpath($destination);
|
||||
}
|
||||
else {
|
||||
/** @see _pm_download_destination_lookup() */
|
||||
// _pm_download_destination_lookup() pluralizes the passed type by
|
||||
// appending an s.
|
||||
// This relies on the fact that there is no library named 'contrib'.
|
||||
// @todo Request that this be turned into a proper API upstream.
|
||||
$install_location = _pm_download_destination('librarie');
|
||||
}
|
||||
|
||||
// @todo Consider invoking a hook similar to
|
||||
// hook_drush_pm_download_destination_alter().
|
||||
|
||||
// @todo Consider adding version-control support similar to pm-download.
|
||||
|
||||
$install_location .= '/' . $machine_name;
|
||||
|
||||
// Check if install location already exists.
|
||||
if (is_dir($install_location)) {
|
||||
if (drush_confirm(dt('Install location !location already exists. Do you want to overwrite it?', array('!location' => $install_location)))) {
|
||||
drush_delete_dir($install_location, TRUE);
|
||||
}
|
||||
else {
|
||||
drush_log(dt("Skip installation of !project to !dest.", array('!project' => $library['machine name'], '!dest' => $install_location)), 'warning');
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the project to the install location.
|
||||
if (drush_op('_drush_recursive_copy', $download_path, $install_location)) {
|
||||
drush_log(dt("Library !project downloaded to !dest.", array('!project' => $machine_name, '!dest' => $install_location)), 'success');
|
||||
|
||||
// @todo Consider invoking a hook similar to
|
||||
// hook_drush_pm_post_download().
|
||||
|
||||
// @todo Support printing release notes.
|
||||
}
|
||||
else {
|
||||
// We don't `return` here in order to proceed with downloading additional projects.
|
||||
drush_set_error('DRUSH_PM_DOWNLOAD_FAILED', dt("Project !project could not be downloaded to !dest.", array('!project' => $machine_name, '!dest' => $install_location)));
|
||||
}
|
||||
|
||||
// @todo Consider adding notify support.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
name = Libraries
|
||||
description = Allows version-dependent and shared usage of external libraries.
|
||||
core = 7.x
|
||||
; We use hook_system_theme_info() which was added in Drupal 7.11
|
||||
dependencies[] = system (>=7.11)
|
||||
files[] = tests/LibrariesAdminWebTest.test
|
||||
files[] = tests/LibrariesLoadWebTest.test
|
||||
files[] = tests/LibrariesUnitTest.test
|
||||
files[] = tests/LibrariesWebTestBase.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-05-12
|
||||
version = "7.x-2.3"
|
||||
core = "7.x"
|
||||
project = "libraries"
|
||||
datestamp = "1463077450"
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, uninstall, and update functions for libraries.module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function libraries_schema() {
|
||||
$schema['cache_libraries'] = drupal_get_schema_unprocessed('system', 'cache');
|
||||
$schema['cache_libraries']['description'] = 'Cache table to store library information.';
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the 'cache_libraries' table.
|
||||
*/
|
||||
function libraries_update_7200() {
|
||||
// Note that previous versions of this function created the table with a
|
||||
// different table comment.
|
||||
if (!db_table_exists('cache_libraries')) {
|
||||
$specs = libraries_schema();
|
||||
db_create_table('cache_libraries', $specs['cache_libraries']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild the class registry.
|
||||
*/
|
||||
function libraries_update_7201() {
|
||||
// The tests were split from a single libraries.test file into multiple files
|
||||
// during the 7.x-2.x cycle.
|
||||
registry_rebuild();
|
||||
}
|
||||
@@ -0,0 +1,946 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* External library handling for Drupal modules.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_flush_caches().
|
||||
*/
|
||||
function libraries_flush_caches() {
|
||||
// Clear static caches.
|
||||
// We don't clear the 'libraries_load' static cache, because that could result
|
||||
// in libraries that had been loaded before the cache flushing to be loaded
|
||||
// again afterwards.
|
||||
foreach (array('libraries_get_path', 'libraries_info') as $name) {
|
||||
drupal_static_reset($name);
|
||||
}
|
||||
|
||||
// @todo When upgrading from 1.x, update.php attempts to flush caches before
|
||||
// the cache table has been created.
|
||||
// @see http://drupal.org/node/1477932
|
||||
if (db_table_exists('cache_libraries')) {
|
||||
return array('cache_libraries');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path of a library.
|
||||
*
|
||||
* @param $name
|
||||
* The machine name of a library to return the path for.
|
||||
* @param $base_path
|
||||
* Whether to prefix the resulting path with base_path().
|
||||
*
|
||||
* @return string
|
||||
* The path to the specified library or FALSE if the library wasn't found.
|
||||
*
|
||||
* @ingroup libraries
|
||||
*/
|
||||
function libraries_get_path($name, $base_path = FALSE) {
|
||||
$libraries = &drupal_static(__FUNCTION__);
|
||||
|
||||
if (!isset($libraries)) {
|
||||
$libraries = libraries_get_libraries();
|
||||
}
|
||||
|
||||
$path = ($base_path ? base_path() : '');
|
||||
if (!isset($libraries[$name])) {
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
$path .= $libraries[$name];
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of library directories.
|
||||
*
|
||||
* Returns an array of library directories from the all-sites directory
|
||||
* (i.e. sites/all/libraries/), the profiles directory, and site-specific
|
||||
* directory (i.e. sites/somesite/libraries/). The returned array will be keyed
|
||||
* by the library name. Site-specific libraries are prioritized over libraries
|
||||
* in the default directories. That is, if a library with the same name appears
|
||||
* in both the site-wide directory and site-specific directory, only the
|
||||
* site-specific version will be listed.
|
||||
*
|
||||
* @return array
|
||||
* A list of library directories.
|
||||
*
|
||||
* @ingroup libraries
|
||||
*/
|
||||
function libraries_get_libraries() {
|
||||
$searchdir = array();
|
||||
$profile = drupal_get_path('profile', drupal_get_profile());
|
||||
$config = conf_path();
|
||||
|
||||
// Similar to 'modules' and 'themes' directories in the root directory,
|
||||
// certain distributions may want to place libraries into a 'libraries'
|
||||
// directory in Drupal's root directory.
|
||||
$searchdir[] = 'libraries';
|
||||
|
||||
// Similar to 'modules' and 'themes' directories inside an installation
|
||||
// profile, installation profiles may want to place libraries into a
|
||||
// 'libraries' directory.
|
||||
$searchdir[] = "$profile/libraries";
|
||||
|
||||
// Always search sites/all/libraries.
|
||||
$searchdir[] = 'sites/all/libraries';
|
||||
|
||||
// Also search sites/<domain>/*.
|
||||
$searchdir[] = "$config/libraries";
|
||||
|
||||
// Retrieve list of directories.
|
||||
$directories = array();
|
||||
$nomask = array('CVS');
|
||||
foreach ($searchdir as $dir) {
|
||||
if (is_dir($dir) && $handle = opendir($dir)) {
|
||||
while (FALSE !== ($file = readdir($handle))) {
|
||||
if (!in_array($file, $nomask) && $file[0] != '.') {
|
||||
if (is_dir("$dir/$file")) {
|
||||
$directories[$file] = "$dir/$file";
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
}
|
||||
|
||||
return $directories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for library info files.
|
||||
*
|
||||
* This function scans the following directories for info files:
|
||||
* - libraries
|
||||
* - profiles/$profilename/libraries
|
||||
* - sites/all/libraries
|
||||
* - sites/$sitename/libraries
|
||||
* - any directories specified via hook_libraries_info_file_paths()
|
||||
*
|
||||
* @return array
|
||||
* An array of info files, keyed by library name. The values are the paths of
|
||||
* the files.
|
||||
*/
|
||||
function libraries_scan_info_files() {
|
||||
$profile = drupal_get_path('profile', drupal_get_profile());
|
||||
$config = conf_path();
|
||||
|
||||
// Build a list of directories.
|
||||
$directories = module_invoke_all('libraries_info_file_paths');
|
||||
$directories[] = 'libraries';
|
||||
$directories[] = "$profile/libraries";
|
||||
$directories[] = 'sites/all/libraries';
|
||||
$directories[] = "$config/libraries";
|
||||
|
||||
// Scan for info files.
|
||||
$files = array();
|
||||
foreach ($directories as $dir) {
|
||||
if (file_exists($dir)) {
|
||||
$files = array_merge($files, file_scan_directory($dir, '@^[A-Za-z0-9._-]+\.libraries\.info$@', array(
|
||||
'key' => 'name',
|
||||
'recurse' => FALSE,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($files as $filename => $file) {
|
||||
$files[basename($filename, '.libraries')] = $file;
|
||||
unset($files[$filename]);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes library callbacks.
|
||||
*
|
||||
* @param $group
|
||||
* A string containing the group of callbacks that is to be applied. Should be
|
||||
* either 'info', 'pre-detect', 'post-detect', or 'load'.
|
||||
* @param $library
|
||||
* An array of library information, passed by reference.
|
||||
*/
|
||||
function libraries_invoke($group, &$library) {
|
||||
// When introducing new callback groups in newer versions, stale cached
|
||||
// library information somehow reaches this point during the database update
|
||||
// before clearing the library cache.
|
||||
if (empty($library['callbacks'][$group])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($library['callbacks'][$group] as $callback) {
|
||||
libraries_traverse_library($library, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to apply a callback to all parts of a library.
|
||||
*
|
||||
* Because library declarations can include variants and versions, and those
|
||||
* version declarations can in turn include variants, modifying e.g. the 'files'
|
||||
* property everywhere it is declared can be quite cumbersome, in which case
|
||||
* this helper function is useful.
|
||||
*
|
||||
* @param $library
|
||||
* An array of library information, passed by reference.
|
||||
* @param $callback
|
||||
* A string containing the callback to apply to all parts of a library.
|
||||
*/
|
||||
function libraries_traverse_library(&$library, $callback) {
|
||||
// Always apply the callback to the top-level library.
|
||||
$callback($library, NULL, NULL);
|
||||
|
||||
// Apply the callback to versions.
|
||||
if (isset($library['versions'])) {
|
||||
foreach ($library['versions'] as $version_string => &$version) {
|
||||
$callback($version, $version_string, NULL);
|
||||
// Versions can include variants as well.
|
||||
if (isset($version['variants'])) {
|
||||
foreach ($version['variants'] as $version_variant_name => &$version_variant) {
|
||||
$callback($version_variant, $version_string, $version_variant_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the callback to variants.
|
||||
if (isset($library['variants'])) {
|
||||
foreach ($library['variants'] as $variant_name => &$variant) {
|
||||
$callback($variant, NULL, $variant_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Library info callback to make all 'files' properties consistent.
|
||||
*
|
||||
* This turns libraries' file information declared as e.g.
|
||||
* @code
|
||||
* $library['files']['js'] = array('example_1.js', 'example_2.js');
|
||||
* @endcode
|
||||
* into
|
||||
* @code
|
||||
* $library['files']['js'] = array(
|
||||
* 'example_1.js' => array(),
|
||||
* 'example_2.js' => array(),
|
||||
* );
|
||||
* @endcode
|
||||
* It does the same for the 'integration files' property.
|
||||
*
|
||||
* @param $library
|
||||
* An associative array of library information or a part of it, passed by
|
||||
* reference.
|
||||
* @param $version
|
||||
* If the library information belongs to a specific version, the version
|
||||
* string. NULL otherwise.
|
||||
* @param $variant
|
||||
* If the library information belongs to a specific variant, the variant name.
|
||||
* NULL otherwise.
|
||||
*
|
||||
* @see libraries_info()
|
||||
* @see libraries_invoke()
|
||||
*/
|
||||
function libraries_prepare_files(&$library, $version = NULL, $variant = NULL) {
|
||||
// Both the 'files' property and the 'integration files' property contain file
|
||||
// declarations, and we want to make both consistent.
|
||||
$file_types = array();
|
||||
if (isset($library['files'])) {
|
||||
$file_types[] = &$library['files'];
|
||||
}
|
||||
if (isset($library['integration files'])) {
|
||||
// Integration files are additionally keyed by module.
|
||||
foreach ($library['integration files'] as &$integration_files) {
|
||||
$file_types[] = &$integration_files;
|
||||
}
|
||||
}
|
||||
foreach ($file_types as &$files) {
|
||||
// Go through all supported types of files.
|
||||
foreach (array('js', 'css', 'php') as $type) {
|
||||
if (isset($files[$type])) {
|
||||
foreach ($files[$type] as $key => $value) {
|
||||
// Unset numeric keys and turn the respective values into keys.
|
||||
if (is_numeric($key)) {
|
||||
$files[$type][$value] = array();
|
||||
unset($files[$type][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Library post-detect callback to process and detect dependencies.
|
||||
*
|
||||
* It checks whether each of the dependencies of a library are installed and
|
||||
* available in a compatible version.
|
||||
*
|
||||
* @param $library
|
||||
* An associative array of library information or a part of it, passed by
|
||||
* reference.
|
||||
* @param $version
|
||||
* If the library information belongs to a specific version, the version
|
||||
* string. NULL otherwise.
|
||||
* @param $variant
|
||||
* If the library information belongs to a specific variant, the variant name.
|
||||
* NULL otherwise.
|
||||
*
|
||||
* @see libraries_info()
|
||||
* @see libraries_invoke()
|
||||
*/
|
||||
function libraries_detect_dependencies(&$library, $version = NULL, $variant = NULL) {
|
||||
if (isset($library['dependencies'])) {
|
||||
foreach ($library['dependencies'] as &$dependency_string) {
|
||||
$dependency_info = drupal_parse_dependency($dependency_string);
|
||||
$dependency = libraries_detect($dependency_info['name']);
|
||||
if (!$dependency['installed']) {
|
||||
$library['installed'] = FALSE;
|
||||
$library['error'] = 'missing dependency';
|
||||
$library['error message'] = t('The %dependency library, which the %library library depends on, is not installed.', array(
|
||||
'%dependency' => $dependency['name'],
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
}
|
||||
elseif (drupal_check_incompatibility($dependency_info, $dependency['version'])) {
|
||||
$library['installed'] = FALSE;
|
||||
$library['error'] = 'incompatible dependency';
|
||||
$library['error message'] = t('The version %dependency_version of the %dependency library is not compatible with the %library library.', array(
|
||||
'%dependency_version' => $dependency['version'],
|
||||
'%dependency' => $dependency['name'],
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
}
|
||||
|
||||
// Remove the version string from the dependency, so libraries_load() can
|
||||
// load the libraries directly.
|
||||
$dependency_string = $dependency_info['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about registered libraries.
|
||||
*
|
||||
* The returned information is unprocessed; i.e., as registered by modules.
|
||||
*
|
||||
* @param $name
|
||||
* (optional) The machine name of a library to return registered information
|
||||
* for. If omitted, information about all registered libraries is returned.
|
||||
*
|
||||
* @return array|false
|
||||
* An associative array containing registered information for all libraries,
|
||||
* the registered information for the library specified by $name, or FALSE if
|
||||
* the library $name is not registered.
|
||||
*
|
||||
* @see hook_libraries_info()
|
||||
*
|
||||
* @todo Re-introduce support for include file plugin system - either by copying
|
||||
* Wysiwyg's code, or directly switching to CTools.
|
||||
*/
|
||||
function &libraries_info($name = NULL) {
|
||||
// This static cache is re-used by libraries_detect() to save memory.
|
||||
$libraries = &drupal_static(__FUNCTION__);
|
||||
|
||||
if (!isset($libraries)) {
|
||||
$libraries = array();
|
||||
|
||||
// Gather information from hook_libraries_info() in enabled modules.
|
||||
foreach (module_implements('libraries_info') as $module) {
|
||||
foreach (module_invoke($module, 'libraries_info') as $machine_name => $properties) {
|
||||
$properties['info type'] = 'module';
|
||||
$properties['module'] = $module;
|
||||
$libraries[$machine_name] = $properties;
|
||||
}
|
||||
}
|
||||
|
||||
// Gather information from hook_libraries_info() in enabled themes.
|
||||
$themes = array();
|
||||
foreach (list_themes() as $theme_name => $theme_info) {
|
||||
if ($theme_info->status && file_exists(drupal_get_path('theme', $theme_name) . '/template.php')) {
|
||||
// Collect a list of viable themes for re-use when calling the alter
|
||||
// hook.
|
||||
$themes[] = $theme_name;
|
||||
|
||||
include_once drupal_get_path('theme', $theme_name) . '/template.php';
|
||||
|
||||
$function = $theme_name . '_libraries_info';
|
||||
if (function_exists($function)) {
|
||||
foreach ($function() as $machine_name => $properties) {
|
||||
$properties['info type'] = 'theme';
|
||||
$properties['theme'] = $theme_name;
|
||||
$libraries[$machine_name] = $properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gather information from .info files.
|
||||
// .info files override module definitions.
|
||||
foreach (libraries_scan_info_files() as $machine_name => $file) {
|
||||
$properties = drupal_parse_info_file($file->uri);
|
||||
$properties['info type'] = 'info file';
|
||||
$properties['info file'] = $file->uri;
|
||||
$libraries[$machine_name] = $properties;
|
||||
}
|
||||
|
||||
// Provide defaults.
|
||||
foreach ($libraries as $machine_name => &$properties) {
|
||||
libraries_info_defaults($properties, $machine_name);
|
||||
}
|
||||
|
||||
// Allow enabled modules and themes to alter the registered libraries.
|
||||
// drupal_alter() only takes the currently active theme into account, not
|
||||
// all enabled themes.
|
||||
foreach (module_implements('libraries_info_alter') as $module) {
|
||||
$function = $module . '_libraries_info_alter';
|
||||
$function($libraries);
|
||||
}
|
||||
foreach ($themes as $theme) {
|
||||
$function = $theme . '_libraries_info_alter';
|
||||
// The template.php file was included above.
|
||||
if (function_exists($function)) {
|
||||
$function($libraries);
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke callbacks in the 'info' group.
|
||||
foreach ($libraries as &$properties) {
|
||||
libraries_invoke('info', $properties);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($name)) {
|
||||
if (!empty($libraries[$name])) {
|
||||
return $libraries[$name];
|
||||
}
|
||||
else {
|
||||
$false = FALSE;
|
||||
return $false;
|
||||
}
|
||||
}
|
||||
return $libraries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies default properties to a library definition.
|
||||
*
|
||||
* @param array $library
|
||||
* An array of library information, passed by reference.
|
||||
* @param string $name
|
||||
* The machine name of the passed-in library.
|
||||
*
|
||||
* @return array
|
||||
* The library information array with defaults populated.
|
||||
*/
|
||||
function libraries_info_defaults(array &$library, $name) {
|
||||
$library += array(
|
||||
'machine name' => $name,
|
||||
'name' => $name,
|
||||
'vendor url' => '',
|
||||
'download url' => '',
|
||||
'download file url' => '',
|
||||
'path' => '',
|
||||
'library path' => NULL,
|
||||
'version callback' => 'libraries_get_version',
|
||||
'version arguments' => array(),
|
||||
'files' => array(),
|
||||
'dependencies' => array(),
|
||||
'variants' => array(),
|
||||
'versions' => array(),
|
||||
'integration files' => array(),
|
||||
'callbacks' => array(),
|
||||
// @todo Remove in 7.x-3.x
|
||||
'post-load integration files' => FALSE,
|
||||
);
|
||||
$library['callbacks'] += array(
|
||||
'info' => array(),
|
||||
'pre-detect' => array(),
|
||||
'post-detect' => array(),
|
||||
'pre-dependencies-load' => array(),
|
||||
'pre-load' => array(),
|
||||
'post-load' => array(),
|
||||
);
|
||||
|
||||
// Add our own callbacks before any others.
|
||||
array_unshift($library['callbacks']['info'], 'libraries_prepare_files');
|
||||
array_unshift($library['callbacks']['post-detect'], 'libraries_detect_dependencies');
|
||||
|
||||
return $library;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to detect a library and its installed version.
|
||||
*
|
||||
* @param string $name
|
||||
* (optional) The machine name of a library to detect and return registered
|
||||
* information for. If omitted, information about all registered libraries is
|
||||
* returned.
|
||||
*
|
||||
* @return array|false
|
||||
* An associative array containing registered information for all libraries,
|
||||
* the registered information for the library specified by $name, or FALSE if
|
||||
* the library $name is not registered.
|
||||
* In addition to the keys returned by libraries_info(), the following keys
|
||||
* are contained:
|
||||
* - installed: A boolean indicating whether the library is installed. Note
|
||||
* that not only the top-level library, but also each variant contains this
|
||||
* key.
|
||||
* - version: If the version could be detected, the full version string.
|
||||
* - error: If an error occurred during library detection, one of the
|
||||
* following error statuses: "not found", "not detected", "not supported".
|
||||
* - error message: If an error occurred during library detection, a detailed
|
||||
* error message.
|
||||
*
|
||||
* @see libraries_info()
|
||||
*/
|
||||
function libraries_detect($name = NULL) {
|
||||
if (!isset($name)) {
|
||||
$libraries = &libraries_info();
|
||||
foreach ($libraries as $name => $library) {
|
||||
libraries_detect($name);
|
||||
}
|
||||
return $libraries;
|
||||
}
|
||||
|
||||
// Re-use the statically cached value of libraries_info() to save memory.
|
||||
$library = &libraries_info($name);
|
||||
|
||||
// Exit early if the library was not found.
|
||||
if ($library === FALSE) {
|
||||
return $library;
|
||||
}
|
||||
|
||||
// If 'installed' is set, library detection ran already.
|
||||
if (isset($library['installed'])) {
|
||||
return $library;
|
||||
}
|
||||
|
||||
$library['installed'] = FALSE;
|
||||
|
||||
// Check whether the library exists.
|
||||
if (!isset($library['library path'])) {
|
||||
$library['library path'] = libraries_get_path($library['machine name']);
|
||||
}
|
||||
if ($library['library path'] === FALSE || !file_exists($library['library path'])) {
|
||||
$library['error'] = 'not found';
|
||||
$library['error message'] = t('The %library library could not be found.', array(
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
return $library;
|
||||
}
|
||||
|
||||
// Invoke callbacks in the 'pre-detect' group.
|
||||
libraries_invoke('pre-detect', $library);
|
||||
|
||||
// Detect library version, if not hardcoded.
|
||||
if (!isset($library['version'])) {
|
||||
// We support both a single parameter, which is an associative array, and an
|
||||
// indexed array of multiple parameters.
|
||||
if (isset($library['version arguments'][0])) {
|
||||
// Add the library as the first argument.
|
||||
$library['version'] = call_user_func_array($library['version callback'], array_merge(array($library), $library['version arguments']));
|
||||
}
|
||||
else {
|
||||
$library['version'] = call_user_func($library['version callback'], $library, $library['version arguments']);
|
||||
}
|
||||
if (empty($library['version'])) {
|
||||
$library['error'] = 'not detected';
|
||||
$library['error message'] = t('The version of the %library library could not be detected.', array(
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
return $library;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine to which supported version the installed version maps.
|
||||
if (!empty($library['versions'])) {
|
||||
ksort($library['versions']);
|
||||
$version = 0;
|
||||
foreach ($library['versions'] as $supported_version => $version_properties) {
|
||||
if (version_compare($library['version'], $supported_version, '>=')) {
|
||||
$version = $supported_version;
|
||||
}
|
||||
}
|
||||
if (!$version) {
|
||||
$library['error'] = 'not supported';
|
||||
$library['error message'] = t('The installed version %version of the %library library is not supported.', array(
|
||||
'%version' => $library['version'],
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
return $library;
|
||||
}
|
||||
|
||||
// Apply version specific definitions and overrides.
|
||||
$library = array_merge($library, $library['versions'][$version]);
|
||||
unset($library['versions']);
|
||||
}
|
||||
|
||||
// Check each variant if it is installed.
|
||||
if (!empty($library['variants'])) {
|
||||
foreach ($library['variants'] as $variant_name => &$variant) {
|
||||
// If no variant callback has been set, assume the variant to be
|
||||
// installed.
|
||||
if (!isset($variant['variant callback'])) {
|
||||
$variant['installed'] = TRUE;
|
||||
}
|
||||
else {
|
||||
// We support both a single parameter, which is an associative array,
|
||||
// and an indexed array of multiple parameters.
|
||||
if (isset($variant['variant arguments'][0])) {
|
||||
// Add the library as the first argument, and the variant name as the second.
|
||||
$variant['installed'] = call_user_func_array($variant['variant callback'], array_merge(array($library, $variant_name), $variant['variant arguments']));
|
||||
}
|
||||
else {
|
||||
$variant['installed'] = $variant['variant callback']($library, $variant_name, $variant['variant arguments']);
|
||||
}
|
||||
if (!$variant['installed']) {
|
||||
$variant['error'] = 'not found';
|
||||
$variant['error message'] = t('The %variant variant of the %library library could not be found.', array(
|
||||
'%variant' => $variant_name,
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we end up here, the library should be usable.
|
||||
$library['installed'] = TRUE;
|
||||
|
||||
// Invoke callbacks in the 'post-detect' group.
|
||||
libraries_invoke('post-detect', $library);
|
||||
|
||||
return $library;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a library.
|
||||
*
|
||||
* @param $name
|
||||
* The name of the library to load.
|
||||
* @param $variant
|
||||
* The name of the variant to load. Note that only one variant of a library
|
||||
* can be loaded within a single request. The variant that has been passed
|
||||
* first is used; different variant names in subsequent calls are ignored.
|
||||
*
|
||||
* @return
|
||||
* An associative array of the library information as returned from
|
||||
* libraries_info(). The top-level properties contain the effective definition
|
||||
* of the library (variant) that has been loaded. Additionally:
|
||||
* - installed: Whether the library is installed, as determined by
|
||||
* libraries_detect_library().
|
||||
* - loaded: Either the amount of library files that have been loaded, or
|
||||
* FALSE if the library could not be loaded.
|
||||
* See hook_libraries_info() for more information.
|
||||
*/
|
||||
function libraries_load($name, $variant = NULL) {
|
||||
$loaded = &drupal_static(__FUNCTION__, array());
|
||||
|
||||
if (!isset($loaded[$name])) {
|
||||
$library = cache_get($name, 'cache_libraries');
|
||||
if ($library) {
|
||||
$library = $library->data;
|
||||
}
|
||||
else {
|
||||
$library = libraries_detect($name);
|
||||
cache_set($name, $library, 'cache_libraries');
|
||||
}
|
||||
|
||||
// Exit early if the library was not found.
|
||||
if ($library === FALSE) {
|
||||
$loaded[$name] = $library;
|
||||
return $loaded[$name];
|
||||
}
|
||||
|
||||
// If a variant was specified, override the top-level properties with the
|
||||
// variant properties.
|
||||
if (isset($variant)) {
|
||||
// Ensure that the $variant key exists, and if it does not, set its
|
||||
// 'installed' property to FALSE by default. This will prevent the loading
|
||||
// of the library files below.
|
||||
$library['variants'] += array($variant => array('installed' => FALSE));
|
||||
$library = array_merge($library, $library['variants'][$variant]);
|
||||
}
|
||||
// Regardless of whether a specific variant was requested or not, there can
|
||||
// only be one variant of a library within a single request.
|
||||
unset($library['variants']);
|
||||
|
||||
// Invoke callbacks in the 'pre-dependencies-load' group.
|
||||
libraries_invoke('pre-dependencies-load', $library);
|
||||
|
||||
// If the library (variant) is installed, load it.
|
||||
$library['loaded'] = FALSE;
|
||||
if ($library['installed']) {
|
||||
// Load library dependencies.
|
||||
if (isset($library['dependencies'])) {
|
||||
foreach ($library['dependencies'] as $dependency) {
|
||||
libraries_load($dependency);
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke callbacks in the 'pre-load' group.
|
||||
libraries_invoke('pre-load', $library);
|
||||
|
||||
// Load all the files associated with the library.
|
||||
$library['loaded'] = libraries_load_files($library);
|
||||
|
||||
// Invoke callbacks in the 'post-load' group.
|
||||
libraries_invoke('post-load', $library);
|
||||
}
|
||||
$loaded[$name] = $library;
|
||||
}
|
||||
|
||||
return $loaded[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a library's files.
|
||||
*
|
||||
* @param $library
|
||||
* An array of library information as returned by libraries_info().
|
||||
*
|
||||
* @return
|
||||
* The number of loaded files.
|
||||
*/
|
||||
function libraries_load_files($library) {
|
||||
// As this key was added after 7.x-2.1 cached library structures might not
|
||||
// have it.
|
||||
$library += array('post-load integration files' => FALSE);
|
||||
|
||||
// Load integration files.
|
||||
if (!$library['post-load integration files'] && !empty($library['integration files'])) {
|
||||
$enabled_themes = array();
|
||||
foreach (list_themes() as $theme_name => $theme) {
|
||||
if ($theme->status) {
|
||||
$enabled_themes[] = $theme_name;
|
||||
}
|
||||
}
|
||||
foreach ($library['integration files'] as $provider => $files) {
|
||||
if (module_exists($provider)) {
|
||||
libraries_load_files(array(
|
||||
'files' => $files,
|
||||
'path' => '',
|
||||
'library path' => drupal_get_path('module', $provider),
|
||||
'post-load integration files' => FALSE,
|
||||
));
|
||||
}
|
||||
elseif (in_array($provider, $enabled_themes)) {
|
||||
libraries_load_files(array(
|
||||
'files' => $files,
|
||||
'path' => '',
|
||||
'library path' => drupal_get_path('theme', $provider),
|
||||
'post-load integration files' => FALSE,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the full path to the library for later use.
|
||||
$path = $library['library path'];
|
||||
$path = ($library['path'] !== '' ? $path . '/' . $library['path'] : $path);
|
||||
|
||||
// Count the number of loaded files for the return value.
|
||||
$count = 0;
|
||||
|
||||
// Load both the JavaScript and the CSS files.
|
||||
// The parameters for drupal_add_js() and drupal_add_css() require special
|
||||
// handling.
|
||||
// @see drupal_process_attached()
|
||||
foreach (array('js', 'css') as $type) {
|
||||
if (!empty($library['files'][$type])) {
|
||||
foreach ($library['files'][$type] as $data => $options) {
|
||||
// If the value is not an array, it's a filename and passed as first
|
||||
// (and only) argument.
|
||||
if (!is_array($options)) {
|
||||
$data = $options;
|
||||
$options = array();
|
||||
}
|
||||
// In some cases, the first parameter ($data) is an array. Arrays can't
|
||||
// be passed as keys in PHP, so we have to get $data from the value
|
||||
// array.
|
||||
if (is_numeric($data)) {
|
||||
$data = $options['data'];
|
||||
unset($options['data']);
|
||||
}
|
||||
// Prepend the library path to the file name.
|
||||
$data = "$path/$data";
|
||||
// Apply the default group if the group isn't explicitly given.
|
||||
if (!isset($options['group'])) {
|
||||
$options['group'] = ($type == 'js') ? JS_DEFAULT : CSS_DEFAULT;
|
||||
}
|
||||
call_user_func('drupal_add_' . $type, $data, $options);
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load PHP files.
|
||||
if (!empty($library['files']['php'])) {
|
||||
foreach ($library['files']['php'] as $file => $array) {
|
||||
$file_path = DRUPAL_ROOT . '/' . $path . '/' . $file;
|
||||
if (file_exists($file_path)) {
|
||||
_libraries_require_once($file_path);
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load integration files.
|
||||
if ($library['post-load integration files'] && !empty($library['integration files'])) {
|
||||
$enabled_themes = array();
|
||||
foreach (list_themes() as $theme_name => $theme) {
|
||||
if ($theme->status) {
|
||||
$enabled_themes[] = $theme_name;
|
||||
}
|
||||
}
|
||||
foreach ($library['integration files'] as $provider => $files) {
|
||||
if (module_exists($provider)) {
|
||||
libraries_load_files(array(
|
||||
'files' => $files,
|
||||
'path' => '',
|
||||
'library path' => drupal_get_path('module', $provider),
|
||||
'post-load integration files' => FALSE,
|
||||
));
|
||||
}
|
||||
elseif (in_array($provider, $enabled_themes)) {
|
||||
libraries_load_files(array(
|
||||
'files' => $files,
|
||||
'path' => '',
|
||||
'library path' => drupal_get_path('theme', $provider),
|
||||
'post-load integration files' => FALSE,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function for require_once.
|
||||
*
|
||||
* A library file could set a $path variable in file scope. Requiring such a
|
||||
* file directly in libraries_load_files() would lead to the local $path
|
||||
* variable being overridden after the require_once statement. This would
|
||||
* break loading further files. Therefore we use this trivial wrapper which has
|
||||
* no local state that can be tampered with.
|
||||
*
|
||||
* @param $file_path
|
||||
* The file path of the file to require.
|
||||
*/
|
||||
function _libraries_require_once($file_path) {
|
||||
require_once $file_path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the version information from an arbitrary library.
|
||||
*
|
||||
* @param $library
|
||||
* An associative array containing all information about the library.
|
||||
* @param $options
|
||||
* An associative array containing with the following keys:
|
||||
* - file: The filename to parse for the version, relative to the library
|
||||
* path. For example: 'docs/changelog.txt'.
|
||||
* - pattern: A string containing a regular expression (PCRE) to match the
|
||||
* library version. For example: '@version\s+([0-9a-zA-Z\.-]+)@'. Note that
|
||||
* the returned version is not the match of the entire pattern (i.e.
|
||||
* '@version 1.2.3' in the above example) but the match of the first
|
||||
* sub-pattern (i.e. '1.2.3' in the above example).
|
||||
* - lines: (optional) The maximum number of lines to search the pattern in.
|
||||
* Defaults to 20.
|
||||
* - cols: (optional) The maximum number of characters per line to take into
|
||||
* account. Defaults to 200. In case of minified or compressed files, this
|
||||
* prevents reading the entire file into memory.
|
||||
*
|
||||
* @return
|
||||
* A string containing the version of the library.
|
||||
*
|
||||
* @see libraries_get_path()
|
||||
*/
|
||||
function libraries_get_version($library, $options) {
|
||||
// Provide defaults.
|
||||
$options += array(
|
||||
'file' => '',
|
||||
'pattern' => '',
|
||||
'lines' => 20,
|
||||
'cols' => 200,
|
||||
);
|
||||
|
||||
$file = DRUPAL_ROOT . '/' . $library['library path'] . '/' . $options['file'];
|
||||
if (empty($options['file']) || !file_exists($file)) {
|
||||
return;
|
||||
}
|
||||
$file = fopen($file, 'r');
|
||||
while ($options['lines'] && $line = fgets($file, $options['cols'])) {
|
||||
if (preg_match($options['pattern'], $line, $version)) {
|
||||
fclose($file);
|
||||
return $version[1];
|
||||
}
|
||||
$options['lines']--;
|
||||
}
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
*/
|
||||
function libraries_help($path, $arg) {
|
||||
switch ($path) {
|
||||
case 'admin/reports/libraries':
|
||||
return t('Click on a library for a status report or detailed installation instructions in case the library is not installed correctly.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function libraries_menu() {
|
||||
$items = array();
|
||||
$items['admin/reports/libraries'] = array(
|
||||
'title' => 'Libraries',
|
||||
'description' => 'An overview of libraries installed on this site.',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('libraries_admin_overview'),
|
||||
'access arguments' => array('access site reports'),
|
||||
'file' => 'libraries.admin.inc'
|
||||
);
|
||||
$items['admin/reports/libraries/%libraries_ui'] = array(
|
||||
'title' => 'Library status report',
|
||||
'description' => 'Status overview for a single library',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('libraries_admin_library_status_form', 3),
|
||||
'access arguments' => array('access site reports'),
|
||||
'file' => 'libraries.admin.inc'
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads library information for display in the user interface.
|
||||
*
|
||||
* This can be used as a menu loader function by specifying a '%libraries_ui'
|
||||
* parameter in a path.
|
||||
*
|
||||
* We do not use libraries_load() (and, thus, a '%libraries' parameter) directly
|
||||
* for displaying library information in the user interface as we do not want
|
||||
* the library files to be loaded.
|
||||
*
|
||||
* @param string $name
|
||||
* The machine name of a library to return registered information for.
|
||||
*
|
||||
* @return array|false
|
||||
* An associative array containing registered information for the library
|
||||
* specified by $name, or FALSE if the library $name is not registered.
|
||||
*
|
||||
* @see libraries_detect()
|
||||
* @see libraries_menu()
|
||||
*/
|
||||
function libraries_ui_load($name) {
|
||||
return libraries_detect($name);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains LibrariesAdminWebTest.
|
||||
*
|
||||
* Simpletest automatically discovers test files using PSR-4. We cannot,
|
||||
* however, declare a namespace for this class, as that would require PHP 5.3.
|
||||
* To prepare the PHP 5.3 requirement and the usage of PSR-4 in 7.x-3.x, we
|
||||
* split each test class into its own file and use the correct base name, but
|
||||
* for now use the 'test' extension and register them explicitly in
|
||||
* libraries.info.
|
||||
*
|
||||
* @see simpletest_test_get_all()
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests the administrative interface for libraries.
|
||||
*/
|
||||
class LibrariesAdminWebTest extends LibrariesWebTestBase {
|
||||
|
||||
/**
|
||||
* Provides metadata about this test.
|
||||
*
|
||||
* @return array
|
||||
* An array of test metadata with the following keys:
|
||||
* - name: The name of the test.
|
||||
* - description: The description of the test.
|
||||
* - group: The group of the test.
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Libraries administration',
|
||||
'description' => 'Tests the administrative interface for libraries.',
|
||||
'group' => 'Libraries API',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the libraries report at /admin/reports/libraries.
|
||||
*/
|
||||
public function testLibrariesReportOverview() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries');
|
||||
$this->assertRaw('Libraries');
|
||||
|
||||
// Make sure that all the libraries are listed.
|
||||
$libraries = libraries_info();
|
||||
$this->assertTrue($libraries);
|
||||
foreach ($libraries as $library) {
|
||||
$this->assertText($library['name']);
|
||||
$this->assertLinkByHref('admin/reports/libraries/' . $library['machine name']);
|
||||
}
|
||||
|
||||
// Make sure that all possible statuses are displayed.
|
||||
$this->assertText('OK');
|
||||
$this->assertText('Not found');
|
||||
$this->assertText('Not detected');
|
||||
$this->assertText('Not supported');
|
||||
$this->assertText('Missing dependency');
|
||||
$this->assertText('Incompatible dependency');
|
||||
|
||||
// Make sure that the providers are displayed.
|
||||
$this->assertRaw('<em class="placeholder">Libraries test module</em> module');
|
||||
$this->assertRaw('<em class="placeholder">Libraries test theme</em> theme');
|
||||
$this->assertRaw('<em class="placeholder">example_info_file.libraries.info</em> info file');
|
||||
|
||||
// Make sure that homepage and download links are displayed.
|
||||
$this->assertLinkByHref('http://example.com');
|
||||
$this->assertLinkByHref('http://example.com/download');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the libraries report for an installed library.
|
||||
*/
|
||||
public function testLibrariesReportInstalled() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_files');
|
||||
$this->assertRaw('Status report for library <em class="placeholder">Example files</em>');
|
||||
$this->assertRaw('The <em class="placeholder">Example files</em> library is installed correctly.');
|
||||
// Check that the information in the status report is displayed.
|
||||
$this->assertText('Example files');
|
||||
$this->assertText('example_files');
|
||||
$this->assertRaw('<em class="placeholder">Libraries test module</em> module');
|
||||
$this->assertText(drupal_get_path('module', 'libraries') . '/tests/libraries/example');
|
||||
$this->assertText('1');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the libraries report for a missing library.
|
||||
*/
|
||||
public function testLibrariesReportMissing() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_missing');
|
||||
$this->assertRaw('Status report for library <em class="placeholder">Example missing</em>');
|
||||
$this->assertRaw('The <em class="placeholder">Example missing</em> library could not be found.');
|
||||
// Check that the download link is being displayed.
|
||||
$this->assertLinkByHref('http://example.com/download');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests the libraries report for a missing library.
|
||||
*/
|
||||
public function testLibrariesReportNotDetected() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_undetected_version');
|
||||
$this->assertRaw('Status report for library <em class="placeholder">Example undetected version</em>');
|
||||
$this->assertRaw('The version of the <em class="placeholder">Example undetected version</em> library could not be detected.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the libraries report for a missing library.
|
||||
*/
|
||||
public function testLibrariesReportNotSupported() {
|
||||
$this->getWithPermissions(array('access site reports'), 'admin/reports/libraries/example_unsupported_version');
|
||||
$this->assertRaw('Status report for library <em class="placeholder">Example unsupported version</em>');
|
||||
$this->assertRaw('The installed version <em class="placeholder">1</em> of the <em class="placeholder">Example unsupported version</em> library is not supported.');
|
||||
// Check that the download link is being displayed.
|
||||
$this->assertLinkByHref('http://example.com/download');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,543 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains LibrariesLoadWebTest.
|
||||
*
|
||||
* Simpletest automatically discovers test files using PSR-4. We cannot,
|
||||
* however, declare a namespace for this class, as that would require PHP 5.3.
|
||||
* To prepare the PHP 5.3 requirement and the usage of PSR-4 in 7.x-3.x, we
|
||||
* place the test files in the correct directory already, but for now register
|
||||
* them explicitly in libraries.info
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests basic detection and loading of libraries.
|
||||
*/
|
||||
class LibrariesLoadWebTest extends LibrariesWebTestBase {
|
||||
|
||||
/**
|
||||
* Provides metadata about this test.
|
||||
*
|
||||
* @return array
|
||||
* An array of test metadata with the following keys:
|
||||
* - name: The name of the test.
|
||||
* - description: The description of the test.
|
||||
* - group: The group of the test.
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Libraries detection and loading',
|
||||
'description' => 'Tests detection and loading of libraries.',
|
||||
'group' => 'Libraries API',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries_detect_dependencies().
|
||||
*/
|
||||
public function testLibrariesDetectDependencies() {
|
||||
$library = array(
|
||||
'name' => 'Example',
|
||||
'dependencies' => array('example_missing'),
|
||||
);
|
||||
libraries_detect_dependencies($library);
|
||||
$this->assertEqual($library['error'], 'missing dependency', 'libraries_detect_dependencies() detects missing dependency');
|
||||
$error_message = t('The %dependency library, which the %library library depends on, is not installed.', array(
|
||||
'%dependency' => 'Example missing',
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
$this->verbose("Expected:<br>$error_message");
|
||||
$this->verbose('Actual:<br>' . $library['error message']);
|
||||
$this->assertEqual($library['error message'], $error_message, 'Correct error message for a missing dependency');
|
||||
// Test versioned dependencies.
|
||||
$version = '1.1';
|
||||
$compatible = array(
|
||||
'1.1',
|
||||
'<=1.1',
|
||||
'>=1.1',
|
||||
'<1.2',
|
||||
'<2.0',
|
||||
'>1.0',
|
||||
'>1.0-rc1',
|
||||
'>1.0-beta2',
|
||||
'>1.0-alpha3',
|
||||
'>0.1',
|
||||
'<1.2, >1.0',
|
||||
'>0.1, <=1.1',
|
||||
);
|
||||
$incompatible = array(
|
||||
'1.2',
|
||||
'2.0',
|
||||
'<1.1',
|
||||
'>1.1',
|
||||
'<=1.0',
|
||||
'<=1.0-rc1',
|
||||
'<=1.0-beta2',
|
||||
'<=1.0-alpha3',
|
||||
'>=1.2',
|
||||
'<1.1, >0.9',
|
||||
'>=0.1, <1.1',
|
||||
);
|
||||
$library = array(
|
||||
'name' => 'Example',
|
||||
);
|
||||
foreach ($compatible as $version_string) {
|
||||
$library['dependencies'][0] = "example_dependency ($version_string)";
|
||||
// libraries_detect_dependencies() is a post-detect callback, so
|
||||
// 'installed' is already set, when it is called. It sets the value to
|
||||
// FALSE for missing or incompatible dependencies.
|
||||
$library['installed'] = TRUE;
|
||||
libraries_detect_dependencies($library);
|
||||
$this->verbose('Library:<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertTrue($library['installed'], "libraries_detect_dependencies() detects compatible version string: '$version_string' is compatible with '$version'");
|
||||
}
|
||||
foreach ($incompatible as $version_string) {
|
||||
$library['dependencies'][0] = "example_dependency ($version_string)";
|
||||
$library['installed'] = TRUE;
|
||||
unset($library['error'], $library['error message']);
|
||||
libraries_detect_dependencies($library);
|
||||
$this->verbose('Library:<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['error'], 'incompatible dependency', "libraries_detect_dependencies() detects incompatible version strings: '$version_string' is incompatible with '$version'");
|
||||
}
|
||||
// Instead of repeating this assertion for each version string, we just
|
||||
// re-use the $library variable from the foreach loop.
|
||||
$error_message = t('The version %dependency_version of the %dependency library is not compatible with the %library library.', array(
|
||||
'%dependency_version' => $version,
|
||||
'%dependency' => 'Example dependency',
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
$this->verbose("Expected:<br>$error_message");
|
||||
$this->verbose('Actual:<br>' . $library['error message']);
|
||||
$this->assertEqual($library['error message'], $error_message, 'Correct error message for an incompatible dependency');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries_scan_info_files().
|
||||
*/
|
||||
public function testLibrariesScanInfoFiles() {
|
||||
$expected = array('example_info_file' => (object) array(
|
||||
'uri' => drupal_get_path('module', 'libraries') . '/tests/libraries/example_info_file.libraries.info',
|
||||
'filename' => 'example_info_file.libraries.info',
|
||||
'name' => 'example_info_file.libraries',
|
||||
));
|
||||
$this->assertEqual(libraries_scan_info_files(), $expected, 'libraries_scan_info_files() correctly finds the example info file.');
|
||||
$this->verbose('<pre>' . var_export(libraries_scan_info_files(), TRUE) . '</pre>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries_info().
|
||||
*/
|
||||
public function testLibrariesInfo() {
|
||||
// Test that modules can provide and alter library information.
|
||||
$info = libraries_info();
|
||||
$this->assertTrue(isset($info['example_module']));
|
||||
$this->verbose('Library:<pre>' . var_export($info['example_module'], TRUE) . '</pre>');
|
||||
$this->assertEqual($info['example_module']['info type'], 'module');
|
||||
$this->assertEqual($info['example_module']['module'], 'libraries_test_module');
|
||||
$this->assertTrue($info['example_module']['module_altered']);
|
||||
|
||||
// Test that themes can provide and alter library information.
|
||||
$this->assertTrue(isset($info['example_theme']));
|
||||
$this->verbose('Library:<pre>' . var_export($info['example_theme'], TRUE) . '</pre>');
|
||||
$this->assertEqual($info['example_theme']['info type'], 'theme');
|
||||
$this->assertEqual($info['example_theme']['theme'], 'libraries_test_theme');
|
||||
$this->assertTrue($info['example_theme']['theme_altered']);
|
||||
|
||||
// Test that library information is found correctly.
|
||||
$expected = array(
|
||||
'name' => 'Example files',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'files' => array(
|
||||
'js' => array('example_1.js' => array()),
|
||||
'css' => array('example_1.css' => array()),
|
||||
'php' => array('example_1.php' => array()),
|
||||
),
|
||||
'info type' => 'module',
|
||||
'module' => 'libraries_test_module',
|
||||
);
|
||||
libraries_info_defaults($expected, 'example_files');
|
||||
$library = libraries_info('example_files');
|
||||
$this->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
|
||||
$this->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library, $expected, 'Library information is correctly gathered.');
|
||||
|
||||
// Test a library specified with an .info file gets detected.
|
||||
$expected = array(
|
||||
'name' => 'Example info file',
|
||||
'info type' => 'info file',
|
||||
'info file' => drupal_get_path('module', 'libraries') . '/tests/libraries/example_info_file.libraries.info',
|
||||
);
|
||||
libraries_info_defaults($expected, 'example_info_file');
|
||||
$library = libraries_info('example_info_file');
|
||||
// If this module was downloaded from Drupal.org, the Drupal.org packaging
|
||||
// system has corrupted the test info file.
|
||||
// @see http://drupal.org/node/1606606
|
||||
unset($library['core'], $library['datestamp'], $library['project'], $library['version']);
|
||||
$this->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
|
||||
$this->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library, $expected, 'Library specified with an .info file found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries_detect().
|
||||
*/
|
||||
public function testLibrariesDetect() {
|
||||
// Test missing library.
|
||||
$library = libraries_detect('example_missing');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['error'], 'not found', 'Missing library not found.');
|
||||
$error_message = t('The %library library could not be found.', array(
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
$this->assertEqual($library['error message'], $error_message, 'Correct error message for a missing library.');
|
||||
|
||||
// Test unknown library version.
|
||||
$library = libraries_detect('example_undetected_version');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['error'], 'not detected', 'Undetected version detected as such.');
|
||||
$error_message = t('The version of the %library library could not be detected.', array(
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
$this->assertEqual($library['error message'], $error_message, 'Correct error message for a library with an undetected version.');
|
||||
|
||||
// Test unsupported library version.
|
||||
$library = libraries_detect('example_unsupported_version');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['error'], 'not supported', 'Unsupported version detected as such.');
|
||||
$error_message = t('The installed version %version of the %library library is not supported.', array(
|
||||
'%version' => $library['version'],
|
||||
'%library' => $library['name'],
|
||||
));
|
||||
$this->assertEqual($library['error message'], $error_message, 'Correct error message for a library with an unsupported version.');
|
||||
|
||||
// Test supported library version.
|
||||
$library = libraries_detect('example_supported_version');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['installed'], TRUE, 'Supported library version found.');
|
||||
|
||||
// Test libraries_get_version().
|
||||
$library = libraries_detect('example_default_version_callback');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['version'], '1', 'Expected version returned by default version callback.');
|
||||
|
||||
// Test a multiple-parameter version callback.
|
||||
$library = libraries_detect('example_multiple_parameter_version_callback');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['version'], '1', 'Expected version returned by multiple parameter version callback.');
|
||||
|
||||
// Test a top-level files property.
|
||||
$library = libraries_detect('example_files');
|
||||
$files = array(
|
||||
'js' => array('example_1.js' => array()),
|
||||
'css' => array('example_1.css' => array()),
|
||||
'php' => array('example_1.php' => array()),
|
||||
);
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['files'], $files, 'Top-level files property works.');
|
||||
|
||||
// Test version-specific library files.
|
||||
$library = libraries_detect('example_versions');
|
||||
$files = array(
|
||||
'js' => array('example_2.js' => array()),
|
||||
'css' => array('example_2.css' => array()),
|
||||
'php' => array('example_2.php' => array()),
|
||||
);
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['files'], $files, 'Version-specific library files found.');
|
||||
|
||||
// Test missing variant.
|
||||
$library = libraries_detect('example_variant_missing');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['variants']['example_variant']['error'], 'not found', 'Missing variant not found');
|
||||
$error_message = t('The %variant variant of the %library library could not be found.', array(
|
||||
'%variant' => 'example_variant',
|
||||
'%library' => 'Example variant missing',
|
||||
));
|
||||
$this->assertEqual($library['variants']['example_variant']['error message'], $error_message, 'Correct error message for a missing variant.');
|
||||
|
||||
// Test existing variant.
|
||||
$library = libraries_detect('example_variant');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['variants']['example_variant']['installed'], TRUE, 'Existing variant found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries_detect() without a $name parameter.
|
||||
*/
|
||||
public function testLibrariesDetectAll() {
|
||||
// Test that an array with all library information is returned and that the
|
||||
// libraries are properly detected.
|
||||
$libraries = libraries_detect();
|
||||
$this->verbose('<pre>' . var_export($libraries, TRUE) . '</pre>');
|
||||
$this->assertEqual($libraries['example_missing']['error'], 'not found');
|
||||
$this->assertEqual($libraries['example_undetected_version']['error'], 'not detected');
|
||||
$this->assertEqual($libraries['example_unsupported_version']['error'], 'not supported');
|
||||
$this->assertEqual($libraries['example_supported_version']['installed'], TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries_load().
|
||||
*/
|
||||
public function testLibrariesLoad() {
|
||||
// Test dependencies.
|
||||
$library = libraries_load('example_dependency_missing');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertFalse($library['loaded'], 'Library with missing dependency cannot be loaded');
|
||||
$library = libraries_load('example_dependency_incompatible');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertFalse($library['loaded'], 'Library with incompatible dependency cannot be loaded');
|
||||
$library = libraries_load('example_dependency_compatible');
|
||||
$this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library['loaded'], 1, 'Library with compatible dependency is loaded');
|
||||
$loaded = &drupal_static('libraries_load');
|
||||
$this->verbose('<pre>' . var_export($loaded, TRUE) . '</pre>');
|
||||
$this->assertEqual($loaded['example_dependency']['loaded'], 1, 'Dependency library is also loaded');
|
||||
|
||||
// Test that PHP files that have a local $path variable do not break library
|
||||
// loading.
|
||||
// @see _libraries_require_once()
|
||||
$library = libraries_load('example_path_variable_override');
|
||||
$this->assertEqual($library['loaded'], 2, 'PHP files cannot break library loading.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the applying of callbacks.
|
||||
*/
|
||||
public function testCallbacks() {
|
||||
$expected = array(
|
||||
'name' => 'Example callback',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'versions' => array(
|
||||
'1' => array(
|
||||
'variants' => array(
|
||||
'example_variant' => array(
|
||||
'info callback' => 'not applied',
|
||||
'pre-detect callback' => 'not applied',
|
||||
'post-detect callback' => 'not applied',
|
||||
'pre-dependencies-load callback' => 'not applied',
|
||||
'pre-load callback' => 'not applied',
|
||||
'post-load callback' => 'not applied',
|
||||
),
|
||||
),
|
||||
'info callback' => 'not applied',
|
||||
'pre-detect callback' => 'not applied',
|
||||
'post-detect callback' => 'not applied',
|
||||
'pre-dependencies-load callback' => 'not applied',
|
||||
'pre-load callback' => 'not applied',
|
||||
'post-load callback' => 'not applied',
|
||||
),
|
||||
),
|
||||
'variants' => array(
|
||||
'example_variant' => array(
|
||||
'info callback' => 'not applied',
|
||||
'pre-detect callback' => 'not applied',
|
||||
'post-detect callback' => 'not applied',
|
||||
'pre-dependencies-load callback' => 'not applied',
|
||||
'pre-load callback' => 'not applied',
|
||||
'post-load callback' => 'not applied',
|
||||
),
|
||||
),
|
||||
'callbacks' => array(
|
||||
'info' => array('_libraries_test_module_info_callback'),
|
||||
'pre-detect' => array('_libraries_test_module_pre_detect_callback'),
|
||||
'post-detect' => array('_libraries_test_module_post_detect_callback'),
|
||||
'pre-dependencies-load' => array('_libraries_test_module_pre_dependencies_load_callback'),
|
||||
'pre-load' => array('_libraries_test_module_pre_load_callback'),
|
||||
'post-load' => array('_libraries_test_module_post_load_callback'),
|
||||
),
|
||||
'info callback' => 'not applied',
|
||||
'pre-detect callback' => 'not applied',
|
||||
'post-detect callback' => 'not applied',
|
||||
'pre-dependencies-load callback' => 'not applied',
|
||||
'pre-load callback' => 'not applied',
|
||||
'post-load callback' => 'not applied',
|
||||
'info type' => 'module',
|
||||
'module' => 'libraries_test_module',
|
||||
);
|
||||
libraries_info_defaults($expected, 'example_callback');
|
||||
|
||||
// Test a callback in the 'info' group.
|
||||
$expected['info callback'] = 'applied (top-level)';
|
||||
$expected['versions']['1']['info callback'] = 'applied (version 1)';
|
||||
$expected['versions']['1']['variants']['example_variant']['info callback'] = 'applied (version 1, variant example_variant)';
|
||||
$expected['variants']['example_variant']['info callback'] = 'applied (variant example_variant)';
|
||||
$library = libraries_info('example_callback');
|
||||
$this->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
|
||||
$this->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library, $expected, 'Prepare callback was applied correctly.');
|
||||
|
||||
// Test a callback in the 'pre-detect' and 'post-detect' phases.
|
||||
// Successfully detected libraries should only contain version information
|
||||
// for the detected version and thus, be marked as installed.
|
||||
unset($expected['versions']);
|
||||
$expected['installed'] = TRUE;
|
||||
// Additionally, version-specific properties of the detected version are
|
||||
// supposed to override the corresponding top-level properties.
|
||||
$expected['info callback'] = 'applied (version 1)';
|
||||
$expected['variants']['example_variant']['installed'] = TRUE;
|
||||
$expected['variants']['example_variant']['info callback'] = 'applied (version 1, variant example_variant)';
|
||||
// Version-overloading takes place after the 'pre-detect' callbacks have
|
||||
// been applied.
|
||||
$expected['pre-detect callback'] = 'applied (version 1)';
|
||||
$expected['post-detect callback'] = 'applied (top-level)';
|
||||
$expected['variants']['example_variant']['pre-detect callback'] = 'applied (version 1, variant example_variant)';
|
||||
$expected['variants']['example_variant']['post-detect callback'] = 'applied (variant example_variant)';
|
||||
$library = libraries_detect('example_callback');
|
||||
$this->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
|
||||
$this->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library, $expected, 'Detect callback was applied correctly.');
|
||||
|
||||
// Test a callback in the 'pre-dependencies-load', 'pre-load' and
|
||||
// 'post-load' phases.
|
||||
// Successfully loaded libraries should only contain information about the
|
||||
// already loaded variant.
|
||||
unset($expected['variants']);
|
||||
$expected['loaded'] = 0;
|
||||
$expected['pre-dependencies-load callback'] = 'applied (top-level)';
|
||||
$expected['pre-load callback'] = 'applied (top-level)';
|
||||
$expected['post-load callback'] = 'applied (top-level)';
|
||||
$library = libraries_load('example_callback');
|
||||
$this->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
|
||||
$this->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library, $expected, 'Pre-load and post-load callbacks were applied correctly.');
|
||||
// This is not recommended usually and is only used for testing purposes.
|
||||
drupal_static_reset('libraries_load');
|
||||
// Successfully loaded library variants are supposed to contain the specific
|
||||
// variant information only.
|
||||
$expected['info callback'] = 'applied (version 1, variant example_variant)';
|
||||
$expected['pre-detect callback'] = 'applied (version 1, variant example_variant)';
|
||||
$expected['post-detect callback'] = 'applied (variant example_variant)';
|
||||
$library = libraries_load('example_callback', 'example_variant');
|
||||
$this->verbose('Expected:<pre>' . var_export($expected, TRUE) . '</pre>');
|
||||
$this->verbose('Actual:<pre>' . var_export($library, TRUE) . '</pre>');
|
||||
$this->assertEqual($library, $expected, 'Pre-detect and post-detect callbacks were applied correctly to a variant.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that library files are properly added to the page output.
|
||||
*
|
||||
* We check for JavaScript and CSS files directly in the DOM and add a list of
|
||||
* included PHP files manually to the page output.
|
||||
*
|
||||
* @see _libraries_test_module_load()
|
||||
*/
|
||||
public function testLibrariesOutput() {
|
||||
// Test loading of a simple library with a top-level files property.
|
||||
$this->drupalGet('libraries-test-module/files');
|
||||
$this->assertLibraryFiles('example_1', 'File loading');
|
||||
|
||||
// Test loading of integration files.
|
||||
$this->drupalGet('libraries-test-module/module-integration-files');
|
||||
$this->assertRaw('libraries_test_module.js', 'Integration file loading: libraries_test_module.js found');
|
||||
$this->assertRaw('libraries_test_module.css', 'Integration file loading: libraries_test_module.css found');
|
||||
$this->assertRaw('libraries_test_module.inc', 'Integration file loading: libraries_test_module.inc found');
|
||||
$this->drupalGet('libraries-test-module/theme-integration-files');
|
||||
$this->assertRaw('libraries_test_theme.js', 'Integration file loading: libraries_test_theme.js found');
|
||||
$this->assertRaw('libraries_test_theme.css', 'Integration file loading: libraries_test_theme.css found');
|
||||
$this->assertRaw('libraries_test_theme.inc', 'Integration file loading: libraries_test_theme.inc found');
|
||||
|
||||
// Test loading of post-load integration files.
|
||||
$this->drupalGet('libraries-test-module/module-integration-files-post-load');
|
||||
// If the files were not loaded correctly, a fatal error occurs.
|
||||
$this->assertResponse(200, 'Post-load integration files are loaded correctly.');
|
||||
|
||||
// Test version overloading.
|
||||
$this->drupalGet('libraries-test-module/versions');
|
||||
$this->assertLibraryFiles('example_2', 'Version overloading');
|
||||
|
||||
// Test variant loading.
|
||||
$this->drupalGet('libraries-test-module/variant');
|
||||
$this->assertLibraryFiles('example_3', 'Variant loading');
|
||||
|
||||
// Test version overloading and variant loading.
|
||||
$this->drupalGet('libraries-test-module/versions-and-variants');
|
||||
$this->assertLibraryFiles('example_4', 'Concurrent version and variant overloading');
|
||||
|
||||
// Test caching.
|
||||
variable_set('libraries_test_module_cache', TRUE);
|
||||
cache_clear_all('example_callback', 'cache_libraries');
|
||||
// When the library information is not cached, all callback groups should be
|
||||
// invoked.
|
||||
$this->drupalGet('libraries-test-module/cache');
|
||||
$this->assertRaw('The <em>info</em> callback group was invoked.', 'Info callback invoked for uncached libraries.');
|
||||
$this->assertRaw('The <em>pre-detect</em> callback group was invoked.', 'Pre-detect callback invoked for uncached libraries.');
|
||||
$this->assertRaw('The <em>post-detect</em> callback group was invoked.', 'Post-detect callback invoked for uncached libraries.');
|
||||
$this->assertRaw('The <em>pre-load</em> callback group was invoked.', 'Pre-load callback invoked for uncached libraries.');
|
||||
$this->assertRaw('The <em>post-load</em> callback group was invoked.', 'Post-load callback invoked for uncached libraries.');
|
||||
// When the library information is cached only the 'pre-load' and
|
||||
// 'post-load' callback groups should be invoked.
|
||||
$this->drupalGet('libraries-test-module/cache');
|
||||
$this->assertNoRaw('The <em>info</em> callback group was not invoked.', 'Info callback not invoked for cached libraries.');
|
||||
$this->assertNoRaw('The <em>pre-detect</em> callback group was not invoked.', 'Pre-detect callback not invoked for cached libraries.');
|
||||
$this->assertNoRaw('The <em>post-detect</em> callback group was not invoked.', 'Post-detect callback not invoked for cached libraries.');
|
||||
$this->assertRaw('The <em>pre-load</em> callback group was invoked.', 'Pre-load callback invoked for cached libraries.');
|
||||
$this->assertRaw('The <em>post-load</em> callback group was invoked.', 'Post-load callback invoked for cached libraries.');
|
||||
variable_set('libraries_test_module_cache', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to assert that a library was correctly loaded.
|
||||
*
|
||||
* Asserts that all the correct files were loaded and all the incorrect ones
|
||||
* were not.
|
||||
*
|
||||
* @param $name
|
||||
* The name of the files that should be loaded. The current testing system
|
||||
* knows of 'example_1', 'example_2', 'example_3' and 'example_4'. Each name
|
||||
* has an associated JavaScript, CSS and PHP file that will be asserted. All
|
||||
* other files will be asserted to not be loaded. See
|
||||
* tests/example/README.txt for more information on how the loading of the
|
||||
* files is tested.
|
||||
* @param $label
|
||||
* (optional) A label to prepend to the assertion messages, to make them
|
||||
* less ambiguous.
|
||||
* @param $extensions
|
||||
* (optional) The expected file extensions of $name. Defaults to
|
||||
* array('js', 'css', 'php').
|
||||
*/
|
||||
public function assertLibraryFiles($name, $label = '', $extensions = array('js', 'css', 'php')) {
|
||||
$label = ($label !== '' ? "$label: " : '');
|
||||
|
||||
// Test that the wrong files are not loaded...
|
||||
$names = array(
|
||||
'example_1' => FALSE,
|
||||
'example_2' => FALSE,
|
||||
'example_3' => FALSE,
|
||||
'example_4' => FALSE,
|
||||
);
|
||||
// ...and the correct ones are.
|
||||
$names[$name] = TRUE;
|
||||
|
||||
// Test for the specific HTML that the different file types appear as in the
|
||||
// DOM.
|
||||
$html = array(
|
||||
'js' => array('<script type="text/javascript" src="', '"></script>'),
|
||||
'css' => array('@import url("', '");'),
|
||||
// PHP files do not get added to the DOM directly.
|
||||
// @see _libraries_test_load()
|
||||
'php' => array('<li>', '</li>'),
|
||||
);
|
||||
|
||||
foreach ($names as $name => $expected) {
|
||||
foreach ($extensions as $extension) {
|
||||
$filepath = drupal_get_path('module', 'libraries') . "/tests/libraries/example/$name.$extension";
|
||||
// JavaScript and CSS files appear as full URLs and with an appended
|
||||
// query string.
|
||||
if (in_array($extension, array('js', 'css'))) {
|
||||
$filepath = url('', array('absolute' => TRUE)) . $filepath . '?' . variable_get('css_js_query_string');
|
||||
}
|
||||
$raw = $html[$extension][0] . $filepath . $html[$extension][1];
|
||||
if ($expected) {
|
||||
$this->assertRaw($raw, "$label$name.$extension found.");
|
||||
}
|
||||
else {
|
||||
$this->assertNoRaw($raw, "$label$name.$extension not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains LibrariesUnitTest.
|
||||
*
|
||||
* Simpletest automatically discovers test files using PSR-4. We cannot,
|
||||
* however, declare a namespace for this class, as that would require PHP 5.3.
|
||||
* To prepare the PHP 5.3 requirement and the usage of PSR-4 in 7.x-3.x, we
|
||||
* place the test files in the correct directory already, but for now register
|
||||
* them explicitly in libraries.info.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests basic Libraries API functions.
|
||||
*/
|
||||
class LibrariesUnitTest extends DrupalUnitTestCase {
|
||||
|
||||
/**
|
||||
* Provides metadata about this test.
|
||||
*
|
||||
* @return array
|
||||
* An array of test metadata with the following keys:
|
||||
* - name: The name of the test.
|
||||
* - description: The description of the test.
|
||||
* - group: The group of the test.
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Libraries API unit tests',
|
||||
'description' => 'Tests basic functions provided by Libraries API.',
|
||||
'group' => 'Libraries API',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
drupal_load('module', 'libraries');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries_get_path().
|
||||
*/
|
||||
public function testLibrariesGetPath() {
|
||||
// Note that, even though libraries_get_path() doesn't find the 'example'
|
||||
// library, we are able to make it 'installed' by specifying the 'library
|
||||
// path' up-front. This is only used for testing purposed and is strongly
|
||||
// discouraged as it defeats the purpose of Libraries API in the first
|
||||
// place.
|
||||
$this->assertEqual(libraries_get_path('example'), FALSE, 'libraries_get_path() returns FALSE for a missing library.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests libraries_prepare_files().
|
||||
*/
|
||||
public function testLibrariesPrepareFiles() {
|
||||
$expected = array(
|
||||
'files' => array(
|
||||
'js' => array('example.js' => array()),
|
||||
'css' => array('example.css' => array()),
|
||||
'php' => array('example.php' => array()),
|
||||
),
|
||||
);
|
||||
$library = array(
|
||||
'files' => array(
|
||||
'js' => array('example.js'),
|
||||
'css' => array('example.css'),
|
||||
'php' => array('example.php'),
|
||||
),
|
||||
);
|
||||
libraries_prepare_files($library, NULL, NULL);
|
||||
$this->assertEqual($expected, $library, 'libraries_prepare_files() works correctly.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains LibrariesWebTestBase.
|
||||
*
|
||||
* Simpletest automatically discovers test files using PSR-4. We cannot,
|
||||
* however, declare a namespace for this class, as that would require PHP 5.3.
|
||||
* To prepare the PHP 5.3 requirement and the usage of PSR-4 in 7.x-3.x, we
|
||||
* place the test files in the correct directory already, but for now register
|
||||
* them explicitly in libraries.info
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for Libraries API web tests.
|
||||
*/
|
||||
abstract class LibrariesWebTestBase extends DrupalWebTestCase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $profile = 'testing';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp('libraries', 'libraries_test_module');
|
||||
theme_enable(array('libraries_test_theme'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a path making sure a set of permissions is required to access it.
|
||||
*
|
||||
* After calling this method, a user with the given permissions is logged in
|
||||
* and the retrieved page is loaded into the internal browser.
|
||||
*
|
||||
* @param array $permissions
|
||||
* An array of permission names to assign to user. Note that the user always
|
||||
* has the default permissions derived from the "authenticated users" role.
|
||||
* @param string $path
|
||||
* Drupal path or URL to load into the internal browser.
|
||||
* @param array $options
|
||||
* Options to be forwarded to url().
|
||||
* @param array $headers
|
||||
* An array containing additional HTTP request headers, each formatted as
|
||||
* "name: value".
|
||||
*
|
||||
* @return string
|
||||
* The retrieved HTML string, also available as $this->drupalGetContent().
|
||||
*
|
||||
* @see \DrupalWebTestCase::drupalGet()
|
||||
* @see \DrupalWebTestCase::drupalCreateUser()
|
||||
*/
|
||||
protected function getWithPermissions(array $permissions, $path, array $options = array(), array $headers = array()) {
|
||||
$this->drupalGet($path, $options, $headers);
|
||||
$this->assertResponse(403);
|
||||
|
||||
$this->drupalLogin($this->drupalCreateUser($permissions));
|
||||
$this->drupalGet($path, $options, $headers);
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
Example library
|
||||
|
||||
Version 1
|
||||
|
||||
This file is an example file to test version detection.
|
||||
|
||||
The various other files in this directory are to test the loading of JavaScript,
|
||||
CSS and PHP files.
|
||||
- JavaScript: The filenames of the JavaScript files are asserted to be in the
|
||||
raw HTML via SimpleTest. Since the filename could appear, for instance, in an
|
||||
error message, this is not very robust. Explicit testing of JavaScript,
|
||||
though, is not yet possible with SimpleTest. To allow for easier debugging, we
|
||||
place the following text on the page:
|
||||
"If this text shows up, no JavaScript test file was loaded."
|
||||
This text is replaced via JavaScript by a text of the form:
|
||||
"If this text shows up, [file] was loaded successfully."
|
||||
[file] is either 'example_1.js', 'example_2.js', 'example_3.js',
|
||||
'example_4.js' or 'libraries_test_module.js'. If you have SimpleTest's verbose
|
||||
mode enabled and see the above text in one of the debug pages, the noted
|
||||
JavaScript file was loaded successfully.
|
||||
- CSS: The filenames of the CSS files are asserted to be in the raw HTML via
|
||||
SimpleTest. Since the filename could appear, for instance, in an error
|
||||
message, this is not very robust. Explicit testing of CSS, though, is not yet
|
||||
possible with SimpleTest. Hence, the CSS files, if loaded, make the following
|
||||
text a certain color:
|
||||
"If one of the CSS test files has been loaded, this text will be colored:
|
||||
- example_1: red
|
||||
- example_2: green
|
||||
- example_3: orange
|
||||
- example_4: blue
|
||||
- libraries_test_module: purple"
|
||||
If you have SimpleTest's verbose mode enabled, and see the above text in a
|
||||
certain color (i.e. not in black), a CSS file was loaded successfully. Which
|
||||
file depends on the color as referenced in the text above.
|
||||
- PHP: The loading of PHP files is tested by defining a dummy function in the
|
||||
PHP files and then checking whether this function was defined using
|
||||
function_exists(). This can be checked programatically with SimpleTest.
|
||||
The loading of integration files is tested with the same method. The integration
|
||||
files are libraries_test_module.js, libraries_test_module.css,
|
||||
libraries_test_module.inc and are located in the test module's directory
|
||||
alongside libraries_test_module.info (i.e. they are not in the same directory as
|
||||
this file).
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test CSS file for Libraries loading.
|
||||
*
|
||||
* Color the 'libraries-test-module-css' div red. See README.txt for more
|
||||
* information.
|
||||
*/
|
||||
|
||||
.libraries-test-module-css {
|
||||
color: red;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test JavaScript file for Libraries loading.
|
||||
*
|
||||
* Replace the text in the 'libraries-test-module-js' div. See README.txt for
|
||||
* more information.
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.librariesTest = {
|
||||
attach: function(context, settings) {
|
||||
$('.libraries-test-module-js').text('If this text shows up, example_1.js was loaded successfully.')
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test PHP file for Libraries loading.
|
||||
*/
|
||||
|
||||
// @see _libraries_require_once()
|
||||
$path = 'abc';
|
||||
|
||||
/**
|
||||
* Dummy function to see if this file was loaded.
|
||||
*/
|
||||
function _libraries_test_module_example_1() {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test CSS file for Libraries loading.
|
||||
*
|
||||
* Color the 'libraries-test-module-css' div green. See README.txt for more
|
||||
* information.
|
||||
*/
|
||||
|
||||
.libraries-test-module-css {
|
||||
color: green;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test JavaScript file for Libraries loading.
|
||||
*
|
||||
* Replace the text in the 'libraries-test-module-js' div. See README.txt for
|
||||
* more information.
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.librariesTest = {
|
||||
attach: function(context, settings) {
|
||||
$('.libraries-test-module-js').text('If this text shows up, example_2.js was loaded successfully.')
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test PHP file for Libraries loading.
|
||||
*/
|
||||
|
||||
// @see _libraries_require_once()
|
||||
$path = 'abc';
|
||||
|
||||
/**
|
||||
* Dummy function to see if this file was loaded.
|
||||
*/
|
||||
function _libraries_test_module_example_2() {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test CSS file for Libraries loading.
|
||||
*
|
||||
* Color the 'libraries-test-module-css' div orange. See README.txt for more
|
||||
* information.
|
||||
*/
|
||||
|
||||
.libraries-test-module-css {
|
||||
color: orange;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test JavaScript file for Libraries loading.
|
||||
*
|
||||
* Replace the text in the 'libraries-test-module-js' div. See README.txt for
|
||||
* more information.
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.librariesTest = {
|
||||
attach: function(context, settings) {
|
||||
$('.libraries-test-module-js').text('If this text shows up, example_3.js was loaded successfully.')
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test PHP file for Libraries loading.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dummy function to see if this file was loaded.
|
||||
*/
|
||||
function _libraries_test_module_example_3() {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test CSS file for Libraries loading.
|
||||
*
|
||||
* Color the 'libraries-test-module-css' div blue. See README.txt for more
|
||||
* information.
|
||||
*/
|
||||
|
||||
.libraries-test-module-css {
|
||||
color: blue;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test JavaScript file for Libraries loading.
|
||||
*
|
||||
* Replace the text in the 'libraries-test-module-js' div. See README.txt for
|
||||
* more information.
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.librariesTest = {
|
||||
attach: function(context, settings) {
|
||||
$('.libraries-test-module-js').text('If this text shows up, example_4.js was loaded successfully.')
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test PHP file for Libraries loading.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dummy function to see if this file was loaded.
|
||||
*/
|
||||
function _libraries_test_module_example_4() {
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
; This is an example info file of a library used for testing purposes.
|
||||
name = Example info file
|
||||
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-05-12
|
||||
version = "7.x-2.3"
|
||||
core = "7.x"
|
||||
project = "libraries"
|
||||
datestamp = "1463077450"
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test CSS file for Libraries loading.
|
||||
*
|
||||
* Color the 'libraries-test-module-css' div purple. See README.txt for more
|
||||
* information.
|
||||
*/
|
||||
|
||||
.libraries-test-module-css {
|
||||
color: purple;
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test PHP file for Libraries loading.
|
||||
|
||||
/**
|
||||
* Dummy function to see if this file was loaded.
|
||||
*/
|
||||
function _libraries_test_module_integration_file() {
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
name = Libraries test module
|
||||
description = Tests library detection and loading.
|
||||
core = 7.x
|
||||
package = Testing
|
||||
dependencies[] = libraries
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-05-12
|
||||
version = "7.x-2.3"
|
||||
core = "7.x"
|
||||
project = "libraries"
|
||||
datestamp = "1463077450"
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test JavaScript file for Libraries loading.
|
||||
*
|
||||
* Replace the text in the 'libraries-test-module-js' div. See README.txt for
|
||||
* more information.
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.librariesTest = {
|
||||
attach: function(context, settings) {
|
||||
$('.libraries-test-module-js').text('If this text shows up, libraries_test_module.js was loaded successfully.')
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
+631
@@ -0,0 +1,631 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests the library detection and loading.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_libraries_info().
|
||||
*/
|
||||
function libraries_test_module_libraries_info() {
|
||||
// Test library information gathering.
|
||||
$libraries['example_module'] = array(
|
||||
'name' => 'Example module',
|
||||
'module_altered' => FALSE,
|
||||
);
|
||||
|
||||
// Test library detection.
|
||||
$libraries['example_missing'] = array(
|
||||
'name' => 'Example missing',
|
||||
// Provide a vendor and download URL to test that the UI links to it.
|
||||
'vendor url' => 'http://example.com',
|
||||
'download url' => 'http://example.com/download',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/missing',
|
||||
);
|
||||
$libraries['example_undetected_version'] = array(
|
||||
'name' => 'Example undetected version',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version callback' => '_libraries_test_module_return_version',
|
||||
'version arguments' => array(FALSE),
|
||||
);
|
||||
$libraries['example_unsupported_version'] = array(
|
||||
'name' => 'Example unsupported version',
|
||||
// Provide a download URL to test that the UI links to it.
|
||||
'download url' => 'http://example.com/download',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version callback' => '_libraries_test_module_return_version',
|
||||
'version arguments' => array('1'),
|
||||
'versions' => array(
|
||||
'2' => array(),
|
||||
),
|
||||
);
|
||||
$libraries['example_supported_version'] = array(
|
||||
'name' => 'Example supported version',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version callback' => '_libraries_test_module_return_version',
|
||||
'version arguments' => array('1'),
|
||||
'versions' => array(
|
||||
'1' => array(),
|
||||
),
|
||||
);
|
||||
|
||||
// Test the default version callback.
|
||||
$libraries['example_default_version_callback'] = array(
|
||||
'name' => 'Example default version callback',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version arguments' => array(
|
||||
'file' => 'README.txt',
|
||||
// Version 1
|
||||
'pattern' => '/Version (\d+)/',
|
||||
'lines' => 5,
|
||||
),
|
||||
);
|
||||
|
||||
// Test a multiple-parameter version callback.
|
||||
$libraries['example_multiple_parameter_version_callback'] = array(
|
||||
'name' => 'Example multiple parameter version callback',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
// Version 1
|
||||
'version callback' => '_libraries_test_module_get_version',
|
||||
'version arguments' => array('README.txt', '/Version (\d+)/', 5),
|
||||
);
|
||||
|
||||
// Test a top-level files property.
|
||||
$libraries['example_files'] = array(
|
||||
'name' => 'Example files',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'files' => array(
|
||||
'js' => array('example_1.js'),
|
||||
'css' => array('example_1.css'),
|
||||
'php' => array('example_1.php'),
|
||||
),
|
||||
);
|
||||
|
||||
// Test loading of integration files.
|
||||
// Normally added by the corresponding module via hook_libraries_info_alter(),
|
||||
// these files should be automatically loaded when the library is loaded.
|
||||
$libraries['example_module_integration_files'] = array(
|
||||
'name' => 'Example module integration files',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'integration files' => array(
|
||||
'libraries_test_module' => array(
|
||||
'js' => array('libraries_test_module.js'),
|
||||
'css' => array('libraries_test_module.css'),
|
||||
'php' => array('libraries_test_module.inc'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Test loading of integration files after library files.
|
||||
// We test the correct loading order by calling a function that is defined in
|
||||
// example_1.php in libraries_test_module_post_load.inc.
|
||||
$libraries['example_module_integration_files_post_load'] = array(
|
||||
'name' => 'Example module post-load integration files',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'files' => array(
|
||||
'php' => array('example_1.php'),
|
||||
),
|
||||
'integration files' => array(
|
||||
'libraries_test_module' => array(
|
||||
'php' => array('libraries_test_module_post_load.inc'),
|
||||
),
|
||||
),
|
||||
'post-load integration files' => TRUE,
|
||||
);
|
||||
|
||||
// Test version overloading.
|
||||
$libraries['example_versions'] = array(
|
||||
'name' => 'Example versions',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '2',
|
||||
'versions' => array(
|
||||
'1' => array(
|
||||
'files' => array(
|
||||
'js' => array('example_1.js'),
|
||||
'css' => array('example_1.css'),
|
||||
'php' => array('example_1.php'),
|
||||
),
|
||||
),
|
||||
'2' => array(
|
||||
'files' => array(
|
||||
'js' => array('example_2.js'),
|
||||
'css' => array('example_2.css'),
|
||||
'php' => array('example_2.php'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Test variant detection.
|
||||
$libraries['example_variant_missing'] = array(
|
||||
'name' => 'Example variant missing',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'variants' => array(
|
||||
'example_variant' => array(
|
||||
'files' => array(
|
||||
'js' => array('example_3.js'),
|
||||
'css' => array('example_3.css'),
|
||||
'php' => array('example_3.php'),
|
||||
),
|
||||
'variant callback' => '_libraries_test_module_return_installed',
|
||||
'variant arguments' => array(FALSE),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$libraries['example_variant'] = array(
|
||||
'name' => 'Example variant',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'variants' => array(
|
||||
'example_variant' => array(
|
||||
'files' => array(
|
||||
'js' => array('example_3.js'),
|
||||
'css' => array('example_3.css'),
|
||||
'php' => array('example_3.php'),
|
||||
),
|
||||
'variant callback' => '_libraries_test_module_return_installed',
|
||||
'variant arguments' => array(TRUE),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Test correct behaviour with multiple versions and multiple variants.
|
||||
$libraries['example_versions_and_variants'] = array(
|
||||
'name' => 'Example versions and variants',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '2',
|
||||
'versions' => array(
|
||||
'1' => array(
|
||||
'variants' => array(
|
||||
'example_variant_1' => array(
|
||||
'files' => array(
|
||||
'js' => array('example_1.js'),
|
||||
'css' => array('example_1.css'),
|
||||
'php' => array('example_1.php'),
|
||||
),
|
||||
'variant callback' => '_libraries_test_module_return_installed',
|
||||
'variant arguments' => array(TRUE),
|
||||
),
|
||||
'example_variant_2' => array(
|
||||
'files' => array(
|
||||
'js' => array('example_2.js'),
|
||||
'css' => array('example_2.css'),
|
||||
'php' => array('example_2.php'),
|
||||
),
|
||||
'variant callback' => '_libraries_test_module_return_installed',
|
||||
'variant arguments' => array(TRUE),
|
||||
),
|
||||
),
|
||||
),
|
||||
'2' => array(
|
||||
'variants' => array(
|
||||
'example_variant_1' => array(
|
||||
'files' => array(
|
||||
'js' => array('example_3.js'),
|
||||
'css' => array('example_3.css'),
|
||||
'php' => array('example_3.php'),
|
||||
),
|
||||
'variant callback' => '_libraries_test_module_return_installed',
|
||||
'variant arguments' => array(TRUE),
|
||||
),
|
||||
'example_variant_2' => array(
|
||||
'files' => array(
|
||||
'js' => array('example_4.js'),
|
||||
'css' => array('example_4.css'),
|
||||
'php' => array('example_4.php'),
|
||||
),
|
||||
'variant callback' => '_libraries_test_module_return_installed',
|
||||
'variant arguments' => array(TRUE),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Test dependency loading.
|
||||
// We add one file to each library to be able to verify if it was loaded with
|
||||
// libraries_load().
|
||||
// This library acts as a dependency for the libraries below.
|
||||
$libraries['example_dependency'] = array(
|
||||
'name' => 'Example dependency',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1.1',
|
||||
'files' => array('js' => array('example_1.js')),
|
||||
);
|
||||
$libraries['example_dependency_missing'] = array(
|
||||
'name' => 'Example dependency missing',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'dependencies' => array('example_missing'),
|
||||
'files' => array('js' => array('example_1.js')),
|
||||
);
|
||||
$libraries['example_dependency_incompatible'] = array(
|
||||
'name' => 'Example dependency incompatible',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'dependencies' => array('example_dependency (>1.1)'),
|
||||
'files' => array('js' => array('example_1.js')),
|
||||
);
|
||||
$libraries['example_dependency_compatible'] = array(
|
||||
'name' => 'Example dependency compatible',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'dependencies' => array('example_dependency (>=1.1)'),
|
||||
'files' => array('js' => array('example_1.js')),
|
||||
);
|
||||
|
||||
// Test the applying of callbacks.
|
||||
$libraries['example_callback'] = array(
|
||||
'name' => 'Example callback',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'versions' => array(
|
||||
'1' => array(
|
||||
'variants' => array(
|
||||
'example_variant' => array(
|
||||
// These keys are for testing purposes only.
|
||||
'info callback' => 'not applied',
|
||||
'pre-detect callback' => 'not applied',
|
||||
'post-detect callback' => 'not applied',
|
||||
'pre-dependencies-load callback' => 'not applied',
|
||||
'pre-load callback' => 'not applied',
|
||||
'post-load callback' => 'not applied',
|
||||
),
|
||||
),
|
||||
// These keys are for testing purposes only.
|
||||
'info callback' => 'not applied',
|
||||
'pre-detect callback' => 'not applied',
|
||||
'post-detect callback' => 'not applied',
|
||||
'pre-dependencies-load callback' => 'not applied',
|
||||
'pre-load callback' => 'not applied',
|
||||
'post-load callback' => 'not applied',
|
||||
),
|
||||
),
|
||||
'variants' => array(
|
||||
'example_variant' => array(
|
||||
// These keys are for testing purposes only.
|
||||
'info callback' => 'not applied',
|
||||
'pre-detect callback' => 'not applied',
|
||||
'post-detect callback' => 'not applied',
|
||||
'pre-dependencies-load callback' => 'not applied',
|
||||
'pre-load callback' => 'not applied',
|
||||
'post-load callback' => 'not applied',
|
||||
),
|
||||
),
|
||||
'callbacks' => array(
|
||||
'info' => array('_libraries_test_module_info_callback'),
|
||||
'pre-detect' => array('_libraries_test_module_pre_detect_callback'),
|
||||
'post-detect' => array('_libraries_test_module_post_detect_callback'),
|
||||
'pre-dependencies-load' => array('_libraries_test_module_pre_dependencies_load_callback'),
|
||||
'pre-load' => array('_libraries_test_module_pre_load_callback'),
|
||||
'post-load' => array('_libraries_test_module_post_load_callback'),
|
||||
),
|
||||
// These keys are for testing purposes only.
|
||||
'info callback' => 'not applied',
|
||||
'pre-detect callback' => 'not applied',
|
||||
'post-detect callback' => 'not applied',
|
||||
'pre-dependencies-load callback' => 'not applied',
|
||||
'pre-load callback' => 'not applied',
|
||||
'post-load callback' => 'not applied',
|
||||
);
|
||||
|
||||
$libraries['example_path_variable_override'] = array(
|
||||
'name' => 'Example path variable override',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'files' => array(
|
||||
'php' => array('example_1.php', 'example_2.php'),
|
||||
),
|
||||
);
|
||||
|
||||
return $libraries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_libraries_info_alter().
|
||||
*/
|
||||
function libraries_test_module_libraries_info_alter(&$libraries) {
|
||||
$libraries['example_module']['module_altered'] = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_libraries_info_file_paths()
|
||||
*/
|
||||
function libraries_test_module_libraries_info_file_paths() {
|
||||
return array(drupal_get_path('module', 'libraries') . '/tests/libraries');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version of an example library.
|
||||
*
|
||||
* Returns exactly the version string entered as the $version parameter. This
|
||||
* function cannot be collapsed with _libraries_test_module_return_installed(),
|
||||
* because of the different arguments that are passed automatically.
|
||||
*/
|
||||
function _libraries_test_module_return_version($library, $version) {
|
||||
return $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version information from an arbitrary library.
|
||||
*
|
||||
* Test function for a version callback with multiple arguments. This is an
|
||||
* exact copy of libraries_get_version(), which uses a single $option argument,
|
||||
* except for the fact that it uses multiple arguments. Since we support both
|
||||
* type of version callbacks, detecting the version of a test library with this
|
||||
* function ensures that the arguments are passed correctly. This function might
|
||||
* be a useful reference for a custom version callback that uses multiple
|
||||
* parameters.
|
||||
*
|
||||
* @param $library
|
||||
* An associative array containing all information about the library.
|
||||
* @param $file
|
||||
* The filename to parse for the version, relative to the library path. For
|
||||
* example: 'docs/changelog.txt'.
|
||||
* @param pattern
|
||||
* A string containing a regular expression (PCRE) to match the library
|
||||
* version. For example: '/@version (\d+)\.(\d+)/'.
|
||||
* @param lines
|
||||
* (optional) The maximum number of lines to search the pattern in. Defaults
|
||||
* to 20.
|
||||
* @param cols
|
||||
* (optional) The maximum number of characters per line to take into account.
|
||||
* Defaults to 200. In case of minified or compressed files, this prevents
|
||||
* reading the entire file into memory.
|
||||
*
|
||||
* @return
|
||||
* A string containing the version of the library.
|
||||
*
|
||||
* @see libraries_get_version()
|
||||
*/
|
||||
function _libraries_test_module_get_version($library, $file, $pattern, $lines = 20, $cols = 200) {
|
||||
|
||||
$file = DRUPAL_ROOT . '/' . $library['library path'] . '/' . $file;
|
||||
if (!file_exists($file)) {
|
||||
return;
|
||||
}
|
||||
$file = fopen($file, 'r');
|
||||
while ($lines && $line = fgets($file, $cols)) {
|
||||
if (preg_match($pattern, $line, $version)) {
|
||||
fclose($file);
|
||||
return $version[1];
|
||||
}
|
||||
$lines--;
|
||||
}
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the variant of an example library.
|
||||
*
|
||||
* Returns exactly the value of $installed, either TRUE or FALSE. This function
|
||||
* cannot be collapsed with _libraries_test_module_return_version(), because of
|
||||
* the different arguments that are passed automatically.
|
||||
*/
|
||||
function _libraries_test_module_return_installed($library, $name, $installed) {
|
||||
return $installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'info callback' key.
|
||||
*
|
||||
* This function is used as a test callback for the 'info' callback group.
|
||||
*
|
||||
* @see _libraries_test_module_callback()
|
||||
*/
|
||||
function _libraries_test_module_info_callback(&$library, $version, $variant) {
|
||||
_libraries_test_module_callback($library, $version, $variant, 'info');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'pre-detect callback' key.
|
||||
*
|
||||
* This function is used as a test callback for the 'pre-detect' callback group.
|
||||
*
|
||||
* @see _libraries_test_module_callback()
|
||||
*/
|
||||
function _libraries_test_module_pre_detect_callback(&$library, $version, $variant) {
|
||||
_libraries_test_module_callback($library, $version, $variant, 'pre-detect');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'post-detect callback' key.
|
||||
*
|
||||
* This function is used as a test callback for the 'post-detect callback group.
|
||||
*
|
||||
* @see _libraries_test_module_callback()
|
||||
*/
|
||||
function _libraries_test_module_post_detect_callback(&$library, $version, $variant) {
|
||||
_libraries_test_module_callback($library, $version, $variant, 'post-detect');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'pre-dependencies-load callback' key.
|
||||
*
|
||||
* This function is used as a test callback for the 'pre-dependencies-load'
|
||||
* callback group.
|
||||
*
|
||||
* @see _libraries_test_module_callback()
|
||||
*/
|
||||
function _libraries_test_module_pre_dependencies_load_callback(&$library, $version, $variant) {
|
||||
_libraries_test_module_callback($library, $version, $variant, 'pre-dependencies-load');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'pre-load callback' key.
|
||||
*
|
||||
* This function is used as a test callback for the 'pre-load' callback group.
|
||||
*
|
||||
* @see _libraries_test_module_callback()
|
||||
*/
|
||||
function _libraries_test_module_pre_load_callback(&$library, $version, $variant) {
|
||||
_libraries_test_module_callback($library, $version, $variant, 'pre-load');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'post-load callback' key.
|
||||
*
|
||||
* This function is used as a test callback for the 'post-load' callback group.
|
||||
*
|
||||
* @see _libraries_test_module_callback()
|
||||
*/
|
||||
function _libraries_test_module_post_load_callback(&$library, $version, $variant) {
|
||||
_libraries_test_module_callback($library, $version, $variant, 'post-load');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the '[group] callback' key, where [group] is prepare, detect, or load.
|
||||
*
|
||||
* This function is used as a test callback for the all callback groups.
|
||||
*
|
||||
* It sets the '[group] callback' (see above) key to 'applied ([part])' where
|
||||
* [part] is either 'top-level', 'version x.y' (where x.y is the passed-in
|
||||
* version string), 'variant example' (where example is the passed-in variant
|
||||
* name), or 'version x.y, variant example' (see above), depending on the part
|
||||
* of the library the passed-in library information belongs to.
|
||||
*
|
||||
* @param $library
|
||||
* An array of library information, which may be version- or variant-specific.
|
||||
* Passed by reference.
|
||||
* @param $version
|
||||
* The version the library information passed in $library belongs to, or NULL
|
||||
* if the passed library information is not version-specific.
|
||||
* @param $variant
|
||||
* The variant the library information passed in $library belongs to, or NULL
|
||||
* if the passed library information is not variant-specific.
|
||||
*/
|
||||
function _libraries_test_module_callback(&$library, $version, $variant, $group) {
|
||||
$string = 'applied';
|
||||
if (isset($version) && isset($variant)) {
|
||||
$string .= " (version $version, variant $variant)";
|
||||
}
|
||||
elseif (isset($version)) {
|
||||
$string .= " (version $version)";
|
||||
}
|
||||
elseif (isset($variant)) {
|
||||
$string .= " (variant $variant)";
|
||||
}
|
||||
else {
|
||||
$string .= ' (top-level)';
|
||||
}
|
||||
$library["$group callback"] = $string;
|
||||
|
||||
// The following is used to test caching of library information.
|
||||
// Only set the message for the top-level library to prevent confusing,
|
||||
// duplicate messages.
|
||||
if (!isset($version) && !isset($variant) && variable_get('libraries_test_module_cache', FALSE)) {
|
||||
drupal_set_message("The <em>$group</em> callback group was invoked.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function libraries_test_module_menu() {
|
||||
$base = array(
|
||||
'page callback' => '_libraries_test_module_load',
|
||||
'access callback' => TRUE,
|
||||
);
|
||||
$items['libraries-test-module/files'] = $base + array(
|
||||
'title' => 'Test files',
|
||||
'page arguments' => array('example_files'),
|
||||
);
|
||||
$items['libraries-test-module/module-integration-files'] = $base + array(
|
||||
'title' => 'Test module integration files',
|
||||
'page arguments' => array('example_module_integration_files'),
|
||||
);
|
||||
$items['libraries-test-module/module-integration-files-post-load'] = $base + array(
|
||||
'title' => 'Test module post-load integration files',
|
||||
'page arguments' => array('example_module_integration_files_post_load'),
|
||||
);
|
||||
$items['libraries-test-module/theme-integration-files'] = $base + array(
|
||||
'title' => 'Test theme integration files',
|
||||
'page arguments' => array('example_theme_integration_files'),
|
||||
);
|
||||
$items['libraries-test-module/versions'] = $base + array(
|
||||
'title' => 'Test version loading',
|
||||
'page arguments' => array('example_versions'),
|
||||
);
|
||||
$items['libraries-test-module/variant'] = $base + array(
|
||||
'title' => 'Test variant loading',
|
||||
'page arguments' => array('example_variant', 'example_variant'),
|
||||
);
|
||||
$items['libraries-test-module/versions-and-variants'] = $base + array(
|
||||
'title' => 'Test concurrent version and variant loading',
|
||||
'page arguments' => array('example_versions_and_variants', 'example_variant_2'),
|
||||
);
|
||||
$items['libraries-test-module/cache'] = $base + array(
|
||||
'title' => 'Test caching of library information',
|
||||
'page arguments' => array('example_callback'),
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a specified library (variant) for testing.
|
||||
*
|
||||
* JavaScript and CSS files can be checked directly by SimpleTest, so we only
|
||||
* need to manually check for PHP files. We provide information about the loaded
|
||||
* JavaScript and CSS files for easier debugging. See example/README.txt for
|
||||
* more information.
|
||||
*/
|
||||
function _libraries_test_module_load($library, $variant = NULL) {
|
||||
libraries_load($library, $variant);
|
||||
// JavaScript and CSS files can be checked directly by SimpleTest, so we only
|
||||
// need to manually check for PHP files.
|
||||
$output = '';
|
||||
|
||||
// For easer debugging of JS loading, a text is shown that the JavaScript will
|
||||
// replace.
|
||||
$output .= '<h2>JavaScript</h2>';
|
||||
$output .= '<div class="libraries-test-module-js">';
|
||||
$output .= 'If this text shows up, no JavaScript test file was loaded.';
|
||||
$output .= '</div>';
|
||||
|
||||
// For easier debugging of CSS loading, the loaded CSS files will color the
|
||||
// following text.
|
||||
$output .= '<h2>CSS</h2>';
|
||||
$output .= '<div class="libraries-test-module-css">';
|
||||
$output .= 'If one of the CSS test files has been loaded, this text will be colored:';
|
||||
$output .= '<ul>';
|
||||
// Do not reference the actual CSS files (i.e. including '.css'), because that
|
||||
// breaks testing.
|
||||
$output .= '<li>example_1: red</li>';
|
||||
$output .= '<li>example_2: green</li>';
|
||||
$output .= '<li>example_3: orange</li>';
|
||||
$output .= '<li>example_4: blue</li>';
|
||||
$output .= '<li>libraries_test_module: purple</li>';
|
||||
$output .= '<li>libraries_test_theme: turquoise</li>';
|
||||
$output .= '</ul>';
|
||||
$output .= '</div>';
|
||||
|
||||
$output .= '<h2>PHP</h2>';
|
||||
$output .= '<div class="libraries-test-module-php">';
|
||||
$output .= 'The following is a list of all loaded test PHP files:';
|
||||
$output .= '<ul>';
|
||||
$files = get_included_files();
|
||||
foreach ($files as $file) {
|
||||
if (strpos($file, 'libraries/test') && !strpos($file, 'libraries_test_module.module') && !strpos($file, 'template.php')) {
|
||||
$output .= '<li>' . str_replace(DRUPAL_ROOT . '/', '', $file) . '</li>';
|
||||
}
|
||||
}
|
||||
$output .= '</ul>';
|
||||
$output .= '</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_system_theme_info().
|
||||
*/
|
||||
function libraries_test_module_system_theme_info() {
|
||||
$themes = array();
|
||||
$themes['libraries_test_theme'] = drupal_get_path('module', 'libraries') . '/tests/themes/libraries_test_theme/libraries_test_theme.info';
|
||||
return $themes;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test PHP file for Libraries loading.
|
||||
|
||||
/**
|
||||
* Dummy function to see if this file was loaded.
|
||||
*/
|
||||
function _libraries_test_module_integration_file_post_load() {
|
||||
}
|
||||
|
||||
// Call a function that is defined in the library file, to ensure that was
|
||||
// loaded prior to this file.
|
||||
_libraries_test_module_example_1();
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test CSS file for Libraries loading.
|
||||
*
|
||||
* Color the 'libraries-test-module-css' div purple. See README.txt for more
|
||||
* information.
|
||||
*/
|
||||
|
||||
.libraries-test-module-css {
|
||||
color: turquoise;
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test PHP file for Libraries loading.
|
||||
|
||||
/**
|
||||
* Dummy function to see if this file was loaded.
|
||||
*/
|
||||
function _libraries_test_theme_integration_file() {
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
name = Libraries test theme
|
||||
description = Tests that themes can provide and alter library information.
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-05-12
|
||||
version = "7.x-2.3"
|
||||
core = "7.x"
|
||||
project = "libraries"
|
||||
datestamp = "1463077450"
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test JavaScript file for Libraries loading.
|
||||
*
|
||||
* Replace the text in the 'libraries-test-module-js' div. See README.txt for
|
||||
* more information.
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.librariesTest = {
|
||||
attach: function(context, settings) {
|
||||
$('.libraries-test-module-js').text('If this text shows up, libraries_test_theme.js was loaded successfully.')
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Libraries test theme.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_libraries_info().
|
||||
*/
|
||||
function libraries_test_theme_libraries_info() {
|
||||
$libraries['example_theme'] = array(
|
||||
'name' => 'Example theme',
|
||||
'theme_altered' => FALSE,
|
||||
);
|
||||
$libraries['example_theme_integration_files'] = array(
|
||||
'name' => 'Example theme integration file',
|
||||
'library path' => drupal_get_path('module', 'libraries') . '/tests/libraries/example',
|
||||
'version' => '1',
|
||||
'integration files' => array(
|
||||
'libraries_test_theme' => array(
|
||||
'js' => array('libraries_test_theme.js'),
|
||||
'css' => array('libraries_test_theme.css'),
|
||||
'php' => array('libraries_test_theme.inc'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $libraries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_libraries_info_alter().
|
||||
*/
|
||||
function libraries_test_theme_libraries_info_alter(&$libraries) {
|
||||
$libraries['example_theme']['theme_altered'] = TRUE;
|
||||
}
|
||||
Reference in New Issue
Block a user