primo commit
This commit is contained in:
345
libraries/f0f/LICENSE.txt
Normal file
345
libraries/f0f/LICENSE.txt
Normal file
@ -0,0 +1,345 @@
|
||||
================================================================================
|
||||
Historical note
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
On February 21st, 2013 FOF changed its license to GPLv2 or later.
|
||||
================================================================================
|
||||
|
||||
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.
|
||||
780
libraries/f0f/autoloader/component.php
Normal file
780
libraries/f0f/autoloader/component.php
Normal file
@ -0,0 +1,780 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage autoloader
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2, or later
|
||||
*/
|
||||
|
||||
defined('F0F_INCLUDED') or die();
|
||||
|
||||
/**
|
||||
* An autoloader for F0F-powered components. It allows the autoloading of
|
||||
* various classes related to the operation of a component, from Controllers
|
||||
* and Models to Helpers and Fields. If a class doesn't exist, it will be
|
||||
* created on the fly.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage autoloader
|
||||
* @since 2.1
|
||||
*/
|
||||
class F0FAutoloaderComponent
|
||||
{
|
||||
/**
|
||||
* An instance of this autoloader
|
||||
*
|
||||
* @var F0FAutoloaderComponent
|
||||
*/
|
||||
public static $autoloader = null;
|
||||
|
||||
/**
|
||||
* The path to the F0F root directory
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $fofPath = null;
|
||||
|
||||
/**
|
||||
* An array holding component names and their F0F-ness status
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $fofComponents = array();
|
||||
|
||||
/**
|
||||
* Initialise this autoloader
|
||||
*
|
||||
* @return F0FAutoloaderComponent
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
if (self::$autoloader == null)
|
||||
{
|
||||
self::$autoloader = new self;
|
||||
}
|
||||
|
||||
return self::$autoloader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public constructor. Registers the autoloader with PHP.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$fofPath = realpath(__DIR__ . '/../');
|
||||
|
||||
spl_autoload_register(array($this,'autoload_fof_controller'));
|
||||
spl_autoload_register(array($this,'autoload_fof_model'));
|
||||
spl_autoload_register(array($this,'autoload_fof_view'));
|
||||
spl_autoload_register(array($this,'autoload_fof_table'));
|
||||
spl_autoload_register(array($this,'autoload_fof_helper'));
|
||||
spl_autoload_register(array($this,'autoload_fof_toolbar'));
|
||||
spl_autoload_register(array($this,'autoload_fof_field'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a F0F-powered component, i.e. if it has a fof.xml
|
||||
* file in its main directory.
|
||||
*
|
||||
* @param string $component The component's name
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isF0FComponent($component)
|
||||
{
|
||||
if (!isset($fofComponents[$component]))
|
||||
{
|
||||
$componentPaths = F0FPlatform::getInstance()->getComponentBaseDirs($component);
|
||||
$fofComponents[$component] = file_exists($componentPaths['admin'] . '/fof.xml');
|
||||
}
|
||||
|
||||
return $fofComponents[$component];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates class aliases. On systems where eval() is enabled it creates a
|
||||
* real class. On other systems it merely creates an alias. The eval()
|
||||
* method is preferred as class_aliases result in the name of the class
|
||||
* being instanciated not being available, making it impossible to create
|
||||
* a class instance without passing a $config array :(
|
||||
*
|
||||
* @param string $original The name of the original (existing) class
|
||||
* @param string $alias The name of the new (aliased) class
|
||||
* @param boolean $autoload Should I try to autoload the $original class?
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function class_alias($original, $alias, $autoload = true)
|
||||
{
|
||||
static $hasEval = null;
|
||||
|
||||
if (is_null($hasEval))
|
||||
{
|
||||
$hasEval = false;
|
||||
|
||||
if (function_exists('ini_get'))
|
||||
{
|
||||
$disabled_functions = ini_get('disabled_functions');
|
||||
|
||||
if (!is_string($disabled_functions))
|
||||
{
|
||||
$hasEval = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$disabled_functions = explode(',', $disabled_functions);
|
||||
$hasEval = !in_array('eval', $disabled_functions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists($original, $autoload))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ($hasEval)
|
||||
{
|
||||
$phpCode = "class $alias extends $original {}";
|
||||
eval($phpCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
class_alias($original, $alias, $autoload);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload Controllers
|
||||
*
|
||||
* @param string $class_name The name of the class to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function autoload_fof_controller($class_name)
|
||||
{
|
||||
F0FPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
|
||||
|
||||
static $isCli = null, $isAdmin = null;
|
||||
|
||||
if (is_null($isCli) && is_null($isAdmin))
|
||||
{
|
||||
list($isCli, $isAdmin) = F0FDispatcher::isCliAdmin();
|
||||
}
|
||||
|
||||
if (strpos($class_name, 'Controller') === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Change from camel cased into a lowercase array
|
||||
$class_modified = preg_replace('/(\s)+/', '_', $class_name);
|
||||
$class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
|
||||
$parts = explode('_', $class_modified);
|
||||
|
||||
// We need three parts in the name
|
||||
if (count($parts) != 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We need the second part to be "controller"
|
||||
if ($parts[1] != 'controller')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the information about this class
|
||||
$component_raw = $parts[0];
|
||||
$component = 'com_' . $parts[0];
|
||||
$view = $parts[2];
|
||||
|
||||
// Is this an F0F 2.1 or later component?
|
||||
if (!$this->isF0FComponent($component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the alternate view and class name (opposite singular/plural name)
|
||||
$alt_view = F0FInflector::isSingular($view) ? F0FInflector::pluralize($view) : F0FInflector::singularize($view);
|
||||
$alt_class = F0FInflector::camelize($component_raw . '_controller_' . $alt_view);
|
||||
|
||||
// Get the component's paths
|
||||
$componentPaths = F0FPlatform::getInstance()->getComponentBaseDirs($component);
|
||||
|
||||
// Get the proper and alternate paths and file names
|
||||
$file = "/controllers/$view.php";
|
||||
$altFile = "/controllers/$alt_view.php";
|
||||
$path = $componentPaths['main'];
|
||||
$altPath = $componentPaths['alt'];
|
||||
|
||||
// Try to find the proper class in the proper path
|
||||
if (file_exists($path . $file))
|
||||
{
|
||||
@include_once $path . $file;
|
||||
}
|
||||
|
||||
// Try to find the proper class in the alternate path
|
||||
if (!class_exists($class_name) && file_exists($altPath . $file))
|
||||
{
|
||||
@include_once $altPath . $file;
|
||||
}
|
||||
|
||||
// Try to find the alternate class in the proper path
|
||||
if (!class_exists($alt_class) && file_exists($path . $altFile))
|
||||
{
|
||||
@include_once $path . $altFile;
|
||||
}
|
||||
|
||||
// Try to find the alternate class in the alternate path
|
||||
if (!class_exists($alt_class) && file_exists($altPath . $altFile))
|
||||
{
|
||||
@include_once $altPath . $altFile;
|
||||
}
|
||||
|
||||
// If the alternate class exists just map the class to the alternate
|
||||
if (!class_exists($class_name) && class_exists($alt_class))
|
||||
{
|
||||
$this->class_alias($alt_class, $class_name);
|
||||
}
|
||||
|
||||
// No class found? Map to F0FController
|
||||
elseif (!class_exists($class_name))
|
||||
{
|
||||
if ($view != 'default')
|
||||
{
|
||||
$defaultClass = F0FInflector::camelize($component_raw . '_controller_default');
|
||||
$this->class_alias($defaultClass, $class_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->class_alias('F0FController', $class_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload Models
|
||||
*
|
||||
* @param string $class_name The name of the class to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function autoload_fof_model($class_name)
|
||||
{
|
||||
F0FPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
|
||||
|
||||
static $isCli = null, $isAdmin = null;
|
||||
|
||||
if (is_null($isCli) && is_null($isAdmin))
|
||||
{
|
||||
list($isCli, $isAdmin) = F0FDispatcher::isCliAdmin();
|
||||
}
|
||||
|
||||
if (strpos($class_name, 'Model') === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Change from camel cased into a lowercase array
|
||||
$class_modified = preg_replace('/(\s)+/', '_', $class_name);
|
||||
$class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
|
||||
$parts = explode('_', $class_modified);
|
||||
|
||||
// We need three parts in the name
|
||||
if (count($parts) != 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We need the second part to be "model"
|
||||
if ($parts[1] != 'model')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the information about this class
|
||||
$component_raw = $parts[0];
|
||||
$component = 'com_' . $parts[0];
|
||||
$view = $parts[2];
|
||||
|
||||
// Is this an F0F 2.1 or later component?
|
||||
if (!$this->isF0FComponent($component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the alternate view and class name (opposite singular/plural name)
|
||||
$alt_view = F0FInflector::isSingular($view) ? F0FInflector::pluralize($view) : F0FInflector::singularize($view);
|
||||
$alt_class = F0FInflector::camelize($component_raw . '_model_' . $alt_view);
|
||||
|
||||
// Get the proper and alternate paths and file names
|
||||
$componentPaths = F0FPlatform::getInstance()->getComponentBaseDirs($component);
|
||||
|
||||
$file = "/models/$view.php";
|
||||
$altFile = "/models/$alt_view.php";
|
||||
$path = $componentPaths['main'];
|
||||
$altPath = $componentPaths['alt'];
|
||||
|
||||
// Try to find the proper class in the proper path
|
||||
if (file_exists($path . $file))
|
||||
{
|
||||
@include_once $path . $file;
|
||||
}
|
||||
|
||||
// Try to find the proper class in the alternate path
|
||||
if (!class_exists($class_name) && file_exists($altPath . $file))
|
||||
{
|
||||
@include_once $altPath . $file;
|
||||
}
|
||||
|
||||
// Try to find the alternate class in the proper path
|
||||
if (!class_exists($alt_class) && file_exists($path . $altFile))
|
||||
{
|
||||
@include_once $path . $altFile;
|
||||
}
|
||||
|
||||
// Try to find the alternate class in the alternate path
|
||||
if (!class_exists($alt_class) && file_exists($altPath . $altFile))
|
||||
{
|
||||
@include_once $altPath . $altFile;
|
||||
}
|
||||
|
||||
// If the alternate class exists just map the class to the alternate
|
||||
if (!class_exists($class_name) && class_exists($alt_class))
|
||||
{
|
||||
$this->class_alias($alt_class, $class_name);
|
||||
}
|
||||
|
||||
// No class found? Map to F0FModel
|
||||
elseif (!class_exists($class_name))
|
||||
{
|
||||
if ($view != 'default')
|
||||
{
|
||||
$defaultClass = F0FInflector::camelize($component_raw . '_model_default');
|
||||
$this->class_alias($defaultClass, $class_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->class_alias('F0FModel', $class_name, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload Views
|
||||
*
|
||||
* @param string $class_name The name of the class to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function autoload_fof_view($class_name)
|
||||
{
|
||||
F0FPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
|
||||
|
||||
static $isCli = null, $isAdmin = null;
|
||||
|
||||
if (is_null($isCli) && is_null($isAdmin))
|
||||
{
|
||||
list($isCli, $isAdmin) = F0FDispatcher::isCliAdmin();
|
||||
}
|
||||
|
||||
if (strpos($class_name, 'View') === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Change from camel cased into a lowercase array
|
||||
$class_modified = preg_replace('/(\s)+/', '_', $class_name);
|
||||
$class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
|
||||
$parts = explode('_', $class_modified);
|
||||
|
||||
// We need at least three parts in the name
|
||||
|
||||
if (count($parts) < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We need the second part to be "view"
|
||||
|
||||
if ($parts[1] != 'view')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the information about this class
|
||||
$component_raw = $parts[0];
|
||||
$component = 'com_' . $parts[0];
|
||||
$view = $parts[2];
|
||||
|
||||
if (count($parts) > 3)
|
||||
{
|
||||
$format = $parts[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
$input = new F0FInput;
|
||||
$format = $input->getCmd('format', 'html', 'cmd');
|
||||
}
|
||||
|
||||
// Is this an F0F 2.1 or later component?
|
||||
if (!$this->isF0FComponent($component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the alternate view and class name (opposite singular/plural name)
|
||||
$alt_view = F0FInflector::isSingular($view) ? F0FInflector::pluralize($view) : F0FInflector::singularize($view);
|
||||
$alt_class = F0FInflector::camelize($component_raw . '_view_' . $alt_view);
|
||||
|
||||
// Get the proper and alternate paths and file names
|
||||
$componentPaths = F0FPlatform::getInstance()->getComponentBaseDirs($component);
|
||||
|
||||
$protoFile = "/models/$view";
|
||||
$protoAltFile = "/models/$alt_view";
|
||||
$path = $componentPaths['main'];
|
||||
$altPath = $componentPaths['alt'];
|
||||
|
||||
$formats = array($format);
|
||||
|
||||
if ($format != 'html')
|
||||
{
|
||||
$formats[] = 'raw';
|
||||
}
|
||||
|
||||
foreach ($formats as $currentFormat)
|
||||
{
|
||||
$file = $protoFile . '.' . $currentFormat . '.php';
|
||||
$altFile = $protoAltFile . '.' . $currentFormat . '.php';
|
||||
|
||||
// Try to find the proper class in the proper path
|
||||
if (!class_exists($class_name) && file_exists($path . $file))
|
||||
{
|
||||
@include_once $path . $file;
|
||||
}
|
||||
|
||||
// Try to find the proper class in the alternate path
|
||||
if (!class_exists($class_name) && file_exists($altPath . $file))
|
||||
{
|
||||
@include_once $altPath . $file;
|
||||
}
|
||||
|
||||
// Try to find the alternate class in the proper path
|
||||
if (!class_exists($alt_class) && file_exists($path . $altFile))
|
||||
{
|
||||
@include_once $path . $altFile;
|
||||
}
|
||||
|
||||
// Try to find the alternate class in the alternate path
|
||||
if (!class_exists($alt_class) && file_exists($altPath . $altFile))
|
||||
{
|
||||
@include_once $altPath . $altFile;
|
||||
}
|
||||
}
|
||||
|
||||
// If the alternate class exists just map the class to the alternate
|
||||
if (!class_exists($class_name) && class_exists($alt_class))
|
||||
{
|
||||
$this->class_alias($alt_class, $class_name);
|
||||
}
|
||||
|
||||
// No class found? Map to F0FModel
|
||||
elseif (!class_exists($class_name))
|
||||
{
|
||||
if ($view != 'default')
|
||||
{
|
||||
$defaultClass = F0FInflector::camelize($component_raw . '_view_default');
|
||||
$this->class_alias($defaultClass, $class_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!file_exists(self::$fofPath . '/view/' . $format . '.php'))
|
||||
{
|
||||
$default_class = 'F0FView';
|
||||
}
|
||||
else
|
||||
{
|
||||
$default_class = 'F0FView' . ucfirst($format);
|
||||
}
|
||||
|
||||
$this->class_alias($default_class, $class_name, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload Tables
|
||||
*
|
||||
* @param string $class_name The name of the class to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function autoload_fof_table($class_name)
|
||||
{
|
||||
F0FPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
|
||||
|
||||
static $isCli = null, $isAdmin = null;
|
||||
|
||||
if (is_null($isCli) && is_null($isAdmin))
|
||||
{
|
||||
list($isCli, $isAdmin) = F0FDispatcher::isCliAdmin();
|
||||
}
|
||||
|
||||
if (strpos($class_name, 'Table') === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Change from camel cased into a lowercase array
|
||||
$class_modified = preg_replace('/(\s)+/', '_', $class_name);
|
||||
$class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
|
||||
$parts = explode('_', $class_modified);
|
||||
|
||||
// We need three parts in the name
|
||||
|
||||
if (count($parts) != 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We need the second part to be "model"
|
||||
if ($parts[1] != 'table')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the information about this class
|
||||
$component_raw = $parts[0];
|
||||
$component = 'com_' . $parts[0];
|
||||
$view = $parts[2];
|
||||
|
||||
// Is this an F0F 2.1 or later component?
|
||||
if (!$this->isF0FComponent($component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the alternate view and class name (opposite singular/plural name)
|
||||
$alt_view = F0FInflector::isSingular($view) ? F0FInflector::pluralize($view) : F0FInflector::singularize($view);
|
||||
$alt_class = F0FInflector::camelize($component_raw . '_table_' . $alt_view);
|
||||
|
||||
// Get the proper and alternate paths and file names
|
||||
$componentPaths = F0FPlatform::getInstance()->getComponentBaseDirs($component);
|
||||
|
||||
$file = "/tables/$view.php";
|
||||
$altFile = "/tables/$alt_view.php";
|
||||
$path = $componentPaths['admin'];
|
||||
|
||||
// Try to find the proper class in the proper path
|
||||
if (file_exists($path . $file))
|
||||
{
|
||||
@include_once $path . $file;
|
||||
}
|
||||
|
||||
// Try to find the alternate class in the proper path
|
||||
if (!class_exists($alt_class) && file_exists($path . $altFile))
|
||||
{
|
||||
@include_once $path . $altFile;
|
||||
}
|
||||
|
||||
// If the alternate class exists just map the class to the alternate
|
||||
if (!class_exists($class_name) && class_exists($alt_class))
|
||||
{
|
||||
$this->class_alias($alt_class, $class_name);
|
||||
}
|
||||
|
||||
// No class found? Map to F0FModel
|
||||
elseif (!class_exists($class_name))
|
||||
{
|
||||
if ($view != 'default')
|
||||
{
|
||||
$defaultClass = F0FInflector::camelize($component_raw . '_table_default');
|
||||
$this->class_alias($defaultClass, $class_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->class_alias('F0FTable', $class_name, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload Helpers
|
||||
*
|
||||
* @param string $class_name The name of the class to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function autoload_fof_helper($class_name)
|
||||
{
|
||||
F0FPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
|
||||
|
||||
static $isCli = null, $isAdmin = null;
|
||||
|
||||
if (is_null($isCli) && is_null($isAdmin))
|
||||
{
|
||||
list($isCli, $isAdmin) = F0FDispatcher::isCliAdmin();
|
||||
}
|
||||
|
||||
if (strpos($class_name, 'Helper') === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Change from camel cased into a lowercase array
|
||||
$class_modified = preg_replace('/(\s)+/', '_', $class_name);
|
||||
$class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
|
||||
$parts = explode('_', $class_modified);
|
||||
|
||||
// We need three parts in the name
|
||||
if (count($parts) != 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We need the second part to be "model"
|
||||
if ($parts[1] != 'helper')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the information about this class
|
||||
$component_raw = $parts[0];
|
||||
$component = 'com_' . $parts[0];
|
||||
$view = $parts[2];
|
||||
|
||||
// Is this an F0F 2.1 or later component?
|
||||
if (!$this->isF0FComponent($component))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the alternate view and class name (opposite singular/plural name)
|
||||
$alt_view = F0FInflector::isSingular($view) ? F0FInflector::pluralize($view) : F0FInflector::singularize($view);
|
||||
$alt_class = F0FInflector::camelize($component_raw . '_helper_' . $alt_view);
|
||||
|
||||
// Get the proper and alternate paths and file names
|
||||
$componentPaths = F0FPlatform::getInstance()->getComponentBaseDirs($component);
|
||||
|
||||
$file = "/helpers/$view.php";
|
||||
$altFile = "/helpers/$alt_view.php";
|
||||
$path = $componentPaths['main'];
|
||||
$altPath = $componentPaths['alt'];
|
||||
|
||||
// Try to find the proper class in the proper path
|
||||
if (file_exists($path . $file))
|
||||
{
|
||||
@include_once $path . $file;
|
||||
}
|
||||
|
||||
// Try to find the proper class in the alternate path
|
||||
if (!class_exists($class_name) && file_exists($altPath . $file))
|
||||
{
|
||||
@include_once $altPath . $file;
|
||||
}
|
||||
|
||||
// Try to find the alternate class in the proper path
|
||||
if (!class_exists($alt_class) && file_exists($path . $altFile))
|
||||
{
|
||||
@include_once $path . $altFile;
|
||||
}
|
||||
|
||||
// Try to find the alternate class in the alternate path
|
||||
if (!class_exists($alt_class) && file_exists($altPath . $altFile))
|
||||
{
|
||||
@include_once $altPath . $altFile;
|
||||
}
|
||||
|
||||
// If the alternate class exists just map the class to the alternate
|
||||
if (!class_exists($class_name) && class_exists($alt_class))
|
||||
{
|
||||
$this->class_alias($alt_class, $class_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload Toolbars
|
||||
*
|
||||
* @param string $class_name The name of the class to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function autoload_fof_toolbar($class_name)
|
||||
{
|
||||
F0FPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
|
||||
|
||||
static $isCli = null, $isAdmin = null;
|
||||
|
||||
if (is_null($isCli) && is_null($isAdmin))
|
||||
{
|
||||
list($isCli, $isAdmin) = F0FDispatcher::isCliAdmin();
|
||||
}
|
||||
|
||||
if (strpos($class_name, 'Toolbar') === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Change from camel cased into a lowercase array
|
||||
$class_modified = preg_replace('/(\s)+/', '_', $class_name);
|
||||
$class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
|
||||
$parts = explode('_', $class_modified);
|
||||
|
||||
// We need two parts in the name
|
||||
if (count($parts) != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We need the second part to be "model"
|
||||
if ($parts[1] != 'toolbar')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the information about this class
|
||||
$component_raw = $parts[0];
|
||||
$component = 'com_' . $parts[0];
|
||||
|
||||
$platformDirs = F0FPlatform::getInstance()->getPlatformBaseDirs();
|
||||
|
||||
// Get the proper and alternate paths and file names
|
||||
$file = "/components/$component/toolbar.php";
|
||||
$path = ($isAdmin || $isCli) ? $platformDirs['admin'] : $platformDirs['public'];
|
||||
$altPath = ($isAdmin || $isCli) ? $platformDirs['public'] : $platformDirs['admin'];
|
||||
|
||||
// Try to find the proper class in the proper path
|
||||
|
||||
if (file_exists($path . $file))
|
||||
{
|
||||
@include_once $path . $file;
|
||||
}
|
||||
|
||||
// Try to find the proper class in the alternate path
|
||||
if (!class_exists($class_name) && file_exists($altPath . $file))
|
||||
{
|
||||
@include_once $altPath . $file;
|
||||
}
|
||||
|
||||
// No class found? Map to F0FToolbar
|
||||
if (!class_exists($class_name))
|
||||
{
|
||||
$this->class_alias('F0FToolbar', $class_name, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload Fields
|
||||
*
|
||||
* @param string $class_name The name of the class to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function autoload_fof_field($class_name)
|
||||
{
|
||||
F0FPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
|
||||
|
||||
// @todo
|
||||
}
|
||||
}
|
||||
116
libraries/f0f/autoloader/fof.php
Normal file
116
libraries/f0f/autoloader/fof.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage autoloader
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2, or later
|
||||
*/
|
||||
|
||||
defined('F0F_INCLUDED') or die();
|
||||
|
||||
/**
|
||||
* The main class autoloader for F0F itself
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage autoloader
|
||||
* @since 2.1
|
||||
*/
|
||||
class F0FAutoloaderFof
|
||||
{
|
||||
/**
|
||||
* An instance of this autoloader
|
||||
*
|
||||
* @var F0FAutoloaderFof
|
||||
*/
|
||||
public static $autoloader = null;
|
||||
|
||||
/**
|
||||
* The path to the F0F root directory
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $fofPath = null;
|
||||
|
||||
/**
|
||||
* Initialise this autoloader
|
||||
*
|
||||
* @return F0FAutoloaderFof
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
if (self::$autoloader == null)
|
||||
{
|
||||
self::$autoloader = new self;
|
||||
}
|
||||
|
||||
return self::$autoloader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public constructor. Registers the autoloader with PHP.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
self::$fofPath = realpath(__DIR__ . '/../');
|
||||
|
||||
spl_autoload_register(array($this,'autoload_fof_core'));
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual autoloader
|
||||
*
|
||||
* @param string $class_name The name of the class to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function autoload_fof_core($class_name)
|
||||
{
|
||||
// Make sure the class has a F0F prefix
|
||||
if (substr($class_name, 0, 3) != 'F0F')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the prefix
|
||||
$class = substr($class_name, 3);
|
||||
|
||||
// Change from camel cased (e.g. ViewHtml) into a lowercase array (e.g. 'view','html')
|
||||
$class = preg_replace('/(\s)+/', '_', $class);
|
||||
$class = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class));
|
||||
$class = explode('_', $class);
|
||||
|
||||
// First try finding in structured directory format (preferred)
|
||||
$path = self::$fofPath . '/' . implode('/', $class) . '.php';
|
||||
|
||||
if (@file_exists($path))
|
||||
{
|
||||
include_once $path;
|
||||
}
|
||||
|
||||
// Then try the duplicate last name structured directory format (not recommended)
|
||||
|
||||
if (!class_exists($class_name, false))
|
||||
{
|
||||
reset($class);
|
||||
$lastPart = end($class);
|
||||
$path = self::$fofPath . '/' . implode('/', $class) . '/' . $lastPart . '.php';
|
||||
|
||||
if (@file_exists($path))
|
||||
{
|
||||
include_once $path;
|
||||
}
|
||||
}
|
||||
|
||||
// If it still fails, try looking in the legacy folder (used for backwards compatibility)
|
||||
|
||||
if (!class_exists($class_name, false))
|
||||
{
|
||||
$path = self::$fofPath . '/legacy/' . implode('/', $class) . '.php';
|
||||
|
||||
if (@file_exists($path))
|
||||
{
|
||||
include_once $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
libraries/f0f/config/domain/dispatcher.php
Normal file
74
libraries/f0f/config/domain/dispatcher.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage config
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2, or later
|
||||
*/
|
||||
|
||||
defined('F0F_INCLUDED') or die();
|
||||
|
||||
/**
|
||||
* Configuration parser for the dispatcher-specific settings
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.1
|
||||
*/
|
||||
class F0FConfigDomainDispatcher implements F0FConfigDomainInterface
|
||||
{
|
||||
/**
|
||||
* Parse the XML data, adding them to the $ret array
|
||||
*
|
||||
* @param SimpleXMLElement $xml The XML data of the component's configuration area
|
||||
* @param array &$ret The parsed data, in the form of a hash array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function parseDomain(SimpleXMLElement $xml, array &$ret)
|
||||
{
|
||||
// Initialise
|
||||
$ret['dispatcher'] = array();
|
||||
|
||||
// Parse the dispatcher configuration
|
||||
$dispatcherData = $xml->dispatcher;
|
||||
|
||||
// Sanity check
|
||||
|
||||
if (empty($dispatcherData))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$options = $xml->xpath('dispatcher/option');
|
||||
|
||||
if (!empty($options))
|
||||
{
|
||||
foreach ($options as $option)
|
||||
{
|
||||
$key = (string) $option['name'];
|
||||
$ret['dispatcher'][$key] = (string) $option;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a configuration variable
|
||||
*
|
||||
* @param string &$configuration Configuration variables (hashed array)
|
||||
* @param string $var The variable we want to fetch
|
||||
* @param mixed $default Default value
|
||||
*
|
||||
* @return mixed The variable's value
|
||||
*/
|
||||
public function get(&$configuration, $var, $default)
|
||||
{
|
||||
if (isset($configuration['dispatcher'][$var]))
|
||||
{
|
||||
return $configuration['dispatcher'][$var];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
libraries/f0f/config/domain/interface.php
Normal file
41
libraries/f0f/config/domain/interface.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage config
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2, or later
|
||||
*/
|
||||
|
||||
defined('F0F_INCLUDED') or die();
|
||||
|
||||
/**
|
||||
* The Interface of an F0FConfigDomain class. The methods are used to parse and
|
||||
* privision sensible information to consumers. F0FConfigProvider acts as an
|
||||
* adapter to the F0FConfigDomain classes.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.1
|
||||
*/
|
||||
interface F0FConfigDomainInterface
|
||||
{
|
||||
/**
|
||||
* Parse the XML data, adding them to the $ret array
|
||||
*
|
||||
* @param SimpleXMLElement $xml The XML data of the component's configuration area
|
||||
* @param array &$ret The parsed data, in the form of a hash array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function parseDomain(SimpleXMLElement $xml, array &$ret);
|
||||
|
||||
/**
|
||||
* Return a configuration variable
|
||||
*
|
||||
* @param string &$configuration Configuration variables (hashed array)
|
||||
* @param string $var The variable we want to fetch
|
||||
* @param mixed $default Default value
|
||||
*
|
||||
* @return mixed The variable's value
|
||||
*/
|
||||
public function get(&$configuration, $var, $default);
|
||||
}
|
||||
262
libraries/f0f/config/domain/tables.php
Normal file
262
libraries/f0f/config/domain/tables.php
Normal file
@ -0,0 +1,262 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage config
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2, or later
|
||||
*/
|
||||
|
||||
defined('F0F_INCLUDED') or die();
|
||||
|
||||
/**
|
||||
* Configuration parser for the tables-specific settings
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.1
|
||||
*/
|
||||
class F0FConfigDomainTables implements F0FConfigDomainInterface
|
||||
{
|
||||
/**
|
||||
* Parse the XML data, adding them to the $ret array
|
||||
*
|
||||
* @param SimpleXMLElement $xml The XML data of the component's configuration area
|
||||
* @param array &$ret The parsed data, in the form of a hash array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function parseDomain(SimpleXMLElement $xml, array &$ret)
|
||||
{
|
||||
// Initialise
|
||||
$ret['tables'] = array();
|
||||
|
||||
// Parse table configuration
|
||||
$tableData = $xml->xpath('table');
|
||||
|
||||
// Sanity check
|
||||
if (empty($tableData))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($tableData as $aTable)
|
||||
{
|
||||
$key = (string) $aTable['name'];
|
||||
|
||||
$ret['tables'][$key]['behaviors'] = (string) $aTable->behaviors;
|
||||
$ret['tables'][$key]['tablealias'] = $aTable->xpath('tablealias');
|
||||
$ret['tables'][$key]['fields'] = array();
|
||||
$ret['tables'][$key]['relations'] = array();
|
||||
|
||||
$fieldData = $aTable->xpath('field');
|
||||
|
||||
if (!empty($fieldData))
|
||||
{
|
||||
foreach ($fieldData as $field)
|
||||
{
|
||||
$k = (string) $field['name'];
|
||||
$ret['tables'][$key]['fields'][$k] = (string) $field;
|
||||
}
|
||||
}
|
||||
|
||||
$relationsData = $aTable->xpath('relation');
|
||||
|
||||
if (!empty($relationsData))
|
||||
{
|
||||
foreach ($relationsData as $relationData)
|
||||
{
|
||||
$type = (string)$relationData['type'];
|
||||
$itemName = (string)$relationData['name'];
|
||||
|
||||
if (empty($type) || empty($itemName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$tableClass = (string)$relationData['tableClass'];
|
||||
$localKey = (string)$relationData['localKey'];
|
||||
$remoteKey = (string)$relationData['remoteKey'];
|
||||
$ourPivotKey = (string)$relationData['ourPivotKey'];
|
||||
$theirPivotKey = (string)$relationData['theirPivotKey'];
|
||||
$pivotTable = (string)$relationData['pivotTable'];
|
||||
$default = (string)$relationData['default'];
|
||||
|
||||
$default = !in_array($default, array('no', 'false', 0));
|
||||
|
||||
$relation = array(
|
||||
'type' => $type,
|
||||
'itemName' => $itemName,
|
||||
'tableClass' => empty($tableClass) ? null : $tableClass,
|
||||
'localKey' => empty($localKey) ? null : $localKey,
|
||||
'remoteKey' => empty($remoteKey) ? null : $remoteKey,
|
||||
'default' => $default,
|
||||
);
|
||||
|
||||
if (!empty($ourPivotKey) || !empty($theirPivotKey) || !empty($pivotTable))
|
||||
{
|
||||
$relation['ourPivotKey'] = empty($ourPivotKey) ? null : $ourPivotKey;
|
||||
$relation['theirPivotKey'] = empty($theirPivotKey) ? null : $theirPivotKey;
|
||||
$relation['pivotTable'] = empty($pivotTable) ? null : $pivotTable;
|
||||
}
|
||||
|
||||
$ret['tables'][$key]['relations'][] = $relation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a configuration variable
|
||||
*
|
||||
* @param string &$configuration Configuration variables (hashed array)
|
||||
* @param string $var The variable we want to fetch
|
||||
* @param mixed $default Default value
|
||||
*
|
||||
* @return mixed The variable's value
|
||||
*/
|
||||
public function get(&$configuration, $var, $default)
|
||||
{
|
||||
$parts = explode('.', $var);
|
||||
|
||||
$view = $parts[0];
|
||||
$method = 'get' . ucfirst($parts[1]);
|
||||
|
||||
if (!method_exists($this, $method))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
array_shift($parts);
|
||||
array_shift($parts);
|
||||
|
||||
$ret = $this->$method($view, $configuration, $parts, $default);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to return the magic field mapping
|
||||
*
|
||||
* @param string $table The table for which we will be fetching a field map
|
||||
* @param array &$configuration The configuration parameters hash array
|
||||
* @param array $params Extra options; key 0 defines the table we want to fetch
|
||||
* @param string $default Default magic field mapping; empty if not defined
|
||||
*
|
||||
* @return array Field map
|
||||
*/
|
||||
protected function getField($table, &$configuration, $params, $default = '')
|
||||
{
|
||||
$fieldmap = array();
|
||||
|
||||
if (isset($configuration['tables']['*']) && isset($configuration['tables']['*']['fields']))
|
||||
{
|
||||
$fieldmap = $configuration['tables']['*']['fields'];
|
||||
}
|
||||
|
||||
if (isset($configuration['tables'][$table]) && isset($configuration['tables'][$table]['fields']))
|
||||
{
|
||||
$fieldmap = array_merge($fieldmap, $configuration['tables'][$table]['fields']);
|
||||
}
|
||||
|
||||
$map = $default;
|
||||
|
||||
if (empty($params[0]))
|
||||
{
|
||||
$map = $fieldmap;
|
||||
}
|
||||
elseif (isset($fieldmap[$params[0]]))
|
||||
{
|
||||
$map = $fieldmap[$params[0]];
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to get table alias
|
||||
*
|
||||
* @param string $table The table for which we will be fetching table alias
|
||||
* @param array &$configuration The configuration parameters hash array
|
||||
* @param array $params Extra options; key 0 defines the table we want to fetch
|
||||
* @param string $default Default table alias
|
||||
*
|
||||
* @return string Table alias
|
||||
*/
|
||||
protected function getTablealias($table, &$configuration, $params, $default = '')
|
||||
{
|
||||
$tablealias = $default;
|
||||
|
||||
if (isset($configuration['tables']['*'])
|
||||
&& isset($configuration['tables']['*']['tablealias'])
|
||||
&& isset($configuration['tables']['*']['tablealias'][0]))
|
||||
{
|
||||
$tablealias = (string) $configuration['tables']['*']['tablealias'][0];
|
||||
}
|
||||
|
||||
if (isset($configuration['tables'][$table])
|
||||
&& isset($configuration['tables'][$table]['tablealias'])
|
||||
&& isset($configuration['tables'][$table]['tablealias'][0]))
|
||||
{
|
||||
$tablealias = (string) $configuration['tables'][$table]['tablealias'][0];
|
||||
}
|
||||
|
||||
return $tablealias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to get table behaviours
|
||||
*
|
||||
* @param string $table The table for which we will be fetching table alias
|
||||
* @param array &$configuration The configuration parameters hash array
|
||||
* @param array $params Extra options; key 0 defines the table we want to fetch
|
||||
* @param string $default Default table alias
|
||||
*
|
||||
* @return string Table behaviours
|
||||
*/
|
||||
protected function getBehaviors($table, &$configuration, $params, $default = '')
|
||||
{
|
||||
$behaviors = $default;
|
||||
|
||||
if (isset($configuration['tables']['*'])
|
||||
&& isset($configuration['tables']['*']['behaviors']))
|
||||
{
|
||||
$behaviors = (string) $configuration['tables']['*']['behaviors'];
|
||||
}
|
||||
|
||||
if (isset($configuration['tables'][$table])
|
||||
&& isset($configuration['tables'][$table]['behaviors']))
|
||||
{
|
||||
$behaviors = (string) $configuration['tables'][$table]['behaviors'];
|
||||
}
|
||||
|
||||
return $behaviors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to get table relations
|
||||
*
|
||||
* @param string $table The table for which we will be fetching table alias
|
||||
* @param array &$configuration The configuration parameters hash array
|
||||
* @param array $params Extra options; key 0 defines the table we want to fetch
|
||||
* @param string $default Default table alias
|
||||
*
|
||||
* @return array Table relations
|
||||
*/
|
||||
protected function getRelations($table, &$configuration, $params, $default = '')
|
||||
{
|
||||
$relations = $default;
|
||||
|
||||
if (isset($configuration['tables']['*'])
|
||||
&& isset($configuration['tables']['*']['relations']))
|
||||
{
|
||||
$relations = $configuration['tables']['*']['relations'];
|
||||
}
|
||||
|
||||
if (isset($configuration['tables'][$table])
|
||||
&& isset($configuration['tables'][$table]['relations']))
|
||||
{
|
||||
$relations = $configuration['tables'][$table]['relations'];
|
||||
}
|
||||
|
||||
return $relations;
|
||||
}
|
||||
}
|
||||
302
libraries/f0f/config/domain/views.php
Normal file
302
libraries/f0f/config/domain/views.php
Normal file
@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage config
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2, or later
|
||||
*/
|
||||
|
||||
defined('F0F_INCLUDED') or die();
|
||||
|
||||
/**
|
||||
* Configuration parser for the view-specific settings
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.1
|
||||
*/
|
||||
class F0FConfigDomainViews implements F0FConfigDomainInterface
|
||||
{
|
||||
/**
|
||||
* Parse the XML data, adding them to the $ret array
|
||||
*
|
||||
* @param SimpleXMLElement $xml The XML data of the component's configuration area
|
||||
* @param array &$ret The parsed data, in the form of a hash array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function parseDomain(SimpleXMLElement $xml, array &$ret)
|
||||
{
|
||||
// Initialise
|
||||
$ret['views'] = array();
|
||||
|
||||
// Parse view configuration
|
||||
$viewData = $xml->xpath('view');
|
||||
|
||||
// Sanity check
|
||||
|
||||
if (empty($viewData))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($viewData as $aView)
|
||||
{
|
||||
$key = (string) $aView['name'];
|
||||
|
||||
// Parse ACL options
|
||||
$ret['views'][$key]['acl'] = array();
|
||||
$aclData = $aView->xpath('acl/task');
|
||||
|
||||
if (!empty($aclData))
|
||||
{
|
||||
foreach ($aclData as $acl)
|
||||
{
|
||||
$k = (string) $acl['name'];
|
||||
$ret['views'][$key]['acl'][$k] = (string) $acl;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse taskmap
|
||||
$ret['views'][$key]['taskmap'] = array();
|
||||
$taskmapData = $aView->xpath('taskmap/task');
|
||||
|
||||
if (!empty($taskmapData))
|
||||
{
|
||||
foreach ($taskmapData as $map)
|
||||
{
|
||||
$k = (string) $map['name'];
|
||||
$ret['views'][$key]['taskmap'][$k] = (string) $map;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse controller configuration
|
||||
$ret['views'][$key]['config'] = array();
|
||||
$optionData = $aView->xpath('config/option');
|
||||
|
||||
if (!empty($optionData))
|
||||
{
|
||||
foreach ($optionData as $option)
|
||||
{
|
||||
$k = (string) $option['name'];
|
||||
$ret['views'][$key]['config'][$k] = (string) $option;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the toolbar
|
||||
$ret['views'][$key]['toolbar'] = array();
|
||||
$toolBars = $aView->xpath('toolbar');
|
||||
|
||||
if (!empty($toolBars))
|
||||
{
|
||||
foreach ($toolBars as $toolBar)
|
||||
{
|
||||
$taskName = isset($toolBar['task']) ? (string) $toolBar['task'] : '*';
|
||||
|
||||
// If a toolbar title is specified, create a title element.
|
||||
if (isset($toolBar['title']))
|
||||
{
|
||||
$ret['views'][$key]['toolbar'][$taskName]['title'] = array(
|
||||
'value' => (string) $toolBar['title']
|
||||
);
|
||||
}
|
||||
|
||||
// Parse the toolbar buttons data
|
||||
$toolbarData = $toolBar->xpath('button');
|
||||
|
||||
if (!empty($toolbarData))
|
||||
{
|
||||
foreach ($toolbarData as $button)
|
||||
{
|
||||
$k = (string) $button['type'];
|
||||
$ret['views'][$key]['toolbar'][$taskName][$k] = current($button->attributes());
|
||||
$ret['views'][$key]['toolbar'][$taskName][$k]['value'] = (string) $button;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a configuration variable
|
||||
*
|
||||
* @param string &$configuration Configuration variables (hashed array)
|
||||
* @param string $var The variable we want to fetch
|
||||
* @param mixed $default Default value
|
||||
*
|
||||
* @return mixed The variable's value
|
||||
*/
|
||||
public function get(&$configuration, $var, $default)
|
||||
{
|
||||
$parts = explode('.', $var);
|
||||
|
||||
$view = $parts[0];
|
||||
$method = 'get' . ucfirst($parts[1]);
|
||||
|
||||
if (!method_exists($this, $method))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
array_shift($parts);
|
||||
array_shift($parts);
|
||||
|
||||
$ret = $this->$method($view, $configuration, $parts, $default);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to return the task map for a view
|
||||
*
|
||||
* @param string $view The view for which we will be fetching a task map
|
||||
* @param array &$configuration The configuration parameters hash array
|
||||
* @param array $params Extra options (not used)
|
||||
* @param array $default ßDefault task map; empty array if not provided
|
||||
*
|
||||
* @return array The task map as a hash array in the format task => method
|
||||
*/
|
||||
protected function getTaskmap($view, &$configuration, $params, $default = array())
|
||||
{
|
||||
$taskmap = array();
|
||||
|
||||
if (isset($configuration['views']['*']) && isset($configuration['views']['*']['taskmap']))
|
||||
{
|
||||
$taskmap = $configuration['views']['*']['taskmap'];
|
||||
}
|
||||
|
||||
if (isset($configuration['views'][$view]) && isset($configuration['views'][$view]['taskmap']))
|
||||
{
|
||||
$taskmap = array_merge($taskmap, $configuration['views'][$view]['taskmap']);
|
||||
}
|
||||
|
||||
if (empty($taskmap))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $taskmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to return the ACL mapping (privilege required to access
|
||||
* a specific task) for the given view's tasks
|
||||
*
|
||||
* @param string $view The view for which we will be fetching a task map
|
||||
* @param array &$configuration The configuration parameters hash array
|
||||
* @param array $params Extra options; key 0 defines the task we want to fetch
|
||||
* @param string $default Default ACL option; empty (no ACL check) if not defined
|
||||
*
|
||||
* @return string The privilege required to access this view
|
||||
*/
|
||||
protected function getAcl($view, &$configuration, $params, $default = '')
|
||||
{
|
||||
$aclmap = array();
|
||||
|
||||
if (isset($configuration['views']['*']) && isset($configuration['views']['*']['acl']))
|
||||
{
|
||||
$aclmap = $configuration['views']['*']['acl'];
|
||||
}
|
||||
|
||||
if (isset($configuration['views'][$view]) && isset($configuration['views'][$view]['acl']))
|
||||
{
|
||||
$aclmap = array_merge($aclmap, $configuration['views'][$view]['acl']);
|
||||
}
|
||||
|
||||
$acl = $default;
|
||||
|
||||
if (isset($aclmap['*']))
|
||||
{
|
||||
$acl = $aclmap['*'];
|
||||
}
|
||||
|
||||
if (isset($aclmap[$params[0]]))
|
||||
{
|
||||
$acl = $aclmap[$params[0]];
|
||||
}
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to return the a configuration option for the view. These
|
||||
* are equivalent to $config array options passed to the Controller
|
||||
*
|
||||
* @param string $view The view for which we will be fetching a task map
|
||||
* @param array &$configuration The configuration parameters hash array
|
||||
* @param array $params Extra options; key 0 defines the option variable we want to fetch
|
||||
* @param mixed $default Default option; null if not defined
|
||||
*
|
||||
* @return string The setting for the requested option
|
||||
*/
|
||||
protected function getConfig($view, &$configuration, $params, $default = null)
|
||||
{
|
||||
$ret = $default;
|
||||
|
||||
if (isset($configuration['views']['*'])
|
||||
&& isset($configuration['views']['*']['config'])
|
||||
&& isset($configuration['views']['*']['config'][$params[0]]))
|
||||
{
|
||||
$ret = $configuration['views']['*']['config'][$params[0]];
|
||||
}
|
||||
|
||||
if (isset($configuration['views'][$view])
|
||||
&& isset($configuration['views'][$view]['config'])
|
||||
&& isset($configuration['views'][$view]['config'][$params[0]]))
|
||||
{
|
||||
$ret = $configuration['views'][$view]['config'][$params[0]];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to return the toolbar infos.
|
||||
*
|
||||
* @param string $view The view for which we will be fetching buttons
|
||||
* @param array &$configuration The configuration parameters hash array
|
||||
* @param array $params Extra options
|
||||
* @param string $default Default option
|
||||
*
|
||||
* @return string The toolbar data for this view
|
||||
*/
|
||||
protected function getToolbar($view, &$configuration, $params, $default = '')
|
||||
{
|
||||
$toolbar = array();
|
||||
|
||||
if (isset($configuration['views']['*'])
|
||||
&& isset($configuration['views']['*']['toolbar'])
|
||||
&& isset($configuration['views']['*']['toolbar']['*']))
|
||||
{
|
||||
$toolbar = $configuration['views']['*']['toolbar']['*'];
|
||||
}
|
||||
|
||||
if (isset($configuration['views']['*'])
|
||||
&& isset($configuration['views']['*']['toolbar'])
|
||||
&& isset($configuration['views']['*']['toolbar'][$params[0]]))
|
||||
{
|
||||
$toolbar = array_merge($toolbar, $configuration['views']['*']['toolbar'][$params[0]]);
|
||||
}
|
||||
|
||||
if (isset($configuration['views'][$view])
|
||||
&& isset($configuration['views'][$view]['toolbar'])
|
||||
&& isset($configuration['views'][$view]['toolbar']['*']))
|
||||
{
|
||||
$toolbar = array_merge($toolbar, $configuration['views'][$view]['toolbar']['*']);
|
||||
}
|
||||
|
||||
if (isset($configuration['views'][$view])
|
||||
&& isset($configuration['views'][$view]['toolbar'])
|
||||
&& isset($configuration['views'][$view]['toolbar'][$params[0]]))
|
||||
{
|
||||
$toolbar = array_merge($toolbar, $configuration['views'][$view]['toolbar'][$params[0]]);
|
||||
}
|
||||
|
||||
if (empty($toolbar))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $toolbar;
|
||||
}
|
||||
}
|
||||
212
libraries/f0f/config/provider.php
Normal file
212
libraries/f0f/config/provider.php
Normal file
@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage config
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2, or later
|
||||
*/
|
||||
|
||||
defined('F0F_INCLUDED') or die();
|
||||
|
||||
/**
|
||||
* Reads and parses the fof.xml file in the back-end of a F0F-powered component,
|
||||
* provisioning the data to the rest of the F0F framework
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.1
|
||||
*/
|
||||
class F0FConfigProvider
|
||||
{
|
||||
/**
|
||||
* Cache of F0F components' configuration variables
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $configurations = array();
|
||||
|
||||
/**
|
||||
* Parses the configuration of the specified component
|
||||
*
|
||||
* @param string $component The name of the component, e.g. com_foobar
|
||||
* @param boolean $force Force reload even if it's already parsed?
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function parseComponent($component, $force = false)
|
||||
{
|
||||
if (!$force && isset(self::$configurations[$component]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (F0FPlatform::getInstance()->isCli())
|
||||
{
|
||||
$order = array('cli', 'backend');
|
||||
}
|
||||
elseif (F0FPlatform::getInstance()->isBackend())
|
||||
{
|
||||
$order = array('backend');
|
||||
}
|
||||
else
|
||||
{
|
||||
$order = array('frontend');
|
||||
}
|
||||
|
||||
$order[] = 'common';
|
||||
|
||||
$order = array_reverse($order);
|
||||
self::$configurations[$component] = array();
|
||||
|
||||
foreach ($order as $area)
|
||||
{
|
||||
$config = $this->parseComponentArea($component, $area);
|
||||
self::$configurations[$component] = array_merge_recursive(self::$configurations[$component], $config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of a variable. Variables use a dot notation, e.g.
|
||||
* view.config.whatever where the first part is the domain, the rest of the
|
||||
* parts specify the path to the variable.
|
||||
*
|
||||
* @param string $variable The variable name
|
||||
* @param mixed $default The default value, or null if not specified
|
||||
*
|
||||
* @return mixed The value of the variable
|
||||
*/
|
||||
public function get($variable, $default = null)
|
||||
{
|
||||
static $domains = null;
|
||||
|
||||
if (is_null($domains))
|
||||
{
|
||||
$domains = $this->getDomains();
|
||||
}
|
||||
|
||||
list($component, $domain, $var) = explode('.', $variable, 3);
|
||||
|
||||
if (!isset(self::$configurations[$component]))
|
||||
{
|
||||
$this->parseComponent($component);
|
||||
}
|
||||
|
||||
if (!in_array($domain, $domains))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
$class = 'F0FConfigDomain' . ucfirst($domain);
|
||||
$o = new $class;
|
||||
|
||||
return $o->get(self::$configurations[$component], $var, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the configuration options of a specific component area
|
||||
*
|
||||
* @param string $component Which component's cionfiguration to parse
|
||||
* @param string $area Which area to parse (frontend, backend, cli)
|
||||
*
|
||||
* @return array A hash array with the configuration data
|
||||
*/
|
||||
protected function parseComponentArea($component, $area)
|
||||
{
|
||||
// Initialise the return array
|
||||
$ret = array();
|
||||
|
||||
// Get the folders of the component
|
||||
$componentPaths = F0FPlatform::getInstance()->getComponentBaseDirs($component);
|
||||
$filesystem = F0FPlatform::getInstance()->getIntegrationObject('filesystem');
|
||||
|
||||
// Check that the path exists
|
||||
$path = $componentPaths['admin'];
|
||||
$path = $filesystem->pathCheck($path);
|
||||
|
||||
if (!$filesystem->folderExists($path))
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// Read the filename if it exists
|
||||
$filename = $path . '/fof.xml';
|
||||
|
||||
if (!$filesystem->fileExists($filename))
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$data = file_get_contents($filename);
|
||||
|
||||
// Load the XML data in a SimpleXMLElement object
|
||||
$xml = simplexml_load_string($data);
|
||||
|
||||
if (!($xml instanceof SimpleXMLElement))
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// Get this area's data
|
||||
$areaData = $xml->xpath('//' . $area);
|
||||
|
||||
if (empty($areaData))
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$xml = array_shift($areaData);
|
||||
|
||||
// Parse individual configuration domains
|
||||
$domains = $this->getDomains();
|
||||
|
||||
foreach ($domains as $dom)
|
||||
{
|
||||
$class = 'F0FConfigDomain' . ucfirst($dom);
|
||||
|
||||
if (class_exists($class, true))
|
||||
{
|
||||
$o = new $class;
|
||||
$o->parseDomain($xml, $ret);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, return the result
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of the available configuration domain adapters
|
||||
*
|
||||
* @return array A list of the available domains
|
||||
*/
|
||||
protected function getDomains()
|
||||
{
|
||||
static $domains = array();
|
||||
|
||||
if (empty($domains))
|
||||
{
|
||||
$filesystem = F0FPlatform::getInstance()->getIntegrationObject('filesystem');
|
||||
|
||||
$files = $filesystem->folderFiles(__DIR__ . '/domain', '.php');
|
||||
|
||||
if (!empty($files))
|
||||
{
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$domain = basename($file, '.php');
|
||||
|
||||
if ($domain == 'interface')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$domain = preg_replace('/[^A-Za-z0-9]/', '', $domain);
|
||||
$domains[] = $domain;
|
||||
}
|
||||
|
||||
$domains = array_unique($domains);
|
||||
}
|
||||
}
|
||||
|
||||
return $domains;
|
||||
}
|
||||
}
|
||||
3413
libraries/f0f/controller/controller.php
Normal file
3413
libraries/f0f/controller/controller.php
Normal file
File diff suppressed because it is too large
Load Diff
199
libraries/f0f/database/database.php
Normal file
199
libraries/f0f/database/database.php
Normal file
@ -0,0 +1,199 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Database connector class.
|
||||
*
|
||||
* @since 11.1
|
||||
* @deprecated 13.3 (Platform) & 4.0 (CMS)
|
||||
*/
|
||||
abstract class F0FDatabase
|
||||
{
|
||||
/**
|
||||
* Execute the SQL statement.
|
||||
*
|
||||
* @return mixed A database cursor resource on success, boolean false on failure.
|
||||
*
|
||||
* @since 11.1
|
||||
* @throws RuntimeException
|
||||
* @deprecated 13.1 (Platform) & 4.0 (CMS)
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add('F0FDatabase::query() is deprecated, use F0FDatabaseDriver::execute() instead.', JLog::WARNING, 'deprecated');
|
||||
}
|
||||
|
||||
return $this->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of available database connectors. The list will only be populated with connectors that both
|
||||
* the class exists and the static test method returns true. This gives us the ability to have a multitude
|
||||
* of connector classes that are self-aware as to whether or not they are able to be used on a given system.
|
||||
*
|
||||
* @return array An array of available database connectors.
|
||||
*
|
||||
* @since 11.1
|
||||
* @deprecated 13.1 (Platform) & 4.0 (CMS)
|
||||
*/
|
||||
public static function getConnectors()
|
||||
{
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add('F0FDatabase::getConnectors() is deprecated, use F0FDatabaseDriver::getConnectors() instead.', JLog::WARNING, 'deprecated');
|
||||
}
|
||||
|
||||
return F0FDatabaseDriver::getConnectors();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the error message from the database connection.
|
||||
*
|
||||
* @param boolean $escaped True to escape the message string for use in JavaScript.
|
||||
*
|
||||
* @return string The error message for the most recent query.
|
||||
*
|
||||
* @deprecated 13.3 (Platform) & 4.0 (CMS)
|
||||
* @since 11.1
|
||||
*/
|
||||
public function getErrorMsg($escaped = false)
|
||||
{
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add('F0FDatabase::getErrorMsg() is deprecated, use exception handling instead.', JLog::WARNING, 'deprecated');
|
||||
}
|
||||
|
||||
if ($escaped)
|
||||
{
|
||||
return addslashes($this->errorMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->errorMsg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the error number from the database connection.
|
||||
*
|
||||
* @return integer The error number for the most recent query.
|
||||
*
|
||||
* @since 11.1
|
||||
* @deprecated 13.3 (Platform) & 4.0 (CMS)
|
||||
*/
|
||||
public function getErrorNum()
|
||||
{
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add('F0FDatabase::getErrorNum() is deprecated, use exception handling instead.', JLog::WARNING, 'deprecated');
|
||||
}
|
||||
|
||||
return $this->errorNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to return a F0FDatabaseDriver instance based on the given options. There are three global options and then
|
||||
* the rest are specific to the database driver. The 'driver' option defines which F0FDatabaseDriver class is
|
||||
* used for the connection -- the default is 'mysqli'. The 'database' option determines which database is to
|
||||
* be used for the connection. The 'select' option determines whether the connector should automatically select
|
||||
* the chosen database.
|
||||
*
|
||||
* Instances are unique to the given options and new objects are only created when a unique options array is
|
||||
* passed into the method. This ensures that we don't end up with unnecessary database connection resources.
|
||||
*
|
||||
* @param array $options Parameters to be passed to the database driver.
|
||||
*
|
||||
* @return F0FDatabaseDriver A database object.
|
||||
*
|
||||
* @since 11.1
|
||||
* @deprecated 13.1 (Platform) & 4.0 (CMS)
|
||||
*/
|
||||
public static function getInstance($options = array())
|
||||
{
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add('F0FDatabase::getInstance() is deprecated, use F0FDatabaseDriver::getInstance() instead.', JLog::WARNING, 'deprecated');
|
||||
}
|
||||
|
||||
return F0FDatabaseDriver::getInstance($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a string of multiple queries into an array of individual queries.
|
||||
*
|
||||
* @param string $query Input SQL string with which to split into individual queries.
|
||||
*
|
||||
* @return array The queries from the input string separated into an array.
|
||||
*
|
||||
* @since 11.1
|
||||
* @deprecated 13.1 (Platform) & 4.0 (CMS)
|
||||
*/
|
||||
public static function splitSql($query)
|
||||
{
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add('F0FDatabase::splitSql() is deprecated, use F0FDatabaseDriver::splitSql() instead.', JLog::WARNING, 'deprecated');
|
||||
}
|
||||
|
||||
return F0FDatabaseDriver::splitSql($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the most recent error message for the database connector.
|
||||
*
|
||||
* @param boolean $showSQL True to display the SQL statement sent to the database as well as the error.
|
||||
*
|
||||
* @return string The error message for the most recent query.
|
||||
*
|
||||
* @since 11.1
|
||||
* @deprecated 13.3 (Platform) & 4.0 (CMS)
|
||||
*/
|
||||
public function stderr($showSQL = false)
|
||||
{
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add('F0FDatabase::stderr() is deprecated.', JLog::WARNING, 'deprecated');
|
||||
}
|
||||
|
||||
if ($this->errorNum != 0)
|
||||
{
|
||||
return JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $this->errorNum, $this->errorMsg)
|
||||
. ($showSQL ? "<br />SQL = <pre>$this->sql</pre>" : '');
|
||||
}
|
||||
else
|
||||
{
|
||||
return JText::_('JLIB_DATABASE_FUNCTION_NOERROR');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the connector is available.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @since 11.1
|
||||
* @deprecated 12.3 (Platform) & 4.0 (CMS) - Use F0FDatabaseDriver::isSupported() instead.
|
||||
*/
|
||||
public static function test()
|
||||
{
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add('F0FDatabase::test() is deprecated. Use F0FDatabaseDriver::isSupported() instead.', JLog::WARNING, 'deprecated');
|
||||
}
|
||||
|
||||
return static::isSupported();
|
||||
}
|
||||
}
|
||||
2255
libraries/f0f/database/driver.php
Normal file
2255
libraries/f0f/database/driver.php
Normal file
File diff suppressed because it is too large
Load Diff
778
libraries/f0f/database/driver/joomla.php
Normal file
778
libraries/f0f/database/driver/joomla.php
Normal file
@ -0,0 +1,778 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* This crazy three line bit is required to convince Joomla! to load JDatabaseInterface which is on the same file as the
|
||||
* abstract JDatabaseDriver class for reasons that beat me. It makes no sense. Furthermore, jimport on Joomla! 3.4
|
||||
* doesn't seem to actually load the file, merely registering the association in the autoloader. Hence the class_exists
|
||||
* in here.
|
||||
*/
|
||||
jimport('joomla.database.driver');
|
||||
jimport('joomla.database.driver.mysqli');
|
||||
class_exists('JDatabaseDriver', true);
|
||||
|
||||
/**
|
||||
* Joomla! pass-through database driver.
|
||||
*/
|
||||
class F0FDatabaseDriverJoomla extends F0FDatabase implements F0FDatabaseInterface
|
||||
{
|
||||
/** @var F0FDatabase The real database connection object */
|
||||
private $dbo;
|
||||
|
||||
/**
|
||||
* @var string The character(s) used to quote SQL statement names such as table names or field names,
|
||||
* etc. The child classes should define this as necessary. If a single character string the
|
||||
* same character is used for both sides of the quoted name, else the first character will be
|
||||
* used for the opening quote and the second for the closing quote.
|
||||
* @since 11.1
|
||||
*/
|
||||
protected $nameQuote = '';
|
||||
|
||||
/**
|
||||
* Is this driver supported
|
||||
*
|
||||
* @since 11.2
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Database object constructor
|
||||
*
|
||||
* @param array $options List of options used to configure the connection
|
||||
*/
|
||||
public function __construct($options = array())
|
||||
{
|
||||
// Get best matching Akeeba Backup driver instance
|
||||
$this->dbo = JFactory::getDbo();
|
||||
|
||||
$reflection = new ReflectionClass($this->dbo);
|
||||
|
||||
try
|
||||
{
|
||||
$refProp = $reflection->getProperty('nameQuote');
|
||||
$refProp->setAccessible(true);
|
||||
$this->nameQuote = $refProp->getValue($this->dbo);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$this->nameQuote = '`';
|
||||
}
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
if (method_exists($this->dbo, 'close'))
|
||||
{
|
||||
$this->dbo->close();
|
||||
}
|
||||
elseif (method_exists($this->dbo, 'disconnect'))
|
||||
{
|
||||
$this->dbo->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public function disconnect()
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
public function open()
|
||||
{
|
||||
if (method_exists($this->dbo, 'open'))
|
||||
{
|
||||
$this->dbo->open();
|
||||
}
|
||||
elseif (method_exists($this->dbo, 'connect'))
|
||||
{
|
||||
$this->dbo->connect();
|
||||
}
|
||||
}
|
||||
|
||||
public function connect()
|
||||
{
|
||||
$this->open();
|
||||
}
|
||||
|
||||
public function connected()
|
||||
{
|
||||
if (method_exists($this->dbo, 'connected'))
|
||||
{
|
||||
return $this->dbo->connected();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function escape($text, $extra = false)
|
||||
{
|
||||
return $this->dbo->escape($text, $extra);
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
if (method_exists($this->dbo, 'execute'))
|
||||
{
|
||||
return $this->dbo->execute();
|
||||
}
|
||||
|
||||
return $this->dbo->query();
|
||||
}
|
||||
|
||||
public function getAffectedRows()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getAffectedRows'))
|
||||
{
|
||||
return $this->dbo->getAffectedRows();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getCollation()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getCollation'))
|
||||
{
|
||||
return $this->dbo->getCollation();
|
||||
}
|
||||
|
||||
return 'utf8_general_ci';
|
||||
}
|
||||
|
||||
public function getConnection()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getConnection'))
|
||||
{
|
||||
return $this->dbo->getConnection();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getCount()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getCount'))
|
||||
{
|
||||
return $this->dbo->getCount();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDateFormat()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getDateFormat'))
|
||||
{
|
||||
return $this->dbo->getDateFormat();
|
||||
}
|
||||
|
||||
return 'Y-m-d H:i:s';;
|
||||
}
|
||||
|
||||
public function getMinimum()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getMinimum'))
|
||||
{
|
||||
return $this->dbo->getMinimum();
|
||||
}
|
||||
|
||||
return '5.0.40';
|
||||
}
|
||||
|
||||
public function getNullDate()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getNullDate'))
|
||||
{
|
||||
return $this->dbo->getNullDate();
|
||||
}
|
||||
|
||||
return '0000-00-00 00:00:00';
|
||||
}
|
||||
|
||||
public function getNumRows($cursor = null)
|
||||
{
|
||||
if (method_exists($this->dbo, 'getNumRows'))
|
||||
{
|
||||
return $this->dbo->getNumRows($cursor);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getQuery($new = false)
|
||||
{
|
||||
if (method_exists($this->dbo, 'getQuery'))
|
||||
{
|
||||
return $this->dbo->getQuery($new);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getTableColumns($table, $typeOnly = true)
|
||||
{
|
||||
if (method_exists($this->dbo, 'getTableColumns'))
|
||||
{
|
||||
return $this->dbo->getTableColumns($table, $typeOnly);
|
||||
}
|
||||
|
||||
$result = $this->dbo->getTableFields(array($table), $typeOnly);
|
||||
|
||||
return $result[$table];
|
||||
}
|
||||
|
||||
public function getTableKeys($tables)
|
||||
{
|
||||
if (method_exists($this->dbo, 'getTableKeys'))
|
||||
{
|
||||
return $this->dbo->getTableKeys($tables);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getTableList()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getTableList'))
|
||||
{
|
||||
return $this->dbo->getTableList();
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getVersion()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getVersion'))
|
||||
{
|
||||
return $this->dbo->getVersion();
|
||||
}
|
||||
|
||||
return '5.0.40';
|
||||
}
|
||||
|
||||
public function insertid()
|
||||
{
|
||||
if (method_exists($this->dbo, 'insertid'))
|
||||
{
|
||||
return $this->dbo->insertid();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function insertObject($table, &$object, $key = null)
|
||||
{
|
||||
if (method_exists($this->dbo, 'insertObject'))
|
||||
{
|
||||
return $this->dbo->insertObject($table, $object, $key);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadAssoc()
|
||||
{
|
||||
if (method_exists($this->dbo, 'loadAssoc'))
|
||||
{
|
||||
return $this->dbo->loadAssoc();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadAssocList($key = null, $column = null)
|
||||
{
|
||||
if (method_exists($this->dbo, 'loadAssocList'))
|
||||
{
|
||||
return $this->dbo->loadAssocList($key, $column);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadObject($class = 'stdClass')
|
||||
{
|
||||
if (method_exists($this->dbo, 'loadObject'))
|
||||
{
|
||||
return $this->dbo->loadObject($class);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadObjectList($key = '', $class = 'stdClass')
|
||||
{
|
||||
if (method_exists($this->dbo, 'loadObjectList'))
|
||||
{
|
||||
return $this->dbo->loadObjectList($key, $class);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadResult()
|
||||
{
|
||||
if (method_exists($this->dbo, 'loadResult'))
|
||||
{
|
||||
return $this->dbo->loadResult();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadRow()
|
||||
{
|
||||
if (method_exists($this->dbo, 'loadRow'))
|
||||
{
|
||||
return $this->dbo->loadRow();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function loadRowList($key = null)
|
||||
{
|
||||
if (method_exists($this->dbo, 'loadRowList'))
|
||||
{
|
||||
return $this->dbo->loadRowList($key);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function lockTable($tableName)
|
||||
{
|
||||
if (method_exists($this->dbo, 'lockTable'))
|
||||
{
|
||||
return $this->dbo->lockTable($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function quote($text, $escape = true)
|
||||
{
|
||||
if (method_exists($this->dbo, 'quote'))
|
||||
{
|
||||
return $this->dbo->quote($text, $escape);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
public function select($database)
|
||||
{
|
||||
if (method_exists($this->dbo, 'select'))
|
||||
{
|
||||
return $this->dbo->select($database);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setQuery($query, $offset = 0, $limit = 0)
|
||||
{
|
||||
if (method_exists($this->dbo, 'setQuery'))
|
||||
{
|
||||
return $this->dbo->setQuery($query, $offset, $limit);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function transactionCommit($toSavepoint = false)
|
||||
{
|
||||
if (method_exists($this->dbo, 'transactionCommit'))
|
||||
{
|
||||
$this->dbo->transactionCommit($toSavepoint);
|
||||
}
|
||||
}
|
||||
|
||||
public function transactionRollback($toSavepoint = false)
|
||||
{
|
||||
if (method_exists($this->dbo, 'transactionRollback'))
|
||||
{
|
||||
$this->dbo->transactionRollback($toSavepoint);
|
||||
}
|
||||
}
|
||||
|
||||
public function transactionStart($asSavepoint = false)
|
||||
{
|
||||
if (method_exists($this->dbo, 'transactionStart'))
|
||||
{
|
||||
$this->dbo->transactionStart($asSavepoint);
|
||||
}
|
||||
}
|
||||
|
||||
public function unlockTables()
|
||||
{
|
||||
if (method_exists($this->dbo, 'unlockTables'))
|
||||
{
|
||||
return $this->dbo->unlockTables();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function updateObject($table, &$object, $key, $nulls = false)
|
||||
{
|
||||
if (method_exists($this->dbo, 'updateObject'))
|
||||
{
|
||||
return $this->dbo->updateObject($table, $object, $key, $nulls);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getLog()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getLog'))
|
||||
{
|
||||
return $this->dbo->getLog();
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function dropTable($table, $ifExists = true)
|
||||
{
|
||||
if (method_exists($this->dbo, 'dropTable'))
|
||||
{
|
||||
return $this->dbo->dropTable($table, $ifExists);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTableCreate($tables)
|
||||
{
|
||||
if (method_exists($this->dbo, 'getTableCreate'))
|
||||
{
|
||||
return $this->dbo->getTableCreate($tables);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function renameTable($oldTable, $newTable, $backup = null, $prefix = null)
|
||||
{
|
||||
if (method_exists($this->dbo, 'renameTable'))
|
||||
{
|
||||
return $this->dbo->renameTable($oldTable, $newTable, $backup, $prefix);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUtf()
|
||||
{
|
||||
if (method_exists($this->dbo, 'setUtf'))
|
||||
{
|
||||
return $this->dbo->setUtf();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected function freeResult($cursor = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an array of values from the <var>$offset</var> field in each row of the result set from
|
||||
* the database query.
|
||||
*
|
||||
* @param integer $offset The row offset to use to build the result array.
|
||||
*
|
||||
* @return mixed The return value or null if the query failed.
|
||||
*
|
||||
* @since 11.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function loadColumn($offset = 0)
|
||||
{
|
||||
if (method_exists($this->dbo, 'loadColumn'))
|
||||
{
|
||||
return $this->dbo->loadColumn($offset);
|
||||
}
|
||||
|
||||
return $this->dbo->loadResultArray($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap an SQL statement identifier name such as column, table or database names in quotes to prevent injection
|
||||
* risks and reserved word conflicts.
|
||||
*
|
||||
* @param mixed $name The identifier name to wrap in quotes, or an array of identifier names to wrap in quotes.
|
||||
* Each type supports dot-notation name.
|
||||
* @param mixed $as The AS query part associated to $name. It can be string or array, in latter case it has to be
|
||||
* same length of $name; if is null there will not be any AS part for string or array element.
|
||||
*
|
||||
* @return mixed The quote wrapped name, same type of $name.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function quoteName($name, $as = null)
|
||||
{
|
||||
if (is_string($name))
|
||||
{
|
||||
$quotedName = $this->quoteNameStr(explode('.', $name));
|
||||
|
||||
$quotedAs = '';
|
||||
|
||||
if (!is_null($as))
|
||||
{
|
||||
settype($as, 'array');
|
||||
$quotedAs .= ' AS ' . $this->quoteNameStr($as);
|
||||
}
|
||||
|
||||
return $quotedName . $quotedAs;
|
||||
}
|
||||
else
|
||||
{
|
||||
$fin = array();
|
||||
|
||||
if (is_null($as))
|
||||
{
|
||||
foreach ($name as $str)
|
||||
{
|
||||
$fin[] = $this->quoteName($str);
|
||||
}
|
||||
}
|
||||
elseif (is_array($name) && (count($name) == count($as)))
|
||||
{
|
||||
$count = count($name);
|
||||
|
||||
for ($i = 0; $i < $count; $i++)
|
||||
{
|
||||
$fin[] = $this->quoteName($name[$i], $as[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
return $fin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote strings coming from quoteName call.
|
||||
*
|
||||
* @param array $strArr Array of strings coming from quoteName dot-explosion.
|
||||
*
|
||||
* @return string Dot-imploded string of quoted parts.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
protected function quoteNameStr($strArr)
|
||||
{
|
||||
$parts = array();
|
||||
$q = $this->nameQuote;
|
||||
|
||||
foreach ($strArr as $part)
|
||||
{
|
||||
if (is_null($part))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen($q) == 1)
|
||||
{
|
||||
$parts[] = $q . $part . $q;
|
||||
}
|
||||
else
|
||||
{
|
||||
$parts[] = $q{0} . $part . $q{1};
|
||||
}
|
||||
}
|
||||
|
||||
return implode('.', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the error message from the database connection.
|
||||
*
|
||||
* @param boolean $escaped True to escape the message string for use in JavaScript.
|
||||
*
|
||||
* @return string The error message for the most recent query.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function getErrorMsg($escaped = false)
|
||||
{
|
||||
if (method_exists($this->dbo, 'getErrorMsg'))
|
||||
{
|
||||
$errorMessage = $this->dbo->getErrorMsg();
|
||||
}
|
||||
else
|
||||
{
|
||||
$errorMessage = $this->errorMsg;
|
||||
}
|
||||
|
||||
if ($escaped)
|
||||
{
|
||||
return addslashes($errorMessage);
|
||||
}
|
||||
|
||||
return $errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the error number from the database connection.
|
||||
*
|
||||
* @return integer The error number for the most recent query.
|
||||
*
|
||||
* @since 11.1
|
||||
* @deprecated 13.3 (Platform) & 4.0 (CMS)
|
||||
*/
|
||||
public function getErrorNum()
|
||||
{
|
||||
if (method_exists($this->dbo, 'getErrorNum'))
|
||||
{
|
||||
$errorNum = $this->dbo->getErrorNum();
|
||||
}
|
||||
else
|
||||
{
|
||||
$errorNum = $this->getErrorNum;
|
||||
}
|
||||
|
||||
return $errorNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the most recent error message for the database connector.
|
||||
*
|
||||
* @param boolean $showSQL True to display the SQL statement sent to the database as well as the error.
|
||||
*
|
||||
* @return string The error message for the most recent query.
|
||||
*/
|
||||
public function stderr($showSQL = false)
|
||||
{
|
||||
if (method_exists($this->dbo, 'stderr'))
|
||||
{
|
||||
return $this->dbo->stderr($showSQL);
|
||||
}
|
||||
|
||||
return parent::stderr($showSQL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to proxy all calls to the loaded database driver object
|
||||
*/
|
||||
public function __call($name, array $arguments)
|
||||
{
|
||||
if (is_null($this->dbo))
|
||||
{
|
||||
throw new Exception('F0F database driver is not loaded');
|
||||
}
|
||||
|
||||
if (method_exists($this->dbo, $name) || in_array($name, array('q', 'nq', 'qn', 'query')))
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'execute':
|
||||
$name = 'query';
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
$name = 'quote';
|
||||
break;
|
||||
|
||||
case 'qn':
|
||||
case 'nq':
|
||||
switch (count($arguments))
|
||||
{
|
||||
case 0 :
|
||||
$result = $this->quoteName();
|
||||
break;
|
||||
case 1 :
|
||||
$result = $this->quoteName($arguments[0]);
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
$result = $this->quoteName($arguments[0], $arguments[1]);
|
||||
break;
|
||||
}
|
||||
return $result;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
switch (count($arguments))
|
||||
{
|
||||
case 0 :
|
||||
$result = $this->dbo->$name();
|
||||
break;
|
||||
case 1 :
|
||||
$result = $this->dbo->$name($arguments[0]);
|
||||
break;
|
||||
case 2:
|
||||
$result = $this->dbo->$name($arguments[0], $arguments[1]);
|
||||
break;
|
||||
case 3:
|
||||
$result = $this->dbo->$name($arguments[0], $arguments[1], $arguments[2]);
|
||||
break;
|
||||
case 4:
|
||||
$result = $this->dbo->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3]);
|
||||
break;
|
||||
case 5:
|
||||
$result = $this->dbo->$name($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]);
|
||||
break;
|
||||
default:
|
||||
// Resort to using call_user_func_array for many segments
|
||||
$result = call_user_func_array(array($this->dbo, $name), $arguments);
|
||||
}
|
||||
|
||||
if (class_exists('JDatabase') && is_object($result) && ($result instanceof JDatabase))
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \Exception('Method ' . $name . ' not found in F0FDatabase');
|
||||
}
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
if (isset($this->dbo->$name) || property_exists($this->dbo, $name))
|
||||
{
|
||||
return $this->dbo->$name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dbo->$name = null;
|
||||
user_error('Database driver does not support property ' . $name);
|
||||
}
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
if (isset($this->dbo->name) || property_exists($this->dbo, $name))
|
||||
{
|
||||
$this->dbo->$name = $value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dbo->$name = null;
|
||||
user_error('Database driver not support property ' . $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
577
libraries/f0f/database/driver/mysql.php
Normal file
577
libraries/f0f/database/driver/mysql.php
Normal file
@ -0,0 +1,577 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* MySQL database driver
|
||||
*
|
||||
* @see http://dev.mysql.com/doc/
|
||||
* @since 12.1
|
||||
* @deprecated Will be removed when the minimum supported PHP version no longer includes the deprecated PHP `mysql` extension
|
||||
*/
|
||||
class F0FDatabaseDriverMysql extends F0FDatabaseDriverMysqli
|
||||
{
|
||||
/**
|
||||
* The name of the database driver.
|
||||
*
|
||||
* @var string
|
||||
* @since 12.1
|
||||
*/
|
||||
public $name = 'mysql';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $options Array of database options with keys: host, user, password, database, select.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function __construct($options)
|
||||
{
|
||||
// PHP's `mysql` extension is not present in PHP 7, block instantiation in this environment
|
||||
if (PHP_MAJOR_VERSION >= 7)
|
||||
{
|
||||
throw new RuntimeException(
|
||||
'This driver is unsupported in PHP 7, please use the MySQLi or PDO MySQL driver instead.'
|
||||
);
|
||||
}
|
||||
|
||||
// Get some basic values from the options.
|
||||
$options['host'] = (isset($options['host'])) ? $options['host'] : 'localhost';
|
||||
$options['user'] = (isset($options['user'])) ? $options['user'] : 'root';
|
||||
$options['password'] = (isset($options['password'])) ? $options['password'] : '';
|
||||
$options['database'] = (isset($options['database'])) ? $options['database'] : '';
|
||||
$options['select'] = (isset($options['select'])) ? (bool) $options['select'] : true;
|
||||
|
||||
// Finalize initialisation.
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->disconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the database if needed.
|
||||
*
|
||||
* @return void Returns void if the database connected successfully.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if ($this->connection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the MySQL extension for PHP is installed and enabled.
|
||||
if (!self::isSupported())
|
||||
{
|
||||
throw new RuntimeException('Could not connect to MySQL.');
|
||||
}
|
||||
|
||||
// Attempt to connect to the server.
|
||||
if (!($this->connection = @ mysql_connect($this->options['host'], $this->options['user'], $this->options['password'], true)))
|
||||
{
|
||||
throw new RuntimeException('Could not connect to MySQL.');
|
||||
}
|
||||
|
||||
// Set sql_mode to non_strict mode
|
||||
mysql_query("SET @@SESSION.sql_mode = '';", $this->connection);
|
||||
|
||||
// If auto-select is enabled select the given database.
|
||||
if ($this->options['select'] && !empty($this->options['database']))
|
||||
{
|
||||
$this->select($this->options['database']);
|
||||
}
|
||||
|
||||
// Pre-populate the UTF-8 Multibyte compatibility flag based on server version
|
||||
$this->utf8mb4 = $this->serverClaimsUtf8mb4Support();
|
||||
|
||||
// Set the character set (needed for MySQL 4.1.2+).
|
||||
$this->utf = $this->setUtf();
|
||||
|
||||
// Turn MySQL profiling ON in debug mode:
|
||||
if ($this->debug && $this->hasProfiling())
|
||||
{
|
||||
mysql_query("SET profiling = 1;", $this->connection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the database.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
// Close the connection.
|
||||
if (is_resource($this->connection))
|
||||
{
|
||||
foreach ($this->disconnectHandlers as $h)
|
||||
{
|
||||
call_user_func_array($h, array( &$this));
|
||||
}
|
||||
|
||||
mysql_close($this->connection);
|
||||
}
|
||||
|
||||
$this->connection = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to escape a string for usage in an SQL statement.
|
||||
*
|
||||
* @param string $text The string to be escaped.
|
||||
* @param boolean $extra Optional parameter to provide extra escaping.
|
||||
*
|
||||
* @return string The escaped string.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function escape($text, $extra = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$result = mysql_real_escape_string($text, $this->getConnection());
|
||||
|
||||
if ($extra)
|
||||
{
|
||||
$result = addcslashes($result, '%_');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the MySQL connector is available.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return (function_exists('mysql_connect'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the connection to the server is active.
|
||||
*
|
||||
* @return boolean True if connected to the database engine.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function connected()
|
||||
{
|
||||
if (is_resource($this->connection))
|
||||
{
|
||||
return @mysql_ping($this->connection);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of affected rows by the last INSERT, UPDATE, REPLACE or DELETE for the previous executed SQL statement.
|
||||
*
|
||||
* @return integer The number of affected rows.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return mysql_affected_rows($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of returned rows for the previous executed SQL statement.
|
||||
* This command is only valid for statements like SELECT or SHOW that return an actual result set.
|
||||
* To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE or DELETE query, use getAffectedRows().
|
||||
*
|
||||
* @param resource $cursor An optional database cursor resource to extract the row count from.
|
||||
*
|
||||
* @return integer The number of returned rows.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function getNumRows($cursor = null)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return mysql_num_rows($cursor ? $cursor : $this->cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of the database connector.
|
||||
*
|
||||
* @return string The database connector version.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return mysql_get_server_info($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the auto-incremented value from the last INSERT statement.
|
||||
*
|
||||
* @return integer The value of the auto-increment field from the last inserted row.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function insertid()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return mysql_insert_id($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the SQL statement.
|
||||
*
|
||||
* @return mixed A database cursor resource on success, boolean false on failure.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!is_resource($this->connection))
|
||||
{
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database');
|
||||
}
|
||||
throw new RuntimeException($this->errorMsg, $this->errorNum);
|
||||
}
|
||||
|
||||
// Take a local copy so that we don't modify the original query and cause issues later
|
||||
$query = $this->replacePrefix((string) $this->sql);
|
||||
|
||||
if (!($this->sql instanceof F0FDatabaseQuery) && ($this->limit > 0 || $this->offset > 0))
|
||||
{
|
||||
$query .= ' LIMIT ' . $this->offset . ', ' . $this->limit;
|
||||
}
|
||||
|
||||
// Increment the query counter.
|
||||
$this->count++;
|
||||
|
||||
// Reset the error values.
|
||||
$this->errorNum = 0;
|
||||
$this->errorMsg = '';
|
||||
|
||||
// If debugging is enabled then let's log the query.
|
||||
if ($this->debug)
|
||||
{
|
||||
// Add the query to the object queue.
|
||||
$this->log[] = $query;
|
||||
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add($query, JLog::DEBUG, 'databasequery');
|
||||
}
|
||||
|
||||
$this->timings[] = microtime(true);
|
||||
}
|
||||
|
||||
// Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost.
|
||||
$this->cursor = @mysql_query($query, $this->connection);
|
||||
|
||||
if ($this->debug)
|
||||
{
|
||||
$this->timings[] = microtime(true);
|
||||
|
||||
if (defined('DEBUG_BACKTRACE_IGNORE_ARGS'))
|
||||
{
|
||||
$this->callStacks[] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->callStacks[] = debug_backtrace();
|
||||
}
|
||||
}
|
||||
|
||||
// If an error occurred handle it.
|
||||
if (!$this->cursor)
|
||||
{
|
||||
// Get the error number and message before we execute any more queries.
|
||||
$this->errorNum = $this->getErrorNumber();
|
||||
$this->errorMsg = $this->getErrorMessage($query);
|
||||
|
||||
// Check if the server was disconnected.
|
||||
if (!$this->connected())
|
||||
{
|
||||
try
|
||||
{
|
||||
// Attempt to reconnect.
|
||||
$this->connection = null;
|
||||
$this->connect();
|
||||
}
|
||||
// If connect fails, ignore that exception and throw the normal exception.
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
// Get the error number and message.
|
||||
$this->errorNum = $this->getErrorNumber();
|
||||
$this->errorMsg = $this->getErrorMessage($query);
|
||||
|
||||
// Throw the normal query exception.
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error');
|
||||
}
|
||||
|
||||
throw new RuntimeException($this->errorMsg, $this->errorNum, $e);
|
||||
}
|
||||
|
||||
// Since we were able to reconnect, run the query again.
|
||||
return $this->execute();
|
||||
}
|
||||
// The server was not disconnected.
|
||||
else
|
||||
{
|
||||
// Throw the normal query exception.
|
||||
if (class_exists('JLog'))
|
||||
{
|
||||
JLog::add(JText::sprintf('JLIB_DATABASE_QUERY_FAILED', $this->errorNum, $this->errorMsg), JLog::ERROR, 'database-error');
|
||||
}
|
||||
|
||||
throw new RuntimeException($this->errorMsg, $this->errorNum);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a database for use.
|
||||
*
|
||||
* @param string $database The name of the database to select for use.
|
||||
*
|
||||
* @return boolean True if the database was successfully selected.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function select($database)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$database)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mysql_select_db($database, $this->connection))
|
||||
{
|
||||
throw new RuntimeException('Could not connect to database');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection to use UTF-8 character encoding.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setUtf()
|
||||
{
|
||||
// If UTF is not supported return false immediately
|
||||
if (!$this->utf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure we're connected to the server
|
||||
$this->connect();
|
||||
|
||||
// Which charset should I use, plain utf8 or multibyte utf8mb4?
|
||||
$charset = $this->utf8mb4 ? 'utf8mb4' : 'utf8';
|
||||
|
||||
$result = @mysql_set_charset($charset, $this->connection);
|
||||
|
||||
/**
|
||||
* If I could not set the utf8mb4 charset then the server doesn't support utf8mb4 despite claiming otherwise.
|
||||
* This happens on old MySQL server versions (less than 5.5.3) using the mysqlnd PHP driver. Since mysqlnd
|
||||
* masks the server version and reports only its own we can not be sure if the server actually does support
|
||||
* UTF-8 Multibyte (i.e. it's MySQL 5.5.3 or later). Since the utf8mb4 charset is undefined in this case we
|
||||
* catch the error and determine that utf8mb4 is not supported!
|
||||
*/
|
||||
if (!$result && $this->utf8mb4)
|
||||
{
|
||||
$this->utf8mb4 = false;
|
||||
$result = @mysql_set_charset('utf8', $this->connection);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch a row from the result set cursor as an array.
|
||||
*
|
||||
* @param mixed $cursor The optional result set cursor from which to fetch the row.
|
||||
*
|
||||
* @return mixed Either the next row from the result set or false if there are no more rows.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
protected function fetchArray($cursor = null)
|
||||
{
|
||||
return mysql_fetch_row($cursor ? $cursor : $this->cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch a row from the result set cursor as an associative array.
|
||||
*
|
||||
* @param mixed $cursor The optional result set cursor from which to fetch the row.
|
||||
*
|
||||
* @return mixed Either the next row from the result set or false if there are no more rows.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
protected function fetchAssoc($cursor = null)
|
||||
{
|
||||
return mysql_fetch_assoc($cursor ? $cursor : $this->cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch a row from the result set cursor as an object.
|
||||
*
|
||||
* @param mixed $cursor The optional result set cursor from which to fetch the row.
|
||||
* @param string $class The class name to use for the returned row object.
|
||||
*
|
||||
* @return mixed Either the next row from the result set or false if there are no more rows.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
protected function fetchObject($cursor = null, $class = 'stdClass')
|
||||
{
|
||||
return mysql_fetch_object($cursor ? $cursor : $this->cursor, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to free up the memory used for the result set.
|
||||
*
|
||||
* @param mixed $cursor The optional result set cursor from which to fetch the row.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
protected function freeResult($cursor = null)
|
||||
{
|
||||
mysql_free_result($cursor ? $cursor : $this->cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to check if profiling is available
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 3.1.3
|
||||
*/
|
||||
private function hasProfiling()
|
||||
{
|
||||
try
|
||||
{
|
||||
$res = mysql_query("SHOW VARIABLES LIKE 'have_profiling'", $this->connection);
|
||||
$row = mysql_fetch_assoc($res);
|
||||
|
||||
return isset($row);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the database server claim to have support for UTF-8 Multibyte (utf8mb4) collation?
|
||||
*
|
||||
* libmysql supports utf8mb4 since 5.5.3 (same version as the MySQL server). mysqlnd supports utf8mb4 since 5.0.9.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since CMS 3.5.0
|
||||
*/
|
||||
private function serverClaimsUtf8mb4Support()
|
||||
{
|
||||
$client_version = mysql_get_client_info();
|
||||
|
||||
if (strpos($client_version, 'mysqlnd') !== false)
|
||||
{
|
||||
$client_version = preg_replace('/^\D+([\d.]+).*/', '$1', $client_version);
|
||||
|
||||
return version_compare($client_version, '5.0.9', '>=');
|
||||
}
|
||||
else
|
||||
{
|
||||
return version_compare($client_version, '5.5.3', '>=');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the actual SQL Error number
|
||||
*
|
||||
* @return integer The SQL Error number
|
||||
*
|
||||
* @since 3.4.6
|
||||
*/
|
||||
protected function getErrorNumber()
|
||||
{
|
||||
return (int) mysql_errno($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the actual SQL Error message
|
||||
*
|
||||
* @param string $query The SQL Query that fails
|
||||
*
|
||||
* @return string The SQL Error message
|
||||
*
|
||||
* @since 3.4.6
|
||||
*/
|
||||
protected function getErrorMessage($query)
|
||||
{
|
||||
$errorMessage = (string) mysql_error($this->connection);
|
||||
|
||||
// Replace the Databaseprefix with `#__` if we are not in Debug
|
||||
if (!$this->debug)
|
||||
{
|
||||
$errorMessage = str_replace($this->tablePrefix, '#__', $errorMessage);
|
||||
$query = str_replace($this->tablePrefix, '#__', $query);
|
||||
}
|
||||
|
||||
return $errorMessage . ' SQL=' . $query;
|
||||
}
|
||||
}
|
||||
1019
libraries/f0f/database/driver/mysqli.php
Normal file
1019
libraries/f0f/database/driver/mysqli.php
Normal file
File diff suppressed because it is too large
Load Diff
712
libraries/f0f/database/driver/oracle.php
Normal file
712
libraries/f0f/database/driver/oracle.php
Normal file
@ -0,0 +1,712 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Oracle database driver
|
||||
*
|
||||
* @see http://php.net/pdo
|
||||
* @since 12.1
|
||||
*/
|
||||
class F0FDatabaseDriverOracle extends F0FDatabaseDriverPdo
|
||||
{
|
||||
/**
|
||||
* The name of the database driver.
|
||||
*
|
||||
* @var string
|
||||
* @since 12.1
|
||||
*/
|
||||
public $name = 'oracle';
|
||||
|
||||
/**
|
||||
* The type of the database server family supported by this driver.
|
||||
*
|
||||
* @var string
|
||||
* @since CMS 3.5.0
|
||||
*/
|
||||
public $serverType = 'oracle';
|
||||
|
||||
/**
|
||||
* The character(s) used to quote SQL statement names such as table names or field names,
|
||||
* etc. The child classes should define this as necessary. If a single character string the
|
||||
* same character is used for both sides of the quoted name, else the first character will be
|
||||
* used for the opening quote and the second for the closing quote.
|
||||
*
|
||||
* @var string
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $nameQuote = '"';
|
||||
|
||||
/**
|
||||
* Returns the current dateformat
|
||||
*
|
||||
* @var string
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $dateformat;
|
||||
|
||||
/**
|
||||
* Returns the current character set
|
||||
*
|
||||
* @var string
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $charset;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $options List of options used to configure the connection
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function __construct($options)
|
||||
{
|
||||
$options['driver'] = 'oci';
|
||||
$options['charset'] = (isset($options['charset'])) ? $options['charset'] : 'AL32UTF8';
|
||||
$options['dateformat'] = (isset($options['dateformat'])) ? $options['dateformat'] : 'RRRR-MM-DD HH24:MI:SS';
|
||||
|
||||
$this->charset = $options['charset'];
|
||||
$this->dateformat = $options['dateformat'];
|
||||
|
||||
// Finalize initialisation
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->freeResult();
|
||||
unset($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the database if needed.
|
||||
*
|
||||
* @return void Returns void if the database connected successfully.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if ($this->connection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parent::connect();
|
||||
|
||||
if (isset($this->options['schema']))
|
||||
{
|
||||
$this->setQuery('ALTER SESSION SET CURRENT_SCHEMA = ' . $this->quoteName($this->options['schema']))->execute();
|
||||
}
|
||||
|
||||
$this->setDateFormat($this->dateformat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the database.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
// Close the connection.
|
||||
$this->freeResult();
|
||||
unset($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a table from the database.
|
||||
*
|
||||
* Note: The IF EXISTS flag is unused in the Oracle driver.
|
||||
*
|
||||
* @param string $tableName The name of the database table to drop.
|
||||
* @param boolean $ifExists Optionally specify that the table must exist before it is dropped.
|
||||
*
|
||||
* @return F0FDatabaseDriverOracle Returns this object to support chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function dropTable($tableName, $ifExists = true)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$query = $this->getQuery(true)
|
||||
->setQuery('DROP TABLE :tableName');
|
||||
$query->bind(':tableName', $tableName);
|
||||
|
||||
$this->setQuery($query);
|
||||
|
||||
$this->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the database collation in use by sampling a text field of a table in the database.
|
||||
*
|
||||
* @return mixed The collation in use by the database or boolean false if not supported.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function getCollation()
|
||||
{
|
||||
return $this->charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the database connection collation, as reported by the driver. If the connector doesn't support
|
||||
* reporting this value please return an empty string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getConnectionCollation()
|
||||
{
|
||||
return $this->charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a query to run and verify the database is operational.
|
||||
*
|
||||
* @return string The query to check the health of the DB.
|
||||
*
|
||||
* @since 12.2
|
||||
*/
|
||||
public function getConnectedQuery()
|
||||
{
|
||||
return 'SELECT 1 FROM dual';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current date format
|
||||
* This method should be useful in the case that
|
||||
* somebody actually wants to use a different
|
||||
* date format and needs to check what the current
|
||||
* one is to see if it needs to be changed.
|
||||
*
|
||||
* @return string The current date format
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function getDateFormat()
|
||||
{
|
||||
return $this->dateformat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the table CREATE statement that creates the given tables.
|
||||
*
|
||||
* Note: You must have the correct privileges before this method
|
||||
* will return usable results!
|
||||
*
|
||||
* @param mixed $tables A table name or a list of table names.
|
||||
*
|
||||
* @return array A list of the create SQL for the tables.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableCreate($tables)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$result = array();
|
||||
$query = $this->getQuery(true)
|
||||
->select('dbms_metadata.get_ddl(:type, :tableName)')
|
||||
->from('dual')
|
||||
->bind(':type', 'TABLE');
|
||||
|
||||
// Sanitize input to an array and iterate over the list.
|
||||
settype($tables, 'array');
|
||||
|
||||
foreach ($tables as $table)
|
||||
{
|
||||
$query->bind(':tableName', $table);
|
||||
$this->setQuery($query);
|
||||
$statement = (string) $this->loadResult();
|
||||
$result[$table] = $statement;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves field information about a given table.
|
||||
*
|
||||
* @param string $table The name of the database table.
|
||||
* @param boolean $typeOnly True to only return field types.
|
||||
*
|
||||
* @return array An array of fields for the database table.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableColumns($table, $typeOnly = true)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$columns = array();
|
||||
$query = $this->getQuery(true);
|
||||
|
||||
$fieldCasing = $this->getOption(PDO::ATTR_CASE);
|
||||
|
||||
$this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER);
|
||||
|
||||
$table = strtoupper($table);
|
||||
|
||||
$query->select('*');
|
||||
$query->from('ALL_TAB_COLUMNS');
|
||||
$query->where('table_name = :tableName');
|
||||
|
||||
$prefixedTable = str_replace('#__', strtoupper($this->tablePrefix), $table);
|
||||
$query->bind(':tableName', $prefixedTable);
|
||||
$this->setQuery($query);
|
||||
$fields = $this->loadObjectList();
|
||||
|
||||
if ($typeOnly)
|
||||
{
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
$columns[$field->COLUMN_NAME] = $field->DATA_TYPE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
$columns[$field->COLUMN_NAME] = $field;
|
||||
$columns[$field->COLUMN_NAME]->Default = null;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setOption(PDO::ATTR_CASE, $fieldCasing);
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the details list of keys for a table.
|
||||
*
|
||||
* @param string $table The name of the table.
|
||||
*
|
||||
* @return array An array of the column specification for the table.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableKeys($table)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$query = $this->getQuery(true);
|
||||
|
||||
$fieldCasing = $this->getOption(PDO::ATTR_CASE);
|
||||
|
||||
$this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER);
|
||||
|
||||
$table = strtoupper($table);
|
||||
$query->select('*')
|
||||
->from('ALL_CONSTRAINTS')
|
||||
->where('table_name = :tableName')
|
||||
->bind(':tableName', $table);
|
||||
|
||||
$this->setQuery($query);
|
||||
$keys = $this->loadObjectList();
|
||||
|
||||
$this->setOption(PDO::ATTR_CASE, $fieldCasing);
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an array of all tables in the database (schema).
|
||||
*
|
||||
* @param string $databaseName The database (schema) name
|
||||
* @param boolean $includeDatabaseName Whether to include the schema name in the results
|
||||
*
|
||||
* @return array An array of all the tables in the database.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableList($databaseName = null, $includeDatabaseName = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$query = $this->getQuery(true);
|
||||
|
||||
if ($includeDatabaseName)
|
||||
{
|
||||
$query->select('owner, table_name');
|
||||
}
|
||||
else
|
||||
{
|
||||
$query->select('table_name');
|
||||
}
|
||||
|
||||
$query->from('all_tables');
|
||||
|
||||
if ($databaseName)
|
||||
{
|
||||
$query->where('owner = :database')
|
||||
->bind(':database', $databaseName);
|
||||
}
|
||||
|
||||
$query->order('table_name');
|
||||
|
||||
$this->setQuery($query);
|
||||
|
||||
if ($includeDatabaseName)
|
||||
{
|
||||
$tables = $this->loadAssocList();
|
||||
}
|
||||
else
|
||||
{
|
||||
$tables = $this->loadColumn();
|
||||
}
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of the database connector.
|
||||
*
|
||||
* @return string The database connector version.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$this->setQuery("select value from nls_database_parameters where parameter = 'NLS_RDBMS_VERSION'");
|
||||
|
||||
return $this->loadResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a database for use.
|
||||
*
|
||||
* @param string $database The name of the database to select for use.
|
||||
*
|
||||
* @return boolean True if the database was successfully selected.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function select($database)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Oracle Date Format for the session
|
||||
* Default date format for Oracle is = DD-MON-RR
|
||||
* The default date format for this driver is:
|
||||
* 'RRRR-MM-DD HH24:MI:SS' since it is the format
|
||||
* that matches the MySQL one used within most Joomla
|
||||
* tables.
|
||||
*
|
||||
* @param string $dateFormat Oracle Date Format String
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setDateFormat($dateFormat = 'DD-MON-RR')
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$this->setQuery("ALTER SESSION SET NLS_DATE_FORMAT = '$dateFormat'");
|
||||
|
||||
if (!$this->execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setQuery("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = '$dateFormat'");
|
||||
|
||||
if (!$this->execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->dateformat = $dateFormat;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection to use UTF-8 character encoding.
|
||||
*
|
||||
* Returns false automatically for the Oracle driver since
|
||||
* you can only set the character set when the connection
|
||||
* is created.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setUtf()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks a table in the database.
|
||||
*
|
||||
* @param string $table The name of the table to unlock.
|
||||
*
|
||||
* @return F0FDatabaseDriverOracle Returns this object to support chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function lockTable($table)
|
||||
{
|
||||
$this->setQuery('LOCK TABLE ' . $this->quoteName($table) . ' IN EXCLUSIVE MODE')->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a table in the database.
|
||||
*
|
||||
* @param string $oldTable The name of the table to be renamed
|
||||
* @param string $newTable The new name for the table.
|
||||
* @param string $backup Not used by Oracle.
|
||||
* @param string $prefix Not used by Oracle.
|
||||
*
|
||||
* @return F0FDatabaseDriverOracle Returns this object to support chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function renameTable($oldTable, $newTable, $backup = null, $prefix = null)
|
||||
{
|
||||
$this->setQuery('RENAME ' . $oldTable . ' TO ' . $newTable)->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks tables in the database.
|
||||
*
|
||||
* @return F0FDatabaseDriverOracle Returns this object to support chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function unlockTables()
|
||||
{
|
||||
$this->setQuery('COMMIT')->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the PDO ODBC connector is available.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return class_exists('PDO') && in_array('oci', PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
* This function replaces a string identifier <var>$prefix</var> with the string held is the
|
||||
* <var>tablePrefix</var> class variable.
|
||||
*
|
||||
* @param string $query The SQL statement to prepare.
|
||||
* @param string $prefix The common table prefix.
|
||||
*
|
||||
* @return string The processed SQL statement.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function replacePrefix($query, $prefix = '#__')
|
||||
{
|
||||
$startPos = 0;
|
||||
$quoteChar = "'";
|
||||
$literal = '';
|
||||
|
||||
$query = trim($query);
|
||||
$n = strlen($query);
|
||||
|
||||
while ($startPos < $n)
|
||||
{
|
||||
$ip = strpos($query, $prefix, $startPos);
|
||||
|
||||
if ($ip === false)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$j = strpos($query, "'", $startPos);
|
||||
|
||||
if ($j === false)
|
||||
{
|
||||
$j = $n;
|
||||
}
|
||||
|
||||
$literal .= str_replace($prefix, $this->tablePrefix, substr($query, $startPos, $j - $startPos));
|
||||
$startPos = $j;
|
||||
|
||||
$j = $startPos + 1;
|
||||
|
||||
if ($j >= $n)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Quote comes first, find end of quote
|
||||
while (true)
|
||||
{
|
||||
$k = strpos($query, $quoteChar, $j);
|
||||
$escaped = false;
|
||||
|
||||
if ($k === false)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
$l = $k - 1;
|
||||
|
||||
while ($l >= 0 && $query{$l} == '\\')
|
||||
{
|
||||
$l--;
|
||||
$escaped = !$escaped;
|
||||
}
|
||||
|
||||
if ($escaped)
|
||||
{
|
||||
$j = $k + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($k === false)
|
||||
{
|
||||
// Error in the query - no end quote; ignore it
|
||||
break;
|
||||
}
|
||||
|
||||
$literal .= substr($query, $startPos, $k - $startPos + 1);
|
||||
$startPos = $k + 1;
|
||||
}
|
||||
|
||||
if ($startPos < $n)
|
||||
{
|
||||
$literal .= substr($query, $startPos, $n - $startPos);
|
||||
}
|
||||
|
||||
return $literal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to commit a transaction.
|
||||
*
|
||||
* @param boolean $toSavepoint If true, commit to the last savepoint.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.3
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function transactionCommit($toSavepoint = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$toSavepoint || $this->transactionDepth <= 1)
|
||||
{
|
||||
parent::transactionCommit($toSavepoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->transactionDepth--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to roll back a transaction.
|
||||
*
|
||||
* @param boolean $toSavepoint If true, rollback to the last savepoint.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.3
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function transactionRollback($toSavepoint = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$toSavepoint || $this->transactionDepth <= 1)
|
||||
{
|
||||
parent::transactionRollback($toSavepoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
$savepoint = 'SP_' . ($this->transactionDepth - 1);
|
||||
$this->setQuery('ROLLBACK TO SAVEPOINT ' . $this->quoteName($savepoint));
|
||||
|
||||
if ($this->execute())
|
||||
{
|
||||
$this->transactionDepth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to initialize a transaction.
|
||||
*
|
||||
* @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.3
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function transactionStart($asSavepoint = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$asSavepoint || !$this->transactionDepth)
|
||||
{
|
||||
return parent::transactionStart($asSavepoint);
|
||||
}
|
||||
|
||||
$savepoint = 'SP_' . $this->transactionDepth;
|
||||
$this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint));
|
||||
|
||||
if ($this->execute())
|
||||
{
|
||||
$this->transactionDepth++;
|
||||
}
|
||||
}
|
||||
}
|
||||
1106
libraries/f0f/database/driver/pdo.php
Normal file
1106
libraries/f0f/database/driver/pdo.php
Normal file
File diff suppressed because it is too large
Load Diff
559
libraries/f0f/database/driver/pdomysql.php
Normal file
559
libraries/f0f/database/driver/pdomysql.php
Normal file
@ -0,0 +1,559 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* MySQL database driver supporting PDO based connections
|
||||
*
|
||||
* @package Joomla.Platform
|
||||
* @subpackage Database
|
||||
* @see http://php.net/manual/en/ref.pdo-mysql.php
|
||||
* @since 3.4
|
||||
*/
|
||||
class F0FDatabaseDriverPdomysql extends F0FDatabaseDriverPdo
|
||||
{
|
||||
/**
|
||||
* The name of the database driver.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.4
|
||||
*/
|
||||
public $name = 'pdomysql';
|
||||
|
||||
/**
|
||||
* The type of the database server family supported by this driver.
|
||||
*
|
||||
* @var string
|
||||
* @since CMS 3.5.0
|
||||
*/
|
||||
public $serverType = 'mysql';
|
||||
|
||||
/**
|
||||
* The character(s) used to quote SQL statement names such as table names or field names,
|
||||
* etc. The child classes should define this as necessary. If a single character string the
|
||||
* same character is used for both sides of the quoted name, else the first character will be
|
||||
* used for the opening quote and the second for the closing quote.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.4
|
||||
*/
|
||||
protected $nameQuote = '`';
|
||||
|
||||
/**
|
||||
* The null or zero representation of a timestamp for the database driver. This should be
|
||||
* defined in child classes to hold the appropriate value for the engine.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.4
|
||||
*/
|
||||
protected $nullDate = '0000-00-00 00:00:00';
|
||||
|
||||
/**
|
||||
* The minimum supported database version.
|
||||
*
|
||||
* @var string
|
||||
* @since 3.4
|
||||
*/
|
||||
protected static $dbMinimum = '5.0.4';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $options Array of database options with keys: host, user, password, database, select.
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public function __construct($options)
|
||||
{
|
||||
/**
|
||||
* Pre-populate the UTF-8 Multibyte compatibility flag. Unfortuantely PDO won't report the server version
|
||||
* unless we're connected to it and we cannot connect to it unless we know if it supports utf8mb4 which requires
|
||||
* us knowing the server version. Between this chicken and egg issue we _assume_ it's supported and we'll just
|
||||
* catch any problems at connection time.
|
||||
*/
|
||||
$this->utf8mb4 = true;
|
||||
|
||||
// Get some basic values from the options.
|
||||
$options['driver'] = 'mysql';
|
||||
$options['charset'] = (isset($options['charset'])) ? $options['charset'] : 'utf8';
|
||||
|
||||
if ($this->utf8mb4 && ($options['charset'] == 'utf8'))
|
||||
{
|
||||
$options['charset'] = 'utf8mb4';
|
||||
}
|
||||
|
||||
$this->charset = $options['charset'];
|
||||
|
||||
// Finalize initialisation.
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the database if needed.
|
||||
*
|
||||
* @return void Returns void if the database connected successfully.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Try to connect to MySQL
|
||||
parent::connect();
|
||||
}
|
||||
catch (\RuntimeException $e)
|
||||
{
|
||||
// If the connection failed but not because of the wrong character set bubble up the exception
|
||||
if (!$this->utf8mb4 || ($this->options['charset'] != 'utf8mb4'))
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the connection failed and I was trying to use the utf8mb4 charset then it is likely that the server
|
||||
* doesn't support utf8mb4 despite claiming otherwise.
|
||||
*
|
||||
* This happens on old MySQL server versions (less than 5.5.3) using the mysqlnd PHP driver. Since mysqlnd
|
||||
* masks the server version and reports only its own we can not be sure if the server actually does support
|
||||
* UTF-8 Multibyte (i.e. it's MySQL 5.5.3 or later). Since the utf8mb4 charset is undefined in this case we
|
||||
* catch the error and determine that utf8mb4 is not supported!
|
||||
*/
|
||||
$this->utf8mb4 = false;
|
||||
$this->options['charset'] = 'utf8';
|
||||
|
||||
parent::connect();
|
||||
}
|
||||
|
||||
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the MySQL connector is available.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return class_exists('PDO') && in_array('mysql', PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a table from the database.
|
||||
*
|
||||
* @param string $tableName The name of the database table to drop.
|
||||
* @param boolean $ifExists Optionally specify that the table must exist before it is dropped.
|
||||
*
|
||||
* @return F0FDatabaseDriverPdomysql Returns this object to support chaining.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function dropTable($tableName, $ifExists = true)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$query = $this->getQuery(true);
|
||||
|
||||
$query->setQuery('DROP TABLE ' . ($ifExists ? 'IF EXISTS ' : '') . $this->quoteName($tableName));
|
||||
|
||||
$this->setQuery($query);
|
||||
|
||||
$this->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a database for use.
|
||||
*
|
||||
* @param string $database The name of the database to select for use.
|
||||
*
|
||||
* @return boolean True if the database was successfully selected.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function select($database)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$this->setQuery('USE ' . $this->quoteName($database));
|
||||
|
||||
$this->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the database collation in use by sampling a text field of a table in the database.
|
||||
*
|
||||
* @return mixed The collation in use by the database (string) or boolean false if not supported.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getCollation()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
// Attempt to get the database collation by accessing the server system variable.
|
||||
$this->setQuery('SHOW VARIABLES LIKE "collation_database"');
|
||||
$result = $this->loadObject();
|
||||
|
||||
if (property_exists($result, 'Value'))
|
||||
{
|
||||
return $result->Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the database connection collation, as reported by the driver. If the connector doesn't support
|
||||
* reporting this value please return an empty string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getConnectionCollation()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
// Attempt to get the database collation by accessing the server system variable.
|
||||
$this->setQuery('SHOW VARIABLES LIKE "collation_connection"');
|
||||
$result = $this->loadObject();
|
||||
|
||||
if (property_exists($result, 'Value'))
|
||||
{
|
||||
return $result->Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the table CREATE statement that creates the given tables.
|
||||
*
|
||||
* @param mixed $tables A table name or a list of table names.
|
||||
*
|
||||
* @return array A list of the create SQL for the tables.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableCreate($tables)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
// Initialise variables.
|
||||
$result = array();
|
||||
|
||||
// Sanitize input to an array and iterate over the list.
|
||||
settype($tables, 'array');
|
||||
|
||||
foreach ($tables as $table)
|
||||
{
|
||||
$this->setQuery('SHOW CREATE TABLE ' . $this->quoteName($table));
|
||||
|
||||
$row = $this->loadRow();
|
||||
|
||||
// Populate the result array based on the create statements.
|
||||
$result[$table] = $row[1];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves field information about a given table.
|
||||
*
|
||||
* @param string $table The name of the database table.
|
||||
* @param boolean $typeOnly True to only return field types.
|
||||
*
|
||||
* @return array An array of fields for the database table.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableColumns($table, $typeOnly = true)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$result = array();
|
||||
|
||||
// Set the query to get the table fields statement.
|
||||
$this->setQuery('SHOW FULL COLUMNS FROM ' . $this->quoteName($table));
|
||||
|
||||
$fields = $this->loadObjectList();
|
||||
|
||||
// If we only want the type as the value add just that to the list.
|
||||
if ($typeOnly)
|
||||
{
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
$result[$field->Field] = preg_replace("/[(0-9)]/", '', $field->Type);
|
||||
}
|
||||
}
|
||||
// If we want the whole field data object add that to the list.
|
||||
else
|
||||
{
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
$result[$field->Field] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the details list of keys for a table.
|
||||
*
|
||||
* @param string $table The name of the table.
|
||||
*
|
||||
* @return array An array of the column specification for the table.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableKeys($table)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
// Get the details columns information.
|
||||
$this->setQuery('SHOW KEYS FROM ' . $this->quoteName($table));
|
||||
|
||||
$keys = $this->loadObjectList();
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an array of all tables in the database.
|
||||
*
|
||||
* @return array An array of all the tables in the database.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableList()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
// Set the query to get the tables statement.
|
||||
$this->setQuery('SHOW TABLES');
|
||||
$tables = $this->loadColumn();
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of the database connector.
|
||||
*
|
||||
* @return string The database connector version.
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return $this->getOption(PDO::ATTR_SERVER_VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks a table in the database.
|
||||
*
|
||||
* @param string $table The name of the table to unlock.
|
||||
*
|
||||
* @return F0FDatabaseDriverPdomysql Returns this object to support chaining.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function lockTable($table)
|
||||
{
|
||||
$this->setQuery('LOCK TABLES ' . $this->quoteName($table) . ' WRITE')->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a table in the database.
|
||||
*
|
||||
* @param string $oldTable The name of the table to be renamed
|
||||
* @param string $newTable The new name for the table.
|
||||
* @param string $backup Not used by MySQL.
|
||||
* @param string $prefix Not used by MySQL.
|
||||
*
|
||||
* @return F0FDatabaseDriverPdomysql Returns this object to support chaining.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function renameTable($oldTable, $newTable, $backup = null, $prefix = null)
|
||||
{
|
||||
$this->setQuery('RENAME TABLE ' . $this->quoteName($oldTable) . ' TO ' . $this->quoteName($newTable));
|
||||
|
||||
$this->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to escape a string for usage in an SQL statement.
|
||||
*
|
||||
* Oracle escaping reference:
|
||||
* http://www.orafaq.com/wiki/SQL_FAQ#How_does_one_escape_special_characters_when_writing_SQL_queries.3F
|
||||
*
|
||||
* SQLite escaping notes:
|
||||
* http://www.sqlite.org/faq.html#q14
|
||||
*
|
||||
* Method body is as implemented by the Zend Framework
|
||||
*
|
||||
* Note: Using query objects with bound variables is
|
||||
* preferable to the below.
|
||||
*
|
||||
* @param string $text The string to be escaped.
|
||||
* @param boolean $extra Unused optional parameter to provide extra escaping.
|
||||
*
|
||||
* @return string The escaped string.
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public function escape($text, $extra = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (is_int($text) || is_float($text))
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
|
||||
$result = substr($this->connection->quote($text), 1, -1);
|
||||
|
||||
if ($extra)
|
||||
{
|
||||
$result = addcslashes($result, '%_');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks tables in the database.
|
||||
*
|
||||
* @return F0FDatabaseDriverPdomysql Returns this object to support chaining.
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function unlockTables()
|
||||
{
|
||||
$this->setQuery('UNLOCK TABLES')->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to commit a transaction.
|
||||
*
|
||||
* @param boolean $toSavepoint If true, commit to the last savepoint.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function transactionCommit($toSavepoint = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$toSavepoint || $this->transactionDepth <= 1)
|
||||
{
|
||||
parent::transactionCommit($toSavepoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->transactionDepth--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to roll back a transaction.
|
||||
*
|
||||
* @param boolean $toSavepoint If true, rollback to the last savepoint.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function transactionRollback($toSavepoint = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$toSavepoint || $this->transactionDepth <= 1)
|
||||
{
|
||||
parent::transactionRollback($toSavepoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
$savepoint = 'SP_' . ($this->transactionDepth - 1);
|
||||
$this->setQuery('ROLLBACK TO SAVEPOINT ' . $this->quoteName($savepoint));
|
||||
|
||||
if ($this->execute())
|
||||
{
|
||||
$this->transactionDepth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to initialize a transaction.
|
||||
*
|
||||
* @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 3.4
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function transactionStart($asSavepoint = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$asSavepoint || !$this->transactionDepth)
|
||||
{
|
||||
parent::transactionStart($asSavepoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
$savepoint = 'SP_' . $this->transactionDepth;
|
||||
$this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint));
|
||||
|
||||
if ($this->execute())
|
||||
{
|
||||
$this->transactionDepth++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1529
libraries/f0f/database/driver/postgresql.php
Normal file
1529
libraries/f0f/database/driver/postgresql.php
Normal file
File diff suppressed because it is too large
Load Diff
30
libraries/f0f/database/driver/sqlazure.php
Normal file
30
libraries/f0f/database/driver/sqlazure.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* SQL Server database driver
|
||||
*
|
||||
* @see http://msdn.microsoft.com/en-us/library/ee336279.aspx
|
||||
* @since 12.1
|
||||
*/
|
||||
class F0FDatabaseDriverSqlazure extends F0FDatabaseDriverSqlsrv
|
||||
{
|
||||
/**
|
||||
* The name of the database driver.
|
||||
*
|
||||
* @var string
|
||||
* @since 12.1
|
||||
*/
|
||||
public $name = 'sqlazure';
|
||||
}
|
||||
484
libraries/f0f/database/driver/sqlite.php
Normal file
484
libraries/f0f/database/driver/sqlite.php
Normal file
@ -0,0 +1,484 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* SQLite database driver
|
||||
*
|
||||
* @see http://php.net/pdo
|
||||
* @since 12.1
|
||||
*/
|
||||
class F0FDatabaseDriverSqlite extends F0FDatabaseDriverPdo
|
||||
{
|
||||
/**
|
||||
* The name of the database driver.
|
||||
*
|
||||
* @var string
|
||||
* @since 12.1
|
||||
*/
|
||||
public $name = 'sqlite';
|
||||
|
||||
/**
|
||||
* The type of the database server family supported by this driver.
|
||||
*
|
||||
* @var string
|
||||
* @since CMS 3.5.0
|
||||
*/
|
||||
public $serverType = 'sqlite';
|
||||
|
||||
/**
|
||||
* The character(s) used to quote SQL statement names such as table names or field names,
|
||||
* etc. The child classes should define this as necessary. If a single character string the
|
||||
* same character is used for both sides of the quoted name, else the first character will be
|
||||
* used for the opening quote and the second for the closing quote.
|
||||
*
|
||||
* @var string
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $nameQuote = '`';
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->freeResult();
|
||||
unset($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the database.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
$this->freeResult();
|
||||
unset($this->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a table from the database.
|
||||
*
|
||||
* @param string $tableName The name of the database table to drop.
|
||||
* @param boolean $ifExists Optionally specify that the table must exist before it is dropped.
|
||||
*
|
||||
* @return F0FDatabaseDriverSqlite Returns this object to support chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function dropTable($tableName, $ifExists = true)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$query = $this->getQuery(true);
|
||||
|
||||
$this->setQuery('DROP TABLE ' . ($ifExists ? 'IF EXISTS ' : '') . $query->quoteName($tableName));
|
||||
|
||||
$this->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to escape a string for usage in an SQLite statement.
|
||||
*
|
||||
* Note: Using query objects with bound variables is
|
||||
* preferable to the below.
|
||||
*
|
||||
* @param string $text The string to be escaped.
|
||||
* @param boolean $extra Unused optional parameter to provide extra escaping.
|
||||
*
|
||||
* @return string The escaped string.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function escape($text, $extra = false)
|
||||
{
|
||||
if (is_int($text) || is_float($text))
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
|
||||
return SQLite3::escapeString($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the database collation in use by sampling a text field of a table in the database.
|
||||
*
|
||||
* @return mixed The collation in use by the database or boolean false if not supported.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function getCollation()
|
||||
{
|
||||
return $this->charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the database connection collation, as reported by the driver. If the connector doesn't support
|
||||
* reporting this value please return an empty string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getConnectionCollation()
|
||||
{
|
||||
return $this->charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the table CREATE statement that creates the given tables.
|
||||
*
|
||||
* Note: Doesn't appear to have support in SQLite
|
||||
*
|
||||
* @param mixed $tables A table name or a list of table names.
|
||||
*
|
||||
* @return array A list of the create SQL for the tables.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableCreate($tables)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
// Sanitize input to an array and iterate over the list.
|
||||
settype($tables, 'array');
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves field information about a given table.
|
||||
*
|
||||
* @param string $table The name of the database table.
|
||||
* @param boolean $typeOnly True to only return field types.
|
||||
*
|
||||
* @return array An array of fields for the database table.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableColumns($table, $typeOnly = true)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$columns = array();
|
||||
$query = $this->getQuery(true);
|
||||
|
||||
$fieldCasing = $this->getOption(PDO::ATTR_CASE);
|
||||
|
||||
$this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER);
|
||||
|
||||
$table = strtoupper($table);
|
||||
|
||||
$query->setQuery('pragma table_info(' . $table . ')');
|
||||
|
||||
$this->setQuery($query);
|
||||
$fields = $this->loadObjectList();
|
||||
|
||||
if ($typeOnly)
|
||||
{
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
$columns[$field->NAME] = $field->TYPE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
// Do some dirty translation to MySQL output.
|
||||
// TODO: Come up with and implement a standard across databases.
|
||||
$columns[$field->NAME] = (object) array(
|
||||
'Field' => $field->NAME,
|
||||
'Type' => $field->TYPE,
|
||||
'Null' => ($field->NOTNULL == '1' ? 'NO' : 'YES'),
|
||||
'Default' => $field->DFLT_VALUE,
|
||||
'Key' => ($field->PK != '0' ? 'PRI' : '')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setOption(PDO::ATTR_CASE, $fieldCasing);
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the details list of keys for a table.
|
||||
*
|
||||
* @param string $table The name of the table.
|
||||
*
|
||||
* @return array An array of the column specification for the table.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableKeys($table)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$keys = array();
|
||||
$query = $this->getQuery(true);
|
||||
|
||||
$fieldCasing = $this->getOption(PDO::ATTR_CASE);
|
||||
|
||||
$this->setOption(PDO::ATTR_CASE, PDO::CASE_UPPER);
|
||||
|
||||
$table = strtoupper($table);
|
||||
$query->setQuery('pragma table_info( ' . $table . ')');
|
||||
|
||||
// $query->bind(':tableName', $table);
|
||||
|
||||
$this->setQuery($query);
|
||||
$rows = $this->loadObjectList();
|
||||
|
||||
foreach ($rows as $column)
|
||||
{
|
||||
if ($column->PK == 1)
|
||||
{
|
||||
$keys[$column->NAME] = $column;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setOption(PDO::ATTR_CASE, $fieldCasing);
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an array of all tables in the database (schema).
|
||||
*
|
||||
* @return array An array of all the tables in the database.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getTableList()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$type = 'table';
|
||||
|
||||
$query = $this->getQuery(true)
|
||||
->select('name')
|
||||
->from('sqlite_master')
|
||||
->where('type = :type')
|
||||
->bind(':type', $type)
|
||||
->order('name');
|
||||
|
||||
$this->setQuery($query);
|
||||
|
||||
$tables = $this->loadColumn();
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of the database connector.
|
||||
*
|
||||
* @return string The database connector version.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
$this->setQuery("SELECT sqlite_version()");
|
||||
|
||||
return $this->loadResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a database for use.
|
||||
*
|
||||
* @param string $database The name of the database to select for use.
|
||||
*
|
||||
* @return boolean True if the database was successfully selected.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function select($database)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the connection to use UTF-8 character encoding.
|
||||
*
|
||||
* Returns false automatically for the Oracle driver since
|
||||
* you can only set the character set when the connection
|
||||
* is created.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setUtf()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks a table in the database.
|
||||
*
|
||||
* @param string $table The name of the table to unlock.
|
||||
*
|
||||
* @return F0FDatabaseDriverSqlite Returns this object to support chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function lockTable($table)
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames a table in the database.
|
||||
*
|
||||
* @param string $oldTable The name of the table to be renamed
|
||||
* @param string $newTable The new name for the table.
|
||||
* @param string $backup Not used by Sqlite.
|
||||
* @param string $prefix Not used by Sqlite.
|
||||
*
|
||||
* @return F0FDatabaseDriverSqlite Returns this object to support chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function renameTable($oldTable, $newTable, $backup = null, $prefix = null)
|
||||
{
|
||||
$this->setQuery('ALTER TABLE ' . $oldTable . ' RENAME TO ' . $newTable)->execute();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks tables in the database.
|
||||
*
|
||||
* @return F0FDatabaseDriverSqlite Returns this object to support chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function unlockTables()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the PDO ODBC connector is available.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
return class_exists('PDO') && in_array('sqlite', PDO::getAvailableDrivers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to commit a transaction.
|
||||
*
|
||||
* @param boolean $toSavepoint If true, commit to the last savepoint.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.3
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function transactionCommit($toSavepoint = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$toSavepoint || $this->transactionDepth <= 1)
|
||||
{
|
||||
parent::transactionCommit($toSavepoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->transactionDepth--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to roll back a transaction.
|
||||
*
|
||||
* @param boolean $toSavepoint If true, rollback to the last savepoint.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.3
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function transactionRollback($toSavepoint = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$toSavepoint || $this->transactionDepth <= 1)
|
||||
{
|
||||
parent::transactionRollback($toSavepoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
$savepoint = 'SP_' . ($this->transactionDepth - 1);
|
||||
$this->setQuery('ROLLBACK TO ' . $this->quoteName($savepoint));
|
||||
|
||||
if ($this->execute())
|
||||
{
|
||||
$this->transactionDepth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to initialize a transaction.
|
||||
*
|
||||
* @param boolean $asSavepoint If true and a transaction is already active, a savepoint will be created.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.3
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function transactionStart($asSavepoint = false)
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
if (!$asSavepoint || !$this->transactionDepth)
|
||||
{
|
||||
parent::transactionStart($asSavepoint);
|
||||
}
|
||||
|
||||
$savepoint = 'SP_' . $this->transactionDepth;
|
||||
$this->setQuery('SAVEPOINT ' . $this->quoteName($savepoint));
|
||||
|
||||
if ($this->execute())
|
||||
{
|
||||
$this->transactionDepth++;
|
||||
}
|
||||
}
|
||||
}
|
||||
1171
libraries/f0f/database/driver/sqlsrv.php
Normal file
1171
libraries/f0f/database/driver/sqlsrv.php
Normal file
File diff suppressed because it is too large
Load Diff
127
libraries/f0f/database/factory.php
Normal file
127
libraries/f0f/database/factory.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Joomla Platform Database Factory class
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
class F0FDatabaseFactory
|
||||
{
|
||||
/**
|
||||
* Contains the current F0FDatabaseFactory instance
|
||||
*
|
||||
* @var F0FDatabaseFactory
|
||||
* @since 12.1
|
||||
*/
|
||||
private static $_instance = null;
|
||||
|
||||
/**
|
||||
* Method to return a F0FDatabaseDriver instance based on the given options. There are three global options and then
|
||||
* the rest are specific to the database driver. The 'database' option determines which database is to
|
||||
* be used for the connection. The 'select' option determines whether the connector should automatically select
|
||||
* the chosen database.
|
||||
*
|
||||
* Instances are unique to the given options and new objects are only created when a unique options array is
|
||||
* passed into the method. This ensures that we don't end up with unnecessary database connection resources.
|
||||
*
|
||||
* @param string $name Name of the database driver you'd like to instantiate
|
||||
* @param array $options Parameters to be passed to the database driver.
|
||||
*
|
||||
* @return F0FDatabaseDriver A database driver object.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getDriver($name = 'joomla', $options = array())
|
||||
{
|
||||
// Sanitize the database connector options.
|
||||
$options['driver'] = preg_replace('/[^A-Z0-9_\.-]/i', '', $name);
|
||||
$options['database'] = (isset($options['database'])) ? $options['database'] : null;
|
||||
$options['select'] = (isset($options['select'])) ? $options['select'] : true;
|
||||
|
||||
// Derive the class name from the driver.
|
||||
$class = 'F0FDatabaseDriver' . ucfirst(strtolower($options['driver']));
|
||||
|
||||
// If the class still doesn't exist we have nothing left to do but throw an exception. We did our best.
|
||||
if (!class_exists($class))
|
||||
{
|
||||
throw new RuntimeException(sprintf('Unable to load Database Driver: %s', $options['driver']));
|
||||
}
|
||||
|
||||
// Create our new F0FDatabaseDriver connector based on the options given.
|
||||
try
|
||||
{
|
||||
$instance = new $class($options);
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
throw new RuntimeException(sprintf('Unable to connect to the Database: %s', $e->getMessage()), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of the factory object.
|
||||
*
|
||||
* @return F0FDatabaseFactory
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
return self::$_instance ? self::$_instance : new F0FDatabaseFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current query object or a new F0FDatabaseQuery object.
|
||||
*
|
||||
* @param string $name Name of the driver you want an query object for.
|
||||
* @param F0FDatabaseDriver $db Optional F0FDatabaseDriver instance
|
||||
*
|
||||
* @return F0FDatabaseQuery The current query object or a new object extending the F0FDatabaseQuery class.
|
||||
*
|
||||
* @since 12.1
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getQuery($name, F0FDatabaseDriver $db = null)
|
||||
{
|
||||
// Derive the class name from the driver.
|
||||
$class = 'F0FDatabaseQuery' . ucfirst(strtolower($name));
|
||||
|
||||
// Make sure we have a query class for this driver.
|
||||
if (!class_exists($class))
|
||||
{
|
||||
// If it doesn't exist we are at an impasse so throw an exception.
|
||||
throw new RuntimeException('Database Query class not found');
|
||||
}
|
||||
|
||||
return new $class($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of a factory object to return on subsequent calls of getInstance.
|
||||
*
|
||||
* @param F0FDatabaseFactory $instance A F0FDatabaseFactory object.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public static function setInstance(F0FDatabaseFactory $instance = null)
|
||||
{
|
||||
self::$_instance = $instance;
|
||||
}
|
||||
}
|
||||
1020
libraries/f0f/database/installer.php
Normal file
1020
libraries/f0f/database/installer.php
Normal file
File diff suppressed because it is too large
Load Diff
37
libraries/f0f/database/interface.php
Normal file
37
libraries/f0f/database/interface.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
if (!interface_exists('JDatabaseInterface'))
|
||||
{
|
||||
/**
|
||||
* Joomla Platform Database Interface
|
||||
*
|
||||
* @since 11.2
|
||||
*/
|
||||
interface JDatabaseInterface
|
||||
{
|
||||
/**
|
||||
* Test to see if the connector is available.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @since 11.2
|
||||
*/
|
||||
public static function isSupported();
|
||||
}
|
||||
}
|
||||
|
||||
interface F0FDatabaseInterface extends JDatabaseInterface
|
||||
{
|
||||
}
|
||||
251
libraries/f0f/database/iterator.php
Normal file
251
libraries/f0f/database/iterator.php
Normal file
@ -0,0 +1,251 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Database iterator
|
||||
*/
|
||||
abstract class F0FDatabaseIterator implements Iterator
|
||||
{
|
||||
/**
|
||||
* The database cursor.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $cursor;
|
||||
|
||||
/**
|
||||
* The class of object to create.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $class;
|
||||
|
||||
/**
|
||||
* The name of the column to use for the key of the database record.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $_column;
|
||||
|
||||
/**
|
||||
* The current database record.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $_current;
|
||||
|
||||
/**
|
||||
* The current database record as a F0FTable object.
|
||||
*
|
||||
* @var F0FTable
|
||||
*/
|
||||
private $_currentTable;
|
||||
|
||||
/**
|
||||
* A numeric or string key for the current database record.
|
||||
*
|
||||
* @var scalar
|
||||
*/
|
||||
private $_key;
|
||||
|
||||
/**
|
||||
* The number of fetched records.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_fetched = 0;
|
||||
|
||||
/**
|
||||
* A F0FTable object created using the class type $class, used by getTable
|
||||
*
|
||||
* @var F0FTable
|
||||
*/
|
||||
private $_tableObject = null;
|
||||
|
||||
/**
|
||||
* Returns an iterator object for a specific database type
|
||||
*
|
||||
* @param string $dbName The database type, e.g. mysql, mysqli, sqlazure etc.
|
||||
* @param mixed $cursor The database cursor
|
||||
* @param string $column An option column to use as the iterator key
|
||||
* @param string $class The table class of the returned objects
|
||||
* @param array $config Configuration parameters to push to the table class
|
||||
*
|
||||
* @return F0FDatabaseIterator
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function &getIterator($dbName, $cursor, $column = null, $class, $config = array())
|
||||
{
|
||||
$className = 'F0FDatabaseIterator' . ucfirst($dbName);
|
||||
|
||||
$object = new $className($cursor, $column, $class, $config);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Database iterator constructor.
|
||||
*
|
||||
* @param mixed $cursor The database cursor.
|
||||
* @param string $column An option column to use as the iterator key.
|
||||
* @param string $class The table class of the returned objects.
|
||||
* @param array $config Configuration parameters to push to the table class
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct($cursor, $column = null, $class, $config = array())
|
||||
{
|
||||
// Figure out the type and prefix of the class by the class name
|
||||
$parts = F0FInflector::explode($class);
|
||||
|
||||
if(count($parts) != 3)
|
||||
{
|
||||
throw new InvalidArgumentException('Invalid table name, expected a pattern like ComponentTableFoobar got '.$class);
|
||||
}
|
||||
|
||||
$this->_tableObject = F0FTable::getInstance($parts[2], ucfirst($parts[0]) . ucfirst($parts[1]))->getClone();
|
||||
|
||||
$this->cursor = $cursor;
|
||||
$this->class = 'stdClass';
|
||||
$this->_column = $column;
|
||||
$this->_fetched = 0;
|
||||
|
||||
$this->next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Database iterator destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->cursor)
|
||||
{
|
||||
$this->freeResult($this->cursor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The current element in the iterator.
|
||||
*
|
||||
* @return object
|
||||
*
|
||||
* @see Iterator::current()
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return $this->_currentTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* The key of the current element in the iterator.
|
||||
*
|
||||
* @return scalar
|
||||
*
|
||||
* @see Iterator::key()
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves forward to the next result from the SQL query.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @see Iterator::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
// Set the default key as being the number of fetched object
|
||||
$this->_key = $this->_fetched;
|
||||
|
||||
// Try to get an object
|
||||
$this->_current = $this->fetchObject();
|
||||
|
||||
// If an object has been found
|
||||
if ($this->_current)
|
||||
{
|
||||
$this->_currentTable = $this->getTable();
|
||||
|
||||
// Set the key as being the indexed column (if it exists)
|
||||
if (isset($this->_current->{$this->_column}))
|
||||
{
|
||||
$this->_key = $this->_current->{$this->_column};
|
||||
}
|
||||
|
||||
// Update the number of fetched object
|
||||
$this->_fetched++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewinds the iterator.
|
||||
*
|
||||
* This iterator cannot be rewound.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @see Iterator::rewind()
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current position of the iterator is valid.
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @see Iterator::valid()
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return (boolean) $this->_current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch a row from the result set cursor as an object.
|
||||
*
|
||||
* @return mixed Either the next row from the result set or false if there are no more rows.
|
||||
*/
|
||||
abstract protected function fetchObject();
|
||||
|
||||
/**
|
||||
* Method to free up the memory used for the result set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function freeResult();
|
||||
|
||||
/**
|
||||
* Returns the data in $this->_current as a F0FTable instance
|
||||
*
|
||||
* @return F0FTable
|
||||
*
|
||||
* @throws OutOfBoundsException
|
||||
*/
|
||||
protected function getTable()
|
||||
{
|
||||
if (!$this->valid())
|
||||
{
|
||||
throw new OutOfBoundsException('Cannot get item past iterator\'s bounds', 500);
|
||||
}
|
||||
|
||||
$this->_tableObject->bind($this->_current);
|
||||
|
||||
return $this->_tableObject;
|
||||
}
|
||||
}
|
||||
20
libraries/f0f/database/iterator/azure.php
Normal file
20
libraries/f0f/database/iterator/azure.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* SQL azure database iterator.
|
||||
*/
|
||||
class F0FDatabaseIteratorAzure extends F0FDatabaseIteratorSqlsrv
|
||||
{
|
||||
}
|
||||
51
libraries/f0f/database/iterator/mysql.php
Normal file
51
libraries/f0f/database/iterator/mysql.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* MySQL database iterator.
|
||||
*/
|
||||
class F0FDatabaseIteratorMysql extends F0FDatabaseIterator
|
||||
{
|
||||
/**
|
||||
* Get the number of rows in the result set for the executed SQL given by the cursor.
|
||||
*
|
||||
* @return integer The number of rows in the result set.
|
||||
*
|
||||
* @see Countable::count()
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return @mysql_num_rows($this->cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch a row from the result set cursor as an object.
|
||||
*
|
||||
* @return mixed Either the next row from the result set or false if there are no more rows.
|
||||
*/
|
||||
protected function fetchObject()
|
||||
{
|
||||
return @mysql_fetch_object($this->cursor, $this->class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to free up the memory used for the result set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function freeResult()
|
||||
{
|
||||
@mysql_free_result($this->cursor);
|
||||
}
|
||||
}
|
||||
51
libraries/f0f/database/iterator/mysqli.php
Normal file
51
libraries/f0f/database/iterator/mysqli.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* MySQLi database iterator.
|
||||
*/
|
||||
class F0FDatabaseIteratorMysqli extends F0FDatabaseIterator
|
||||
{
|
||||
/**
|
||||
* Get the number of rows in the result set for the executed SQL given by the cursor.
|
||||
*
|
||||
* @return integer The number of rows in the result set.
|
||||
*
|
||||
* @see Countable::count()
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return @mysqli_num_rows($this->cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch a row from the result set cursor as an object.
|
||||
*
|
||||
* @return mixed Either the next row from the result set or false if there are no more rows.
|
||||
*/
|
||||
protected function fetchObject()
|
||||
{
|
||||
return @mysqli_fetch_object($this->cursor, $this->class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to free up the memory used for the result set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function freeResult()
|
||||
{
|
||||
@mysqli_free_result($this->cursor);
|
||||
}
|
||||
}
|
||||
20
libraries/f0f/database/iterator/oracle.php
Normal file
20
libraries/f0f/database/iterator/oracle.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* MySQLi database iterator.
|
||||
*/
|
||||
class F0FDatabaseIteratorOracle extends F0FDatabaseIteratorPdo
|
||||
{
|
||||
}
|
||||
68
libraries/f0f/database/iterator/pdo.php
Normal file
68
libraries/f0f/database/iterator/pdo.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* PDO database iterator.
|
||||
*/
|
||||
class F0FDatabaseIteratorPdo extends F0FDatabaseIterator
|
||||
{
|
||||
/**
|
||||
* Get the number of rows in the result set for the executed SQL given by the cursor.
|
||||
*
|
||||
* @return integer The number of rows in the result set.
|
||||
*
|
||||
* @see Countable::count()
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if (!empty($this->cursor) && $this->cursor instanceof PDOStatement)
|
||||
{
|
||||
return @$this->cursor->rowCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch a row from the result set cursor as an object.
|
||||
*
|
||||
* @return mixed Either the next row from the result set or false if there are no more rows.
|
||||
*/
|
||||
protected function fetchObject()
|
||||
{
|
||||
if (!empty($this->cursor) && $this->cursor instanceof PDOStatement)
|
||||
{
|
||||
return @$this->cursor->fetchObject($this->class);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to free up the memory used for the result set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function freeResult()
|
||||
{
|
||||
if (!empty($this->cursor) && $this->cursor instanceof PDOStatement)
|
||||
{
|
||||
@$this->cursor->closeCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
20
libraries/f0f/database/iterator/pdomysql.php
Normal file
20
libraries/f0f/database/iterator/pdomysql.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* MySQLi database iterator.
|
||||
*/
|
||||
class F0FDatabaseIteratorPdomysql extends F0FDatabaseIteratorPdo
|
||||
{
|
||||
}
|
||||
51
libraries/f0f/database/iterator/postgresql.php
Normal file
51
libraries/f0f/database/iterator/postgresql.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* PostgreSQL database iterator.
|
||||
*/
|
||||
class F0FDatabaseIteratorPostgresql extends F0FDatabaseIterator
|
||||
{
|
||||
/**
|
||||
* Get the number of rows in the result set for the executed SQL given by the cursor.
|
||||
*
|
||||
* @return integer The number of rows in the result set.
|
||||
*
|
||||
* @see Countable::count()
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return @pg_num_rows($this->cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch a row from the result set cursor as an object.
|
||||
*
|
||||
* @return mixed Either the next row from the result set or false if there are no more rows.
|
||||
*/
|
||||
protected function fetchObject()
|
||||
{
|
||||
return @pg_fetch_object($this->cursor, null, $this->class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to free up the memory used for the result set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function freeResult()
|
||||
{
|
||||
@pg_free_result($this->cursor);
|
||||
}
|
||||
}
|
||||
20
libraries/f0f/database/iterator/sqlite.php
Normal file
20
libraries/f0f/database/iterator/sqlite.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* MySQLi database iterator.
|
||||
*/
|
||||
class F0FDatabaseIteratorSqlite extends F0FDatabaseIteratorPdo
|
||||
{
|
||||
}
|
||||
51
libraries/f0f/database/iterator/sqlsrv.php
Normal file
51
libraries/f0f/database/iterator/sqlsrv.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* SQL server database iterator.
|
||||
*/
|
||||
class F0FDatabaseIteratorSqlsrv extends F0FDatabaseIterator
|
||||
{
|
||||
/**
|
||||
* Get the number of rows in the result set for the executed SQL given by the cursor.
|
||||
*
|
||||
* @return integer The number of rows in the result set.
|
||||
*
|
||||
* @see Countable::count()
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return @sqlsrv_num_rows($this->cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to fetch a row from the result set cursor as an object.
|
||||
*
|
||||
* @return mixed Either the next row from the result set or false if there are no more rows.
|
||||
*/
|
||||
protected function fetchObject()
|
||||
{
|
||||
return @sqlsrv_fetch_object($this->cursor, $this->class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to free up the memory used for the result set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function freeResult()
|
||||
{
|
||||
@sqlsrv_free_stmt($this->cursor);
|
||||
}
|
||||
}
|
||||
1732
libraries/f0f/database/query.php
Normal file
1732
libraries/f0f/database/query.php
Normal file
File diff suppressed because it is too large
Load Diff
132
libraries/f0f/database/query/element.php
Normal file
132
libraries/f0f/database/query/element.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Query Element Class.
|
||||
*
|
||||
* @property-read string $name The name of the element.
|
||||
* @property-read array $elements An array of elements.
|
||||
* @property-read string $glue Glue piece.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
class F0FDatabaseQueryElement
|
||||
{
|
||||
/**
|
||||
* @var string The name of the element.
|
||||
* @since 11.1
|
||||
*/
|
||||
protected $name = null;
|
||||
|
||||
/**
|
||||
* @var array An array of elements.
|
||||
* @since 11.1
|
||||
*/
|
||||
protected $elements = null;
|
||||
|
||||
/**
|
||||
* @var string Glue piece.
|
||||
* @since 11.1
|
||||
*/
|
||||
protected $glue = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name The name of the element.
|
||||
* @param mixed $elements String or array.
|
||||
* @param string $glue The glue for elements.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function __construct($name, $elements, $glue = ',')
|
||||
{
|
||||
$this->elements = array();
|
||||
$this->name = $name;
|
||||
$this->glue = $glue;
|
||||
|
||||
$this->append($elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic function to convert the query element to a string.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
if (substr($this->name, -2) == '()')
|
||||
{
|
||||
return PHP_EOL . substr($this->name, 0, -2) . '(' . implode($this->glue, $this->elements) . ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
return PHP_EOL . $this->name . ' ' . implode($this->glue, $this->elements);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends element parts to the internal list.
|
||||
*
|
||||
* @param mixed $elements String or array.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function append($elements)
|
||||
{
|
||||
if (is_array($elements))
|
||||
{
|
||||
$this->elements = array_merge($this->elements, $elements);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->elements = array_merge($this->elements, array($elements));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the elements of this element.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function getElements()
|
||||
{
|
||||
return $this->elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to provide deep copy support to nested objects and arrays
|
||||
* when cloning.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
foreach ($this as $k => $v)
|
||||
{
|
||||
if (is_object($v) || is_array($v))
|
||||
{
|
||||
$this->{$k} = unserialize(serialize($v));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
libraries/f0f/database/query/limitable.php
Normal file
72
libraries/f0f/database/query/limitable.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
if (!interface_exists('JDatabaseQueryLimitable'))
|
||||
{
|
||||
/**
|
||||
* Joomla Database Query Limitable Interface.
|
||||
* Adds bind/unbind methods as well as a getBounded() method
|
||||
* to retrieve the stored bounded variables on demand prior to
|
||||
* query execution.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
interface JDatabaseQueryLimitable
|
||||
{
|
||||
/**
|
||||
* Method to modify a query already in string format with the needed
|
||||
* additions to make the query limited to a particular number of
|
||||
* results, or start at a particular offset. This method is used
|
||||
* automatically by the __toString() method if it detects that the
|
||||
* query implements the F0FDatabaseQueryLimitable interface.
|
||||
*
|
||||
* @param string $query The query in string format
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function processLimit($query, $limit, $offset = 0);
|
||||
|
||||
/**
|
||||
* Sets the offset and limit for the result set, if the database driver supports it.
|
||||
*
|
||||
* Usage:
|
||||
* $query->setLimit(100, 0); (retrieve 100 rows, starting at first record)
|
||||
* $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record)
|
||||
*
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return F0FDatabaseQuery Returns this object to allow chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setLimit($limit = 0, $offset = 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Joomla Database Query Limitable Interface.
|
||||
* Adds bind/unbind methods as well as a getBounded() method
|
||||
* to retrieve the stored bounded variables on demand prior to
|
||||
* query execution.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
interface F0FDatabaseQueryLimitable extends JDatabaseQueryLimitable
|
||||
{
|
||||
}
|
||||
23
libraries/f0f/database/query/mysql.php
Normal file
23
libraries/f0f/database/query/mysql.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Query Building Class.
|
||||
*
|
||||
* @since 11.1
|
||||
* @deprecated Will be removed when the minimum supported PHP version no longer includes the deprecated PHP `mysql` extension
|
||||
*/
|
||||
class F0FDatabaseQueryMysql extends F0FDatabaseQueryMysqli
|
||||
{
|
||||
}
|
||||
143
libraries/f0f/database/query/mysqli.php
Normal file
143
libraries/f0f/database/query/mysqli.php
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Query Building Class.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
class F0FDatabaseQueryMysqli extends F0FDatabaseQuery implements F0FDatabaseQueryLimitable
|
||||
{
|
||||
/**
|
||||
* @var integer The offset for the result set.
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $offset;
|
||||
|
||||
/**
|
||||
* @var integer The limit for the result set.
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $limit;
|
||||
|
||||
/**
|
||||
* Method to modify a query already in string format with the needed
|
||||
* additions to make the query limited to a particular number of
|
||||
* results, or start at a particular offset.
|
||||
*
|
||||
* @param string $query The query in string format
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function processLimit($query, $limit, $offset = 0)
|
||||
{
|
||||
if ($limit > 0 || $offset > 0)
|
||||
{
|
||||
$query .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates an array of column names or values.
|
||||
*
|
||||
* @param array $values An array of values to concatenate.
|
||||
* @param string $separator As separator to place between each value.
|
||||
*
|
||||
* @return string The concatenated values.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function concatenate($values, $separator = null)
|
||||
{
|
||||
if ($separator)
|
||||
{
|
||||
$concat_string = 'CONCAT_WS(' . $this->quote($separator);
|
||||
|
||||
foreach ($values as $value)
|
||||
{
|
||||
$concat_string .= ', ' . $value;
|
||||
}
|
||||
|
||||
return $concat_string . ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'CONCAT(' . implode(',', $values) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset and limit for the result set, if the database driver supports it.
|
||||
*
|
||||
* Usage:
|
||||
* $query->setLimit(100, 0); (retrieve 100 rows, starting at first record)
|
||||
* $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record)
|
||||
*
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return F0FDatabaseQuery Returns this object to allow chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setLimit($limit = 0, $offset = 0)
|
||||
{
|
||||
$this->limit = (int) $limit;
|
||||
$this->offset = (int) $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return correct regexp operator for mysqli.
|
||||
*
|
||||
* Ensure that the regexp operator is mysqli compatible.
|
||||
*
|
||||
* Usage:
|
||||
* $query->where('field ' . $query->regexp($search));
|
||||
*
|
||||
* @param string $value The regex pattern.
|
||||
*
|
||||
* @return string Returns the regex operator.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function regexp($value)
|
||||
{
|
||||
return ' REGEXP ' . $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return correct rand() function for Mysql.
|
||||
*
|
||||
* Ensure that the rand() function is Mysql compatible.
|
||||
*
|
||||
* Usage:
|
||||
* $query->Rand();
|
||||
*
|
||||
* @return string The correct rand function.
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
public function Rand()
|
||||
{
|
||||
return ' RAND() ';
|
||||
}
|
||||
}
|
||||
205
libraries/f0f/database/query/oracle.php
Normal file
205
libraries/f0f/database/query/oracle.php
Normal file
@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Oracle Query Building Class.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
class F0FDatabaseQueryOracle extends F0FDatabaseQueryPdo implements F0FDatabaseQueryPreparable, F0FDatabaseQueryLimitable
|
||||
{
|
||||
/**
|
||||
* @var integer The offset for the result set.
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $offset;
|
||||
|
||||
/**
|
||||
* @var integer The limit for the result set.
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $limit;
|
||||
|
||||
/**
|
||||
* @var array Bounded object array
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $bounded = array();
|
||||
|
||||
/**
|
||||
* Method to add a variable to an internal array that will be bound to a prepared SQL statement before query execution. Also
|
||||
* removes a variable that has been bounded from the internal bounded array when the passed in value is null.
|
||||
*
|
||||
* @param string|integer $key The key that will be used in your SQL query to reference the value. Usually of
|
||||
* the form ':key', but can also be an integer.
|
||||
* @param mixed &$value The value that will be bound. The value is passed by reference to support output
|
||||
* parameters such as those possible with stored procedures.
|
||||
* @param integer $dataType Constant corresponding to a SQL datatype.
|
||||
* @param integer $length The length of the variable. Usually required for OUTPUT parameters.
|
||||
* @param array $driverOptions Optional driver options to be used.
|
||||
*
|
||||
* @return F0FDatabaseQueryOracle
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function bind($key = null, &$value = null, $dataType = PDO::PARAM_STR, $length = 0, $driverOptions = array())
|
||||
{
|
||||
// Case 1: Empty Key (reset $bounded array)
|
||||
if (empty($key))
|
||||
{
|
||||
$this->bounded = array();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Case 2: Key Provided, null value (unset key from $bounded array)
|
||||
if (is_null($value))
|
||||
{
|
||||
if (isset($this->bounded[$key]))
|
||||
{
|
||||
unset($this->bounded[$key]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$obj = new stdClass;
|
||||
|
||||
$obj->value = &$value;
|
||||
$obj->dataType = $dataType;
|
||||
$obj->length = $length;
|
||||
$obj->driverOptions = $driverOptions;
|
||||
|
||||
// Case 3: Simply add the Key/Value into the bounded array
|
||||
$this->bounded[$key] = $obj;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the bound parameters array when key is null and returns it by reference. If a key is provided then that item is
|
||||
* returned.
|
||||
*
|
||||
* @param mixed $key The bounded variable key to retrieve.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function &getBounded($key = null)
|
||||
{
|
||||
if (empty($key))
|
||||
{
|
||||
return $this->bounded;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($this->bounded[$key]))
|
||||
{
|
||||
return $this->bounded[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear data from the query or a specific clause of the query.
|
||||
*
|
||||
* @param string $clause Optionally, the name of the clause to clear, or nothing to clear the whole query.
|
||||
*
|
||||
* @return F0FDatabaseQueryOracle Returns this object to allow chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function clear($clause = null)
|
||||
{
|
||||
switch ($clause)
|
||||
{
|
||||
case null:
|
||||
$this->bounded = array();
|
||||
break;
|
||||
}
|
||||
|
||||
parent::clear($clause);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to modify a query already in string format with the needed
|
||||
* additions to make the query limited to a particular number of
|
||||
* results, or start at a particular offset. This method is used
|
||||
* automatically by the __toString() method if it detects that the
|
||||
* query implements the F0FDatabaseQueryLimitable interface.
|
||||
*
|
||||
* @param string $query The query in string format
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function processLimit($query, $limit, $offset = 0)
|
||||
{
|
||||
// Check if we need to mangle the query.
|
||||
if ($limit || $offset)
|
||||
{
|
||||
$query = "SELECT joomla2.*
|
||||
FROM (
|
||||
SELECT joomla1.*, ROWNUM AS joomla_db_rownum
|
||||
FROM (
|
||||
" . $query . "
|
||||
) joomla1
|
||||
) joomla2";
|
||||
|
||||
// Check if the limit value is greater than zero.
|
||||
if ($limit > 0)
|
||||
{
|
||||
$query .= ' WHERE joomla2.joomla_db_rownum BETWEEN ' . ($offset + 1) . ' AND ' . ($offset + $limit);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if there is an offset and then use this.
|
||||
if ($offset)
|
||||
{
|
||||
$query .= ' WHERE joomla2.joomla_db_rownum > ' . ($offset + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset and limit for the result set, if the database driver supports it.
|
||||
*
|
||||
* Usage:
|
||||
* $query->setLimit(100, 0); (retrieve 100 rows, starting at first record)
|
||||
* $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record)
|
||||
*
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return F0FDatabaseQueryOracle Returns this object to allow chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setLimit($limit = 0, $offset = 0)
|
||||
{
|
||||
$this->limit = (int) $limit;
|
||||
$this->offset = (int) $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
22
libraries/f0f/database/query/pdo.php
Normal file
22
libraries/f0f/database/query/pdo.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* PDO Query Building Class.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
class F0FDatabaseQueryPdo extends F0FDatabaseQuery
|
||||
{
|
||||
}
|
||||
24
libraries/f0f/database/query/pdomysql.php
Normal file
24
libraries/f0f/database/query/pdomysql.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Query Building Class.
|
||||
*
|
||||
* @package Joomla.Platform
|
||||
* @subpackage Database
|
||||
* @since 3.4
|
||||
*/
|
||||
class F0FDatabaseQueryPdomysql extends F0FDatabaseQueryMysqli
|
||||
{
|
||||
}
|
||||
661
libraries/f0f/database/query/postgresql.php
Normal file
661
libraries/f0f/database/query/postgresql.php
Normal file
@ -0,0 +1,661 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Query Building Class.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
class F0FDatabaseQueryPostgresql extends F0FDatabaseQuery implements F0FDatabaseQueryLimitable
|
||||
{
|
||||
/**
|
||||
* @var object The FOR UPDATE element used in "FOR UPDATE" lock
|
||||
* @since 11.3
|
||||
*/
|
||||
protected $forUpdate = null;
|
||||
|
||||
/**
|
||||
* @var object The FOR SHARE element used in "FOR SHARE" lock
|
||||
* @since 11.3
|
||||
*/
|
||||
protected $forShare = null;
|
||||
|
||||
/**
|
||||
* @var object The NOWAIT element used in "FOR SHARE" and "FOR UPDATE" lock
|
||||
* @since 11.3
|
||||
*/
|
||||
protected $noWait = null;
|
||||
|
||||
/**
|
||||
* @var object The LIMIT element
|
||||
* @since 11.3
|
||||
*/
|
||||
protected $limit = null;
|
||||
|
||||
/**
|
||||
* @var object The OFFSET element
|
||||
* @since 11.3
|
||||
*/
|
||||
protected $offset = null;
|
||||
|
||||
/**
|
||||
* @var object The RETURNING element of INSERT INTO
|
||||
* @since 11.3
|
||||
*/
|
||||
protected $returning = null;
|
||||
|
||||
/**
|
||||
* Magic function to convert the query to a string, only for postgresql specific query
|
||||
*
|
||||
* @return string The completed query.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$query = '';
|
||||
|
||||
switch ($this->type)
|
||||
{
|
||||
case 'select':
|
||||
$query .= (string) $this->select;
|
||||
$query .= (string) $this->from;
|
||||
|
||||
if ($this->join)
|
||||
{
|
||||
// Special case for joins
|
||||
foreach ($this->join as $join)
|
||||
{
|
||||
$query .= (string) $join;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->where)
|
||||
{
|
||||
$query .= (string) $this->where;
|
||||
}
|
||||
|
||||
if ($this->group)
|
||||
{
|
||||
$query .= (string) $this->group;
|
||||
}
|
||||
|
||||
if ($this->having)
|
||||
{
|
||||
$query .= (string) $this->having;
|
||||
}
|
||||
|
||||
if ($this->order)
|
||||
{
|
||||
$query .= (string) $this->order;
|
||||
}
|
||||
|
||||
if ($this->forUpdate)
|
||||
{
|
||||
$query .= (string) $this->forUpdate;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->forShare)
|
||||
{
|
||||
$query .= (string) $this->forShare;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->noWait)
|
||||
{
|
||||
$query .= (string) $this->noWait;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$query .= (string) $this->update;
|
||||
$query .= (string) $this->set;
|
||||
|
||||
if ($this->join)
|
||||
{
|
||||
$onWord = ' ON ';
|
||||
|
||||
// Workaround for special case of JOIN with UPDATE
|
||||
foreach ($this->join as $join)
|
||||
{
|
||||
$joinElem = $join->getElements();
|
||||
|
||||
$joinArray = explode($onWord, $joinElem[0]);
|
||||
|
||||
$this->from($joinArray[0]);
|
||||
$this->where($joinArray[1]);
|
||||
}
|
||||
|
||||
$query .= (string) $this->from;
|
||||
}
|
||||
|
||||
if ($this->where)
|
||||
{
|
||||
$query .= (string) $this->where;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'insert':
|
||||
$query .= (string) $this->insert;
|
||||
|
||||
if ($this->values)
|
||||
{
|
||||
if ($this->columns)
|
||||
{
|
||||
$query .= (string) $this->columns;
|
||||
}
|
||||
|
||||
$elements = $this->values->getElements();
|
||||
|
||||
if (!($elements[0] instanceof $this))
|
||||
{
|
||||
$query .= ' VALUES ';
|
||||
}
|
||||
|
||||
$query .= (string) $this->values;
|
||||
|
||||
if ($this->returning)
|
||||
{
|
||||
$query .= (string) $this->returning;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$query = parent::__toString();
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this instanceof F0FDatabaseQueryLimitable)
|
||||
{
|
||||
$query = $this->processLimit($query, $this->limit, $this->offset);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear data from the query or a specific clause of the query.
|
||||
*
|
||||
* @param string $clause Optionally, the name of the clause to clear, or nothing to clear the whole query.
|
||||
*
|
||||
* @return F0FDatabaseQueryPostgresql Returns this object to allow chaining.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function clear($clause = null)
|
||||
{
|
||||
switch ($clause)
|
||||
{
|
||||
case 'limit':
|
||||
$this->limit = null;
|
||||
break;
|
||||
|
||||
case 'offset':
|
||||
$this->offset = null;
|
||||
break;
|
||||
|
||||
case 'forUpdate':
|
||||
$this->forUpdate = null;
|
||||
break;
|
||||
|
||||
case 'forShare':
|
||||
$this->forShare = null;
|
||||
break;
|
||||
|
||||
case 'noWait':
|
||||
$this->noWait = null;
|
||||
break;
|
||||
|
||||
case 'returning':
|
||||
$this->returning = null;
|
||||
break;
|
||||
|
||||
case 'select':
|
||||
case 'update':
|
||||
case 'delete':
|
||||
case 'insert':
|
||||
case 'from':
|
||||
case 'join':
|
||||
case 'set':
|
||||
case 'where':
|
||||
case 'group':
|
||||
case 'having':
|
||||
case 'order':
|
||||
case 'columns':
|
||||
case 'values':
|
||||
parent::clear($clause);
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->type = null;
|
||||
$this->limit = null;
|
||||
$this->offset = null;
|
||||
$this->forUpdate = null;
|
||||
$this->forShare = null;
|
||||
$this->noWait = null;
|
||||
$this->returning = null;
|
||||
parent::clear($clause);
|
||||
break;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts a value to a char.
|
||||
*
|
||||
* Ensure that the value is properly quoted before passing to the method.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->castAsChar('a'));
|
||||
*
|
||||
* @param string $value The value to cast as a char.
|
||||
*
|
||||
* @return string Returns the cast value.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function castAsChar($value)
|
||||
{
|
||||
return $value . '::text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates an array of column names or values.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->concatenate(array('a', 'b')));
|
||||
*
|
||||
* @param array $values An array of values to concatenate.
|
||||
* @param string $separator As separator to place between each value.
|
||||
*
|
||||
* @return string The concatenated values.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function concatenate($values, $separator = null)
|
||||
{
|
||||
if ($separator)
|
||||
{
|
||||
return implode(' || ' . $this->quote($separator) . ' || ', $values);
|
||||
}
|
||||
else
|
||||
{
|
||||
return implode(' || ', $values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current date and time.
|
||||
*
|
||||
* @return string Return string used in query to obtain
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function currentTimestamp()
|
||||
{
|
||||
return 'NOW()';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the FOR UPDATE lock on select's output row
|
||||
*
|
||||
* @param string $table_name The table to lock
|
||||
* @param string $glue The glue by which to join the conditions. Defaults to ',' .
|
||||
*
|
||||
* @return F0FDatabaseQueryPostgresql FOR UPDATE query element
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function forUpdate($table_name, $glue = ',')
|
||||
{
|
||||
$this->type = 'forUpdate';
|
||||
|
||||
if (is_null($this->forUpdate))
|
||||
{
|
||||
$glue = strtoupper($glue);
|
||||
$this->forUpdate = new F0FDatabaseQueryElement('FOR UPDATE', 'OF ' . $table_name, "$glue ");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->forUpdate->append($table_name);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the FOR SHARE lock on select's output row
|
||||
*
|
||||
* @param string $table_name The table to lock
|
||||
* @param string $glue The glue by which to join the conditions. Defaults to ',' .
|
||||
*
|
||||
* @return F0FDatabaseQueryPostgresql FOR SHARE query element
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function forShare($table_name, $glue = ',')
|
||||
{
|
||||
$this->type = 'forShare';
|
||||
|
||||
if (is_null($this->forShare))
|
||||
{
|
||||
$glue = strtoupper($glue);
|
||||
$this->forShare = new F0FDatabaseQueryElement('FOR SHARE', 'OF ' . $table_name, "$glue ");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->forShare->append($table_name);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get a string to extract year from date column.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->year($query->quoteName('dateColumn')));
|
||||
*
|
||||
* @param string $date Date column containing year to be extracted.
|
||||
*
|
||||
* @return string Returns string to extract year from a date.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function year($date)
|
||||
{
|
||||
return 'EXTRACT (YEAR FROM ' . $date . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get a string to extract month from date column.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->month($query->quoteName('dateColumn')));
|
||||
*
|
||||
* @param string $date Date column containing month to be extracted.
|
||||
*
|
||||
* @return string Returns string to extract month from a date.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function month($date)
|
||||
{
|
||||
return 'EXTRACT (MONTH FROM ' . $date . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get a string to extract day from date column.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->day($query->quoteName('dateColumn')));
|
||||
*
|
||||
* @param string $date Date column containing day to be extracted.
|
||||
*
|
||||
* @return string Returns string to extract day from a date.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function day($date)
|
||||
{
|
||||
return 'EXTRACT (DAY FROM ' . $date . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get a string to extract hour from date column.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->hour($query->quoteName('dateColumn')));
|
||||
*
|
||||
* @param string $date Date column containing hour to be extracted.
|
||||
*
|
||||
* @return string Returns string to extract hour from a date.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function hour($date)
|
||||
{
|
||||
return 'EXTRACT (HOUR FROM ' . $date . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get a string to extract minute from date column.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->minute($query->quoteName('dateColumn')));
|
||||
*
|
||||
* @param string $date Date column containing minute to be extracted.
|
||||
*
|
||||
* @return string Returns string to extract minute from a date.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function minute($date)
|
||||
{
|
||||
return 'EXTRACT (MINUTE FROM ' . $date . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get a string to extract seconds from date column.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->second($query->quoteName('dateColumn')));
|
||||
*
|
||||
* @param string $date Date column containing second to be extracted.
|
||||
*
|
||||
* @return string Returns string to extract second from a date.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function second($date)
|
||||
{
|
||||
return 'EXTRACT (SECOND FROM ' . $date . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the NOWAIT lock on select's output row
|
||||
*
|
||||
* @return F0FDatabaseQueryPostgresql NO WAIT query element
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function noWait ()
|
||||
{
|
||||
$this->type = 'noWait';
|
||||
|
||||
if (is_null($this->noWait))
|
||||
{
|
||||
$this->noWait = new F0FDatabaseQueryElement('NOWAIT', null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the LIMIT clause to the query
|
||||
*
|
||||
* @param integer $limit An int of how many row will be returned
|
||||
*
|
||||
* @return F0FDatabaseQueryPostgresql Returns this object to allow chaining.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function limit($limit = 0)
|
||||
{
|
||||
if (is_null($this->limit))
|
||||
{
|
||||
$this->limit = new F0FDatabaseQueryElement('LIMIT', (int) $limit);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the OFFSET clause to the query
|
||||
*
|
||||
* @param integer $offset An int for skipping row
|
||||
*
|
||||
* @return F0FDatabaseQueryPostgresql Returns this object to allow chaining.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function offset($offset = 0)
|
||||
{
|
||||
if (is_null($this->offset))
|
||||
{
|
||||
$this->offset = new F0FDatabaseQueryElement('OFFSET', (int) $offset);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the RETURNING element to INSERT INTO statement.
|
||||
*
|
||||
* @param mixed $pkCol The name of the primary key column.
|
||||
*
|
||||
* @return F0FDatabaseQueryPostgresql Returns this object to allow chaining.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function returning($pkCol)
|
||||
{
|
||||
if (is_null($this->returning))
|
||||
{
|
||||
$this->returning = new F0FDatabaseQueryElement('RETURNING', $pkCol);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset and limit for the result set, if the database driver supports it.
|
||||
*
|
||||
* Usage:
|
||||
* $query->setLimit(100, 0); (retrieve 100 rows, starting at first record)
|
||||
* $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record)
|
||||
*
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return F0FDatabaseQueryPostgresql Returns this object to allow chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setLimit($limit = 0, $offset = 0)
|
||||
{
|
||||
$this->limit = (int) $limit;
|
||||
$this->offset = (int) $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to modify a query already in string format with the needed
|
||||
* additions to make the query limited to a particular number of
|
||||
* results, or start at a particular offset.
|
||||
*
|
||||
* @param string $query The query in string format
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function processLimit($query, $limit, $offset = 0)
|
||||
{
|
||||
if ($limit > 0)
|
||||
{
|
||||
$query .= ' LIMIT ' . $limit;
|
||||
}
|
||||
|
||||
if ($offset > 0)
|
||||
{
|
||||
$query .= ' OFFSET ' . $offset;
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to the current date and time in Postgresql.
|
||||
* Usage:
|
||||
* $query->select($query->dateAdd());
|
||||
* Prefixing the interval with a - (negative sign) will cause subtraction to be used.
|
||||
*
|
||||
* @param datetime $date The date to add to
|
||||
* @param string $interval The string representation of the appropriate number of units
|
||||
* @param string $datePart The part of the date to perform the addition on
|
||||
*
|
||||
* @return string The string with the appropriate sql for addition of dates
|
||||
*
|
||||
* @since 13.1
|
||||
* @note Not all drivers support all units. Check appropriate references
|
||||
* @link http://www.postgresql.org/docs/9.0/static/functions-datetime.html.
|
||||
*/
|
||||
public function dateAdd($date, $interval, $datePart)
|
||||
{
|
||||
if (substr($interval, 0, 1) != '-')
|
||||
{
|
||||
return "timestamp '" . $date . "' + interval '" . $interval . " " . $datePart . "'";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "timestamp '" . $date . "' - interval '" . ltrim($interval, '-') . " " . $datePart . "'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return correct regexp operator for Postgresql.
|
||||
*
|
||||
* Ensure that the regexp operator is Postgresql compatible.
|
||||
*
|
||||
* Usage:
|
||||
* $query->where('field ' . $query->regexp($search));
|
||||
*
|
||||
* @param string $value The regex pattern.
|
||||
*
|
||||
* @return string Returns the regex operator.
|
||||
*
|
||||
* @since 11.3
|
||||
*/
|
||||
public function regexp($value)
|
||||
{
|
||||
return ' ~* ' . $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return correct rand() function for Postgresql.
|
||||
*
|
||||
* Ensure that the rand() function is Postgresql compatible.
|
||||
*
|
||||
* Usage:
|
||||
* $query->Rand();
|
||||
*
|
||||
* @return string The correct rand function.
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
public function Rand()
|
||||
{
|
||||
return ' RANDOM() ';
|
||||
}
|
||||
}
|
||||
62
libraries/f0f/database/query/preparable.php
Normal file
62
libraries/f0f/database/query/preparable.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
if (!interface_exists('JDatabaseQueryPreparable'))
|
||||
{
|
||||
/**
|
||||
* Joomla Database Query Preparable Interface.
|
||||
* Adds bind/unbind methods as well as a getBounded() method
|
||||
* to retrieve the stored bounded variables on demand prior to
|
||||
* query execution.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
interface JDatabaseQueryPreparable
|
||||
{
|
||||
/**
|
||||
* Method to add a variable to an internal array that will be bound to a prepared SQL statement before query execution. Also
|
||||
* removes a variable that has been bounded from the internal bounded array when the passed in value is null.
|
||||
*
|
||||
* @param string|integer $key The key that will be used in your SQL query to reference the value. Usually of
|
||||
* the form ':key', but can also be an integer.
|
||||
* @param mixed &$value The value that will be bound. The value is passed by reference to support output
|
||||
* parameters such as those possible with stored procedures.
|
||||
* @param integer $dataType Constant corresponding to a SQL datatype.
|
||||
* @param integer $length The length of the variable. Usually required for OUTPUT parameters.
|
||||
* @param array $driverOptions Optional driver options to be used.
|
||||
*
|
||||
* @return F0FDatabaseQuery
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function bind($key = null, &$value = null, $dataType = PDO::PARAM_STR, $length = 0, $driverOptions = array());
|
||||
|
||||
/**
|
||||
* Retrieves the bound parameters array when key is null and returns it by reference. If a key is provided then that item is
|
||||
* returned.
|
||||
*
|
||||
* @param mixed $key The bounded variable key to retrieve.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function &getBounded($key = null);
|
||||
}
|
||||
}
|
||||
|
||||
interface F0FDatabaseQueryPreparable extends JDatabaseQueryPreparable
|
||||
{
|
||||
|
||||
}
|
||||
33
libraries/f0f/database/query/sqlazure.php
Normal file
33
libraries/f0f/database/query/sqlazure.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Query Building Class.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
class F0FDatabaseQuerySqlazure extends F0FDatabaseQuerySqlsrv
|
||||
{
|
||||
/**
|
||||
* The character(s) used to quote SQL statement names such as table names or field names,
|
||||
* etc. The child classes should define this as necessary. If a single character string the
|
||||
* same character is used for both sides of the quoted name, else the first character will be
|
||||
* used for the opening quote and the second for the closing quote.
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
protected $name_quotes = '';
|
||||
}
|
||||
279
libraries/f0f/database/query/sqlite.php
Normal file
279
libraries/f0f/database/query/sqlite.php
Normal file
@ -0,0 +1,279 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* SQLite Query Building Class.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
class F0FDatabaseQuerySqlite extends F0FDatabaseQueryPdo implements F0FDatabaseQueryPreparable, F0FDatabaseQueryLimitable
|
||||
{
|
||||
/**
|
||||
* @var integer The offset for the result set.
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $offset;
|
||||
|
||||
/**
|
||||
* @var integer The limit for the result set.
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $limit;
|
||||
|
||||
/**
|
||||
* @var array Bounded object array
|
||||
* @since 12.1
|
||||
*/
|
||||
protected $bounded = array();
|
||||
|
||||
/**
|
||||
* Method to add a variable to an internal array that will be bound to a prepared SQL statement before query execution. Also
|
||||
* removes a variable that has been bounded from the internal bounded array when the passed in value is null.
|
||||
*
|
||||
* @param string|integer $key The key that will be used in your SQL query to reference the value. Usually of
|
||||
* the form ':key', but can also be an integer.
|
||||
* @param mixed &$value The value that will be bound. The value is passed by reference to support output
|
||||
* parameters such as those possible with stored procedures.
|
||||
* @param integer $dataType Constant corresponding to a SQL datatype.
|
||||
* @param integer $length The length of the variable. Usually required for OUTPUT parameters.
|
||||
* @param array $driverOptions Optional driver options to be used.
|
||||
*
|
||||
* @return F0FDatabaseQuerySqlite
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function bind($key = null, &$value = null, $dataType = PDO::PARAM_STR, $length = 0, $driverOptions = array())
|
||||
{
|
||||
// Case 1: Empty Key (reset $bounded array)
|
||||
if (empty($key))
|
||||
{
|
||||
$this->bounded = array();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Case 2: Key Provided, null value (unset key from $bounded array)
|
||||
if (is_null($value))
|
||||
{
|
||||
if (isset($this->bounded[$key]))
|
||||
{
|
||||
unset($this->bounded[$key]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$obj = new stdClass;
|
||||
|
||||
$obj->value = &$value;
|
||||
$obj->dataType = $dataType;
|
||||
$obj->length = $length;
|
||||
$obj->driverOptions = $driverOptions;
|
||||
|
||||
// Case 3: Simply add the Key/Value into the bounded array
|
||||
$this->bounded[$key] = $obj;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the bound parameters array when key is null and returns it by reference. If a key is provided then that item is
|
||||
* returned.
|
||||
*
|
||||
* @param mixed $key The bounded variable key to retrieve.
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function &getBounded($key = null)
|
||||
{
|
||||
if (empty($key))
|
||||
{
|
||||
return $this->bounded;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($this->bounded[$key]))
|
||||
{
|
||||
return $this->bounded[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of characters in a string.
|
||||
*
|
||||
* Note, use 'length' to find the number of bytes in a string.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->charLength('a'));
|
||||
*
|
||||
* @param string $field A value.
|
||||
* @param string $operator Comparison operator between charLength integer value and $condition
|
||||
* @param string $condition Integer value to compare charLength with.
|
||||
*
|
||||
* @return string The required char length call.
|
||||
*
|
||||
* @since 13.1
|
||||
*/
|
||||
public function charLength($field, $operator = null, $condition = null)
|
||||
{
|
||||
return 'length(' . $field . ')' . (isset($operator) && isset($condition) ? ' ' . $operator . ' ' . $condition : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear data from the query or a specific clause of the query.
|
||||
*
|
||||
* @param string $clause Optionally, the name of the clause to clear, or nothing to clear the whole query.
|
||||
*
|
||||
* @return F0FDatabaseQuerySqlite Returns this object to allow chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function clear($clause = null)
|
||||
{
|
||||
switch ($clause)
|
||||
{
|
||||
case null:
|
||||
$this->bounded = array();
|
||||
break;
|
||||
}
|
||||
|
||||
parent::clear($clause);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates an array of column names or values.
|
||||
*
|
||||
* Usage:
|
||||
* $query->select($query->concatenate(array('a', 'b')));
|
||||
*
|
||||
* @param array $values An array of values to concatenate.
|
||||
* @param string $separator As separator to place between each value.
|
||||
*
|
||||
* @return string The concatenated values.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function concatenate($values, $separator = null)
|
||||
{
|
||||
if ($separator)
|
||||
{
|
||||
return implode(' || ' . $this->quote($separator) . ' || ', $values);
|
||||
}
|
||||
else
|
||||
{
|
||||
return implode(' || ', $values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to modify a query already in string format with the needed
|
||||
* additions to make the query limited to a particular number of
|
||||
* results, or start at a particular offset. This method is used
|
||||
* automatically by the __toString() method if it detects that the
|
||||
* query implements the F0FDatabaseQueryLimitable interface.
|
||||
*
|
||||
* @param string $query The query in string format
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function processLimit($query, $limit, $offset = 0)
|
||||
{
|
||||
if ($limit > 0 || $offset > 0)
|
||||
{
|
||||
$query .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset and limit for the result set, if the database driver supports it.
|
||||
*
|
||||
* Usage:
|
||||
* $query->setLimit(100, 0); (retrieve 100 rows, starting at first record)
|
||||
* $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record)
|
||||
*
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return F0FDatabaseQuerySqlite Returns this object to allow chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setLimit($limit = 0, $offset = 0)
|
||||
{
|
||||
$this->limit = (int) $limit;
|
||||
$this->offset = (int) $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to the current date and time.
|
||||
* Usage:
|
||||
* $query->select($query->dateAdd());
|
||||
* Prefixing the interval with a - (negative sign) will cause subtraction to be used.
|
||||
*
|
||||
* @param datetime $date The date or datetime to add to
|
||||
* @param string $interval The string representation of the appropriate number of units
|
||||
* @param string $datePart The part of the date to perform the addition on
|
||||
*
|
||||
* @return string The string with the appropriate sql for addition of dates
|
||||
*
|
||||
* @since 13.1
|
||||
* @link http://www.sqlite.org/lang_datefunc.html
|
||||
*/
|
||||
public function dateAdd($date, $interval, $datePart)
|
||||
{
|
||||
// SQLite does not support microseconds as a separate unit. Convert the interval to seconds
|
||||
if (strcasecmp($datePart, 'microseconds') == 0)
|
||||
{
|
||||
$interval = .001 * $interval;
|
||||
$datePart = 'seconds';
|
||||
}
|
||||
|
||||
if (substr($interval, 0, 1) != '-')
|
||||
{
|
||||
return "datetime('" . $date . "', '+" . $interval . " " . $datePart . "')";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "datetime('" . $date . "', '" . $interval . " " . $datePart . "')";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current date and time.
|
||||
*
|
||||
* Usage:
|
||||
* $query->where('published_up < '.$query->currentTimestamp());
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 3.4
|
||||
*/
|
||||
public function currentTimestamp()
|
||||
{
|
||||
return 'CURRENT_TIMESTAMP';
|
||||
}
|
||||
}
|
||||
380
libraries/f0f/database/query/sqlsrv.php
Normal file
380
libraries/f0f/database/query/sqlsrv.php
Normal file
@ -0,0 +1,380 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage database
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*
|
||||
* This file is adapted from the Joomla! Platform. It is used to iterate a database cursor returning F0FTable objects
|
||||
* instead of plain stdClass objects
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Query Building Class.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
class F0FDatabaseQuerySqlsrv extends F0FDatabaseQuery implements F0FDatabaseQueryLimitable
|
||||
{
|
||||
/**
|
||||
* The character(s) used to quote SQL statement names such as table names or field names,
|
||||
* etc. The child classes should define this as necessary. If a single character string the
|
||||
* same character is used for both sides of the quoted name, else the first character will be
|
||||
* used for the opening quote and the second for the closing quote.
|
||||
*
|
||||
* @var string
|
||||
* @since 11.1
|
||||
*/
|
||||
protected $name_quotes = '`';
|
||||
|
||||
/**
|
||||
* The null or zero representation of a timestamp for the database driver. This should be
|
||||
* defined in child classes to hold the appropriate value for the engine.
|
||||
*
|
||||
* @var string
|
||||
* @since 11.1
|
||||
*/
|
||||
protected $null_date = '1900-01-01 00:00:00';
|
||||
|
||||
/**
|
||||
* @var integer The affected row limit for the current SQL statement.
|
||||
* @since 3.2
|
||||
*/
|
||||
protected $limit = 0;
|
||||
|
||||
/**
|
||||
* @var integer The affected row offset to apply for the current SQL statement.
|
||||
* @since 3.2
|
||||
*/
|
||||
protected $offset = 0;
|
||||
|
||||
/**
|
||||
* Magic function to convert the query to a string.
|
||||
*
|
||||
* @return string The completed query.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$query = '';
|
||||
|
||||
switch ($this->type)
|
||||
{
|
||||
case 'select':
|
||||
$query .= (string) $this->select;
|
||||
$query .= (string) $this->from;
|
||||
|
||||
if ($this->join)
|
||||
{
|
||||
// Special case for joins
|
||||
foreach ($this->join as $join)
|
||||
{
|
||||
$query .= (string) $join;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->where)
|
||||
{
|
||||
$query .= (string) $this->where;
|
||||
}
|
||||
|
||||
if ($this->group)
|
||||
{
|
||||
$query .= (string) $this->group;
|
||||
}
|
||||
|
||||
if ($this->order)
|
||||
{
|
||||
$query .= (string) $this->order;
|
||||
}
|
||||
|
||||
if ($this->having)
|
||||
{
|
||||
$query .= (string) $this->having;
|
||||
}
|
||||
|
||||
if ($this instanceof F0FDatabaseQueryLimitable && ($this->limit > 0 || $this->offset > 0))
|
||||
{
|
||||
$query = $this->processLimit($query, $this->limit, $this->offset);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'insert':
|
||||
$query .= (string) $this->insert;
|
||||
|
||||
// Set method
|
||||
if ($this->set)
|
||||
{
|
||||
$query .= (string) $this->set;
|
||||
}
|
||||
// Columns-Values method
|
||||
elseif ($this->values)
|
||||
{
|
||||
if ($this->columns)
|
||||
{
|
||||
$query .= (string) $this->columns;
|
||||
}
|
||||
|
||||
$elements = $this->insert->getElements();
|
||||
$tableName = array_shift($elements);
|
||||
|
||||
$query .= 'VALUES ';
|
||||
$query .= (string) $this->values;
|
||||
|
||||
if ($this->autoIncrementField)
|
||||
{
|
||||
$query = 'SET IDENTITY_INSERT ' . $tableName . ' ON;' . $query . 'SET IDENTITY_INSERT ' . $tableName . ' OFF;';
|
||||
}
|
||||
|
||||
if ($this->where)
|
||||
{
|
||||
$query .= (string) $this->where;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
$query .= (string) $this->delete;
|
||||
$query .= (string) $this->from;
|
||||
|
||||
if ($this->join)
|
||||
{
|
||||
// Special case for joins
|
||||
foreach ($this->join as $join)
|
||||
{
|
||||
$query .= (string) $join;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->where)
|
||||
{
|
||||
$query .= (string) $this->where;
|
||||
}
|
||||
|
||||
if ($this->order)
|
||||
{
|
||||
$query .= (string) $this->order;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$query .= (string) $this->update;
|
||||
|
||||
if ($this->join)
|
||||
{
|
||||
// Special case for joins
|
||||
foreach ($this->join as $join)
|
||||
{
|
||||
$query .= (string) $join;
|
||||
}
|
||||
}
|
||||
|
||||
$query .= (string) $this->set;
|
||||
|
||||
if ($this->where)
|
||||
{
|
||||
$query .= (string) $this->where;
|
||||
}
|
||||
|
||||
if ($this->order)
|
||||
{
|
||||
$query .= (string) $this->order;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$query = parent::__toString();
|
||||
break;
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts a value to a char.
|
||||
*
|
||||
* Ensure that the value is properly quoted before passing to the method.
|
||||
*
|
||||
* @param string $value The value to cast as a char.
|
||||
*
|
||||
* @return string Returns the cast value.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function castAsChar($value)
|
||||
{
|
||||
return 'CAST(' . $value . ' as NVARCHAR(10))';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the function to determine the length of a character string.
|
||||
*
|
||||
* @param string $field A value.
|
||||
* @param string $operator Comparison operator between charLength integer value and $condition
|
||||
* @param string $condition Integer value to compare charLength with.
|
||||
*
|
||||
* @return string The required char length call.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function charLength($field, $operator = null, $condition = null)
|
||||
{
|
||||
return 'DATALENGTH(' . $field . ')' . (isset($operator) && isset($condition) ? ' ' . $operator . ' ' . $condition : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates an array of column names or values.
|
||||
*
|
||||
* @param array $values An array of values to concatenate.
|
||||
* @param string $separator As separator to place between each value.
|
||||
*
|
||||
* @return string The concatenated values.
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function concatenate($values, $separator = null)
|
||||
{
|
||||
if ($separator)
|
||||
{
|
||||
return '(' . implode('+' . $this->quote($separator) . '+', $values) . ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
return '(' . implode('+', $values) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current date and time.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function currentTimestamp()
|
||||
{
|
||||
return 'GETDATE()';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of a string in bytes.
|
||||
*
|
||||
* @param string $value The string to measure.
|
||||
*
|
||||
* @return integer
|
||||
*
|
||||
* @since 11.1
|
||||
*/
|
||||
public function length($value)
|
||||
{
|
||||
return 'LEN(' . $value . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to the current date and time.
|
||||
* Usage:
|
||||
* $query->select($query->dateAdd());
|
||||
* Prefixing the interval with a - (negative sign) will cause subtraction to be used.
|
||||
*
|
||||
* @param datetime $date The date to add to; type may be time or datetime.
|
||||
* @param string $interval The string representation of the appropriate number of units
|
||||
* @param string $datePart The part of the date to perform the addition on
|
||||
*
|
||||
* @return string The string with the appropriate sql for addition of dates
|
||||
*
|
||||
* @since 13.1
|
||||
* @note Not all drivers support all units.
|
||||
* @link http://msdn.microsoft.com/en-us/library/ms186819.aspx for more information
|
||||
*/
|
||||
public function dateAdd($date, $interval, $datePart)
|
||||
{
|
||||
return "DATEADD('" . $datePart . "', '" . $interval . "', '" . $date . "'" . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to modify a query already in string format with the needed
|
||||
* additions to make the query limited to a particular number of
|
||||
* results, or start at a particular offset.
|
||||
*
|
||||
* @param string $query The query in string format
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function processLimit($query, $limit, $offset = 0)
|
||||
{
|
||||
if ($limit == 0 && $offset == 0)
|
||||
{
|
||||
return $query;
|
||||
}
|
||||
|
||||
$start = $offset + 1;
|
||||
$end = $offset + $limit;
|
||||
|
||||
$orderBy = stristr($query, 'ORDER BY');
|
||||
|
||||
if (is_null($orderBy) || empty($orderBy))
|
||||
{
|
||||
$orderBy = 'ORDER BY (select 0)';
|
||||
}
|
||||
|
||||
$query = str_ireplace($orderBy, '', $query);
|
||||
|
||||
$rowNumberText = ', ROW_NUMBER() OVER (' . $orderBy . ') AS RowNumber FROM ';
|
||||
|
||||
$query = preg_replace('/\sFROM\s/i', $rowNumberText, $query, 1);
|
||||
$query = 'SELECT * FROM (' . $query . ') A WHERE A.RowNumber BETWEEN ' . $start . ' AND ' . $end;
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset and limit for the result set, if the database driver supports it.
|
||||
*
|
||||
* Usage:
|
||||
* $query->setLimit(100, 0); (retrieve 100 rows, starting at first record)
|
||||
* $query->setLimit(50, 50); (retrieve 50 rows, starting at 50th record)
|
||||
*
|
||||
* @param integer $limit The limit for the result set
|
||||
* @param integer $offset The offset for the result set
|
||||
*
|
||||
* @return F0FDatabaseQuery Returns this object to allow chaining.
|
||||
*
|
||||
* @since 12.1
|
||||
*/
|
||||
public function setLimit($limit = 0, $offset = 0)
|
||||
{
|
||||
$this->limit = (int) $limit;
|
||||
$this->offset = (int) $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return correct rand() function for MSSQL.
|
||||
*
|
||||
* Ensure that the rand() function is MSSQL compatible.
|
||||
*
|
||||
* Usage:
|
||||
* $query->Rand();
|
||||
*
|
||||
* @return string The correct rand function.
|
||||
*
|
||||
* @since 3.5
|
||||
*/
|
||||
public function Rand()
|
||||
{
|
||||
return ' NEWID() ';
|
||||
}
|
||||
}
|
||||
718
libraries/f0f/dispatcher/dispatcher.php
Normal file
718
libraries/f0f/dispatcher/dispatcher.php
Normal file
@ -0,0 +1,718 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage dispatcher
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* FrameworkOnFramework dispatcher class
|
||||
*
|
||||
* FrameworkOnFramework is a set of classes which extend Joomla! 1.5 and later's
|
||||
* MVC framework with features making maintaining complex software much easier,
|
||||
* without tedious repetitive copying of the same code over and over again.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 1.0
|
||||
*/
|
||||
class F0FDispatcher extends F0FUtilsObject
|
||||
{
|
||||
/** @var array Configuration variables */
|
||||
protected $config = array();
|
||||
|
||||
/** @var F0FInput Input variables */
|
||||
protected $input = array();
|
||||
|
||||
/** @var string The name of the default view, in case none is specified */
|
||||
public $defaultView = 'cpanel';
|
||||
|
||||
// Variables for F0F's transparent user authentication. You can override them
|
||||
// in your Dispatcher's __construct() method.
|
||||
|
||||
/** @var int The Time Step for the TOTP used in F0F's transparent user authentication */
|
||||
protected $fofAuth_timeStep = 6;
|
||||
|
||||
/** @var string The key for the TOTP, Base32 encoded (watch out; Base32, NOT Base64!) */
|
||||
protected $fofAuth_Key = null;
|
||||
|
||||
/** @var array Which formats to be handled by transparent authentication */
|
||||
protected $fofAuth_Formats = array('json', 'csv', 'xml', 'raw');
|
||||
|
||||
/**
|
||||
* Should I logout the transparently authenticated user on logout?
|
||||
* Recommended to leave it on in order to avoid crashing the sessions table.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $fofAuth_LogoutOnReturn = true;
|
||||
|
||||
/** @var array Which methods to use to fetch authentication credentials and in which order */
|
||||
protected $fofAuth_AuthMethods = array(
|
||||
/* HTTP Basic Authentication using encrypted information protected
|
||||
* with a TOTP (the username must be "_fof_auth") */
|
||||
'HTTPBasicAuth_TOTP',
|
||||
/* Encrypted information protected with a TOTP passed in the
|
||||
* _fofauthentication query string parameter */
|
||||
'QueryString_TOTP',
|
||||
/* HTTP Basic Authentication using a username and password pair in plain text */
|
||||
'HTTPBasicAuth_Plaintext',
|
||||
/* Plaintext, JSON-encoded username and password pair passed in the
|
||||
* _fofauthentication query string parameter */
|
||||
'QueryString_Plaintext',
|
||||
/* Plaintext username and password in the _fofauthentication_username
|
||||
* and _fofauthentication_username query string parameters */
|
||||
'SplitQueryString_Plaintext',
|
||||
);
|
||||
|
||||
/** @var bool Did we successfully and transparently logged in a user? */
|
||||
private $_fofAuth_isLoggedIn = false;
|
||||
|
||||
/** @var string The calculated encryption key for the _TOTP methods, used if we have to encrypt the reply */
|
||||
private $_fofAuth_CryptoKey = '';
|
||||
|
||||
/**
|
||||
* Get a static (Singleton) instance of a particular Dispatcher
|
||||
*
|
||||
* @param string $option The component name
|
||||
* @param string $view The View name
|
||||
* @param array $config Configuration data
|
||||
*
|
||||
* @staticvar array $instances Holds the array of Dispatchers F0F knows about
|
||||
*
|
||||
* @return F0FDispatcher
|
||||
*/
|
||||
public static function &getAnInstance($option = null, $view = null, $config = array())
|
||||
{
|
||||
static $instances = array();
|
||||
|
||||
$hash = $option . $view;
|
||||
|
||||
if (!array_key_exists($hash, $instances))
|
||||
{
|
||||
$instances[$hash] = self::getTmpInstance($option, $view, $config);
|
||||
}
|
||||
|
||||
return $instances[$hash];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a temporary instance of a Dispatcher
|
||||
*
|
||||
* @param string $option The component name
|
||||
* @param string $view The View name
|
||||
* @param array $config Configuration data
|
||||
*
|
||||
* @return F0FDispatcher
|
||||
*/
|
||||
public static function &getTmpInstance($option = null, $view = null, $config = array())
|
||||
{
|
||||
if (array_key_exists('input', $config))
|
||||
{
|
||||
if ($config['input'] instanceof F0FInput)
|
||||
{
|
||||
$input = $config['input'];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_array($config['input']))
|
||||
{
|
||||
$config['input'] = (array) $config['input'];
|
||||
}
|
||||
|
||||
$config['input'] = array_merge($_REQUEST, $config['input']);
|
||||
$input = new F0FInput($config['input']);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$input = new F0FInput;
|
||||
}
|
||||
|
||||
$config['option'] = !is_null($option) ? $option : $input->getCmd('option', 'com_foobar');
|
||||
$config['view'] = !is_null($view) ? $view : $input->getCmd('view', '');
|
||||
|
||||
$input->set('option', $config['option']);
|
||||
$input->set('view', $config['view']);
|
||||
|
||||
$config['input'] = $input;
|
||||
|
||||
$className = ucfirst(str_replace('com_', '', $config['option'])) . 'Dispatcher';
|
||||
|
||||
if (!class_exists($className))
|
||||
{
|
||||
$componentPaths = F0FPlatform::getInstance()->getComponentBaseDirs($config['option']);
|
||||
|
||||
$searchPaths = array(
|
||||
$componentPaths['main'],
|
||||
$componentPaths['main'] . '/dispatchers',
|
||||
$componentPaths['admin'],
|
||||
$componentPaths['admin'] . '/dispatchers'
|
||||
);
|
||||
|
||||
if (array_key_exists('searchpath', $config))
|
||||
{
|
||||
array_unshift($searchPaths, $config['searchpath']);
|
||||
}
|
||||
|
||||
$filesystem = F0FPlatform::getInstance()->getIntegrationObject('filesystem');
|
||||
|
||||
$path = $filesystem->pathFind(
|
||||
$searchPaths, 'dispatcher.php'
|
||||
);
|
||||
|
||||
if ($path)
|
||||
{
|
||||
require_once $path;
|
||||
}
|
||||
}
|
||||
|
||||
if (!class_exists($className))
|
||||
{
|
||||
$className = 'F0FDispatcher';
|
||||
}
|
||||
|
||||
$instance = new $className($config);
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public constructor
|
||||
*
|
||||
* @param array $config The configuration variables
|
||||
*/
|
||||
public function __construct($config = array())
|
||||
{
|
||||
// Cache the config
|
||||
$this->config = $config;
|
||||
|
||||
// Get the input for this MVC triad
|
||||
if (array_key_exists('input', $config))
|
||||
{
|
||||
$this->input = $config['input'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->input = new F0FInput;
|
||||
}
|
||||
|
||||
// Get the default values for the component name
|
||||
$this->component = $this->input->getCmd('option', 'com_foobar');
|
||||
|
||||
// Load the component's fof.xml configuration file
|
||||
$configProvider = new F0FConfigProvider;
|
||||
$this->defaultView = $configProvider->get($this->component . '.dispatcher.default_view', $this->defaultView);
|
||||
|
||||
// Get the default values for the view name
|
||||
$this->view = $this->input->getCmd('view', null);
|
||||
|
||||
if (empty($this->view))
|
||||
{
|
||||
// Do we have a task formatted as controller.task?
|
||||
$task = $this->input->getCmd('task', '');
|
||||
|
||||
if (!empty($task) && (strstr($task, '.') !== false))
|
||||
{
|
||||
list($this->view, $task) = explode('.', $task, 2);
|
||||
$this->input->set('task', $task);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->view))
|
||||
{
|
||||
$this->view = $this->defaultView;
|
||||
}
|
||||
|
||||
$this->layout = $this->input->getCmd('layout', null);
|
||||
|
||||
// Overrides from the config
|
||||
if (array_key_exists('option', $config))
|
||||
{
|
||||
$this->component = $config['option'];
|
||||
}
|
||||
|
||||
if (array_key_exists('view', $config))
|
||||
{
|
||||
$this->view = empty($config['view']) ? $this->view : $config['view'];
|
||||
}
|
||||
|
||||
if (array_key_exists('layout', $config))
|
||||
{
|
||||
$this->layout = $config['layout'];
|
||||
}
|
||||
|
||||
$this->input->set('option', $this->component);
|
||||
$this->input->set('view', $this->view);
|
||||
$this->input->set('layout', $this->layout);
|
||||
|
||||
if (array_key_exists('authTimeStep', $config))
|
||||
{
|
||||
$this->fofAuth_timeStep = empty($config['authTimeStep']) ? 6 : $config['authTimeStep'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The main code of the Dispatcher. It spawns the necessary controller and
|
||||
* runs it.
|
||||
*
|
||||
* @throws Exception
|
||||
*
|
||||
* @return void|Exception
|
||||
*/
|
||||
public function dispatch()
|
||||
{
|
||||
$platform = F0FPlatform::getInstance();
|
||||
|
||||
if (!$platform->authorizeAdmin($this->input->getCmd('option', 'com_foobar')))
|
||||
{
|
||||
return $platform->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'));
|
||||
}
|
||||
|
||||
$this->transparentAuthentication();
|
||||
|
||||
// Merge English and local translations
|
||||
$platform->loadTranslations($this->component);
|
||||
|
||||
$canDispatch = true;
|
||||
|
||||
if ($platform->isCli())
|
||||
{
|
||||
$canDispatch = $canDispatch && $this->onBeforeDispatchCLI();
|
||||
}
|
||||
|
||||
$canDispatch = $canDispatch && $this->onBeforeDispatch();
|
||||
|
||||
if (!$canDispatch)
|
||||
{
|
||||
// We can set header only if we're not in CLI
|
||||
if(!$platform->isCli())
|
||||
{
|
||||
$platform->setHeader('Status', '403 Forbidden', true);
|
||||
}
|
||||
|
||||
return $platform->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'));
|
||||
}
|
||||
|
||||
// Get and execute the controller
|
||||
$option = $this->input->getCmd('option', 'com_foobar');
|
||||
$view = $this->input->getCmd('view', $this->defaultView);
|
||||
$task = $this->input->getCmd('task', null);
|
||||
|
||||
if (empty($task))
|
||||
{
|
||||
$task = $this->getTask($view);
|
||||
}
|
||||
|
||||
// Pluralise/sungularise the view name for typical tasks
|
||||
if (in_array($task, array('edit', 'add', 'read')))
|
||||
{
|
||||
$view = F0FInflector::singularize($view);
|
||||
}
|
||||
elseif (in_array($task, array('browse')))
|
||||
{
|
||||
$view = F0FInflector::pluralize($view);
|
||||
}
|
||||
|
||||
$this->input->set('view', $view);
|
||||
$this->input->set('task', $task);
|
||||
|
||||
$config = $this->config;
|
||||
$config['input'] = $this->input;
|
||||
|
||||
$controller = F0FController::getTmpInstance($option, $view, $config);
|
||||
$status = $controller->execute($task);
|
||||
|
||||
if (!$this->onAfterDispatch())
|
||||
{
|
||||
// We can set header only if we're not in CLI
|
||||
if(!$platform->isCli())
|
||||
{
|
||||
$platform->setHeader('Status', '403 Forbidden', true);
|
||||
}
|
||||
|
||||
return $platform->raiseError(403, JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'));
|
||||
}
|
||||
|
||||
$format = $this->input->get('format', 'html', 'cmd');
|
||||
$format = empty($format) ? 'html' : $format;
|
||||
|
||||
if ($controller->hasRedirect())
|
||||
{
|
||||
$controller->redirect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to guess the controller task to execute based on the view name and
|
||||
* the HTTP request method.
|
||||
*
|
||||
* @param string $view The name of the view
|
||||
*
|
||||
* @return string The best guess of the task to execute
|
||||
*/
|
||||
protected function getTask($view)
|
||||
{
|
||||
// Get a default task based on plural/singular view
|
||||
$request_task = $this->input->getCmd('task', null);
|
||||
$task = F0FInflector::isPlural($view) ? 'browse' : 'edit';
|
||||
|
||||
// Get a potential ID, we might need it later
|
||||
$id = $this->input->get('id', null, 'int');
|
||||
|
||||
if ($id == 0)
|
||||
{
|
||||
$ids = $this->input->get('ids', array(), 'array');
|
||||
|
||||
if (!empty($ids))
|
||||
{
|
||||
$id = array_shift($ids);
|
||||
}
|
||||
}
|
||||
|
||||
// Check the request method
|
||||
|
||||
if (!isset($_SERVER['REQUEST_METHOD']))
|
||||
{
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
}
|
||||
|
||||
$requestMethod = strtoupper($_SERVER['REQUEST_METHOD']);
|
||||
|
||||
switch ($requestMethod)
|
||||
{
|
||||
case 'POST':
|
||||
case 'PUT':
|
||||
if (!is_null($id))
|
||||
{
|
||||
$task = 'save';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'DELETE':
|
||||
if ($id != 0)
|
||||
{
|
||||
$task = 'delete';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'GET':
|
||||
default:
|
||||
// If it's an edit without an ID or ID=0, it's really an add
|
||||
if (($task == 'edit') && ($id == 0))
|
||||
{
|
||||
$task = 'add';
|
||||
}
|
||||
|
||||
// If it's an edit in the frontend, it's really a read
|
||||
elseif (($task == 'edit') && F0FPlatform::getInstance()->isFrontend())
|
||||
{
|
||||
$task = 'read';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes right before the dispatcher tries to instantiate and run the
|
||||
* controller.
|
||||
*
|
||||
* @return boolean Return false to abort
|
||||
*/
|
||||
public function onBeforeDispatch()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up some environment variables, so we can work as usually on CLI, too.
|
||||
*
|
||||
* @return boolean Return false to abort
|
||||
*/
|
||||
public function onBeforeDispatchCLI()
|
||||
{
|
||||
JLoader::import('joomla.environment.uri');
|
||||
JLoader::import('joomla.application.component.helper');
|
||||
|
||||
// Trick to create a valid url used by JURI
|
||||
$this->_originalPhpScript = '';
|
||||
|
||||
// We have no Application Helper (there is no Application!), so I have to define these constants manually
|
||||
$option = $this->input->get('option', '', 'cmd');
|
||||
|
||||
if ($option)
|
||||
{
|
||||
$componentPaths = F0FPlatform::getInstance()->getComponentBaseDirs($option);
|
||||
|
||||
if (!defined('JPATH_COMPONENT'))
|
||||
{
|
||||
define('JPATH_COMPONENT', $componentPaths['main']);
|
||||
}
|
||||
|
||||
if (!defined('JPATH_COMPONENT_SITE'))
|
||||
{
|
||||
define('JPATH_COMPONENT_SITE', $componentPaths['site']);
|
||||
}
|
||||
|
||||
if (!defined('JPATH_COMPONENT_ADMINISTRATOR'))
|
||||
{
|
||||
define('JPATH_COMPONENT_ADMINISTRATOR', $componentPaths['admin']);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes right after the dispatcher runs the controller.
|
||||
*
|
||||
* @return boolean Return false to abort
|
||||
*/
|
||||
public function onAfterDispatch()
|
||||
{
|
||||
// If we have to log out the user, please do so now
|
||||
if ($this->fofAuth_LogoutOnReturn && $this->_fofAuth_isLoggedIn)
|
||||
{
|
||||
F0FPlatform::getInstance()->logoutUser();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transparently authenticates a user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function transparentAuthentication()
|
||||
{
|
||||
// Only run when there is no logged in user
|
||||
if (!F0FPlatform::getInstance()->getUser()->guest)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// @todo Check the format
|
||||
$format = $this->input->getCmd('format', 'html');
|
||||
|
||||
if (!in_array($format, $this->fofAuth_Formats))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->fofAuth_AuthMethods as $method)
|
||||
{
|
||||
// If we're already logged in, don't bother
|
||||
if ($this->_fofAuth_isLoggedIn)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// This will hold our authentication data array (username, password)
|
||||
$authInfo = null;
|
||||
|
||||
switch ($method)
|
||||
{
|
||||
case 'HTTPBasicAuth_TOTP':
|
||||
|
||||
if (empty($this->fofAuth_Key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($_SERVER['PHP_AUTH_USER']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($_SERVER['PHP_AUTH_PW']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($_SERVER['PHP_AUTH_USER'] != '_fof_auth')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$encryptedData = $_SERVER['PHP_AUTH_PW'];
|
||||
|
||||
$authInfo = $this->_decryptWithTOTP($encryptedData);
|
||||
break;
|
||||
|
||||
case 'QueryString_TOTP':
|
||||
$encryptedData = $this->input->get('_fofauthentication', '', 'raw');
|
||||
|
||||
if (empty($encryptedData))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$authInfo = $this->_decryptWithTOTP($encryptedData);
|
||||
break;
|
||||
|
||||
case 'HTTPBasicAuth_Plaintext':
|
||||
if (!isset($_SERVER['PHP_AUTH_USER']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($_SERVER['PHP_AUTH_PW']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$authInfo = array(
|
||||
'username' => $_SERVER['PHP_AUTH_USER'],
|
||||
'password' => $_SERVER['PHP_AUTH_PW']
|
||||
);
|
||||
break;
|
||||
|
||||
case 'QueryString_Plaintext':
|
||||
$jsonencoded = $this->input->get('_fofauthentication', '', 'raw');
|
||||
|
||||
if (empty($jsonencoded))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$authInfo = json_decode($jsonencoded, true);
|
||||
|
||||
if (!is_array($authInfo))
|
||||
{
|
||||
$authInfo = null;
|
||||
}
|
||||
elseif (!array_key_exists('username', $authInfo) || !array_key_exists('password', $authInfo))
|
||||
{
|
||||
$authInfo = null;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'SplitQueryString_Plaintext':
|
||||
$authInfo = array(
|
||||
'username' => $this->input->get('_fofauthentication_username', '', 'raw'),
|
||||
'password' => $this->input->get('_fofauthentication_password', '', 'raw'),
|
||||
);
|
||||
|
||||
if (empty($authInfo['username']))
|
||||
{
|
||||
$authInfo = null;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// No point trying unless we have a username and password
|
||||
if (!is_array($authInfo))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->_fofAuth_isLoggedIn = F0FPlatform::getInstance()->loginUser($authInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a transparent authentication message using a TOTP
|
||||
*
|
||||
* @param string $encryptedData The encrypted data
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return array The decrypted data
|
||||
*/
|
||||
private function _decryptWithTOTP($encryptedData)
|
||||
{
|
||||
if (empty($this->fofAuth_Key))
|
||||
{
|
||||
$this->_fofAuth_CryptoKey = null;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$totp = new F0FEncryptTotp($this->fofAuth_timeStep);
|
||||
$period = $totp->getPeriod();
|
||||
$period--;
|
||||
|
||||
for ($i = 0; $i <= 2; $i++)
|
||||
{
|
||||
$time = ($period + $i) * $this->fofAuth_timeStep;
|
||||
$otp = $totp->getCode($this->fofAuth_Key, $time);
|
||||
$this->_fofAuth_CryptoKey = hash('sha256', $this->fofAuth_Key . $otp);
|
||||
|
||||
$aes = new F0FEncryptAes($this->_fofAuth_CryptoKey);
|
||||
$ret = $aes->decryptString($encryptedData);
|
||||
$ret = rtrim($ret, "\000");
|
||||
|
||||
$ret = json_decode($ret, true);
|
||||
|
||||
if (!is_array($ret))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!array_key_exists('username', $ret))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!array_key_exists('password', $ret))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Successful decryption!
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// Obviously if we're here we could not decrypt anything. Bail out.
|
||||
$this->_fofAuth_CryptoKey = null;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a decryption key for use with the TOTP decryption method
|
||||
*
|
||||
* @param integer $time The timestamp used for TOTP calculation, leave empty to use current timestamp
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @return string THe encryption key
|
||||
*/
|
||||
private function _createDecryptionKey($time = null)
|
||||
{
|
||||
$totp = new F0FEncryptTotp($this->fofAuth_timeStep);
|
||||
$otp = $totp->getCode($this->fofAuth_Key, $time);
|
||||
|
||||
$key = hash('sha256', $this->fofAuth_Key . $otp);
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function to detect if we're running in a CLI environment and we're admin
|
||||
*
|
||||
* @return array isCLI and isAdmin. It's not an associtive array, so we can use list.
|
||||
*/
|
||||
public static function isCliAdmin()
|
||||
{
|
||||
static $isCLI = null;
|
||||
static $isAdmin = null;
|
||||
|
||||
if (is_null($isCLI) && is_null($isAdmin))
|
||||
{
|
||||
$isCLI = F0FPlatform::getInstance()->isCli();
|
||||
$isAdmin = F0FPlatform::getInstance()->isBackend();
|
||||
}
|
||||
|
||||
return array($isCLI, $isAdmin);
|
||||
}
|
||||
}
|
||||
113
libraries/f0f/download/adapter/abstract.php
Normal file
113
libraries/f0f/download/adapter/abstract.php
Normal file
@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage dispatcher
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Abstract base class for download adapters
|
||||
*/
|
||||
abstract class F0FDownloadAdapterAbstract implements F0FDownloadInterface
|
||||
{
|
||||
public $priority = 100;
|
||||
|
||||
public $name = '';
|
||||
|
||||
public $isSupported = false;
|
||||
|
||||
public $supportsChunkDownload = false;
|
||||
|
||||
public $supportsFileSize = false;
|
||||
|
||||
/**
|
||||
* Does this download adapter support downloading files in chunks?
|
||||
*
|
||||
* @return boolean True if chunk download is supported
|
||||
*/
|
||||
public function supportsChunkDownload()
|
||||
{
|
||||
return $this->supportsChunkDownload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this download adapter support reading the size of a remote file?
|
||||
*
|
||||
* @return boolean True if remote file size determination is supported
|
||||
*/
|
||||
public function supportsFileSize()
|
||||
{
|
||||
return $this->supportsFileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this download class supported in the current server environment?
|
||||
*
|
||||
* @return boolean True if this server environment supports this download class
|
||||
*/
|
||||
public function isSupported()
|
||||
{
|
||||
return $this->isSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the priority of this adapter. If multiple download adapters are
|
||||
* supported on a site, the one with the highest priority will be
|
||||
* used.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getPriority()
|
||||
{
|
||||
return $this->priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this download adapter in use
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a part (or the whole) of a remote URL and return the downloaded
|
||||
* data. You are supposed to check the size of the returned data. If it's
|
||||
* smaller than what you expected you've reached end of file. If it's empty
|
||||
* you have tried reading past EOF. If it's larger than what you expected
|
||||
* the server doesn't support chunk downloads.
|
||||
*
|
||||
* If this class' supportsChunkDownload returns false you should assume
|
||||
* that the $from and $to parameters will be ignored.
|
||||
*
|
||||
* @param string $url The remote file's URL
|
||||
* @param integer $from Byte range to start downloading from. Use null for start of file.
|
||||
* @param integer $to Byte range to stop downloading. Use null to download the entire file ($from is ignored)
|
||||
* @param array $params Additional params that will be added before performing the download
|
||||
*
|
||||
* @return string The raw file data retrieved from the remote URL.
|
||||
*
|
||||
* @throws Exception A generic exception is thrown on error
|
||||
*/
|
||||
public function downloadAndReturn($url, $from = null, $to = null, array $params = array())
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of a remote file in bytes
|
||||
*
|
||||
* @param string $url The remote file's URL
|
||||
*
|
||||
* @return integer The file size, or -1 if the remote server doesn't support this feature
|
||||
*/
|
||||
public function getFileSize($url)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
5104
libraries/f0f/download/adapter/cacert.pem
Normal file
5104
libraries/f0f/download/adapter/cacert.pem
Normal file
File diff suppressed because it is too large
Load Diff
226
libraries/f0f/download/adapter/curl.php
Normal file
226
libraries/f0f/download/adapter/curl.php
Normal file
@ -0,0 +1,226 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage dispatcher
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* A download adapter using the cURL PHP module
|
||||
*/
|
||||
class F0FDownloadAdapterCurl extends F0FDownloadAdapterAbstract implements F0FDownloadInterface
|
||||
{
|
||||
protected $headers = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->priority = 110;
|
||||
$this->supportsFileSize = true;
|
||||
$this->supportsChunkDownload = true;
|
||||
$this->name = 'curl';
|
||||
$this->isSupported = function_exists('curl_init') && function_exists('curl_exec') && function_exists('curl_close');
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a part (or the whole) of a remote URL and return the downloaded
|
||||
* data. You are supposed to check the size of the returned data. If it's
|
||||
* smaller than what you expected you've reached end of file. If it's empty
|
||||
* you have tried reading past EOF. If it's larger than what you expected
|
||||
* the server doesn't support chunk downloads.
|
||||
*
|
||||
* If this class' supportsChunkDownload returns false you should assume
|
||||
* that the $from and $to parameters will be ignored.
|
||||
*
|
||||
* @param string $url The remote file's URL
|
||||
* @param integer $from Byte range to start downloading from. Use null for start of file.
|
||||
* @param integer $to Byte range to stop downloading. Use null to download the entire file ($from is ignored)
|
||||
* @param array $params Additional params that will be added before performing the download
|
||||
*
|
||||
* @return string The raw file data retrieved from the remote URL.
|
||||
*
|
||||
* @throws Exception A generic exception is thrown on error
|
||||
*/
|
||||
public function downloadAndReturn($url, $from = null, $to = null, array $params = array())
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
||||
if (empty($from))
|
||||
{
|
||||
$from = 0;
|
||||
}
|
||||
|
||||
if (empty($to))
|
||||
{
|
||||
$to = 0;
|
||||
}
|
||||
|
||||
if ($to < $from)
|
||||
{
|
||||
$temp = $to;
|
||||
$to = $from;
|
||||
$from = $temp;
|
||||
|
||||
unset($temp);
|
||||
}
|
||||
|
||||
// Default cURL options
|
||||
$options = array(
|
||||
CURLOPT_AUTOREFERER => 1,
|
||||
CURLOPT_SSL_VERIFYPEER => 1,
|
||||
CURLOPT_SSL_VERIFYHOST => 2,
|
||||
CURLOPT_SSLVERSION => 0,
|
||||
CURLOPT_AUTOREFERER => 1,
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_BINARYTRANSFER => 1,
|
||||
CURLOPT_RETURNTRANSFER => 1,
|
||||
CURLOPT_FOLLOWLOCATION => 1,
|
||||
CURLOPT_CAINFO => __DIR__ . '/cacert.pem',
|
||||
CURLOPT_HEADERFUNCTION => array($this, 'reponseHeaderCallback')
|
||||
);
|
||||
|
||||
if (!(empty($from) && empty($to)))
|
||||
{
|
||||
$options[CURLOPT_RANGE] = "$from-$to";
|
||||
}
|
||||
|
||||
// Add any additional options: Since they are numeric, we must use the array operator. If the jey exists in both
|
||||
// arrays, only the first one will be used while the second one will be ignored
|
||||
$options = $params + $options;
|
||||
|
||||
@curl_setopt_array($ch, $options);
|
||||
|
||||
$this->headers = array();
|
||||
|
||||
$result = curl_exec($ch);
|
||||
|
||||
$errno = curl_errno($ch);
|
||||
$errmsg = curl_error($ch);
|
||||
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
$error = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_CURL_ERROR', $errno, $errmsg);
|
||||
}
|
||||
elseif (($http_status >= 300) && ($http_status <= 399) && isset($this->headers['Location']) && !empty($this->headers['Location']))
|
||||
{
|
||||
return $this->downloadAndReturn($this->headers['Location'], $from, $to, $params);
|
||||
}
|
||||
elseif ($http_status > 399)
|
||||
{
|
||||
$result = false;
|
||||
$errno = $http_status;
|
||||
$error = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_HTTPERROR', $http_status);
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
throw new Exception($error, $errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of a remote file in bytes
|
||||
*
|
||||
* @param string $url The remote file's URL
|
||||
*
|
||||
* @return integer The file size, or -1 if the remote server doesn't support this feature
|
||||
*/
|
||||
public function getFileSize($url)
|
||||
{
|
||||
$result = -1;
|
||||
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
|
||||
curl_setopt($ch, CURLOPT_SSLVERSION, 0);
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true );
|
||||
curl_setopt($ch, CURLOPT_HEADER, true );
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
|
||||
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
|
||||
@curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/cacert.pem');
|
||||
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($data)
|
||||
{
|
||||
$content_length = "unknown";
|
||||
$status = "unknown";
|
||||
$redirection = null;
|
||||
|
||||
if (preg_match( "/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches))
|
||||
{
|
||||
$status = (int)$matches[1];
|
||||
}
|
||||
|
||||
if (preg_match( "/Content-Length: (\d+)/", $data, $matches))
|
||||
{
|
||||
$content_length = (int)$matches[1];
|
||||
}
|
||||
|
||||
if (preg_match( "/Location: (.*)/", $data, $matches))
|
||||
{
|
||||
$redirection = (int)$matches[1];
|
||||
}
|
||||
|
||||
if ($status == 200)
|
||||
{
|
||||
$result = $content_length;
|
||||
}
|
||||
|
||||
if (($status > 300) && ($status <= 308))
|
||||
{
|
||||
if (!empty($redirection))
|
||||
{
|
||||
return $this->getFileSize($redirection);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the HTTP headers returned by cURL
|
||||
*
|
||||
* @param resource $ch cURL resource handle (unused)
|
||||
* @param string $data Each header line, as returned by the server
|
||||
*
|
||||
* @return int The length of the $data string
|
||||
*/
|
||||
protected function reponseHeaderCallback(&$ch, &$data)
|
||||
{
|
||||
$strlen = strlen($data);
|
||||
|
||||
if (($strlen) <= 2)
|
||||
{
|
||||
return $strlen;
|
||||
}
|
||||
|
||||
if (substr($data, 0, 4) == 'HTTP')
|
||||
{
|
||||
return $strlen;
|
||||
}
|
||||
|
||||
list($header, $value) = explode(': ', trim($data), 2);
|
||||
|
||||
$this->headers[$header] = $value;
|
||||
|
||||
return $strlen;
|
||||
}
|
||||
}
|
||||
123
libraries/f0f/download/adapter/fopen.php
Normal file
123
libraries/f0f/download/adapter/fopen.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage dispatcher
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* A download adapter using URL fopen() wrappers
|
||||
*/
|
||||
class F0FDownloadAdapterFopen extends F0FDownloadAdapterAbstract implements F0FDownloadInterface
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->priority = 100;
|
||||
$this->supportsFileSize = false;
|
||||
$this->supportsChunkDownload = true;
|
||||
$this->name = 'fopen';
|
||||
|
||||
// If we are not allowed to use ini_get, we assume that URL fopen is
|
||||
// disabled.
|
||||
if (!function_exists('ini_get'))
|
||||
{
|
||||
$this->isSupported = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->isSupported = ini_get('allow_url_fopen');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a part (or the whole) of a remote URL and return the downloaded
|
||||
* data. You are supposed to check the size of the returned data. If it's
|
||||
* smaller than what you expected you've reached end of file. If it's empty
|
||||
* you have tried reading past EOF. If it's larger than what you expected
|
||||
* the server doesn't support chunk downloads.
|
||||
*
|
||||
* If this class' supportsChunkDownload returns false you should assume
|
||||
* that the $from and $to parameters will be ignored.
|
||||
*
|
||||
* @param string $url The remote file's URL
|
||||
* @param integer $from Byte range to start downloading from. Use null for start of file.
|
||||
* @param integer $to Byte range to stop downloading. Use null to download the entire file ($from is ignored)
|
||||
* @param array $params Additional params that will be added before performing the download
|
||||
*
|
||||
* @return string The raw file data retrieved from the remote URL.
|
||||
*
|
||||
* @throws Exception A generic exception is thrown on error
|
||||
*/
|
||||
public function downloadAndReturn($url, $from = null, $to = null, array $params = array())
|
||||
{
|
||||
if (empty($from))
|
||||
{
|
||||
$from = 0;
|
||||
}
|
||||
|
||||
if (empty($to))
|
||||
{
|
||||
$to = 0;
|
||||
}
|
||||
|
||||
if ($to < $from)
|
||||
{
|
||||
$temp = $to;
|
||||
$to = $from;
|
||||
$from = $temp;
|
||||
|
||||
unset($temp);
|
||||
}
|
||||
|
||||
if (!(empty($from) && empty($to)))
|
||||
{
|
||||
$options = array(
|
||||
'http' => array(
|
||||
'method' => 'GET',
|
||||
'header' => "Range: bytes=$from-$to\r\n"
|
||||
),
|
||||
'ssl' => array(
|
||||
'verify_peer' => true,
|
||||
'cafile' => __DIR__ . '/cacert.pem',
|
||||
'verify_depth' => 5,
|
||||
)
|
||||
);
|
||||
|
||||
$options = array_merge($options, $params);
|
||||
|
||||
$context = stream_context_create($options);
|
||||
$result = @file_get_contents($url, false, $context, $from - $to + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$options = array(
|
||||
'http' => array(
|
||||
'method' => 'GET',
|
||||
),
|
||||
'ssl' => array(
|
||||
'verify_peer' => true,
|
||||
'cafile' => __DIR__ . '/cacert.pem',
|
||||
'verify_depth' => 5,
|
||||
)
|
||||
);
|
||||
|
||||
$options = array_merge($options, $params);
|
||||
|
||||
$context = stream_context_create($options);
|
||||
$result = @file_get_contents($url, false, $context);
|
||||
}
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
$error = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_HTTPERROR');
|
||||
throw new Exception($error, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
495
libraries/f0f/download/download.php
Normal file
495
libraries/f0f/download/download.php
Normal file
@ -0,0 +1,495 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage dispatcher
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
class F0FDownload
|
||||
{
|
||||
/**
|
||||
* Parameters passed from the GUI when importing from URL
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $params = array();
|
||||
|
||||
/**
|
||||
* The download adapter which will be used by this class
|
||||
*
|
||||
* @var F0FDownloadInterface
|
||||
*/
|
||||
private $adapter = null;
|
||||
|
||||
/**
|
||||
* Additional params that will be passed to the adapter while performing the download
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $adapterOptions = array();
|
||||
|
||||
/**
|
||||
* Creates a new download object and assigns it the most fitting download adapter
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Find the best fitting adapter
|
||||
$allAdapters = self::getFiles(__DIR__ . '/adapter', array(), array('abstract.php'));
|
||||
$priority = 0;
|
||||
|
||||
foreach ($allAdapters as $adapterInfo)
|
||||
{
|
||||
if (!class_exists($adapterInfo['classname'], true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var F0FDownloadAdapterAbstract $adapter */
|
||||
$adapter = new $adapterInfo['classname'];
|
||||
|
||||
if ( !$adapter->isSupported())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($adapter->priority > $priority)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
$priority = $adapter->priority;
|
||||
}
|
||||
}
|
||||
|
||||
// Load the language strings
|
||||
F0FPlatform::getInstance()->loadTranslations('lib_f0f');
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the use of a specific adapter
|
||||
*
|
||||
* @param string $className The name of the class or the name of the adapter, e.g. 'F0FDownloadAdapterCurl' or
|
||||
* 'curl'
|
||||
*/
|
||||
public function setAdapter($className)
|
||||
{
|
||||
$adapter = null;
|
||||
|
||||
if (class_exists($className, true))
|
||||
{
|
||||
$adapter = new $className;
|
||||
}
|
||||
elseif (class_exists('F0FDownloadAdapter' . ucfirst($className)))
|
||||
{
|
||||
$className = 'F0FDownloadAdapter' . ucfirst($className);
|
||||
$adapter = new $className;
|
||||
}
|
||||
|
||||
if (is_object($adapter) && ($adapter instanceof F0FDownloadInterface))
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the current adapter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAdapterName()
|
||||
{
|
||||
if(is_object($this->adapter))
|
||||
{
|
||||
$class = get_class($this->adapter);
|
||||
|
||||
return strtolower(str_ireplace('F0FDownloadAdapter', '', $class));
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the additional options for the adapter
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
public function setAdapterOptions(array $options)
|
||||
{
|
||||
$this->adapterOptions = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the additional options for the adapter
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAdapterOptions()
|
||||
{
|
||||
return $this->adapterOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to decode the $params array
|
||||
*
|
||||
* @param string $key The parameter key you want to retrieve the value for
|
||||
* @param mixed $default The default value, if none is specified
|
||||
*
|
||||
* @return mixed The value for this parameter key
|
||||
*/
|
||||
private function getParam($key, $default = null)
|
||||
{
|
||||
if (array_key_exists($key, $this->params))
|
||||
{
|
||||
return $this->params[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download data from a URL and return it
|
||||
*
|
||||
* @param string $url The URL to download from
|
||||
*
|
||||
* @return bool|string The downloaded data or false on failure
|
||||
*/
|
||||
public function getFromURL($url)
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->adapter->downloadAndReturn($url, null, null, $this->adapterOptions);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the staggered download of file. The downloaded file will be stored in Joomla!'s temp-path using the
|
||||
* basename of the URL as a filename
|
||||
*
|
||||
* The $params array can have any of the following keys
|
||||
* url The file being downloaded
|
||||
* frag Rolling counter of the file fragment being downloaded
|
||||
* totalSize The total size of the file being downloaded, in bytes
|
||||
* doneSize How many bytes we have already downloaded
|
||||
* maxExecTime Maximum execution time downloading file fragments, in seconds
|
||||
* length How many bytes to download at once
|
||||
*
|
||||
* The array returned is in the following format:
|
||||
*
|
||||
* status True if there are no errors, false if there are errors
|
||||
* error A string with the error message if there are errors
|
||||
* frag The next file fragment to download
|
||||
* totalSize The total size of the downloaded file in bytes, if the server supports HEAD requests
|
||||
* doneSize How many bytes have already been downloaded
|
||||
* percent % of the file already downloaded (if totalSize could be determined)
|
||||
* localfile The name of the local file, without the path
|
||||
*
|
||||
* @param array $params A parameters array, as sent by the user interface
|
||||
*
|
||||
* @return array A return status array
|
||||
*/
|
||||
public function importFromURL($params)
|
||||
{
|
||||
$this->params = $params;
|
||||
|
||||
// Fetch data
|
||||
$url = $this->getParam('url');
|
||||
$localFilename = $this->getParam('localFilename');
|
||||
$frag = $this->getParam('frag', -1);
|
||||
$totalSize = $this->getParam('totalSize', -1);
|
||||
$doneSize = $this->getParam('doneSize', -1);
|
||||
$maxExecTime = $this->getParam('maxExecTime', 5);
|
||||
$runTimeBias = $this->getParam('runTimeBias', 75);
|
||||
$length = $this->getParam('length', 1048576);
|
||||
|
||||
if (empty($localFilename))
|
||||
{
|
||||
$localFilename = basename($url);
|
||||
|
||||
if (strpos($localFilename, '?') !== false)
|
||||
{
|
||||
$paramsPos = strpos($localFilename, '?');
|
||||
$localFilename = substr($localFilename, 0, $paramsPos - 1);
|
||||
}
|
||||
}
|
||||
|
||||
$tmpDir = JFactory::getConfig()->get('tmp_path', JPATH_ROOT . '/tmp');
|
||||
$tmpDir = rtrim($tmpDir, '/\\');
|
||||
|
||||
// Init retArray
|
||||
$retArray = array(
|
||||
"status" => true,
|
||||
"error" => '',
|
||||
"frag" => $frag,
|
||||
"totalSize" => $totalSize,
|
||||
"doneSize" => $doneSize,
|
||||
"percent" => 0,
|
||||
"localfile" => $localFilename
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
$timer = new F0FUtilsTimer($maxExecTime, $runTimeBias);
|
||||
$start = $timer->getRunningTime(); // Mark the start of this download
|
||||
$break = false; // Don't break the step
|
||||
|
||||
// Figure out where on Earth to put that file
|
||||
$local_file = $tmpDir . '/' . $localFilename;
|
||||
|
||||
while (($timer->getTimeLeft() > 0) && !$break)
|
||||
{
|
||||
// Do we have to initialize the file?
|
||||
if ($frag == -1)
|
||||
{
|
||||
// Currently downloaded size
|
||||
$doneSize = 0;
|
||||
|
||||
if (@file_exists($local_file))
|
||||
{
|
||||
@unlink($local_file);
|
||||
}
|
||||
|
||||
// Delete and touch the output file
|
||||
$fp = @fopen($local_file, 'wb');
|
||||
|
||||
if ($fp !== false)
|
||||
{
|
||||
@fclose($fp);
|
||||
}
|
||||
|
||||
// Init
|
||||
$frag = 0;
|
||||
|
||||
//debugMsg("-- First frag, getting the file size");
|
||||
$retArray['totalSize'] = $this->adapter->getFileSize($url);
|
||||
$totalSize = $retArray['totalSize'];
|
||||
}
|
||||
|
||||
// Calculate from and length
|
||||
$from = $frag * $length;
|
||||
$to = $length + $from - 1;
|
||||
|
||||
// Try to download the first frag
|
||||
$required_time = 1.0;
|
||||
|
||||
try
|
||||
{
|
||||
$result = $this->adapter->downloadAndReturn($url, $from, $to, $this->adapterOptions);
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
throw new Exception(JText::sprintf('LIB_FOF_DOWNLOAD_ERR_COULDNOTDOWNLOADFROMURL', $url), 500);
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$result = false;
|
||||
$error = $e->getMessage();
|
||||
}
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
// Failed download
|
||||
if ($frag == 0)
|
||||
{
|
||||
// Failure to download first frag = failure to download. Period.
|
||||
$retArray['status'] = false;
|
||||
$retArray['error'] = $error;
|
||||
|
||||
//debugMsg("-- Download FAILED");
|
||||
|
||||
return $retArray;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since this is a staggered download, consider this normal and finish
|
||||
$frag = -1;
|
||||
//debugMsg("-- Import complete");
|
||||
$totalSize = $doneSize;
|
||||
$break = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the currently downloaded frag to the total size of downloaded files
|
||||
if ($result)
|
||||
{
|
||||
$filesize = strlen($result);
|
||||
//debugMsg("-- Successful download of $filesize bytes");
|
||||
$doneSize += $filesize;
|
||||
|
||||
// Append the file
|
||||
$fp = @fopen($local_file, 'ab');
|
||||
|
||||
if ($fp === false)
|
||||
{
|
||||
//debugMsg("-- Can't open local file $local_file for writing");
|
||||
// Can't open the file for writing
|
||||
$retArray['status'] = false;
|
||||
$retArray['error'] = JText::sprintf('LIB_FOF_DOWNLOAD_ERR_COULDNOTWRITELOCALFILE', $local_file);
|
||||
|
||||
return $retArray;
|
||||
}
|
||||
|
||||
fwrite($fp, $result);
|
||||
fclose($fp);
|
||||
|
||||
//debugMsg("-- Appended data to local file $local_file");
|
||||
|
||||
$frag++;
|
||||
|
||||
//debugMsg("-- Proceeding to next fragment, frag $frag");
|
||||
|
||||
if (($filesize < $length) || ($filesize > $length))
|
||||
{
|
||||
// A partial download or a download larger than the frag size means we are done
|
||||
$frag = -1;
|
||||
//debugMsg("-- Import complete (partial download of last frag)");
|
||||
$totalSize = $doneSize;
|
||||
$break = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Advance the frag pointer and mark the end
|
||||
$end = $timer->getRunningTime();
|
||||
|
||||
// Do we predict that we have enough time?
|
||||
$required_time = max(1.1 * ($end - $start), $required_time);
|
||||
|
||||
if ($required_time > (10 - $end + $start))
|
||||
{
|
||||
$break = true;
|
||||
}
|
||||
|
||||
$start = $end;
|
||||
}
|
||||
|
||||
if ($frag == -1)
|
||||
{
|
||||
$percent = 100;
|
||||
}
|
||||
elseif ($doneSize <= 0)
|
||||
{
|
||||
$percent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($totalSize > 0)
|
||||
{
|
||||
$percent = 100 * ($doneSize / $totalSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
$percent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Update $retArray
|
||||
$retArray = array(
|
||||
"status" => true,
|
||||
"error" => '',
|
||||
"frag" => $frag,
|
||||
"totalSize" => $totalSize,
|
||||
"doneSize" => $doneSize,
|
||||
"percent" => $percent,
|
||||
);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
//debugMsg("EXCEPTION RAISED:");
|
||||
//debugMsg($e->getMessage());
|
||||
$retArray['status'] = false;
|
||||
$retArray['error'] = $e->getMessage();
|
||||
}
|
||||
|
||||
return $retArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will crawl a starting directory and get all the valid files
|
||||
* that will be analyzed by __construct. Then it organizes them into an
|
||||
* associative array.
|
||||
*
|
||||
* @param string $path Folder where we should start looking
|
||||
* @param array $ignoreFolders Folder ignore list
|
||||
* @param array $ignoreFiles File ignore list
|
||||
*
|
||||
* @return array Associative array, where the `fullpath` key contains the path to the file,
|
||||
* and the `classname` key contains the name of the class
|
||||
*/
|
||||
protected static function getFiles($path, array $ignoreFolders = array(), array $ignoreFiles = array())
|
||||
{
|
||||
$return = array();
|
||||
|
||||
$files = self::scanDirectory($path, $ignoreFolders, $ignoreFiles);
|
||||
|
||||
// Ok, I got the files, now I have to organize them
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$clean = str_replace($path, '', $file);
|
||||
$clean = trim(str_replace('\\', '/', $clean), '/');
|
||||
|
||||
$parts = explode('/', $clean);
|
||||
|
||||
$return[] = array(
|
||||
'fullpath' => $file,
|
||||
'classname' => 'F0FDownloadAdapter' . ucfirst(basename($parts[0], '.php'))
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive function that will scan every directory unless it's in the
|
||||
* ignore list. Files that aren't in the ignore list are returned.
|
||||
*
|
||||
* @param string $path Folder where we should start looking
|
||||
* @param array $ignoreFolders Folder ignore list
|
||||
* @param array $ignoreFiles File ignore list
|
||||
*
|
||||
* @return array List of all the files
|
||||
*/
|
||||
protected static function scanDirectory($path, array $ignoreFolders = array(), array $ignoreFiles = array())
|
||||
{
|
||||
$return = array();
|
||||
|
||||
$handle = @opendir($path);
|
||||
|
||||
if ( !$handle)
|
||||
{
|
||||
return $return;
|
||||
}
|
||||
|
||||
while (($file = readdir($handle)) !== false)
|
||||
{
|
||||
if ($file == '.' || $file == '..')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$fullpath = $path . '/' . $file;
|
||||
|
||||
if ((is_dir($fullpath) && in_array($file, $ignoreFolders)) || (is_file($fullpath) && in_array($file, $ignoreFiles)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_dir($fullpath))
|
||||
{
|
||||
$return = array_merge(self::scanDirectory($fullpath, $ignoreFolders, $ignoreFiles), $return);
|
||||
}
|
||||
else
|
||||
{
|
||||
$return[] = $path . '/' . $file;
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
79
libraries/f0f/download/interface.php
Normal file
79
libraries/f0f/download/interface.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage dispatcher
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
interface F0FDownloadInterface
|
||||
{
|
||||
/**
|
||||
* Does this download adapter support downloading files in chunks?
|
||||
*
|
||||
* @return boolean True if chunk download is supported
|
||||
*/
|
||||
public function supportsChunkDownload();
|
||||
|
||||
/**
|
||||
* Does this download adapter support reading the size of a remote file?
|
||||
*
|
||||
* @return boolean True if remote file size determination is supported
|
||||
*/
|
||||
public function supportsFileSize();
|
||||
|
||||
/**
|
||||
* Is this download class supported in the current server environment?
|
||||
*
|
||||
* @return boolean True if this server environment supports this download class
|
||||
*/
|
||||
public function isSupported();
|
||||
|
||||
/**
|
||||
* Get the priority of this adapter. If multiple download adapters are
|
||||
* supported on a site, the one with the highest priority will be
|
||||
* used.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getPriority();
|
||||
|
||||
/**
|
||||
* Returns the name of this download adapter in use
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Download a part (or the whole) of a remote URL and return the downloaded
|
||||
* data. You are supposed to check the size of the returned data. If it's
|
||||
* smaller than what you expected you've reached end of file. If it's empty
|
||||
* you have tried reading past EOF. If it's larger than what you expected
|
||||
* the server doesn't support chunk downloads.
|
||||
*
|
||||
* If this class' supportsChunkDownload returns false you should assume
|
||||
* that the $from and $to parameters will be ignored.
|
||||
*
|
||||
* @param string $url The remote file's URL
|
||||
* @param integer $from Byte range to start downloading from. Use null for start of file.
|
||||
* @param integer $to Byte range to stop downloading. Use null to download the entire file ($from is ignored)
|
||||
* @param array $params Additional params that will be added before performing the download
|
||||
*
|
||||
* @return string The raw file data retrieved from the remote URL.
|
||||
*
|
||||
* @throws Exception A generic exception is thrown on error
|
||||
*/
|
||||
public function downloadAndReturn($url, $from = null, $to = null, array $params = array());
|
||||
|
||||
/**
|
||||
* Get the size of a remote file in bytes
|
||||
*
|
||||
* @param string $url The remote file's URL
|
||||
*
|
||||
* @return integer The file size, or -1 if the remote server doesn't support this feature
|
||||
*/
|
||||
public function getFileSize($url);
|
||||
}
|
||||
239
libraries/f0f/encrypt/aes.php
Normal file
239
libraries/f0f/encrypt/aes.php
Normal file
@ -0,0 +1,239 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage encrypt
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* A simple implementation of AES-128, AES-192 and AES-256 encryption using the
|
||||
* high performance mcrypt library.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 1.0
|
||||
*/
|
||||
class F0FEncryptAes
|
||||
{
|
||||
/** @var string The AES cipher to use (this is an mcrypt identifier, not the bit strength) */
|
||||
private $_cipherType = 0;
|
||||
|
||||
/** @var string Cipher mode. Can be CBC or ECB. We recommend using CBC */
|
||||
private $_cipherMode = 0;
|
||||
|
||||
/** @var string The cipher key (password) */
|
||||
private $_keyString = '';
|
||||
|
||||
/**
|
||||
* Initialise the AES encryption object
|
||||
*
|
||||
* @param string $key The encryption key (password). It can be a raw key (32 bytes) or a passphrase.
|
||||
* @param int $strength Bit strength (128, 192 or 256)
|
||||
* @param string $mode Ecnryption mode. Can be ebc or cbc. We recommend using cbc.
|
||||
*/
|
||||
public function __construct($key, $strength = 256, $mode = 'cbc')
|
||||
{
|
||||
$this->_keyString = $key;
|
||||
|
||||
switch ($strength)
|
||||
{
|
||||
case 256:
|
||||
default:
|
||||
$this->_cipherType = MCRYPT_RIJNDAEL_256;
|
||||
break;
|
||||
|
||||
case 192:
|
||||
$this->_cipherType = MCRYPT_RIJNDAEL_192;
|
||||
break;
|
||||
|
||||
case 128:
|
||||
$this->_cipherType = MCRYPT_RIJNDAEL_128;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (strtoupper($mode))
|
||||
{
|
||||
case 'ECB':
|
||||
$this->_cipherMode = MCRYPT_MODE_ECB;
|
||||
break;
|
||||
|
||||
case 'CBC':
|
||||
$this->_cipherMode = MCRYPT_MODE_CBC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a string using AES
|
||||
*
|
||||
* @param string $stringToEncrypt The plaintext to encrypt
|
||||
* @param bool $base64encoded Should I Base64-encode the result?
|
||||
*
|
||||
* @return string The cryptotext. Please note that the first 16 bytes of
|
||||
* the raw string is the IV (initialisation vector) which
|
||||
* is necessary for decoding the string.
|
||||
*/
|
||||
public function encryptString($stringToEncrypt, $base64encoded = true)
|
||||
{
|
||||
if (strlen($this->_keyString) != 32)
|
||||
{
|
||||
$key = hash('sha256', $this->_keyString, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = $this->_keyString;
|
||||
}
|
||||
|
||||
// Set up the IV (Initialization Vector)
|
||||
$iv_size = mcrypt_get_iv_size($this->_cipherType, $this->_cipherMode);
|
||||
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
|
||||
|
||||
if (empty($iv))
|
||||
{
|
||||
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_RANDOM);
|
||||
}
|
||||
|
||||
if (empty($iv))
|
||||
{
|
||||
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
||||
}
|
||||
|
||||
// Encrypt the data
|
||||
$cipherText = mcrypt_encrypt($this->_cipherType, $key, $stringToEncrypt, $this->_cipherMode, $iv);
|
||||
|
||||
// Prepend the IV to the ciphertext
|
||||
$cipherText = $iv . $cipherText;
|
||||
|
||||
// Optionally pass the result through Base64 encoding
|
||||
if ($base64encoded)
|
||||
{
|
||||
$cipherText = base64_encode($cipherText);
|
||||
}
|
||||
|
||||
// Return the result
|
||||
return $cipherText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a ciphertext into a plaintext string using AES
|
||||
*
|
||||
* @param string $stringToDecrypt The ciphertext to decrypt. The first 16 bytes of the raw string must contain the IV (initialisation vector).
|
||||
* @param bool $base64encoded Should I Base64-decode the data before decryption?
|
||||
*
|
||||
* @return string The plain text string
|
||||
*/
|
||||
public function decryptString($stringToDecrypt, $base64encoded = true)
|
||||
{
|
||||
if (strlen($this->_keyString) != 32)
|
||||
{
|
||||
$key = hash('sha256', $this->_keyString, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = $this->_keyString;
|
||||
}
|
||||
|
||||
if ($base64encoded)
|
||||
{
|
||||
$stringToDecrypt = base64_decode($stringToDecrypt);
|
||||
}
|
||||
|
||||
// Calculate the IV size
|
||||
$iv_size = mcrypt_get_iv_size($this->_cipherType, $this->_cipherMode);
|
||||
|
||||
// Extract IV
|
||||
$iv = substr($stringToDecrypt, 0, $iv_size);
|
||||
$stringToDecrypt = substr($stringToDecrypt, $iv_size);
|
||||
|
||||
// Decrypt the data
|
||||
$plainText = mcrypt_decrypt($this->_cipherType, $key, $stringToDecrypt, $this->_cipherMode, $iv);
|
||||
|
||||
return $plainText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is AES encryption supported by this PHP installation?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isSupported()
|
||||
{
|
||||
if (!function_exists('mcrypt_get_key_size'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('mcrypt_get_iv_size'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('mcrypt_create_iv'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('mcrypt_encrypt'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('mcrypt_decrypt'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('mcrypt_list_algorithms'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('hash'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('hash_algos'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('base64_encode'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('base64_decode'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$algorightms = mcrypt_list_algorithms();
|
||||
|
||||
if (!in_array('rijndael-128', $algorightms))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!in_array('rijndael-192', $algorightms))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!in_array('rijndael-256', $algorightms))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$algorightms = hash_algos();
|
||||
|
||||
if (!in_array('sha256', $algorightms))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
222
libraries/f0f/encrypt/base32.php
Normal file
222
libraries/f0f/encrypt/base32.php
Normal file
@ -0,0 +1,222 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage encrypt
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* F0FEncryptBase32
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 1.0
|
||||
*/
|
||||
class F0FEncryptBase32
|
||||
{
|
||||
/**
|
||||
* CSRFC3548
|
||||
*
|
||||
* The character set as defined by RFC3548
|
||||
* @link http://www.ietf.org/rfc/rfc3548.txt
|
||||
*/
|
||||
const CSRFC3548 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
||||
|
||||
/**
|
||||
* str2bin
|
||||
*
|
||||
* Converts any ascii string to a binary string
|
||||
*
|
||||
* @param string $str The string you want to convert
|
||||
*
|
||||
* @return string String of 0's and 1's
|
||||
*/
|
||||
private function str2bin($str)
|
||||
{
|
||||
$chrs = unpack('C*', $str);
|
||||
|
||||
return vsprintf(str_repeat('%08b', count($chrs)), $chrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* bin2str
|
||||
*
|
||||
* Converts a binary string to an ascii string
|
||||
*
|
||||
* @param string $str The string of 0's and 1's you want to convert
|
||||
*
|
||||
* @return string The ascii output
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function bin2str($str)
|
||||
{
|
||||
if (strlen($str) % 8 > 0)
|
||||
{
|
||||
throw new Exception('Length must be divisible by 8');
|
||||
}
|
||||
|
||||
if (!preg_match('/^[01]+$/', $str))
|
||||
{
|
||||
throw new Exception('Only 0\'s and 1\'s are permitted');
|
||||
}
|
||||
|
||||
preg_match_all('/.{8}/', $str, $chrs);
|
||||
$chrs = array_map('bindec', $chrs[0]);
|
||||
|
||||
// I'm just being slack here
|
||||
array_unshift($chrs, 'C*');
|
||||
|
||||
return call_user_func_array('pack', $chrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* fromBin
|
||||
*
|
||||
* Converts a correct binary string to base32
|
||||
*
|
||||
* @param string $str The string of 0's and 1's you want to convert
|
||||
*
|
||||
* @return string String encoded as base32
|
||||
*
|
||||
* @throws exception
|
||||
*/
|
||||
private function fromBin($str)
|
||||
{
|
||||
if (strlen($str) % 8 > 0)
|
||||
{
|
||||
throw new Exception('Length must be divisible by 8');
|
||||
}
|
||||
|
||||
if (!preg_match('/^[01]+$/', $str))
|
||||
{
|
||||
throw new Exception('Only 0\'s and 1\'s are permitted');
|
||||
}
|
||||
|
||||
// Base32 works on the first 5 bits of a byte, so we insert blanks to pad it out
|
||||
$str = preg_replace('/(.{5})/', '000$1', $str);
|
||||
|
||||
// We need a string divisible by 5
|
||||
$length = strlen($str);
|
||||
$rbits = $length & 7;
|
||||
|
||||
if ($rbits > 0)
|
||||
{
|
||||
// Excessive bits need to be padded
|
||||
$ebits = substr($str, $length - $rbits);
|
||||
$str = substr($str, 0, $length - $rbits);
|
||||
$str .= "000$ebits" . str_repeat('0', 5 - strlen($ebits));
|
||||
}
|
||||
|
||||
preg_match_all('/.{8}/', $str, $chrs);
|
||||
$chrs = array_map(array($this, '_mapcharset'), $chrs[0]);
|
||||
|
||||
return join('', $chrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* toBin
|
||||
*
|
||||
* Accepts a base32 string and returns an ascii binary string
|
||||
*
|
||||
* @param string $str The base32 string to convert
|
||||
*
|
||||
* @return string Ascii binary string
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function toBin($str)
|
||||
{
|
||||
if (!preg_match('/^[' . self::CSRFC3548 . ']+$/', $str))
|
||||
{
|
||||
throw new Exception('Must match character set');
|
||||
}
|
||||
|
||||
// Convert the base32 string back to a binary string
|
||||
$str = join('', array_map(array($this, '_mapbin'), str_split($str)));
|
||||
|
||||
// Remove the extra 0's we added
|
||||
$str = preg_replace('/000(.{5})/', '$1', $str);
|
||||
|
||||
// Unpad if nessicary
|
||||
$length = strlen($str);
|
||||
$rbits = $length & 7;
|
||||
|
||||
if ($rbits > 0)
|
||||
{
|
||||
$str = substr($str, 0, $length - $rbits);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* fromString
|
||||
*
|
||||
* Convert any string to a base32 string
|
||||
* This should be binary safe...
|
||||
*
|
||||
* @param string $str The string to convert
|
||||
*
|
||||
* @return string The converted base32 string
|
||||
*/
|
||||
public function encode($str)
|
||||
{
|
||||
return $this->fromBin($this->str2bin($str));
|
||||
}
|
||||
|
||||
/**
|
||||
* toString
|
||||
*
|
||||
* Convert any base32 string to a normal sctring
|
||||
* This should be binary safe...
|
||||
*
|
||||
* @param string $str The base32 string to convert
|
||||
*
|
||||
* @return string The normal string
|
||||
*/
|
||||
public function decode($str)
|
||||
{
|
||||
$str = strtoupper($str);
|
||||
|
||||
return $this->bin2str($this->tobin($str));
|
||||
}
|
||||
|
||||
/**
|
||||
* _mapcharset
|
||||
*
|
||||
* Used with array_map to map the bits from a binary string
|
||||
* directly into a base32 character set
|
||||
*
|
||||
* @param string $str The string of 0's and 1's you want to convert
|
||||
*
|
||||
* @return string Resulting base32 character
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function _mapcharset($str)
|
||||
{
|
||||
// Huh!
|
||||
$x = self::CSRFC3548;
|
||||
|
||||
return $x[bindec($str)];
|
||||
}
|
||||
|
||||
/**
|
||||
* _mapbin
|
||||
*
|
||||
* Used with array_map to map the characters from a base32
|
||||
* character set directly into a binary string
|
||||
*
|
||||
* @param string $chr The caracter to map
|
||||
*
|
||||
* @return string String of 0's and 1's
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
private function _mapbin($chr)
|
||||
{
|
||||
return sprintf('%08b', strpos(self::CSRFC3548, $chr));
|
||||
}
|
||||
}
|
||||
181
libraries/f0f/encrypt/totp.php
Normal file
181
libraries/f0f/encrypt/totp.php
Normal file
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage encrypt
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* This class provides an RFC6238-compliant Time-based One Time Passwords,
|
||||
* compatible with Google Authenticator (with PassCodeLength = 6 and TimePeriod = 30).
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 1.0
|
||||
*/
|
||||
class F0FEncryptTotp
|
||||
{
|
||||
private $_passCodeLength = 6;
|
||||
|
||||
private $_pinModulo;
|
||||
|
||||
private $_secretLength = 10;
|
||||
|
||||
private $_timeStep = 30;
|
||||
|
||||
private $_base32 = null;
|
||||
|
||||
/**
|
||||
* Initialises an RFC6238-compatible TOTP generator. Please note that this
|
||||
* class does not implement the constraint in the last paragraph of §5.2
|
||||
* of RFC6238. It's up to you to ensure that the same user/device does not
|
||||
* retry validation within the same Time Step.
|
||||
*
|
||||
* @param int $timeStep The Time Step (in seconds). Use 30 to be compatible with Google Authenticator.
|
||||
* @param int $passCodeLength The generated passcode length. Default: 6 digits.
|
||||
* @param int $secretLength The length of the secret key. Default: 10 bytes (80 bits).
|
||||
* @param Object $base32 The base32 en/decrypter
|
||||
*/
|
||||
public function __construct($timeStep = 30, $passCodeLength = 6, $secretLength = 10, $base32=null)
|
||||
{
|
||||
$this->_timeStep = $timeStep;
|
||||
$this->_passCodeLength = $passCodeLength;
|
||||
$this->_secretLength = $secretLength;
|
||||
$this->_pinModulo = pow(10, $this->_passCodeLength);
|
||||
|
||||
if (is_null($base32))
|
||||
{
|
||||
$this->_base32 = new F0FEncryptBase32;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_base32 = $base32;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time period based on the $time timestamp and the Time Step
|
||||
* defined. If $time is skipped or set to null the current timestamp will
|
||||
* be used.
|
||||
*
|
||||
* @param int|null $time Timestamp
|
||||
*
|
||||
* @return int The time period since the UNIX Epoch
|
||||
*/
|
||||
public function getPeriod($time = null)
|
||||
{
|
||||
if (is_null($time))
|
||||
{
|
||||
$time = time();
|
||||
}
|
||||
|
||||
$period = floor($time / $this->_timeStep);
|
||||
|
||||
return $period;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is the given passcode $code is a valid TOTP generated using secret
|
||||
* key $secret
|
||||
*
|
||||
* @param string $secret The Base32-encoded secret key
|
||||
* @param string $code The passcode to check
|
||||
*
|
||||
* @return boolean True if the code is valid
|
||||
*/
|
||||
public function checkCode($secret, $code)
|
||||
{
|
||||
$time = $this->getPeriod();
|
||||
|
||||
for ($i = -1; $i <= 1; $i++)
|
||||
{
|
||||
if ($this->getCode($secret, ($time + $i) * $this->_timeStep) == $code)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the TOTP passcode for a given secret key $secret and a given UNIX
|
||||
* timestamp $time
|
||||
*
|
||||
* @param string $secret The Base32-encoded secret key
|
||||
* @param int $time UNIX timestamp
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCode($secret, $time = null)
|
||||
{
|
||||
$period = $this->getPeriod($time);
|
||||
$secret = $this->_base32->decode($secret);
|
||||
|
||||
$time = pack("N", $period);
|
||||
$time = str_pad($time, 8, chr(0), STR_PAD_LEFT);
|
||||
|
||||
$hash = hash_hmac('sha1', $time, $secret, true);
|
||||
$offset = ord(substr($hash, -1));
|
||||
$offset = $offset & 0xF;
|
||||
|
||||
$truncatedHash = $this->hashToInt($hash, $offset) & 0x7FFFFFFF;
|
||||
$pinValue = str_pad($truncatedHash % $this->_pinModulo, $this->_passCodeLength, "0", STR_PAD_LEFT);
|
||||
|
||||
return $pinValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a part of a hash as an integer
|
||||
*
|
||||
* @param string $bytes The hash
|
||||
* @param string $start The char to start from (0 = first char)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function hashToInt($bytes, $start)
|
||||
{
|
||||
$input = substr($bytes, $start, strlen($bytes) - $start);
|
||||
$val2 = unpack("N", substr($input, 0, 4));
|
||||
|
||||
return $val2[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a QR code URL for easy setup of TOTP apps like Google Authenticator
|
||||
*
|
||||
* @param string $user User
|
||||
* @param string $hostname Hostname
|
||||
* @param string $secret Secret string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl($user, $hostname, $secret)
|
||||
{
|
||||
$url = sprintf("otpauth://totp/%s@%s?secret=%s", $user, $hostname, $secret);
|
||||
$encoder = "https://chart.googleapis.com/chart?chs=200x200&chld=Q|2&cht=qr&chl=";
|
||||
$encoderURL = $encoder . urlencode($url);
|
||||
|
||||
return $encoderURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a (semi-)random Secret Key for TOTP generation
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateSecret()
|
||||
{
|
||||
$secret = "";
|
||||
|
||||
for ($i = 1; $i <= $this->_secretLength; $i++)
|
||||
{
|
||||
$c = rand(0, 255);
|
||||
$secret .= pack("c", $c);
|
||||
}
|
||||
$base32 = new F0FEncryptBase32;
|
||||
|
||||
return $this->_base32->encode($secret);
|
||||
}
|
||||
}
|
||||
38
libraries/f0f/form/field.php
Normal file
38
libraries/f0f/form/field.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Generic interface that a F0F form field class must implement
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
interface F0FFormField
|
||||
{
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @return string The field HTML
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function getStatic();
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @return string The field HTML
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function getRepeatable();
|
||||
}
|
||||
156
libraries/f0f/form/field/accesslevel.php
Normal file
156
libraries/f0f/form/field/accesslevel.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('accesslevel');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Joomla! access levels
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldAccesslevel extends JFormFieldAccessLevel implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
$params = $this->getOptions();
|
||||
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select('a.id AS value, a.title AS text');
|
||||
$query->from('#__viewlevels AS a');
|
||||
$query->group('a.id, a.title, a.ordering');
|
||||
$query->order('a.ordering ASC');
|
||||
$query->order($query->qn('title') . ' ASC');
|
||||
|
||||
// Get the options.
|
||||
$db->setQuery($query);
|
||||
$options = $db->loadObjectList();
|
||||
|
||||
// If params is an array, push these options to the array
|
||||
if (is_array($params))
|
||||
{
|
||||
$options = array_merge($params, $options);
|
||||
}
|
||||
|
||||
// If all levels is allowed, push it into the array.
|
||||
elseif ($params)
|
||||
{
|
||||
array_unshift($options, JHtml::_('select.option', '', JText::_('JOPTION_ACCESS_SHOW_ALL_LEVELS')));
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($options, $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
$params = $this->getOptions();
|
||||
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select('a.id AS value, a.title AS text');
|
||||
$query->from('#__viewlevels AS a');
|
||||
$query->group('a.id, a.title, a.ordering');
|
||||
$query->order('a.ordering ASC');
|
||||
$query->order($query->qn('title') . ' ASC');
|
||||
|
||||
// Get the options.
|
||||
$db->setQuery($query);
|
||||
$options = $db->loadObjectList();
|
||||
|
||||
// If params is an array, push these options to the array
|
||||
if (is_array($params))
|
||||
{
|
||||
$options = array_merge($params, $options);
|
||||
}
|
||||
|
||||
// If all levels is allowed, push it into the array.
|
||||
elseif ($params)
|
||||
{
|
||||
array_unshift($options, JHtml::_('select.option', '', JText::_('JOPTION_ACCESS_SHOW_ALL_LEVELS')));
|
||||
}
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($options, $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
250
libraries/f0f/form/field/actions.php
Normal file
250
libraries/f0f/form/field/actions.php
Normal file
@ -0,0 +1,250 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('list');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Supports a generic list of options.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldActions extends JFormFieldList implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the field configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getConfig()
|
||||
{
|
||||
// If no custom options were defined let's figure out which ones of the
|
||||
// defaults we shall use...
|
||||
$config = array(
|
||||
'published' => 1,
|
||||
'unpublished' => 1,
|
||||
'archived' => 0,
|
||||
'trash' => 0,
|
||||
'all' => 0,
|
||||
);
|
||||
|
||||
$stack = array();
|
||||
|
||||
if (isset($this->element['show_published']))
|
||||
{
|
||||
$config['published'] = F0FStringUtils::toBool($this->element['show_published']);
|
||||
}
|
||||
|
||||
if (isset($this->element['show_unpublished']))
|
||||
{
|
||||
$config['unpublished'] = F0FStringUtils::toBool($this->element['show_unpublished']);
|
||||
}
|
||||
|
||||
if (isset($this->element['show_archived']))
|
||||
{
|
||||
$config['archived'] = F0FStringUtils::toBool($this->element['show_archived']);
|
||||
}
|
||||
|
||||
if (isset($this->element['show_trash']))
|
||||
{
|
||||
$config['trash'] = F0FStringUtils::toBool($this->element['show_trash']);
|
||||
}
|
||||
|
||||
if (isset($this->element['show_all']))
|
||||
{
|
||||
$config['all'] = F0FStringUtils::toBool($this->element['show_all']);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a
|
||||
*
|
||||
* @param string $enabledFieldName Name of the enabled/published field
|
||||
*
|
||||
* @return F0FFormFieldPublished Field
|
||||
*/
|
||||
protected function getPublishedField($enabledFieldName)
|
||||
{
|
||||
$attributes = array(
|
||||
'name' => $enabledFieldName,
|
||||
'type' => 'published',
|
||||
);
|
||||
|
||||
if ($this->element['publish_up'])
|
||||
{
|
||||
$attributes['publish_up'] = (string) $this->element['publish_up'];
|
||||
}
|
||||
|
||||
if ($this->element['publish_down'])
|
||||
{
|
||||
$attributes['publish_down'] = (string) $this->element['publish_down'];
|
||||
}
|
||||
|
||||
foreach ($attributes as $name => $value)
|
||||
{
|
||||
if (!is_null($value))
|
||||
{
|
||||
$renderedAttributes[] = $name . '="' . $value . '"';
|
||||
}
|
||||
}
|
||||
|
||||
$publishedXml = new SimpleXMLElement('<field ' . implode(' ', $renderedAttributes) . ' />');
|
||||
|
||||
$publishedField = new F0FFormFieldPublished($this->form);
|
||||
|
||||
// Pass required objects to the field
|
||||
$publishedField->item = $this->item;
|
||||
$publishedField->rowid = $this->rowid;
|
||||
$publishedField->setup($publishedXml, $this->item->{$enabledFieldName});
|
||||
|
||||
return $publishedField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
throw new Exception(__CLASS__ . ' cannot be used in single item display forms');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
if (!($this->item instanceof F0FTable))
|
||||
{
|
||||
throw new Exception(__CLASS__ . ' needs a F0FTable to act upon');
|
||||
}
|
||||
|
||||
$config = $this->getConfig();
|
||||
|
||||
// Initialise
|
||||
$prefix = '';
|
||||
$checkbox = 'cb';
|
||||
$publish_up = null;
|
||||
$publish_down = null;
|
||||
$enabled = true;
|
||||
|
||||
$html = '<div class="btn-group">';
|
||||
|
||||
// Render a published field
|
||||
if ($publishedFieldName = $this->item->getColumnAlias('enabled'))
|
||||
{
|
||||
if ($config['published'] || $config['unpublished'])
|
||||
{
|
||||
// Generate a F0FFormFieldPublished field
|
||||
$publishedField = $this->getPublishedField($publishedFieldName);
|
||||
|
||||
// Render the publish button
|
||||
$html .= $publishedField->getRepeatable();
|
||||
}
|
||||
|
||||
if ($config['archived'])
|
||||
{
|
||||
$archived = $this->item->{$publishedFieldName} == 2 ? true : false;
|
||||
|
||||
// Create dropdown items
|
||||
$action = $archived ? 'unarchive' : 'archive';
|
||||
JHtml::_('actionsdropdown.' . $action, 'cb' . $this->rowid, $prefix);
|
||||
}
|
||||
|
||||
if ($config['trash'])
|
||||
{
|
||||
$trashed = $this->item->{$publishedFieldName} == -2 ? true : false;
|
||||
|
||||
$action = $trashed ? 'untrash' : 'trash';
|
||||
JHtml::_('actionsdropdown.' . $action, 'cb' . $this->rowid, $prefix);
|
||||
}
|
||||
|
||||
// Render dropdown list
|
||||
if ($config['archived'] || $config['trash'])
|
||||
{
|
||||
$html .= JHtml::_('actionsdropdown.render', $this->item->title);
|
||||
}
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
137
libraries/f0f/form/field/button.php
Normal file
137
libraries/f0f/form/field/button.php
Normal file
@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('text');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a button input.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldButton extends F0FFormFieldText implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
$this->label = '';
|
||||
|
||||
$allowedElement = array('button', 'a');
|
||||
|
||||
if (in_array($this->element['htmlelement'], $allowedElement))
|
||||
$type = $this->element['htmlelement'];
|
||||
else
|
||||
$type = 'button';
|
||||
|
||||
$text = $this->element['text'];
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
$icon = $this->element['icon'] ? (string) $this->element['icon'] : '';
|
||||
$onclick = $this->element['onclick'] ? 'onclick="' . (string) $this->element['onclick'] . '"' : '';
|
||||
$url = $this->element['url'] ? 'href="' . $this->parseFieldTags((string) $this->element['url']) . '"' : '';
|
||||
$title = $this->element['title'] ? 'title="' . JText::_((string) $this->element['title']) . '"' : '';
|
||||
|
||||
$this->value = JText::_($text);
|
||||
|
||||
if ($icon)
|
||||
{
|
||||
$icon = '<span class="icon ' . $icon . '"></span>';
|
||||
}
|
||||
|
||||
return '<' . $type . ' id="' . $this->id . '" class="btn ' . $class . '" ' .
|
||||
$onclick . $url . $title . '>' .
|
||||
$icon .
|
||||
htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') .
|
||||
'</' . $type . '>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field title.
|
||||
*
|
||||
* @return string The field title.
|
||||
*/
|
||||
protected function getTitle()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
102
libraries/f0f/form/field/cachehandler.php
Normal file
102
libraries/f0f/form/field/cachehandler.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('cachehandler');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Joomla! cache handlers
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldCachehandler extends JFormFieldCacheHandler implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
211
libraries/f0f/form/field/calendar.php
Normal file
211
libraries/f0f/form/field/calendar.php
Normal file
@ -0,0 +1,211 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('calendar');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a calendar / date field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldCalendar extends JFormFieldCalendar implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
// ATTENTION: Redirected getInput() to getStatic()
|
||||
case 'input':
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
return $this->getCalendar('static');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getCalendar('repeatable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the calendar input markup.
|
||||
*
|
||||
* @param string $display The display to render ('static' or 'repeatable')
|
||||
*
|
||||
* @return string The field input markup.
|
||||
*
|
||||
* @since 2.1.rc4
|
||||
*/
|
||||
protected function getCalendar($display)
|
||||
{
|
||||
// Initialize some field attributes.
|
||||
$format = $this->element['format'] ? (string) $this->element['format'] : '%Y-%m-%d';
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
$default = $this->element['default'] ? (string) $this->element['default'] : '';
|
||||
|
||||
// PHP date doesn't use percentages (%) for the format, but the calendar Javascript
|
||||
// DOES use it (@see: calendar-uncompressed.js). Therefore we have to convert it.
|
||||
$formatJS = $format;
|
||||
$formatPHP = str_replace(array('%', 'H:M:S', 'B'), array('', 'H:i:s', 'F'), $formatJS);
|
||||
|
||||
// Check for empty date values
|
||||
if (empty($this->value) || $this->value == F0FPlatform::getInstance()->getDbo()->getNullDate() || $this->value == '0000-00-00')
|
||||
{
|
||||
$this->value = $default;
|
||||
}
|
||||
|
||||
// Get some system objects.
|
||||
$config = F0FPlatform::getInstance()->getConfig();
|
||||
$user = JFactory::getUser();
|
||||
|
||||
// Format date if exists
|
||||
if (!empty($this->value))
|
||||
{
|
||||
$date = F0FPlatform::getInstance()->getDate($this->value, 'UTC');
|
||||
|
||||
// If a known filter is given use it.
|
||||
switch (strtoupper((string) $this->element['filter']))
|
||||
{
|
||||
case 'SERVER_UTC':
|
||||
// Convert a date to UTC based on the server timezone.
|
||||
if ((int) $this->value)
|
||||
{
|
||||
// Get a date object based on the correct timezone.
|
||||
$date->setTimezone(new DateTimeZone($config->get('offset')));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'USER_UTC':
|
||||
// Convert a date to UTC based on the user timezone.
|
||||
if ((int) $this->value)
|
||||
{
|
||||
// Get a date object based on the correct timezone.
|
||||
$date->setTimezone(new DateTimeZone($user->getParam('timezone', $config->get('offset'))));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Transform the date string.
|
||||
$this->value = $date->format($formatPHP, true, false);
|
||||
}
|
||||
|
||||
if ($display == 'static')
|
||||
{
|
||||
// Build the attributes array.
|
||||
$attributes = array();
|
||||
|
||||
if ($this->element['size'])
|
||||
{
|
||||
$attributes['size'] = (int) $this->element['size'];
|
||||
}
|
||||
|
||||
if ($this->element['maxlength'])
|
||||
{
|
||||
$attributes['maxlength'] = (int) $this->element['maxlength'];
|
||||
}
|
||||
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$attributes['class'] = (string) $this->element['class'];
|
||||
}
|
||||
|
||||
if ((string) $this->element['readonly'] == 'true')
|
||||
{
|
||||
$attributes['readonly'] = 'readonly';
|
||||
}
|
||||
|
||||
if ((string) $this->element['disabled'] == 'true')
|
||||
{
|
||||
$attributes['disabled'] = 'disabled';
|
||||
}
|
||||
|
||||
if ($this->element['onchange'])
|
||||
{
|
||||
$attributes['onchange'] = (string) $this->element['onchange'];
|
||||
}
|
||||
|
||||
if ($this->required)
|
||||
{
|
||||
$attributes['required'] = 'required';
|
||||
$attributes['aria-required'] = 'true';
|
||||
}
|
||||
|
||||
return JHtml::_('calendar', $this->value, $this->name, $this->id, $formatJS, $attributes);
|
||||
}
|
||||
else
|
||||
{
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
93
libraries/f0f/form/field/captcha.php
Normal file
93
libraries/f0f/form/field/captcha.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('captcha');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a captcha field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldCaptcha extends JFormFieldCaptcha implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
}
|
||||
129
libraries/f0f/form/field/checkbox.php
Normal file
129
libraries/f0f/form/field/checkbox.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('checkbox');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* A single checkbox
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldCheckbox extends JFormFieldCheckbox implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
$value = $this->element['value'] ? (string) $this->element['value'] : '1';
|
||||
$disabled = ((string) $this->element['disabled'] == 'true') ? ' disabled="disabled"' : '';
|
||||
$onclick = $this->element['onclick'] ? ' onclick="' . (string) $this->element['onclick'] . '"' : '';
|
||||
$required = $this->required ? ' required="required" aria-required="true"' : '';
|
||||
|
||||
if (empty($this->value))
|
||||
{
|
||||
$checked = (isset($this->element['checked'])) ? ' checked="checked"' : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$checked = ' checked="checked"';
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
'<input type="checkbox" name="' . $this->name . '" id="' . $this->id . '"' . ' value="'
|
||||
. htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '"' . $class . $checked . $disabled . $onclick . $required . ' />' .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
$value = $this->element['value'] ? (string) $this->element['value'] : '1';
|
||||
$disabled = ((string) $this->element['disabled'] == 'true') ? ' disabled="disabled"' : '';
|
||||
$onclick = $this->element['onclick'] ? ' onclick="' . (string) $this->element['onclick'] . '"' : '';
|
||||
$required = $this->required ? ' required="required" aria-required="true"' : '';
|
||||
|
||||
if (empty($this->value))
|
||||
{
|
||||
$checked = (isset($this->element['checked'])) ? ' checked="checked"' : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$checked = ' checked="checked"';
|
||||
}
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
'<input type="checkbox" name="' . $this->name . '" class="' . $this->id . ' ' . $class . '"' . ' value="'
|
||||
. htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '"' . $checked . $disabled . $onclick . $required . ' />' .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
128
libraries/f0f/form/field/checkboxes.php
Normal file
128
libraries/f0f/form/field/checkboxes.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('checkboxes');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Supports a list of checkbox.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldCheckboxes extends JFormFieldCheckboxes implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
return $this->getRepeatable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : $this->id;
|
||||
$translate = $this->element['translate'] ? (string) $this->element['translate'] : false;
|
||||
|
||||
$html = '<span class="' . $class . '">';
|
||||
foreach ($this->value as $value) {
|
||||
|
||||
$html .= '<span>';
|
||||
|
||||
if ($translate == true)
|
||||
{
|
||||
$html .= JText::_($value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$html .= $value;
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
}
|
||||
$html .= '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
// Used for J! 2.5 compatibility
|
||||
$this->value = !is_array($this->value) ? explode(',', $this->value) : $this->value;
|
||||
|
||||
return parent::getInput();
|
||||
}
|
||||
}
|
||||
237
libraries/f0f/form/field/components.php
Normal file
237
libraries/f0f/form/field/components.php
Normal file
@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('list');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Components installed on the site
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.1
|
||||
*/
|
||||
class F0FFormFieldComponents extends JFormFieldList implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
public $client_ids = null;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all installed components and also translates them.
|
||||
*
|
||||
* The manifest_cache is used to get the extension names, since JInstaller is also
|
||||
* translating those names in stead of the name column. Else some of the translations
|
||||
* fails.
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @return array An array of JHtml options.
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
|
||||
// Check for client_ids override
|
||||
if ($this->client_ids !== null)
|
||||
{
|
||||
$client_ids = $this->client_ids;
|
||||
}
|
||||
else
|
||||
{
|
||||
$client_ids = $this->element['client_ids'];
|
||||
}
|
||||
|
||||
$client_ids = explode(',', $client_ids);
|
||||
|
||||
// Calculate client_ids where clause
|
||||
foreach ($client_ids as &$client_id)
|
||||
{
|
||||
$client_id = (int) trim($client_id);
|
||||
$client_id = $db->q($client_id);
|
||||
}
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select(
|
||||
array(
|
||||
$db->qn('name'),
|
||||
$db->qn('element'),
|
||||
$db->qn('client_id'),
|
||||
$db->qn('manifest_cache'),
|
||||
)
|
||||
)
|
||||
->from($db->qn('#__extensions'))
|
||||
->where($db->qn('type') . ' = ' . $db->q('component'))
|
||||
->where($db->qn('client_id') . ' IN (' . implode(',', $client_ids) . ')');
|
||||
$db->setQuery($query);
|
||||
$components = $db->loadObjectList('element');
|
||||
|
||||
// Convert to array of objects, so we can use sortObjects()
|
||||
// Also translate component names with JText::_()
|
||||
$aComponents = array();
|
||||
$user = JFactory::getUser();
|
||||
|
||||
foreach ($components as $component)
|
||||
{
|
||||
// Don't show components in the list where the user doesn't have access for
|
||||
// TODO: perhaps add an option for this
|
||||
if (!$user->authorise('core.manage', $component->element))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$oData = (object) array(
|
||||
'value' => $component->element,
|
||||
'text' => $this->translate($component, 'component')
|
||||
);
|
||||
$aComponents[$component->element] = $oData;
|
||||
}
|
||||
|
||||
// Reorder the components array, because the alphabetical
|
||||
// ordering changed due to the JText::_() translation
|
||||
uasort(
|
||||
$aComponents,
|
||||
function ($a, $b) {
|
||||
return strcasecmp($a->text, $b->text);
|
||||
}
|
||||
);
|
||||
|
||||
return $aComponents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a list of objects with JText::_().
|
||||
*
|
||||
* @param array $item The array of objects
|
||||
* @param string $type The extension type (e.g. component)
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @return string $text The translated name of the extension
|
||||
*
|
||||
* @see administrator/com_installer/models/extension.php
|
||||
*/
|
||||
public function translate($item, $type)
|
||||
{
|
||||
$platform = F0FPlatform::getInstance();
|
||||
|
||||
// Map the manifest cache to $item. This is needed to get the name from the
|
||||
// manifest_cache and NOT from the name column, else some JText::_() translations fails.
|
||||
$mData = json_decode($item->manifest_cache);
|
||||
|
||||
if ($mData)
|
||||
{
|
||||
foreach ($mData as $key => $value)
|
||||
{
|
||||
if ($key == 'type')
|
||||
{
|
||||
// Ignore the type field
|
||||
continue;
|
||||
}
|
||||
|
||||
$item->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$lang = $platform->getLanguage();
|
||||
|
||||
switch ($type)
|
||||
{
|
||||
case 'component':
|
||||
$source = JPATH_ADMINISTRATOR . '/components/' . $item->element;
|
||||
$lang->load("$item->element.sys", JPATH_ADMINISTRATOR, null, false, false)
|
||||
|| $lang->load("$item->element.sys", $source, null, false, false)
|
||||
|| $lang->load("$item->element.sys", JPATH_ADMINISTRATOR, $lang->getDefault(), false, false)
|
||||
|| $lang->load("$item->element.sys", $source, $lang->getDefault(), false, false);
|
||||
break;
|
||||
}
|
||||
|
||||
$text = JText::_($item->name);
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
97
libraries/f0f/form/field/editor.php
Normal file
97
libraries/f0f/form/field/editor.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('editor');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* An editarea field for content creation and formatted HTML display
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldEditor extends JFormFieldEditor implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<div id="' . $this->id . '" ' . $class . '>' . $this->value . '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<div class="' . $this->id . ' ' . $class . '">' . $this->value . '</div>';
|
||||
}
|
||||
}
|
||||
173
libraries/f0f/form/field/email.php
Normal file
173
libraries/f0f/form/field/email.php
Normal file
@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('email');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a one line text field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldEmail extends JFormFieldEMail implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
$dolink = $this->element['show_link'] == 'true';
|
||||
$empty_replacement = '';
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
if (!empty($empty_replacement) && empty($this->value))
|
||||
{
|
||||
$this->value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
$innerHtml = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
if ($dolink)
|
||||
{
|
||||
$innerHtml = '<a href="mailto:' . $innerHtml . '">' .
|
||||
$innerHtml . '</a>';
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
$innerHtml .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
// Initialise
|
||||
$class = '';
|
||||
$show_link = false;
|
||||
$link_url = '';
|
||||
$empty_replacement = '';
|
||||
|
||||
// Get field parameters
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$class = (string) $this->element['class'];
|
||||
}
|
||||
|
||||
if ($this->element['show_link'] == 'true')
|
||||
{
|
||||
$show_link = true;
|
||||
}
|
||||
|
||||
if ($this->element['url'])
|
||||
{
|
||||
$link_url = $this->element['url'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$link_url = 'mailto:' . htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
// Get the (optionally formatted) value
|
||||
if (!empty($empty_replacement) && empty($this->value))
|
||||
{
|
||||
$this->value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
$value = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
// Create the HTML
|
||||
$html = '<span class="' . $this->id . ' ' . $class . '">';
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '<a href="' . $link_url . '">';
|
||||
}
|
||||
|
||||
$html .= $value;
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
134
libraries/f0f/form/field/groupedbutton.php
Normal file
134
libraries/f0f/form/field/groupedbutton.php
Normal file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('list');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Supports a generic list of options.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldGroupedbutton extends JFormFieldText implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
$html = '<div id="' . $this->id . '" class="btn-group ' . $class . '">';
|
||||
|
||||
foreach ($this->element->children() as $option)
|
||||
{
|
||||
$renderedAttributes = array();
|
||||
|
||||
foreach ($option->attributes() as $name => $value)
|
||||
{
|
||||
if (!is_null($value))
|
||||
{
|
||||
$renderedAttributes[] = $name . '="' . htmlentities($value) . '"';
|
||||
}
|
||||
}
|
||||
|
||||
$buttonXML = new SimpleXMLElement('<field ' . implode(' ', $renderedAttributes) . ' />');
|
||||
$buttonField = new F0FFormFieldButton($this->form);
|
||||
|
||||
// Pass required objects to the field
|
||||
$buttonField->item = $this->item;
|
||||
$buttonField->rowid = $this->rowid;
|
||||
$buttonField->setup($buttonXML, null);
|
||||
|
||||
$html .= $buttonField->getRepeatable();
|
||||
}
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
185
libraries/f0f/form/field/groupedlist.php
Normal file
185
libraries/f0f/form/field/groupedlist.php
Normal file
@ -0,0 +1,185 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('groupedlist');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Supports a generic list of options.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldGroupedlist extends JFormFieldGroupedList implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
$selected = self::getOptionName($this->getGroups(), $this->value);
|
||||
|
||||
if (is_null($selected))
|
||||
{
|
||||
$selected = array(
|
||||
'group' => '',
|
||||
'item' => ''
|
||||
);
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '-group" class="fof-groupedlist-group ' . $class . '>' .
|
||||
htmlspecialchars($selected['group'], ENT_COMPAT, 'UTF-8') .
|
||||
'</span>' .
|
||||
'<span id="' . $this->id . '-item" class="fof-groupedlist-item ' . $class . '>' .
|
||||
htmlspecialchars($selected['item'], ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
$selected = self::getOptionName($this->getGroups(), $this->value);
|
||||
|
||||
if (is_null($selected))
|
||||
{
|
||||
$selected = array(
|
||||
'group' => '',
|
||||
'item' => ''
|
||||
);
|
||||
}
|
||||
|
||||
return '<span class="' . $this->id . '-group fof-groupedlist-group ' . $class . '">' .
|
||||
htmlspecialchars($selected['group'], ENT_COMPAT, 'UTF-8') .
|
||||
'</span>' .
|
||||
'<span class="' . $this->id . '-item fof-groupedlist-item ' . $class . '">' .
|
||||
htmlspecialchars($selected['item'], ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the active option's label given an array of JHtml options
|
||||
*
|
||||
* @param array $data The JHtml options to parse
|
||||
* @param mixed $selected The currently selected value
|
||||
* @param string $groupKey Group name
|
||||
* @param string $optKey Key name
|
||||
* @param string $optText Value name
|
||||
*
|
||||
* @return mixed The label of the currently selected option
|
||||
*/
|
||||
public static function getOptionName($data, $selected = null, $groupKey = 'items', $optKey = 'value', $optText = 'text')
|
||||
{
|
||||
$ret = null;
|
||||
|
||||
foreach ($data as $dataKey => $group)
|
||||
{
|
||||
$label = $dataKey;
|
||||
$noGroup = is_int($dataKey);
|
||||
|
||||
if (is_array($group))
|
||||
{
|
||||
$subList = $group[$groupKey];
|
||||
$label = $group[$optText];
|
||||
$noGroup = false;
|
||||
}
|
||||
elseif (is_object($group))
|
||||
{
|
||||
// Sub-list is in a property of an object
|
||||
$subList = $group->$groupKey;
|
||||
$label = $group->$optText;
|
||||
$noGroup = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException('Invalid group contents.', 1);
|
||||
}
|
||||
|
||||
if ($noGroup)
|
||||
{
|
||||
$label = '';
|
||||
}
|
||||
|
||||
$match = F0FFormFieldList::getOptionName($data, $selected, $optKey, $optText);
|
||||
|
||||
if (!is_null($match))
|
||||
{
|
||||
$ret = array(
|
||||
'group' => $label,
|
||||
'item' => $match
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
93
libraries/f0f/form/field/hidden.php
Normal file
93
libraries/f0f/form/field/hidden.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('hidden');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* A hidden field
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldHidden extends JFormFieldHidden implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
}
|
||||
20
libraries/f0f/form/field/image.php
Normal file
20
libraries/f0f/form/field/image.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Media selection field. This is an alias of the "media" field type.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldImage extends F0FFormFieldMedia
|
||||
{
|
||||
}
|
||||
153
libraries/f0f/form/field/imagelist.php
Normal file
153
libraries/f0f/form/field/imagelist.php
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('imagelist');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Media selection field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldImagelist extends JFormFieldImageList implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$imgattr = array(
|
||||
'id' => $this->id
|
||||
);
|
||||
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$imgattr['class'] = (string) $this->element['class'];
|
||||
}
|
||||
|
||||
if ($this->element['style'])
|
||||
{
|
||||
$imgattr['style'] = (string) $this->element['style'];
|
||||
}
|
||||
|
||||
if ($this->element['width'])
|
||||
{
|
||||
$imgattr['width'] = (string) $this->element['width'];
|
||||
}
|
||||
|
||||
if ($this->element['height'])
|
||||
{
|
||||
$imgattr['height'] = (string) $this->element['height'];
|
||||
}
|
||||
|
||||
if ($this->element['align'])
|
||||
{
|
||||
$imgattr['align'] = (string) $this->element['align'];
|
||||
}
|
||||
|
||||
if ($this->element['rel'])
|
||||
{
|
||||
$imgattr['rel'] = (string) $this->element['rel'];
|
||||
}
|
||||
|
||||
if ($this->element['alt'])
|
||||
{
|
||||
$alt = JText::_((string) $this->element['alt']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$alt = null;
|
||||
}
|
||||
|
||||
if ($this->element['title'])
|
||||
{
|
||||
$imgattr['title'] = JText::_((string) $this->element['title']);
|
||||
}
|
||||
|
||||
$path = (string) $this->element['directory'];
|
||||
$path = trim($path, '/' . DIRECTORY_SEPARATOR);
|
||||
|
||||
if ($this->value && file_exists(JPATH_ROOT . '/' . $path . '/' . $this->value))
|
||||
{
|
||||
$src = F0FPlatform::getInstance()->URIroot() . '/' . $path . '/' . $this->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$src = '';
|
||||
}
|
||||
|
||||
return JHtml::image($src, $alt, $imgattr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getStatic();
|
||||
}
|
||||
}
|
||||
101
libraries/f0f/form/field/integer.php
Normal file
101
libraries/f0f/form/field/integer.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('integer');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a one line text field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldInteger extends JFormFieldInteger implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
122
libraries/f0f/form/field/language.php
Normal file
122
libraries/f0f/form/field/language.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('language');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Available site languages
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldLanguage extends JFormFieldLanguage implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$options = parent::getOptions();
|
||||
|
||||
$noneoption = $this->element['none'] ? $this->element['none'] : null;
|
||||
|
||||
if ($noneoption)
|
||||
{
|
||||
array_unshift($options, JHtml::_('select.option', '*', JText::_($noneoption)));
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
382
libraries/f0f/form/field/list.php
Normal file
382
libraries/f0f/form/field/list.php
Normal file
@ -0,0 +1,382 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('list');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Supports a generic list of options.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldList extends JFormFieldList implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(self::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$show_link = false;
|
||||
$link_url = '';
|
||||
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
if ($this->element['show_link'] == 'true')
|
||||
{
|
||||
$show_link = true;
|
||||
}
|
||||
|
||||
if ($this->element['url'])
|
||||
{
|
||||
$link_url = $this->element['url'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$show_link = false;
|
||||
}
|
||||
|
||||
if ($show_link && ($this->item instanceof F0FTable))
|
||||
{
|
||||
$link_url = $this->parseFieldTags($link_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
$show_link = false;
|
||||
}
|
||||
|
||||
$html = '<span class="' . $this->id . ' ' . $class . '">';
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '<a href="' . $link_url . '">';
|
||||
}
|
||||
|
||||
$html .= htmlspecialchars(self::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8');
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the active option's label given an array of JHtml options
|
||||
*
|
||||
* @param array $data The JHtml options to parse
|
||||
* @param mixed $selected The currently selected value
|
||||
* @param string $optKey Key name
|
||||
* @param string $optText Value name
|
||||
*
|
||||
* @return mixed The label of the currently selected option
|
||||
*/
|
||||
public static function getOptionName($data, $selected = null, $optKey = 'value', $optText = 'text')
|
||||
{
|
||||
$ret = null;
|
||||
|
||||
foreach ($data as $elementKey => &$element)
|
||||
{
|
||||
if (is_array($element))
|
||||
{
|
||||
$key = $optKey === null ? $elementKey : $element[$optKey];
|
||||
$text = $element[$optText];
|
||||
}
|
||||
elseif (is_object($element))
|
||||
{
|
||||
$key = $optKey === null ? $elementKey : $element->$optKey;
|
||||
$text = $element->$optText;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a simple associative array
|
||||
$key = $elementKey;
|
||||
$text = $element;
|
||||
}
|
||||
|
||||
if (is_null($ret))
|
||||
{
|
||||
$ret = $text;
|
||||
}
|
||||
elseif ($selected == $key)
|
||||
{
|
||||
$ret = $text;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* Ordering is disabled by default. You can enable ordering by setting the
|
||||
* 'order' element in your form field. The other order values are optional.
|
||||
*
|
||||
* - order What to order. Possible values: 'name' or 'value' (default = false)
|
||||
* - order_dir Order direction. Possible values: 'asc' = Ascending or 'desc' = Descending (default = 'asc')
|
||||
* - order_case_sensitive Order case sensitive. Possible values: 'true' or 'false' (default = false)
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*
|
||||
* @since Ordering is available since F0F 2.1.b2.
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
// Ordering is disabled by default for backward compatibility
|
||||
$order = false;
|
||||
|
||||
// Set default order direction
|
||||
$order_dir = 'asc';
|
||||
|
||||
// Set default value for case sensitive sorting
|
||||
$order_case_sensitive = false;
|
||||
|
||||
if ($this->element['order'] && $this->element['order'] !== 'false')
|
||||
{
|
||||
$order = $this->element['order'];
|
||||
}
|
||||
|
||||
if ($this->element['order_dir'])
|
||||
{
|
||||
$order_dir = $this->element['order_dir'];
|
||||
}
|
||||
|
||||
if ($this->element['order_case_sensitive'])
|
||||
{
|
||||
// Override default setting when the form element value is 'true'
|
||||
if ($this->element['order_case_sensitive'] == 'true')
|
||||
{
|
||||
$order_case_sensitive = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a $sortOptions array in order to apply sorting
|
||||
$i = 0;
|
||||
$sortOptions = array();
|
||||
|
||||
foreach ($this->element->children() as $option)
|
||||
{
|
||||
$name = JText::alt(trim((string) $option), preg_replace('/[^a-zA-Z0-9_\-]/', '_', $this->fieldname));
|
||||
|
||||
$sortOptions[$i] = new stdClass;
|
||||
$sortOptions[$i]->option = $option;
|
||||
$sortOptions[$i]->value = $option['value'];
|
||||
$sortOptions[$i]->name = $name;
|
||||
$i++;
|
||||
}
|
||||
|
||||
// Only order if it's set
|
||||
if ($order)
|
||||
{
|
||||
jimport('joomla.utilities.arrayhelper');
|
||||
F0FUtilsArray::sortObjects($sortOptions, $order, $order_dir == 'asc' ? 1 : -1, $order_case_sensitive, false);
|
||||
}
|
||||
|
||||
// Initialise the options
|
||||
$options = array();
|
||||
|
||||
// Get the field $options
|
||||
foreach ($sortOptions as $sortOption)
|
||||
{
|
||||
$option = $sortOption->option;
|
||||
$name = $sortOption->name;
|
||||
|
||||
// Only add <option /> elements.
|
||||
if ($option->getName() != 'option')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$tmp = JHtml::_('select.option', (string) $option['value'], $name, 'value', 'text', ((string) $option['disabled'] == 'true'));
|
||||
|
||||
// Set some option attributes.
|
||||
$tmp->class = (string) $option['class'];
|
||||
|
||||
// Set some JavaScript option attributes.
|
||||
$tmp->onclick = (string) $option['onclick'];
|
||||
|
||||
// Add the option object to the result set.
|
||||
$options[] = $tmp;
|
||||
}
|
||||
|
||||
// Do we have a class and method source for our options?
|
||||
$source_file = empty($this->element['source_file']) ? '' : (string) $this->element['source_file'];
|
||||
$source_class = empty($this->element['source_class']) ? '' : (string) $this->element['source_class'];
|
||||
$source_method = empty($this->element['source_method']) ? '' : (string) $this->element['source_method'];
|
||||
$source_key = empty($this->element['source_key']) ? '*' : (string) $this->element['source_key'];
|
||||
$source_value = empty($this->element['source_value']) ? '*' : (string) $this->element['source_value'];
|
||||
$source_translate = empty($this->element['source_translate']) ? 'true' : (string) $this->element['source_translate'];
|
||||
$source_translate = in_array(strtolower($source_translate), array('true','yes','1','on')) ? true : false;
|
||||
$source_format = empty($this->element['source_format']) ? '' : (string) $this->element['source_format'];
|
||||
|
||||
if ($source_class && $source_method)
|
||||
{
|
||||
// Maybe we have to load a file?
|
||||
if (!empty($source_file))
|
||||
{
|
||||
$source_file = F0FTemplateUtils::parsePath($source_file, true);
|
||||
|
||||
if (F0FPlatform::getInstance()->getIntegrationObject('filesystem')->fileExists($source_file))
|
||||
{
|
||||
include_once $source_file;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the class exists
|
||||
if (class_exists($source_class, true))
|
||||
{
|
||||
// ...and so does the option
|
||||
if (in_array($source_method, get_class_methods($source_class)))
|
||||
{
|
||||
// Get the data from the class
|
||||
if ($source_format == 'optionsobject')
|
||||
{
|
||||
$options = array_merge($options, $source_class::$source_method());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the data from the class
|
||||
$source_data = $source_class::$source_method();
|
||||
|
||||
// Loop through the data and prime the $options array
|
||||
foreach ($source_data as $k => $v)
|
||||
{
|
||||
$key = (empty($source_key) || ($source_key == '*')) ? $k : $v[$source_key];
|
||||
$value = (empty($source_value) || ($source_value == '*')) ? $v : $v[$source_value];
|
||||
|
||||
if ($source_translate)
|
||||
{
|
||||
$value = JText::_($value);
|
||||
}
|
||||
|
||||
$options[] = JHtml::_('select.option', $key, $value, 'value', 'text');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reset($options);
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace string with tags that reference fields
|
||||
*
|
||||
* @param string $text Text to process
|
||||
*
|
||||
* @return string Text with tags replace
|
||||
*/
|
||||
protected function parseFieldTags($text)
|
||||
{
|
||||
$ret = $text;
|
||||
|
||||
// Replace [ITEM:ID] in the URL with the item's key value (usually:
|
||||
// the auto-incrementing numeric ID)
|
||||
$keyfield = $this->item->getKeyName();
|
||||
$replace = $this->item->$keyfield;
|
||||
$ret = str_replace('[ITEM:ID]', $replace, $ret);
|
||||
|
||||
// Replace the [ITEMID] in the URL with the current Itemid parameter
|
||||
$ret = str_replace('[ITEMID]', JFactory::getApplication()->input->getInt('Itemid', 0), $ret);
|
||||
|
||||
// Replace other field variables in the URL
|
||||
$fields = $this->item->getTableFields();
|
||||
|
||||
foreach ($fields as $fielddata)
|
||||
{
|
||||
$fieldname = $fielddata->Field;
|
||||
|
||||
if (empty($fieldname))
|
||||
{
|
||||
$fieldname = $fielddata->column_name;
|
||||
}
|
||||
|
||||
$search = '[ITEM:' . strtoupper($fieldname) . ']';
|
||||
$replace = $this->item->$fieldname;
|
||||
$ret = str_replace($search, $replace, $ret);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
150
libraries/f0f/form/field/media.php
Normal file
150
libraries/f0f/form/field/media.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('media');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Media selection field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldMedia extends JFormFieldMedia implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$imgattr = array(
|
||||
'id' => $this->id
|
||||
);
|
||||
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$imgattr['class'] = (string) $this->element['class'];
|
||||
}
|
||||
|
||||
if ($this->element['style'])
|
||||
{
|
||||
$imgattr['style'] = (string) $this->element['style'];
|
||||
}
|
||||
|
||||
if ($this->element['width'])
|
||||
{
|
||||
$imgattr['width'] = (string) $this->element['width'];
|
||||
}
|
||||
|
||||
if ($this->element['height'])
|
||||
{
|
||||
$imgattr['height'] = (string) $this->element['height'];
|
||||
}
|
||||
|
||||
if ($this->element['align'])
|
||||
{
|
||||
$imgattr['align'] = (string) $this->element['align'];
|
||||
}
|
||||
|
||||
if ($this->element['rel'])
|
||||
{
|
||||
$imgattr['rel'] = (string) $this->element['rel'];
|
||||
}
|
||||
|
||||
if ($this->element['alt'])
|
||||
{
|
||||
$alt = JText::_((string) $this->element['alt']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$alt = null;
|
||||
}
|
||||
|
||||
if ($this->element['title'])
|
||||
{
|
||||
$imgattr['title'] = JText::_((string) $this->element['title']);
|
||||
}
|
||||
|
||||
if ($this->value && file_exists(JPATH_ROOT . '/' . $this->value))
|
||||
{
|
||||
$src = F0FPlatform::getInstance()->URIroot() . $this->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$src = '';
|
||||
}
|
||||
|
||||
return JHtml::image($src, $alt, $imgattr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getStatic();
|
||||
}
|
||||
}
|
||||
290
libraries/f0f/form/field/model.php
Normal file
290
libraries/f0f/form/field/model.php
Normal file
@ -0,0 +1,290 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('list');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Generic list from a model's results
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldModel extends F0FFormFieldList implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->id;
|
||||
$format_string = '';
|
||||
$show_link = false;
|
||||
$link_url = '';
|
||||
$empty_replacement = '';
|
||||
|
||||
// Get field parameters
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$class = (string) $this->element['class'];
|
||||
}
|
||||
|
||||
if ($this->element['format'])
|
||||
{
|
||||
$format_string = (string) $this->element['format'];
|
||||
}
|
||||
|
||||
if ($this->element['show_link'] == 'true')
|
||||
{
|
||||
$show_link = true;
|
||||
}
|
||||
|
||||
if ($this->element['url'])
|
||||
{
|
||||
$link_url = $this->element['url'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$show_link = false;
|
||||
}
|
||||
|
||||
if ($show_link && ($this->item instanceof F0FTable))
|
||||
{
|
||||
$link_url = $this->parseFieldTags($link_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
$show_link = false;
|
||||
}
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
$value = F0FFormFieldList::getOptionName($this->getOptions(), $this->value);
|
||||
|
||||
// Get the (optionally formatted) value
|
||||
if (!empty($empty_replacement) && empty($value))
|
||||
{
|
||||
$value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
if (empty($format_string))
|
||||
{
|
||||
$value = htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = sprintf($format_string, $value);
|
||||
}
|
||||
|
||||
// Create the HTML
|
||||
$html = '<span class="' . $class . '">';
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '<a href="' . $link_url . '">';
|
||||
}
|
||||
|
||||
$html .= $value;
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$options = array();
|
||||
|
||||
// Initialize some field attributes.
|
||||
$key = $this->element['key_field'] ? (string) $this->element['key_field'] : 'value';
|
||||
$value = $this->element['value_field'] ? (string) $this->element['value_field'] : (string) $this->element['name'];
|
||||
$translate = $this->element['translate'] ? (string) $this->element['translate'] : false;
|
||||
$applyAccess = $this->element['apply_access'] ? (string) $this->element['apply_access'] : 'false';
|
||||
$modelName = (string) $this->element['model'];
|
||||
$nonePlaceholder = (string) $this->element['none'];
|
||||
|
||||
if (!empty($nonePlaceholder))
|
||||
{
|
||||
$options[] = JHtml::_('select.option', null, JText::_($nonePlaceholder));
|
||||
}
|
||||
|
||||
// Process field atrtibutes
|
||||
$applyAccess = strtolower($applyAccess);
|
||||
$applyAccess = in_array($applyAccess, array('yes', 'on', 'true', '1'));
|
||||
|
||||
// Explode model name into model name and prefix
|
||||
$parts = F0FInflector::explode($modelName);
|
||||
$mName = ucfirst(array_pop($parts));
|
||||
$mPrefix = F0FInflector::implode($parts);
|
||||
|
||||
// Get the model object
|
||||
$config = array('savestate' => 0);
|
||||
$model = F0FModel::getTmpInstance($mName, $mPrefix, $config);
|
||||
|
||||
if ($applyAccess)
|
||||
{
|
||||
$model->applyAccessFiltering();
|
||||
}
|
||||
|
||||
// Process state variables
|
||||
foreach ($this->element->children() as $stateoption)
|
||||
{
|
||||
// Only add <option /> elements.
|
||||
if ($stateoption->getName() != 'state')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$stateKey = (string) $stateoption['key'];
|
||||
$stateValue = (string) $stateoption;
|
||||
|
||||
$model->setState($stateKey, $stateValue);
|
||||
}
|
||||
|
||||
// Set the query and get the result list.
|
||||
$items = $model->getItemList(true);
|
||||
|
||||
// Build the field options.
|
||||
if (!empty($items))
|
||||
{
|
||||
foreach ($items as $item)
|
||||
{
|
||||
if ($translate == true)
|
||||
{
|
||||
$options[] = JHtml::_('select.option', $item->$key, JText::_($item->$value));
|
||||
}
|
||||
else
|
||||
{
|
||||
$options[] = JHtml::_('select.option', $item->$key, $item->$value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge any additional options in the XML definition.
|
||||
$options = array_merge(parent::getOptions(), $options);
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace string with tags that reference fields
|
||||
*
|
||||
* @param string $text Text to process
|
||||
*
|
||||
* @return string Text with tags replace
|
||||
*/
|
||||
protected function parseFieldTags($text)
|
||||
{
|
||||
$ret = $text;
|
||||
|
||||
// Replace [ITEM:ID] in the URL with the item's key value (usually:
|
||||
// the auto-incrementing numeric ID)
|
||||
$keyfield = $this->item->getKeyName();
|
||||
$replace = $this->item->$keyfield;
|
||||
$ret = str_replace('[ITEM:ID]', $replace, $ret);
|
||||
|
||||
// Replace the [ITEMID] in the URL with the current Itemid parameter
|
||||
$ret = str_replace('[ITEMID]', JFactory::getApplication()->input->getInt('Itemid', 0), $ret);
|
||||
|
||||
// Replace other field variables in the URL
|
||||
$fields = $this->item->getTableFields();
|
||||
|
||||
foreach ($fields as $fielddata)
|
||||
{
|
||||
$fieldname = $fielddata->Field;
|
||||
|
||||
if (empty($fieldname))
|
||||
{
|
||||
$fieldname = $fielddata->column_name;
|
||||
}
|
||||
|
||||
$search = '[ITEM:' . strtoupper($fieldname) . ']';
|
||||
$replace = $this->item->$fieldname;
|
||||
$ret = str_replace($search, $replace, $ret);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
218
libraries/f0f/form/field/ordering.php
Normal file
218
libraries/f0f/form/field/ordering.php
Normal file
@ -0,0 +1,218 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Renders the row ordering interface checkbox in browse views
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldOrdering extends JFormField implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field input markup for this field type.
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field input markup.
|
||||
*/
|
||||
protected function getInput()
|
||||
{
|
||||
$html = array();
|
||||
$attr = '';
|
||||
|
||||
// Initialize some field attributes.
|
||||
$attr .= !empty($this->class) ? ' class="' . $this->class . '"' : '';
|
||||
$attr .= $this->disabled ? ' disabled' : '';
|
||||
$attr .= !empty($this->size) ? ' size="' . $this->size . '"' : '';
|
||||
|
||||
// Initialize JavaScript field attributes.
|
||||
$attr .= !empty($this->onchange) ? ' onchange="' . $this->onchange . '"' : '';
|
||||
|
||||
$this->item = $this->form->getModel()->getItem();
|
||||
|
||||
$keyfield = $this->item->getKeyName();
|
||||
$itemId = $this->item->$keyfield;
|
||||
|
||||
$query = $this->getQuery();
|
||||
|
||||
// Create a read-only list (no name) with a hidden input to store the value.
|
||||
if ($this->readonly)
|
||||
{
|
||||
$html[] = JHtml::_('list.ordering', '', $query, trim($attr), $this->value, $itemId ? 0 : 1);
|
||||
$html[] = '<input type="hidden" name="' . $this->name . '" value="' . $this->value . '"/>';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a regular list.
|
||||
$html[] = JHtml::_('list.ordering', $this->name, $query, trim($attr), $this->value, $itemId ? 0 : 1);
|
||||
}
|
||||
|
||||
return implode($html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
throw new Exception(__CLASS__ . ' cannot be used in single item display forms');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
if (!($this->item instanceof F0FTable))
|
||||
{
|
||||
throw new Exception(__CLASS__ . ' needs a F0FTable to act upon');
|
||||
}
|
||||
|
||||
$class = isset($this->element['class']) ? $this->element['class'] : 'input-mini';
|
||||
$icon = isset($this->element['icon']) ? $this->element['icon'] : 'icon-menu';
|
||||
|
||||
$html = '';
|
||||
|
||||
$view = $this->form->getView();
|
||||
|
||||
$ordering = $view->getLists()->order == 'ordering';
|
||||
|
||||
if (!$view->hasAjaxOrderingSupport())
|
||||
{
|
||||
// Ye olde Joomla! 2.5 method
|
||||
$disabled = $ordering ? '' : 'disabled="disabled"';
|
||||
$html .= '<span>';
|
||||
$html .= $view->pagination->orderUpIcon($this->rowid, true, 'orderup', 'Move Up', $ordering);
|
||||
$html .= '</span><span>';
|
||||
$html .= $view->pagination->orderDownIcon($this->rowid, $view->pagination->total, true, 'orderdown', 'Move Down', $ordering);
|
||||
$html .= '</span>';
|
||||
$html .= '<input type="text" name="order[]" size="5" value="' . $this->value . '" ' . $disabled;
|
||||
$html .= 'class="text-area-order" style="text-align: center" />';
|
||||
}
|
||||
else
|
||||
{
|
||||
// The modern drag'n'drop method
|
||||
if ($view->getPerms()->editstate)
|
||||
{
|
||||
$disableClassName = '';
|
||||
$disabledLabel = '';
|
||||
|
||||
$hasAjaxOrderingSupport = $view->hasAjaxOrderingSupport();
|
||||
|
||||
if (!$hasAjaxOrderingSupport['saveOrder'])
|
||||
{
|
||||
$disabledLabel = JText::_('JORDERINGDISABLED');
|
||||
$disableClassName = 'inactive tip-top';
|
||||
}
|
||||
|
||||
$orderClass = $ordering ? 'order-enabled' : 'order-disabled';
|
||||
|
||||
$html .= '<div class="' . $orderClass . '">';
|
||||
$html .= '<span class="sortable-handler ' . $disableClassName . '" title="' . $disabledLabel . '" rel="tooltip">';
|
||||
$html .= '<i class="' . $icon . '"></i>';
|
||||
$html .= '</span>';
|
||||
|
||||
if ($ordering)
|
||||
{
|
||||
$html .= '<input type="text" name="order[]" size="5" class="' . $class . ' text-area-order" value="' . $this->value . '" />';
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$html .= '<span class="sortable-handler inactive" >';
|
||||
$html .= '<i class="' . $icon . '"></i>';
|
||||
$html .= '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the query for the ordering list.
|
||||
*
|
||||
* @since 2.3.2
|
||||
*
|
||||
* @return F0FDatabaseQuery The query for the ordering form field
|
||||
*/
|
||||
protected function getQuery()
|
||||
{
|
||||
$ordering = $this->name;
|
||||
$title = $this->element['ordertitle'] ? (string) $this->element['ordertitle'] : $this->item->getColumnAlias('title');
|
||||
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
$query->select(array($db->quoteName($ordering, 'value'), $db->quoteName($title, 'text')))
|
||||
->from($db->quoteName($this->item->getTableName()))
|
||||
->order($ordering);
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
101
libraries/f0f/form/field/password.php
Normal file
101
libraries/f0f/form/field/password.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('password');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a one line text field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldPassword extends JFormFieldPassword implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
101
libraries/f0f/form/field/plugins.php
Normal file
101
libraries/f0f/form/field/plugins.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('plugins');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Plugins installed on the site
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldPlugins extends JFormFieldPlugins implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
216
libraries/f0f/form/field/published.php
Normal file
216
libraries/f0f/form/field/published.php
Normal file
@ -0,0 +1,216 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('list');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Supports a generic list of options.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldPublished extends JFormFieldList implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$options = parent::getOptions();
|
||||
|
||||
if (!empty($options))
|
||||
{
|
||||
return $options;
|
||||
}
|
||||
|
||||
// If no custom options were defined let's figure out which ones of the
|
||||
// defaults we shall use...
|
||||
|
||||
$config = array(
|
||||
'published' => 1,
|
||||
'unpublished' => 1,
|
||||
'archived' => 0,
|
||||
'trash' => 0,
|
||||
'all' => 0,
|
||||
);
|
||||
|
||||
$configMap = array(
|
||||
'show_published' => array('published', 1),
|
||||
'show_unpublished' => array('unpublished', 1),
|
||||
'show_archived' => array('archived', 0),
|
||||
'show_trash' => array('trash', 0),
|
||||
'show_all' => array('all', 0),
|
||||
);
|
||||
|
||||
foreach ($configMap as $attribute => $preferences)
|
||||
{
|
||||
list($configKey, $default) = $preferences;
|
||||
|
||||
switch (strtolower($this->element[$attribute]))
|
||||
{
|
||||
case 'true':
|
||||
case '1':
|
||||
case 'yes':
|
||||
$config[$configKey] = true;
|
||||
|
||||
case 'false':
|
||||
case '0':
|
||||
case 'no':
|
||||
$config[$configKey] = false;
|
||||
|
||||
default:
|
||||
$config[$configKey] = $default;
|
||||
}
|
||||
}
|
||||
|
||||
if ($config['published'])
|
||||
{
|
||||
$stack[] = JHtml::_('select.option', '1', JText::_('JPUBLISHED'));
|
||||
}
|
||||
|
||||
if ($config['unpublished'])
|
||||
{
|
||||
$stack[] = JHtml::_('select.option', '0', JText::_('JUNPUBLISHED'));
|
||||
}
|
||||
|
||||
if ($config['archived'])
|
||||
{
|
||||
$stack[] = JHtml::_('select.option', '2', JText::_('JARCHIVED'));
|
||||
}
|
||||
|
||||
if ($config['trash'])
|
||||
{
|
||||
$stack[] = JHtml::_('select.option', '-2', JText::_('JTRASHED'));
|
||||
}
|
||||
|
||||
if ($config['all'])
|
||||
{
|
||||
$stack[] = JHtml::_('select.option', '*', JText::_('JALL'));
|
||||
}
|
||||
|
||||
return $stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
if (!($this->item instanceof F0FTable))
|
||||
{
|
||||
throw new Exception(__CLASS__ . ' needs a F0FTable to act upon');
|
||||
}
|
||||
|
||||
// Initialise
|
||||
$prefix = '';
|
||||
$checkbox = 'cb';
|
||||
$publish_up = null;
|
||||
$publish_down = null;
|
||||
$enabled = true;
|
||||
|
||||
// Get options
|
||||
if ($this->element['prefix'])
|
||||
{
|
||||
$prefix = (string) $this->element['prefix'];
|
||||
}
|
||||
|
||||
if ($this->element['checkbox'])
|
||||
{
|
||||
$checkbox = (string) $this->element['checkbox'];
|
||||
}
|
||||
|
||||
if ($this->element['publish_up'])
|
||||
{
|
||||
$publish_up = (string) $this->element['publish_up'];
|
||||
}
|
||||
|
||||
if ($this->element['publish_down'])
|
||||
{
|
||||
$publish_down = (string) $this->element['publish_down'];
|
||||
}
|
||||
|
||||
// @todo Enforce ACL checks to determine if the field should be enabled or not
|
||||
// Get the HTML
|
||||
return JHTML::_('jgrid.published', $this->value, $this->rowid, $prefix, $enabled, $checkbox, $publish_up, $publish_down);
|
||||
}
|
||||
}
|
||||
101
libraries/f0f/form/field/radio.php
Normal file
101
libraries/f0f/form/field/radio.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('radio');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Radio selection list
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldRadio extends JFormFieldRadio implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
194
libraries/f0f/form/field/relation.php
Normal file
194
libraries/f0f/form/field/relation.php
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Relation list
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldRelation extends F0FFormFieldList
|
||||
{
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic() {
|
||||
return $this->getRepeatable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : $this->id;
|
||||
$relationclass = $this->element['relationclass'] ? (string) $this->element['relationclass'] : '';
|
||||
$value_field = $this->element['value_field'] ? (string) $this->element['value_field'] : 'title';
|
||||
$translate = $this->element['translate'] ? (string) $this->element['translate'] : false;
|
||||
$link_url = $this->element['url'] ? (string) $this->element['url'] : false;
|
||||
|
||||
if (!($link_url && $this->item instanceof F0FTable))
|
||||
{
|
||||
$link_url = false;
|
||||
}
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
$relationName = F0FInflector::pluralize($this->name);
|
||||
$relations = $this->item->getRelations()->getMultiple($relationName);
|
||||
|
||||
foreach ($relations as $relation) {
|
||||
|
||||
$html = '<span class="' . $relationclass . '">';
|
||||
|
||||
if ($link_url)
|
||||
{
|
||||
$keyfield = $relation->getKeyName();
|
||||
$this->_relationId = $relation->$keyfield;
|
||||
|
||||
$url = $this->parseFieldTags($link_url);
|
||||
$html .= '<a href="' . $url . '">';
|
||||
}
|
||||
|
||||
$value = $relation->get($relation->getColumnAlias($value_field));
|
||||
|
||||
// Get the (optionally formatted) value
|
||||
if (!empty($empty_replacement) && empty($value))
|
||||
{
|
||||
$value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
if ($translate == true)
|
||||
{
|
||||
$html .= JText::_($value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$html .= $value;
|
||||
}
|
||||
|
||||
if ($link_url)
|
||||
{
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
$rels[] = $html;
|
||||
}
|
||||
|
||||
$html = '<span class="' . $class . '">';
|
||||
$html .= implode(', ', $rels);
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field options.
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$options = array();
|
||||
$this->value = array();
|
||||
|
||||
$value_field = $this->element['value_field'] ? (string) $this->element['value_field'] : 'title';
|
||||
|
||||
$input = new F0FInput;
|
||||
$component = ucfirst(str_replace('com_', '', $input->getString('option')));
|
||||
$view = ucfirst($input->getString('view'));
|
||||
$relation = F0FInflector::pluralize((string) $this->element['name']);
|
||||
|
||||
$model = F0FModel::getTmpInstance(ucfirst($relation), $component . 'Model');
|
||||
$table = $model->getTable();
|
||||
|
||||
$key = $table->getKeyName();
|
||||
$value = $table->getColumnAlias($value_field);
|
||||
|
||||
foreach ($model->getItemList(true) as $option)
|
||||
{
|
||||
$options[] = JHtml::_('select.option', $option->$key, $option->$value);
|
||||
}
|
||||
|
||||
if ($id = F0FModel::getAnInstance($view)->getId())
|
||||
{
|
||||
$table = F0FTable::getInstance($view, $component . 'Table');
|
||||
$table->load($id);
|
||||
|
||||
$relations = $table->getRelations()->getMultiple($relation);
|
||||
|
||||
foreach ($relations as $item)
|
||||
{
|
||||
$this->value[] = $item->getId();
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace string with tags that reference fields
|
||||
*
|
||||
* @param string $text Text to process
|
||||
*
|
||||
* @return string Text with tags replace
|
||||
*/
|
||||
protected function parseFieldTags($text)
|
||||
{
|
||||
$ret = $text;
|
||||
|
||||
// Replace [ITEM:ID] in the URL with the item's key value (usually:
|
||||
// the auto-incrementing numeric ID)
|
||||
$keyfield = $this->item->getKeyName();
|
||||
$replace = $this->item->$keyfield;
|
||||
$ret = str_replace('[ITEM:ID]', $replace, $ret);
|
||||
|
||||
// Replace the [ITEMID] in the URL with the current Itemid parameter
|
||||
$ret = str_replace('[ITEMID]', JFactory::getApplication()->input->getInt('Itemid', 0), $ret);
|
||||
|
||||
// Replace the [RELATION:ID] in the URL with the relation's key value
|
||||
$ret = str_replace('[RELATION:ID]', $this->_relationId, $ret);
|
||||
|
||||
// Replace other field variables in the URL
|
||||
$fields = $this->item->getTableFields();
|
||||
|
||||
foreach ($fields as $fielddata)
|
||||
{
|
||||
$fieldname = $fielddata->Field;
|
||||
|
||||
if (empty($fieldname))
|
||||
{
|
||||
$fieldname = $fielddata->column_name;
|
||||
}
|
||||
|
||||
$search = '[ITEM:' . strtoupper($fieldname) . ']';
|
||||
$replace = $this->item->$fieldname;
|
||||
$ret = str_replace($search, $replace, $ret);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
630
libraries/f0f/form/field/rules.php
Normal file
630
libraries/f0f/form/field/rules.php
Normal file
@ -0,0 +1,630 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('rules');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Joomla! ACL Rules
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.1
|
||||
*/
|
||||
class F0FFormFieldRules extends JFormFieldRules implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
// This field cannot provide a static display
|
||||
case 'static':
|
||||
return '';
|
||||
break;
|
||||
|
||||
// This field cannot provide a repeateable display
|
||||
case 'repeatable':
|
||||
return '';
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* At the timing of this writing (2013-12-03), the Joomla "rules" field is buggy. When you are
|
||||
* dealing with a new record it gets the default permissions from the root asset node, which
|
||||
* is fine for the default permissions of Joomla articles, but unsuitable for third party software.
|
||||
* We had to copy & paste the whole code, since we can't "inject" the correct asset id if one is
|
||||
* not found. Our fixes are surrounded by `F0F Library fix` remarks.
|
||||
*
|
||||
* @return string The input field's HTML for this field type
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
if (version_compare(JVERSION, '3.0', 'ge'))
|
||||
{
|
||||
return $this->getInput3x();
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->getInput25();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getInput25()
|
||||
{
|
||||
JHtml::_('behavior.tooltip');
|
||||
|
||||
// Initialise some field attributes.
|
||||
$section = $this->element['section'] ? (string) $this->element['section'] : '';
|
||||
$component = $this->element['component'] ? (string) $this->element['component'] : '';
|
||||
$assetField = $this->element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id';
|
||||
|
||||
// Get the actions for the asset.
|
||||
$actions = JAccess::getActions($component, $section);
|
||||
|
||||
// Iterate over the children and add to the actions.
|
||||
foreach ($this->element->children() as $el)
|
||||
{
|
||||
if ($el->getName() == 'action')
|
||||
{
|
||||
$actions[] = (object) array('name' => (string) $el['name'], 'title' => (string) $el['title'],
|
||||
'description' => (string) $el['description']);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the explicit rules for this asset.
|
||||
if ($section == 'component')
|
||||
{
|
||||
// Need to find the asset id by the name of the component.
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
$query->select($db->quoteName('id'));
|
||||
$query->from($db->quoteName('#__assets'));
|
||||
$query->where($db->quoteName('name') . ' = ' . $db->quote($component));
|
||||
$db->setQuery($query);
|
||||
$assetId = (int) $db->loadResult();
|
||||
|
||||
if ($error = $db->getErrorMsg())
|
||||
{
|
||||
JError::raiseNotice(500, $error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the asset id of the content.
|
||||
// Note that for global configuration, com_config injects asset_id = 1 into the form.
|
||||
$assetId = $this->form->getValue($assetField);
|
||||
|
||||
// ==== F0F Library fix - Start ====
|
||||
// If there is no assetId (let's say we are dealing with a new record), let's ask the table
|
||||
// to give it to us. Here you should implement your logic (ie getting default permissions from
|
||||
// the component or from the category)
|
||||
if(!$assetId)
|
||||
{
|
||||
$table = $this->form->getModel()->getTable();
|
||||
$assetId = $table->getAssetParentId();
|
||||
}
|
||||
// ==== F0F Library fix - End ====
|
||||
}
|
||||
|
||||
// Use the compact form for the content rules (deprecated).
|
||||
//if (!empty($component) && $section != 'component') {
|
||||
// return JHtml::_('rules.assetFormWidget', $actions, $assetId, $assetId ? null : $component, $this->name, $this->id);
|
||||
//}
|
||||
|
||||
// Full width format.
|
||||
|
||||
// Get the rules for just this asset (non-recursive).
|
||||
$assetRules = JAccess::getAssetRules($assetId);
|
||||
|
||||
// Get the available user groups.
|
||||
$groups = $this->getUserGroups();
|
||||
|
||||
// Build the form control.
|
||||
$curLevel = 0;
|
||||
|
||||
// Prepare output
|
||||
$html = array();
|
||||
$html[] = '<div id="permissions-sliders" class="pane-sliders">';
|
||||
$html[] = '<p class="rule-desc">' . JText::_('JLIB_RULES_SETTINGS_DESC') . '</p>';
|
||||
$html[] = '<ul id="rules">';
|
||||
|
||||
// Start a row for each user group.
|
||||
foreach ($groups as $group)
|
||||
{
|
||||
$difLevel = $group->level - $curLevel;
|
||||
|
||||
if ($difLevel > 0)
|
||||
{
|
||||
$html[] = '<li><ul>';
|
||||
}
|
||||
elseif ($difLevel < 0)
|
||||
{
|
||||
$html[] = str_repeat('</ul></li>', -$difLevel);
|
||||
}
|
||||
|
||||
$html[] = '<li>';
|
||||
|
||||
$html[] = '<div class="panel">';
|
||||
$html[] = '<h3 class="pane-toggler title"><a href="javascript:void(0);"><span>';
|
||||
$html[] = str_repeat('<span class="level">|–</span> ', $curLevel = $group->level) . $group->text;
|
||||
$html[] = '</span></a></h3>';
|
||||
$html[] = '<div class="pane-slider content pane-hide">';
|
||||
$html[] = '<div class="mypanel">';
|
||||
$html[] = '<table class="group-rules">';
|
||||
$html[] = '<thead>';
|
||||
$html[] = '<tr>';
|
||||
|
||||
$html[] = '<th class="actions" id="actions-th' . $group->value . '">';
|
||||
$html[] = '<span class="acl-action">' . JText::_('JLIB_RULES_ACTION') . '</span>';
|
||||
$html[] = '</th>';
|
||||
|
||||
$html[] = '<th class="settings" id="settings-th' . $group->value . '">';
|
||||
$html[] = '<span class="acl-action">' . JText::_('JLIB_RULES_SELECT_SETTING') . '</span>';
|
||||
$html[] = '</th>';
|
||||
|
||||
// The calculated setting is not shown for the root group of global configuration.
|
||||
$canCalculateSettings = ($group->parent_id || !empty($component));
|
||||
if ($canCalculateSettings)
|
||||
{
|
||||
$html[] = '<th id="aclactionth' . $group->value . '">';
|
||||
$html[] = '<span class="acl-action">' . JText::_('JLIB_RULES_CALCULATED_SETTING') . '</span>';
|
||||
$html[] = '</th>';
|
||||
}
|
||||
|
||||
$html[] = '</tr>';
|
||||
$html[] = '</thead>';
|
||||
$html[] = '<tbody>';
|
||||
|
||||
foreach ($actions as $action)
|
||||
{
|
||||
$html[] = '<tr>';
|
||||
$html[] = '<td headers="actions-th' . $group->value . '">';
|
||||
$html[] = '<label class="hasTip" for="' . $this->id . '_' . $action->name . '_' . $group->value . '" title="'
|
||||
. htmlspecialchars(JText::_($action->title) . '::' . JText::_($action->description), ENT_COMPAT, 'UTF-8') . '">';
|
||||
$html[] = JText::_($action->title);
|
||||
$html[] = '</label>';
|
||||
$html[] = '</td>';
|
||||
|
||||
$html[] = '<td headers="settings-th' . $group->value . '">';
|
||||
|
||||
$html[] = '<select name="' . $this->name . '[' . $action->name . '][' . $group->value . ']" id="' . $this->id . '_' . $action->name
|
||||
. '_' . $group->value . '" title="'
|
||||
. JText::sprintf('JLIB_RULES_SELECT_ALLOW_DENY_GROUP', JText::_($action->title), trim($group->text)) . '">';
|
||||
|
||||
$inheritedRule = JAccess::checkGroup($group->value, $action->name, $assetId);
|
||||
|
||||
// Get the actual setting for the action for this group.
|
||||
$assetRule = $assetRules->allow($action->name, $group->value);
|
||||
|
||||
// Build the dropdowns for the permissions sliders
|
||||
|
||||
// The parent group has "Not Set", all children can rightly "Inherit" from that.
|
||||
$html[] = '<option value=""' . ($assetRule === null ? ' selected="selected"' : '') . '>'
|
||||
. JText::_(empty($group->parent_id) && empty($component) ? 'JLIB_RULES_NOT_SET' : 'JLIB_RULES_INHERITED') . '</option>';
|
||||
$html[] = '<option value="1"' . ($assetRule === true ? ' selected="selected"' : '') . '>' . JText::_('JLIB_RULES_ALLOWED')
|
||||
. '</option>';
|
||||
$html[] = '<option value="0"' . ($assetRule === false ? ' selected="selected"' : '') . '>' . JText::_('JLIB_RULES_DENIED')
|
||||
. '</option>';
|
||||
|
||||
$html[] = '</select>  ';
|
||||
|
||||
// If this asset's rule is allowed, but the inherited rule is deny, we have a conflict.
|
||||
if (($assetRule === true) && ($inheritedRule === false))
|
||||
{
|
||||
$html[] = JText::_('JLIB_RULES_CONFLICT');
|
||||
}
|
||||
|
||||
$html[] = '</td>';
|
||||
|
||||
// Build the Calculated Settings column.
|
||||
// The inherited settings column is not displayed for the root group in global configuration.
|
||||
if ($canCalculateSettings)
|
||||
{
|
||||
$html[] = '<td headers="aclactionth' . $group->value . '">';
|
||||
|
||||
// This is where we show the current effective settings considering currrent group, path and cascade.
|
||||
// Check whether this is a component or global. Change the text slightly.
|
||||
|
||||
if (JAccess::checkGroup($group->value, 'core.admin', $assetId) !== true)
|
||||
{
|
||||
if ($inheritedRule === null)
|
||||
{
|
||||
$html[] = '<span class="icon-16-unset">' . JText::_('JLIB_RULES_NOT_ALLOWED') . '</span>';
|
||||
}
|
||||
elseif ($inheritedRule === true)
|
||||
{
|
||||
$html[] = '<span class="icon-16-allowed">' . JText::_('JLIB_RULES_ALLOWED') . '</span>';
|
||||
}
|
||||
elseif ($inheritedRule === false)
|
||||
{
|
||||
if ($assetRule === false)
|
||||
{
|
||||
$html[] = '<span class="icon-16-denied">' . JText::_('JLIB_RULES_NOT_ALLOWED') . '</span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$html[] = '<span class="icon-16-denied"><span class="icon-16-locked">' . JText::_('JLIB_RULES_NOT_ALLOWED_LOCKED')
|
||||
. '</span></span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (!empty($component))
|
||||
{
|
||||
$html[] = '<span class="icon-16-allowed"><span class="icon-16-locked">' . JText::_('JLIB_RULES_ALLOWED_ADMIN')
|
||||
. '</span></span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Special handling for groups that have global admin because they can't be denied.
|
||||
// The admin rights can be changed.
|
||||
if ($action->name === 'core.admin')
|
||||
{
|
||||
$html[] = '<span class="icon-16-allowed">' . JText::_('JLIB_RULES_ALLOWED') . '</span>';
|
||||
}
|
||||
elseif ($inheritedRule === false)
|
||||
{
|
||||
// Other actions cannot be changed.
|
||||
$html[] = '<span class="icon-16-denied"><span class="icon-16-locked">'
|
||||
. JText::_('JLIB_RULES_NOT_ALLOWED_ADMIN_CONFLICT') . '</span></span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$html[] = '<span class="icon-16-allowed"><span class="icon-16-locked">' . JText::_('JLIB_RULES_ALLOWED_ADMIN')
|
||||
. '</span></span>';
|
||||
}
|
||||
}
|
||||
|
||||
$html[] = '</td>';
|
||||
}
|
||||
|
||||
$html[] = '</tr>';
|
||||
}
|
||||
|
||||
$html[] = '</tbody>';
|
||||
$html[] = '</table></div>';
|
||||
|
||||
$html[] = '</div></div>';
|
||||
$html[] = '</li>';
|
||||
|
||||
}
|
||||
|
||||
$html[] = str_repeat('</ul></li>', $curLevel);
|
||||
$html[] = '</ul><div class="rule-notes">';
|
||||
if ($section == 'component' || $section == null)
|
||||
{
|
||||
$html[] = JText::_('JLIB_RULES_SETTING_NOTES');
|
||||
}
|
||||
else
|
||||
{
|
||||
$html[] = JText::_('JLIB_RULES_SETTING_NOTES_ITEM');
|
||||
}
|
||||
$html[] = '</div></div>';
|
||||
|
||||
$js = "window.addEvent('domready', function(){ new Fx.Accordion($$('div#permissions-sliders.pane-sliders .panel h3.pane-toggler'),"
|
||||
. "$$('div#permissions-sliders.pane-sliders .panel div.pane-slider'), {onActive: function(toggler, i) {toggler.addClass('pane-toggler-down');"
|
||||
. "toggler.removeClass('pane-toggler');i.addClass('pane-down');i.removeClass('pane-hide');Cookie.write('jpanesliders_permissions-sliders"
|
||||
. $component
|
||||
. "',$$('div#permissions-sliders.pane-sliders .panel h3').indexOf(toggler));},"
|
||||
. "onBackground: function(toggler, i) {toggler.addClass('pane-toggler');toggler.removeClass('pane-toggler-down');i.addClass('pane-hide');"
|
||||
. "i.removeClass('pane-down');}, duration: 300, display: "
|
||||
. JRequest::getInt('jpanesliders_permissions-sliders' . $component, 0, 'cookie') . ", show: "
|
||||
. JRequest::getInt('jpanesliders_permissions-sliders' . $component, 0, 'cookie') . ", alwaysHide:true, opacity: false}); });";
|
||||
|
||||
JFactory::getDocument()->addScriptDeclaration($js);
|
||||
|
||||
return implode("\n", $html);
|
||||
}
|
||||
|
||||
protected function getInput3x()
|
||||
{
|
||||
JHtml::_('bootstrap.tooltip');
|
||||
|
||||
// Initialise some field attributes.
|
||||
$section = $this->section;
|
||||
$component = $this->component;
|
||||
$assetField = $this->assetField;
|
||||
|
||||
// Get the actions for the asset.
|
||||
$actions = JAccess::getActions($component, $section);
|
||||
|
||||
// Iterate over the children and add to the actions.
|
||||
foreach ($this->element->children() as $el)
|
||||
{
|
||||
if ($el->getName() == 'action')
|
||||
{
|
||||
$actions[] = (object) array('name' => (string) $el['name'], 'title' => (string) $el['title'],
|
||||
'description' => (string) $el['description']);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the explicit rules for this asset.
|
||||
if ($section == 'component')
|
||||
{
|
||||
// Need to find the asset id by the name of the component.
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__assets'))
|
||||
->where($db->quoteName('name') . ' = ' . $db->quote($component));
|
||||
|
||||
$assetId = (int) $db->setQuery($query)->loadResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the asset id of the content.
|
||||
// Note that for global configuration, com_config injects asset_id = 1 into the form.
|
||||
$assetId = $this->form->getValue($assetField);
|
||||
|
||||
// ==== F0F Library fix - Start ====
|
||||
// If there is no assetId (let's say we are dealing with a new record), let's ask the table
|
||||
// to give it to us. Here you should implement your logic (ie getting default permissions from
|
||||
// the component or from the category)
|
||||
if(!$assetId)
|
||||
{
|
||||
$table = $this->form->getModel()->getTable();
|
||||
$assetId = $table->getAssetParentId();
|
||||
}
|
||||
// ==== F0F Library fix - End ====
|
||||
}
|
||||
|
||||
// Full width format.
|
||||
|
||||
// Get the rules for just this asset (non-recursive).
|
||||
$assetRules = JAccess::getAssetRules($assetId);
|
||||
|
||||
// Get the available user groups.
|
||||
$groups = $this->getUserGroups();
|
||||
|
||||
// Prepare output
|
||||
$html = array();
|
||||
|
||||
// Description
|
||||
$html[] = '<p class="rule-desc">' . JText::_('JLIB_RULES_SETTINGS_DESC') . '</p>';
|
||||
|
||||
// Begin tabs
|
||||
$html[] = '<div id="permissions-sliders" class="tabbable tabs-left">';
|
||||
|
||||
// Building tab nav
|
||||
$html[] = '<ul class="nav nav-tabs">';
|
||||
|
||||
foreach ($groups as $group)
|
||||
{
|
||||
// Initial Active Tab
|
||||
$active = "";
|
||||
|
||||
if ($group->value == 1)
|
||||
{
|
||||
$active = "active";
|
||||
}
|
||||
|
||||
$html[] = '<li class="' . $active . '">';
|
||||
$html[] = '<a href="#permission-' . $group->value . '" data-toggle="tab">';
|
||||
$html[] = str_repeat('<span class="level">–</span> ', $curLevel = $group->level) . $group->text;
|
||||
$html[] = '</a>';
|
||||
$html[] = '</li>';
|
||||
}
|
||||
|
||||
$html[] = '</ul>';
|
||||
|
||||
$html[] = '<div class="tab-content">';
|
||||
|
||||
// Start a row for each user group.
|
||||
foreach ($groups as $group)
|
||||
{
|
||||
// Initial Active Pane
|
||||
$active = "";
|
||||
|
||||
if ($group->value == 1)
|
||||
{
|
||||
$active = " active";
|
||||
}
|
||||
|
||||
$html[] = '<div class="tab-pane' . $active . '" id="permission-' . $group->value . '">';
|
||||
$html[] = '<table class="table table-striped">';
|
||||
$html[] = '<thead>';
|
||||
$html[] = '<tr>';
|
||||
|
||||
$html[] = '<th class="actions" id="actions-th' . $group->value . '">';
|
||||
$html[] = '<span class="acl-action">' . JText::_('JLIB_RULES_ACTION') . '</span>';
|
||||
$html[] = '</th>';
|
||||
|
||||
$html[] = '<th class="settings" id="settings-th' . $group->value . '">';
|
||||
$html[] = '<span class="acl-action">' . JText::_('JLIB_RULES_SELECT_SETTING') . '</span>';
|
||||
$html[] = '</th>';
|
||||
|
||||
// The calculated setting is not shown for the root group of global configuration.
|
||||
$canCalculateSettings = ($group->parent_id || !empty($component));
|
||||
|
||||
if ($canCalculateSettings)
|
||||
{
|
||||
$html[] = '<th id="aclactionth' . $group->value . '">';
|
||||
$html[] = '<span class="acl-action">' . JText::_('JLIB_RULES_CALCULATED_SETTING') . '</span>';
|
||||
$html[] = '</th>';
|
||||
}
|
||||
|
||||
$html[] = '</tr>';
|
||||
$html[] = '</thead>';
|
||||
$html[] = '<tbody>';
|
||||
|
||||
foreach ($actions as $action)
|
||||
{
|
||||
$html[] = '<tr>';
|
||||
$html[] = '<td headers="actions-th' . $group->value . '">';
|
||||
$html[] = '<label for="' . $this->id . '_' . $action->name . '_' . $group->value . '" class="hasTooltip" title="'
|
||||
. htmlspecialchars(JText::_($action->title) . ' ' . JText::_($action->description), ENT_COMPAT, 'UTF-8') . '">';
|
||||
$html[] = JText::_($action->title);
|
||||
$html[] = '</label>';
|
||||
$html[] = '</td>';
|
||||
|
||||
$html[] = '<td headers="settings-th' . $group->value . '">';
|
||||
|
||||
$html[] = '<select class="input-small" name="' . $this->name . '[' . $action->name . '][' . $group->value . ']" id="' . $this->id . '_' . $action->name
|
||||
. '_' . $group->value . '" title="'
|
||||
. JText::sprintf('JLIB_RULES_SELECT_ALLOW_DENY_GROUP', JText::_($action->title), trim($group->text)) . '">';
|
||||
|
||||
$inheritedRule = JAccess::checkGroup($group->value, $action->name, $assetId);
|
||||
|
||||
// Get the actual setting for the action for this group.
|
||||
$assetRule = $assetRules->allow($action->name, $group->value);
|
||||
|
||||
// Build the dropdowns for the permissions sliders
|
||||
|
||||
// The parent group has "Not Set", all children can rightly "Inherit" from that.
|
||||
$html[] = '<option value=""' . ($assetRule === null ? ' selected="selected"' : '') . '>'
|
||||
. JText::_(empty($group->parent_id) && empty($component) ? 'JLIB_RULES_NOT_SET' : 'JLIB_RULES_INHERITED') . '</option>';
|
||||
$html[] = '<option value="1"' . ($assetRule === true ? ' selected="selected"' : '') . '>' . JText::_('JLIB_RULES_ALLOWED')
|
||||
. '</option>';
|
||||
$html[] = '<option value="0"' . ($assetRule === false ? ' selected="selected"' : '') . '>' . JText::_('JLIB_RULES_DENIED')
|
||||
. '</option>';
|
||||
|
||||
$html[] = '</select>  ';
|
||||
|
||||
// If this asset's rule is allowed, but the inherited rule is deny, we have a conflict.
|
||||
if (($assetRule === true) && ($inheritedRule === false))
|
||||
{
|
||||
$html[] = JText::_('JLIB_RULES_CONFLICT');
|
||||
}
|
||||
|
||||
$html[] = '</td>';
|
||||
|
||||
// Build the Calculated Settings column.
|
||||
// The inherited settings column is not displayed for the root group in global configuration.
|
||||
if ($canCalculateSettings)
|
||||
{
|
||||
$html[] = '<td headers="aclactionth' . $group->value . '">';
|
||||
|
||||
// This is where we show the current effective settings considering currrent group, path and cascade.
|
||||
// Check whether this is a component or global. Change the text slightly.
|
||||
|
||||
if (JAccess::checkGroup($group->value, 'core.admin', $assetId) !== true)
|
||||
{
|
||||
if ($inheritedRule === null)
|
||||
{
|
||||
$html[] = '<span class="label label-important">' . JText::_('JLIB_RULES_NOT_ALLOWED') . '</span>';
|
||||
}
|
||||
elseif ($inheritedRule === true)
|
||||
{
|
||||
$html[] = '<span class="label label-success">' . JText::_('JLIB_RULES_ALLOWED') . '</span>';
|
||||
}
|
||||
elseif ($inheritedRule === false)
|
||||
{
|
||||
if ($assetRule === false)
|
||||
{
|
||||
$html[] = '<span class="label label-important">' . JText::_('JLIB_RULES_NOT_ALLOWED') . '</span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$html[] = '<span class="label"><i class="icon-lock icon-white"></i> ' . JText::_('JLIB_RULES_NOT_ALLOWED_LOCKED')
|
||||
. '</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (!empty($component))
|
||||
{
|
||||
$html[] = '<span class="label label-success"><i class="icon-lock icon-white"></i> ' . JText::_('JLIB_RULES_ALLOWED_ADMIN')
|
||||
. '</span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Special handling for groups that have global admin because they can't be denied.
|
||||
// The admin rights can be changed.
|
||||
if ($action->name === 'core.admin')
|
||||
{
|
||||
$html[] = '<span class="label label-success">' . JText::_('JLIB_RULES_ALLOWED') . '</span>';
|
||||
}
|
||||
elseif ($inheritedRule === false)
|
||||
{
|
||||
// Other actions cannot be changed.
|
||||
$html[] = '<span class="label label-important"><i class="icon-lock icon-white"></i> '
|
||||
. JText::_('JLIB_RULES_NOT_ALLOWED_ADMIN_CONFLICT') . '</span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$html[] = '<span class="label label-success"><i class="icon-lock icon-white"></i> ' . JText::_('JLIB_RULES_ALLOWED_ADMIN')
|
||||
. '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
$html[] = '</td>';
|
||||
}
|
||||
|
||||
$html[] = '</tr>';
|
||||
}
|
||||
|
||||
$html[] = '</tbody>';
|
||||
$html[] = '</table></div>';
|
||||
}
|
||||
|
||||
$html[] = '</div></div>';
|
||||
|
||||
$html[] = '<div class="alert">';
|
||||
|
||||
if ($section == 'component' || $section == null)
|
||||
{
|
||||
$html[] = JText::_('JLIB_RULES_SETTING_NOTES');
|
||||
}
|
||||
else
|
||||
{
|
||||
$html[] = JText::_('JLIB_RULES_SETTING_NOTES_ITEM');
|
||||
}
|
||||
|
||||
$html[] = '</div>';
|
||||
|
||||
return implode("\n", $html);
|
||||
}
|
||||
}
|
||||
124
libraries/f0f/form/field/selectrow.php
Normal file
124
libraries/f0f/form/field/selectrow.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Renders the checkbox in browse views which allows you to select rows
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldSelectrow extends JFormField implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the field input markup for this field type.
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field input markup.
|
||||
*/
|
||||
protected function getInput()
|
||||
{
|
||||
throw new Exception(__CLASS__ . ' cannot be used in input forms');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
throw new Exception(__CLASS__ . ' cannot be used in single item display forms');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
if (!($this->item instanceof F0FTable))
|
||||
{
|
||||
throw new Exception(__CLASS__ . ' needs a F0FTable to act upon');
|
||||
}
|
||||
|
||||
// Is this record checked out?
|
||||
$checked_out = false;
|
||||
$locked_by_field = $this->item->getColumnAlias('locked_by');
|
||||
$myId = JFactory::getUser()->get('id', 0);
|
||||
|
||||
if (property_exists($this->item, $locked_by_field))
|
||||
{
|
||||
$locked_by = $this->item->$locked_by_field;
|
||||
$checked_out = ($locked_by != 0 && $locked_by != $myId);
|
||||
}
|
||||
|
||||
// Get the key id for this record
|
||||
$key_field = $this->item->getKeyName();
|
||||
$key_id = $this->item->$key_field;
|
||||
|
||||
// Get the HTML
|
||||
return JHTML::_('grid.id', $this->rowid, $key_id, $checked_out);
|
||||
}
|
||||
}
|
||||
101
libraries/f0f/form/field/sessionhandler.php
Normal file
101
libraries/f0f/form/field/sessionhandler.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('sessionhandler');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Joomla! session handlers
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldSessionhandler extends JFormFieldSessionHandler implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
93
libraries/f0f/form/field/spacer.php
Normal file
93
libraries/f0f/form/field/spacer.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('spacer');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Spacer used between form elements
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldSpacer extends JFormFieldSpacer implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getInput();
|
||||
}
|
||||
}
|
||||
101
libraries/f0f/form/field/sql.php
Normal file
101
libraries/f0f/form/field/sql.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('sql');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Radio selection listGeneric list from an SQL statement
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldSql extends JFormFieldSql implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
238
libraries/f0f/form/field/tag.php
Normal file
238
libraries/f0f/form/field/tag.php
Normal file
@ -0,0 +1,238 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('tag');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Tag Fields
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.1
|
||||
*/
|
||||
class F0FFormFieldTag extends JFormFieldTag implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a list of tags
|
||||
*
|
||||
* @return array The field option objects.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
$options = array();
|
||||
|
||||
$published = $this->element['published']? $this->element['published'] : array(0,1);
|
||||
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select('DISTINCT a.id AS value, a.path, a.title AS text, a.level, a.published, a.lft')
|
||||
->from('#__tags AS a')
|
||||
->join('LEFT', $db->quoteName('#__tags') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt');
|
||||
|
||||
if ($this->item instanceof F0FTable)
|
||||
{
|
||||
$item = $this->item;
|
||||
}
|
||||
else
|
||||
{
|
||||
$item = $this->form->getModel()->getItem();
|
||||
}
|
||||
|
||||
if ($item instanceof F0FTable)
|
||||
{
|
||||
// Fake value for selected tags
|
||||
$keyfield = $item->getKeyName();
|
||||
$content_id = $item->$keyfield;
|
||||
$type = $item->getContentType();
|
||||
|
||||
$selected_query = $db->getQuery(true);
|
||||
$selected_query
|
||||
->select('tag_id')
|
||||
->from('#__contentitem_tag_map')
|
||||
->where('content_item_id = ' . (int) $content_id)
|
||||
->where('type_alias = ' . $db->quote($type));
|
||||
|
||||
$db->setQuery($selected_query);
|
||||
|
||||
$this->value = $db->loadColumn();
|
||||
}
|
||||
|
||||
// Filter language
|
||||
if (!empty($this->element['language']))
|
||||
{
|
||||
$query->where('a.language = ' . $db->quote($this->element['language']));
|
||||
}
|
||||
|
||||
$query->where($db->qn('a.lft') . ' > 0');
|
||||
|
||||
// Filter to only load active items
|
||||
|
||||
// Filter on the published state
|
||||
if (is_numeric($published))
|
||||
{
|
||||
$query->where('a.published = ' . (int) $published);
|
||||
}
|
||||
elseif (is_array($published))
|
||||
{
|
||||
F0FUtilsArray::toInteger($published);
|
||||
$query->where('a.published IN (' . implode(',', $published) . ')');
|
||||
}
|
||||
|
||||
$query->order('a.lft ASC');
|
||||
|
||||
// Get the options.
|
||||
$db->setQuery($query);
|
||||
|
||||
try
|
||||
{
|
||||
$options = $db->loadObjectList();
|
||||
}
|
||||
catch (RuntimeException $e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prepare nested data
|
||||
if ($this->isNested())
|
||||
{
|
||||
$this->prepareOptionsNested($options);
|
||||
}
|
||||
else
|
||||
{
|
||||
$options = JHelperTags::convertPathsToNames($options);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
$translate = $this->element['translate'] ? (string) $this->element['translate'] : false;
|
||||
|
||||
$options = $this->getOptions();
|
||||
|
||||
$html = '';
|
||||
|
||||
foreach ($options as $option) {
|
||||
|
||||
$html .= '<span>';
|
||||
|
||||
if ($translate == true)
|
||||
{
|
||||
$html .= JText::_($option->text);
|
||||
}
|
||||
else
|
||||
{
|
||||
$html .= $option->text;
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '" class="' . $class . '">' .
|
||||
$html .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.1
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
$translate = $this->element['translate'] ? (string) $this->element['translate'] : false;
|
||||
|
||||
$options = $this->getOptions();
|
||||
|
||||
$html = '';
|
||||
|
||||
foreach ($options as $option) {
|
||||
|
||||
$html .= '<span>';
|
||||
|
||||
if ($translate == true)
|
||||
{
|
||||
$html .= JText::_($option->text);
|
||||
}
|
||||
else
|
||||
{
|
||||
$html .= $option->text;
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
}
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
$html .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
165
libraries/f0f/form/field/tel.php
Normal file
165
libraries/f0f/form/field/tel.php
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('tel');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a URL text field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldTel extends JFormFieldTel implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
$dolink = $this->element['show_link'] == 'true';
|
||||
$empty_replacement = '';
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
if (!empty($empty_replacement) && empty($this->value))
|
||||
{
|
||||
$this->value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
$innerHtml = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
if ($dolink)
|
||||
{
|
||||
$innerHtml = '<a href="tel:' . $innerHtml . '">' .
|
||||
$innerHtml . '</a>';
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
$innerHtml .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
// Initialise
|
||||
$class = $this->id;
|
||||
$show_link = false;
|
||||
$empty_replacement = '';
|
||||
|
||||
$link_url = 'tel:' . htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
// Get field parameters
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$class = ' ' . (string) $this->element['class'];
|
||||
}
|
||||
|
||||
if ($this->element['show_link'] == 'true')
|
||||
{
|
||||
$show_link = true;
|
||||
}
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
// Get the (optionally formatted) value
|
||||
if (!empty($empty_replacement) && empty($this->value))
|
||||
{
|
||||
$this->value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
$value = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
// Create the HTML
|
||||
$html = '<span class="' . $class . '">';
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '<a href="' . $link_url . '">';
|
||||
}
|
||||
|
||||
$html .= $value;
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
246
libraries/f0f/form/field/text.php
Normal file
246
libraries/f0f/form/field/text.php
Normal file
@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('text');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a one line text field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldText extends JFormFieldText implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
$empty_replacement = '';
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
if (!empty($empty_replacement) && empty($this->value))
|
||||
{
|
||||
$this->value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
// Initialise
|
||||
$class = $this->id;
|
||||
$format_string = '';
|
||||
$format_if_not_empty = false;
|
||||
$parse_value = false;
|
||||
$show_link = false;
|
||||
$link_url = '';
|
||||
$empty_replacement = '';
|
||||
|
||||
// Get field parameters
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$class = (string) $this->element['class'];
|
||||
}
|
||||
|
||||
if ($this->element['format'])
|
||||
{
|
||||
$format_string = (string) $this->element['format'];
|
||||
}
|
||||
|
||||
if ($this->element['show_link'] == 'true')
|
||||
{
|
||||
$show_link = true;
|
||||
}
|
||||
|
||||
if ($this->element['format_if_not_empty'] == 'true')
|
||||
{
|
||||
$format_if_not_empty = true;
|
||||
}
|
||||
|
||||
if ($this->element['parse_value'] == 'true')
|
||||
{
|
||||
$parse_value = true;
|
||||
}
|
||||
|
||||
if ($this->element['url'])
|
||||
{
|
||||
$link_url = $this->element['url'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$show_link = false;
|
||||
}
|
||||
|
||||
if ($show_link && ($this->item instanceof F0FTable))
|
||||
{
|
||||
$link_url = $this->parseFieldTags($link_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
$show_link = false;
|
||||
}
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
// Get the (optionally formatted) value
|
||||
$value = $this->value;
|
||||
|
||||
if (!empty($empty_replacement) && empty($this->value))
|
||||
{
|
||||
$value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
if ($parse_value)
|
||||
{
|
||||
$value = $this->parseFieldTags($value);
|
||||
}
|
||||
|
||||
if (!empty($format_string) && (!$format_if_not_empty || ($format_if_not_empty && !empty($this->value))))
|
||||
{
|
||||
$format_string = $this->parseFieldTags($format_string);
|
||||
$value = sprintf($format_string, $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
|
||||
// Create the HTML
|
||||
$html = '<span class="' . $class . '">';
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '<a href="' . $link_url . '">';
|
||||
}
|
||||
|
||||
$html .= $value;
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace string with tags that reference fields
|
||||
*
|
||||
* @param string $text Text to process
|
||||
*
|
||||
* @return string Text with tags replace
|
||||
*/
|
||||
protected function parseFieldTags($text)
|
||||
{
|
||||
$ret = $text;
|
||||
|
||||
// Replace [ITEM:ID] in the URL with the item's key value (usually:
|
||||
// the auto-incrementing numeric ID)
|
||||
$keyfield = $this->item->getKeyName();
|
||||
$replace = $this->item->$keyfield;
|
||||
$ret = str_replace('[ITEM:ID]', $replace, $ret);
|
||||
|
||||
// Replace the [ITEMID] in the URL with the current Itemid parameter
|
||||
$ret = str_replace('[ITEMID]', JFactory::getApplication()->input->getInt('Itemid', 0), $ret);
|
||||
|
||||
// Replace other field variables in the URL
|
||||
$fields = $this->item->getTableFields();
|
||||
|
||||
foreach ($fields as $fielddata)
|
||||
{
|
||||
$fieldname = $fielddata->Field;
|
||||
|
||||
if (empty($fieldname))
|
||||
{
|
||||
$fieldname = $fielddata->column_name;
|
||||
}
|
||||
|
||||
$search = '[ITEM:' . strtoupper($fieldname) . ']';
|
||||
$replace = $this->item->$fieldname;
|
||||
$ret = str_replace($search, $replace, $ret);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
97
libraries/f0f/form/field/textarea.php
Normal file
97
libraries/f0f/form/field/textarea.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('textarea');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a text area
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldTextarea extends JFormFieldTextarea implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
return '<div id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(nl2br($this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getStatic();
|
||||
}
|
||||
}
|
||||
110
libraries/f0f/form/field/timezone.php
Normal file
110
libraries/f0f/form/field/timezone.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('timezone');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Supports a generic list of options.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldTimezone extends JFormFieldTimezone implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
$selected = F0FFormFieldGroupedlist::getOptionName($this->getOptions(), $this->value);
|
||||
|
||||
if (is_null($selected))
|
||||
{
|
||||
$selected = array(
|
||||
'group' => '',
|
||||
'item' => ''
|
||||
);
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '-group" class="fof-groupedlist-group ' . $class . '>' .
|
||||
htmlspecialchars($selected['group'], ENT_COMPAT, 'UTF-8') .
|
||||
'</span>' .
|
||||
'<span id="' . $this->id . '-item" class="fof-groupedlist-item ' . $class . '>' .
|
||||
htmlspecialchars($selected['item'], ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
return $this->getStatic();
|
||||
}
|
||||
}
|
||||
67
libraries/f0f/form/field/title.php
Normal file
67
libraries/f0f/form/field/title.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('text');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a title field with an optional slug display below it.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldTitle extends F0FFormFieldText implements F0FFormField
|
||||
{
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
// Initialise
|
||||
$slug_format = '(%s)';
|
||||
$slug_class = 'small';
|
||||
|
||||
// Get field parameters
|
||||
if ($this->element['slug_field'])
|
||||
{
|
||||
$slug_field = (string) $this->element['slug_field'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$slug_field = $this->item->getColumnAlias('slug');
|
||||
}
|
||||
|
||||
if ($this->element['slug_format'])
|
||||
{
|
||||
$slug_format = (string) $this->element['slug_format'];
|
||||
}
|
||||
|
||||
if ($this->element['slug_class'])
|
||||
{
|
||||
$slug_class = (string) $this->element['slug_class'];
|
||||
}
|
||||
|
||||
// Get the regular display
|
||||
$html = parent::getRepeatable();
|
||||
|
||||
$slug = $this->item->$slug_field;
|
||||
|
||||
$html .= '<br />' . '<span class="' . $slug_class . '">';
|
||||
$html .= JText::sprintf($slug_format, $slug);
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
165
libraries/f0f/form/field/url.php
Normal file
165
libraries/f0f/form/field/url.php
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('url');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* Supports a URL text field.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldUrl extends JFormFieldUrl implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
$dolink = $this->element['show_link'] == 'true';
|
||||
$empty_replacement = '';
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
if (!empty($empty_replacement) && empty($this->value))
|
||||
{
|
||||
$this->value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
$innerHtml = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
if ($dolink)
|
||||
{
|
||||
$innerHtml = '<a href="' . $innerHtml . '">' .
|
||||
$innerHtml . '</a>';
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
$innerHtml .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
// Initialise
|
||||
$class = $this->id;
|
||||
$show_link = false;
|
||||
$empty_replacement = '';
|
||||
|
||||
$link_url = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
// Get field parameters
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$class .= ' ' . (string) $this->element['class'];
|
||||
}
|
||||
|
||||
if ($this->element['show_link'] == 'true')
|
||||
{
|
||||
$show_link = true;
|
||||
}
|
||||
|
||||
if ($this->element['empty_replacement'])
|
||||
{
|
||||
$empty_replacement = (string) $this->element['empty_replacement'];
|
||||
}
|
||||
|
||||
// Get the (optionally formatted) value
|
||||
if (!empty($empty_replacement) && empty($this->value))
|
||||
{
|
||||
$this->value = JText::_($empty_replacement);
|
||||
}
|
||||
|
||||
$value = htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8');
|
||||
|
||||
// Create the HTML
|
||||
$html = '<span class="' . $class . '">';
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '<a href="' . $link_url . '">';
|
||||
}
|
||||
|
||||
$html .= $value;
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
$html .= '</span>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
349
libraries/f0f/form/field/user.php
Normal file
349
libraries/f0f/form/field/user.php
Normal file
@ -0,0 +1,349 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('user');
|
||||
|
||||
/**
|
||||
* Form Field class for the F0F framework
|
||||
* A user selection box / display field
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldUser extends JFormFieldUser implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
// Initialise
|
||||
$show_username = true;
|
||||
$show_email = false;
|
||||
$show_name = false;
|
||||
$show_id = false;
|
||||
$class = '';
|
||||
|
||||
// Get the field parameters
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$class = ' class="' . (string) $this->element['class'] . '"';
|
||||
}
|
||||
|
||||
if ($this->element['show_username'] == 'false')
|
||||
{
|
||||
$show_username = false;
|
||||
}
|
||||
|
||||
if ($this->element['show_email'] == 'true')
|
||||
{
|
||||
$show_email = true;
|
||||
}
|
||||
|
||||
if ($this->element['show_name'] == 'true')
|
||||
{
|
||||
$show_name = true;
|
||||
}
|
||||
|
||||
if ($this->element['show_id'] == 'true')
|
||||
{
|
||||
$show_id = true;
|
||||
}
|
||||
|
||||
// Get the user record
|
||||
$user = JFactory::getUser($this->value);
|
||||
|
||||
// Render the HTML
|
||||
$html = '<div id="' . $this->id . '" ' . $class . '>';
|
||||
|
||||
if ($show_username)
|
||||
{
|
||||
$html .= '<span class="fof-userfield-username">' . $user->username . '</span>';
|
||||
}
|
||||
|
||||
if ($show_id)
|
||||
{
|
||||
$html .= '<span class="fof-userfield-id">' . $user->id . '</span>';
|
||||
}
|
||||
|
||||
if ($show_name)
|
||||
{
|
||||
$html .= '<span class="fof-userfield-name">' . $user->name . '</span>';
|
||||
}
|
||||
|
||||
if ($show_email)
|
||||
{
|
||||
$html .= '<span class="fof-userfield-email">' . $user->email . '</span>';
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
// Initialise
|
||||
$show_username = true;
|
||||
$show_email = true;
|
||||
$show_name = true;
|
||||
$show_id = true;
|
||||
$show_avatar = true;
|
||||
$show_link = false;
|
||||
$link_url = null;
|
||||
$avatar_method = 'gravatar';
|
||||
$avatar_size = 64;
|
||||
$class = '';
|
||||
|
||||
// Get the user record
|
||||
$user = JFactory::getUser($this->value);
|
||||
|
||||
// Get the field parameters
|
||||
if ($this->element['class'])
|
||||
{
|
||||
$class = ' class="' . (string) $this->element['class'] . '"';
|
||||
}
|
||||
|
||||
if ($this->element['show_username'] == 'false')
|
||||
{
|
||||
$show_username = false;
|
||||
}
|
||||
|
||||
if ($this->element['show_email'] == 'false')
|
||||
{
|
||||
$show_email = false;
|
||||
}
|
||||
|
||||
if ($this->element['show_name'] == 'false')
|
||||
{
|
||||
$show_name = false;
|
||||
}
|
||||
|
||||
if ($this->element['show_id'] == 'false')
|
||||
{
|
||||
$show_id = false;
|
||||
}
|
||||
|
||||
if ($this->element['show_avatar'] == 'false')
|
||||
{
|
||||
$show_avatar = false;
|
||||
}
|
||||
|
||||
if ($this->element['avatar_method'])
|
||||
{
|
||||
$avatar_method = strtolower($this->element['avatar_method']);
|
||||
}
|
||||
|
||||
if ($this->element['avatar_size'])
|
||||
{
|
||||
$avatar_size = $this->element['avatar_size'];
|
||||
}
|
||||
|
||||
if ($this->element['show_link'] == 'true')
|
||||
{
|
||||
$show_link = true;
|
||||
}
|
||||
|
||||
if ($this->element['link_url'])
|
||||
{
|
||||
$link_url = $this->element['link_url'];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (F0FPlatform::getInstance()->isBackend())
|
||||
{
|
||||
// If no link is defined in the back-end, assume the user edit
|
||||
// link in the User Manager component
|
||||
$link_url = 'index.php?option=com_users&task=user.edit&id=[USER:ID]';
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no link is defined in the front-end, we can't create a
|
||||
// default link. Therefore, show no link.
|
||||
$show_link = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Post-process the link URL
|
||||
if ($show_link)
|
||||
{
|
||||
$replacements = array(
|
||||
'[USER:ID]' => $user->id,
|
||||
'[USER:USERNAME]' => $user->username,
|
||||
'[USER:EMAIL]' => $user->email,
|
||||
'[USER:NAME]' => $user->name,
|
||||
);
|
||||
|
||||
foreach ($replacements as $key => $value)
|
||||
{
|
||||
$link_url = str_replace($key, $value, $link_url);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the avatar image, if necessary
|
||||
if ($show_avatar)
|
||||
{
|
||||
$avatar_url = '';
|
||||
|
||||
if ($avatar_method == 'plugin')
|
||||
{
|
||||
// Use the user plugins to get an avatar
|
||||
F0FPlatform::getInstance()->importPlugin('user');
|
||||
$jResponse = F0FPlatform::getInstance()->runPlugins('onUserAvatar', array($user, $avatar_size));
|
||||
|
||||
if (!empty($jResponse))
|
||||
{
|
||||
foreach ($jResponse as $response)
|
||||
{
|
||||
if ($response)
|
||||
{
|
||||
$avatar_url = $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($avatar_url))
|
||||
{
|
||||
$show_avatar = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back to the Gravatar method
|
||||
$md5 = md5($user->email);
|
||||
|
||||
if (F0FPlatform::getInstance()->isCli())
|
||||
{
|
||||
$scheme = 'http';
|
||||
}
|
||||
else
|
||||
{
|
||||
$scheme = JURI::getInstance()->getScheme();
|
||||
}
|
||||
|
||||
if ($scheme == 'http')
|
||||
{
|
||||
$avatar_url = 'http://www.gravatar.com/avatar/' . $md5 . '.jpg?s='
|
||||
. $avatar_size . '&d=mm';
|
||||
}
|
||||
else
|
||||
{
|
||||
$avatar_url = 'https://secure.gravatar.com/avatar/' . $md5 . '.jpg?s='
|
||||
. $avatar_size . '&d=mm';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the HTML
|
||||
$html = '<div id="' . $this->id . '" ' . $class . '>';
|
||||
|
||||
if ($show_avatar)
|
||||
{
|
||||
$html .= '<img src="' . $avatar_url . '" align="left" class="fof-usersfield-avatar" />';
|
||||
}
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '<a href="' . $link_url . '">';
|
||||
}
|
||||
|
||||
if ($show_username)
|
||||
{
|
||||
$html .= '<span class="fof-usersfield-username">' . $user->username
|
||||
. '</span>';
|
||||
}
|
||||
|
||||
if ($show_id)
|
||||
{
|
||||
$html .= '<span class="fof-usersfield-id">' . $user->id
|
||||
. '</span>';
|
||||
}
|
||||
|
||||
if ($show_name)
|
||||
{
|
||||
$html .= '<span class="fof-usersfield-name">' . $user->name
|
||||
. '</span>';
|
||||
}
|
||||
|
||||
if ($show_email)
|
||||
{
|
||||
$html .= '<span class="fof-usersfield-email">' . $user->email
|
||||
. '</span>';
|
||||
}
|
||||
|
||||
if ($show_link)
|
||||
{
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
143
libraries/f0f/form/field/usergroup.php
Normal file
143
libraries/f0f/form/field/usergroup.php
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
JFormHelper::loadFieldClass('usergroup');
|
||||
|
||||
/**
|
||||
* Form Field class for F0F
|
||||
* Joomla! user groups
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FFormFieldUsergroup extends JFormFieldUsergroup implements F0FFormField
|
||||
{
|
||||
protected $static;
|
||||
|
||||
protected $repeatable;
|
||||
|
||||
/** @var int A monotonically increasing number, denoting the row number in a repeatable view */
|
||||
public $rowid;
|
||||
|
||||
/** @var F0FTable The item being rendered in a repeatable form field */
|
||||
public $item;
|
||||
|
||||
/**
|
||||
* Method to get certain otherwise inaccessible properties from the form field object.
|
||||
*
|
||||
* @param string $name The property name for which to the the value.
|
||||
*
|
||||
* @return mixed The property value or null.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
switch ($name)
|
||||
{
|
||||
case 'static':
|
||||
if (empty($this->static))
|
||||
{
|
||||
$this->static = $this->getStatic();
|
||||
}
|
||||
|
||||
return $this->static;
|
||||
break;
|
||||
|
||||
case 'repeatable':
|
||||
if (empty($this->repeatable))
|
||||
{
|
||||
$this->repeatable = $this->getRepeatable();
|
||||
}
|
||||
|
||||
return $this->repeatable;
|
||||
break;
|
||||
|
||||
default:
|
||||
return parent::__get($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for static display, e.g. in a single
|
||||
* item view (typically a "read" task).
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getStatic()
|
||||
{
|
||||
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
|
||||
|
||||
$params = $this->getOptions();
|
||||
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select('a.id AS value, a.title AS text');
|
||||
$query->from('#__usergroups AS a');
|
||||
$query->group('a.id, a.title');
|
||||
$query->order('a.id ASC');
|
||||
$query->order($query->qn('title') . ' ASC');
|
||||
|
||||
// Get the options.
|
||||
$db->setQuery($query);
|
||||
$options = $db->loadObjectList();
|
||||
|
||||
// If params is an array, push these options to the array
|
||||
if (is_array($params))
|
||||
{
|
||||
$options = array_merge($params, $options);
|
||||
}
|
||||
|
||||
// If all levels is allowed, push it into the array.
|
||||
elseif ($params)
|
||||
{
|
||||
array_unshift($options, JHtml::_('select.option', '', JText::_('JOPTION_ACCESS_SHOW_ALL_LEVELS')));
|
||||
}
|
||||
|
||||
return '<span id="' . $this->id . '" ' . $class . '>' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($options, $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rendering of this field type for a repeatable (grid) display,
|
||||
* e.g. in a view listing many item (typically a "browse" task)
|
||||
*
|
||||
* @since 2.0
|
||||
*
|
||||
* @return string The field HTML
|
||||
*/
|
||||
public function getRepeatable()
|
||||
{
|
||||
$class = $this->element['class'] ? (string) $this->element['class'] : '';
|
||||
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select('a.id AS value, a.title AS text');
|
||||
$query->from('#__usergroups AS a');
|
||||
$query->group('a.id, a.title');
|
||||
$query->order('a.id ASC');
|
||||
$query->order($query->qn('title') . ' ASC');
|
||||
|
||||
// Get the options.
|
||||
$db->setQuery($query);
|
||||
$options = $db->loadObjectList();
|
||||
|
||||
|
||||
return '<span class="' . $this->id . ' ' . $class . '">' .
|
||||
htmlspecialchars(F0FFormFieldList::getOptionName($options, $this->value), ENT_COMPAT, 'UTF-8') .
|
||||
'</span>';
|
||||
}
|
||||
}
|
||||
659
libraries/f0f/form/form.php
Normal file
659
libraries/f0f/form/form.php
Normal file
@ -0,0 +1,659 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage form
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
// Protect from unauthorized access
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
if (version_compare(JVERSION, '2.5.0', 'lt'))
|
||||
{
|
||||
jimport('joomla.form.form');
|
||||
jimport('joomla.form.formfield');
|
||||
jimport('joomla.form.formrule');
|
||||
}
|
||||
|
||||
/**
|
||||
* F0FForm is an extension to JForm which support not only edit views but also
|
||||
* browse (record list) and read (single record display) views based on XML
|
||||
* forms.
|
||||
*
|
||||
* @package FrameworkOnFramework
|
||||
* @since 2.0
|
||||
*/
|
||||
class F0FForm extends JForm
|
||||
{
|
||||
/**
|
||||
* The model attached to this view
|
||||
*
|
||||
* @var F0FModel
|
||||
*/
|
||||
protected $model;
|
||||
|
||||
/**
|
||||
* The view used to render this form
|
||||
*
|
||||
* @var F0FView
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* Method to get an instance of a form.
|
||||
*
|
||||
* @param string $name The name of the form.
|
||||
* @param string $data The name of an XML file or string to load as the form definition.
|
||||
* @param array $options An array of form options.
|
||||
* @param bool $replace Flag to toggle whether form fields should be replaced if a field
|
||||
* already exists with the same group/name.
|
||||
* @param bool|string $xpath An optional xpath to search for the fields.
|
||||
*
|
||||
* @return object F0FForm instance.
|
||||
*
|
||||
* @since 2.0
|
||||
* @throws InvalidArgumentException if no data provided.
|
||||
* @throws RuntimeException if the form could not be loaded.
|
||||
*/
|
||||
public static function getInstance($name, $data = null, $options = array(), $replace = true, $xpath = false)
|
||||
{
|
||||
// Reference to array with form instances
|
||||
$forms = &self::$forms;
|
||||
|
||||
// Only instantiate the form if it does not already exist.
|
||||
if (!isset($forms[$name]))
|
||||
{
|
||||
$data = trim($data);
|
||||
|
||||
if (empty($data))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('F0FForm::getInstance(name, *%s*)', gettype($data)));
|
||||
}
|
||||
|
||||
// Instantiate the form.
|
||||
$forms[$name] = new F0FForm($name, $options);
|
||||
|
||||
// Load the data.
|
||||
if (substr(trim($data), 0, 1) == '<')
|
||||
{
|
||||
if ($forms[$name]->load($data, $replace, $xpath) == false)
|
||||
{
|
||||
throw new RuntimeException('F0FForm::getInstance could not load form');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($forms[$name]->loadFile($data, $replace, $xpath) == false)
|
||||
{
|
||||
throw new RuntimeException('F0FForm::getInstance could not load file ' . $data . '.xml');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $forms[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of an attribute of the form itself
|
||||
*
|
||||
* @param string $attribute The name of the attribute
|
||||
* @param mixed $default Optional default value to return
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function getAttribute($attribute, $default = null)
|
||||
{
|
||||
$value = $this->xml->attributes()->$attribute;
|
||||
|
||||
if (is_null($value))
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (string) $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the CSS files defined in the form, based on its cssfiles attribute
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function loadCSSFiles()
|
||||
{
|
||||
// Support for CSS files
|
||||
$cssfiles = $this->getAttribute('cssfiles');
|
||||
|
||||
if (!empty($cssfiles))
|
||||
{
|
||||
$cssfiles = explode(',', $cssfiles);
|
||||
|
||||
foreach ($cssfiles as $cssfile)
|
||||
{
|
||||
F0FTemplateUtils::addCSS(trim($cssfile));
|
||||
}
|
||||
}
|
||||
|
||||
// Support for LESS files
|
||||
$lessfiles = $this->getAttribute('lessfiles');
|
||||
|
||||
if (!empty($lessfiles))
|
||||
{
|
||||
$lessfiles = explode(',', $lessfiles);
|
||||
|
||||
foreach ($lessfiles as $def)
|
||||
{
|
||||
$parts = explode('||', $def, 2);
|
||||
$lessfile = $parts[0];
|
||||
$alt = (count($parts) > 1) ? trim($parts[1]) : null;
|
||||
F0FTemplateUtils::addLESS(trim($lessfile), $alt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the Javascript files defined in the form, based on its jsfiles attribute
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function loadJSFiles()
|
||||
{
|
||||
$jsfiles = $this->getAttribute('jsfiles');
|
||||
|
||||
if (empty($jsfiles))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$jsfiles = explode(',', $jsfiles);
|
||||
|
||||
foreach ($jsfiles as $jsfile)
|
||||
{
|
||||
F0FTemplateUtils::addJS(trim($jsfile));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the protected $data object, allowing direct
|
||||
* access to and manipulation of the form's data.
|
||||
*
|
||||
* @return JRegistry The form's data registry
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a F0FModel to this form
|
||||
*
|
||||
* @param F0FModel &$model The model to attach to the form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setModel(F0FModel &$model)
|
||||
{
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the F0FModel attached to this form
|
||||
*
|
||||
* @return F0FModel
|
||||
*/
|
||||
public function &getModel()
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a F0FView to this form
|
||||
*
|
||||
* @param F0FView &$view The view to attach to the form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setView(F0FView &$view)
|
||||
{
|
||||
$this->view = $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the F0FView attached to this form
|
||||
*
|
||||
* @return F0FView
|
||||
*/
|
||||
public function &getView()
|
||||
{
|
||||
return $this->view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an array of F0FFormHeader objects in the headerset.
|
||||
*
|
||||
* @return array The array of F0FFormHeader objects in the headerset.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function getHeaderset()
|
||||
{
|
||||
$fields = array();
|
||||
|
||||
$elements = $this->findHeadersByGroup();
|
||||
|
||||
// If no field elements were found return empty.
|
||||
|
||||
if (empty($elements))
|
||||
{
|
||||
return $fields;
|
||||
}
|
||||
|
||||
// Build the result array from the found field elements.
|
||||
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
// Get the field groups for the element.
|
||||
$attrs = $element->xpath('ancestor::headers[@name]/@name');
|
||||
$groups = array_map('strval', $attrs ? $attrs : array());
|
||||
$group = implode('.', $groups);
|
||||
|
||||
// If the field is successfully loaded add it to the result array.
|
||||
if ($field = $this->loadHeader($element, $group))
|
||||
{
|
||||
$fields[$field->id] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get an array of <header /> elements from the form XML document which are
|
||||
* in a control group by name.
|
||||
*
|
||||
* @param mixed $group The optional dot-separated form group path on which to find the fields.
|
||||
* Null will return all fields. False will return fields not in a group.
|
||||
* @param boolean $nested True to also include fields in nested groups that are inside of the
|
||||
* group for which to find fields.
|
||||
*
|
||||
* @return mixed Boolean false on error or array of SimpleXMLElement objects.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
protected function &findHeadersByGroup($group = null, $nested = false)
|
||||
{
|
||||
$false = false;
|
||||
$fields = array();
|
||||
|
||||
// Make sure there is a valid JForm XML document.
|
||||
if (!($this->xml instanceof SimpleXMLElement))
|
||||
{
|
||||
return $false;
|
||||
}
|
||||
|
||||
// Get only fields in a specific group?
|
||||
if ($group)
|
||||
{
|
||||
// Get the fields elements for a given group.
|
||||
$elements = &$this->findHeader($group);
|
||||
|
||||
// Get all of the field elements for the fields elements.
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
// If there are field elements add them to the return result.
|
||||
if ($tmp = $element->xpath('descendant::header'))
|
||||
{
|
||||
// If we also want fields in nested groups then just merge the arrays.
|
||||
if ($nested)
|
||||
{
|
||||
$fields = array_merge($fields, $tmp);
|
||||
}
|
||||
|
||||
// If we want to exclude nested groups then we need to check each field.
|
||||
else
|
||||
{
|
||||
$groupNames = explode('.', $group);
|
||||
|
||||
foreach ($tmp as $field)
|
||||
{
|
||||
// Get the names of the groups that the field is in.
|
||||
$attrs = $field->xpath('ancestor::headers[@name]/@name');
|
||||
$names = array_map('strval', $attrs ? $attrs : array());
|
||||
|
||||
// If the field is in the specific group then add it to the return list.
|
||||
if ($names == (array) $groupNames)
|
||||
{
|
||||
$fields = array_merge($fields, array($field));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($group === false)
|
||||
{
|
||||
// Get only field elements not in a group.
|
||||
$fields = $this->xml->xpath('descendant::headers[not(@name)]/header | descendant::headers[not(@name)]/headerset/header ');
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get an array of all the <header /> elements.
|
||||
$fields = $this->xml->xpath('//header');
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a header field represented as a F0FFormHeader object.
|
||||
*
|
||||
* @param string $name The name of the header field.
|
||||
* @param string $group The optional dot-separated form group path on which to find the field.
|
||||
* @param mixed $value The optional value to use as the default for the field.
|
||||
*
|
||||
* @return mixed The F0FFormHeader object for the field or boolean false on error.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public function getHeader($name, $group = null, $value = null)
|
||||
{
|
||||
// Make sure there is a valid F0FForm XML document.
|
||||
if (!($this->xml instanceof SimpleXMLElement))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to find the field by name and group.
|
||||
$element = $this->findHeader($name, $group);
|
||||
|
||||
// If the field element was not found return false.
|
||||
if (!$element)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->loadHeader($element, $group, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get a header field represented as an XML element object.
|
||||
*
|
||||
* @param string $name The name of the form field.
|
||||
* @param string $group The optional dot-separated form group path on which to find the field.
|
||||
*
|
||||
* @return mixed The XML element object for the field or boolean false on error.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
protected function findHeader($name, $group = null)
|
||||
{
|
||||
$element = false;
|
||||
$fields = array();
|
||||
|
||||
// Make sure there is a valid JForm XML document.
|
||||
if (!($this->xml instanceof SimpleXMLElement))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let's get the appropriate field element based on the method arguments.
|
||||
if ($group)
|
||||
{
|
||||
// Get the fields elements for a given group.
|
||||
$elements = &$this->findGroup($group);
|
||||
|
||||
// Get all of the field elements with the correct name for the fields elements.
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
// If there are matching field elements add them to the fields array.
|
||||
if ($tmp = $element->xpath('descendant::header[@name="' . $name . '"]'))
|
||||
{
|
||||
$fields = array_merge($fields, $tmp);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure something was found.
|
||||
if (!$fields)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use the first correct match in the given group.
|
||||
$groupNames = explode('.', $group);
|
||||
|
||||
foreach ($fields as &$field)
|
||||
{
|
||||
// Get the group names as strings for ancestor fields elements.
|
||||
$attrs = $field->xpath('ancestor::headerfields[@name]/@name');
|
||||
$names = array_map('strval', $attrs ? $attrs : array());
|
||||
|
||||
// If the field is in the exact group use it and break out of the loop.
|
||||
if ($names == (array) $groupNames)
|
||||
{
|
||||
$element = &$field;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get an array of fields with the correct name.
|
||||
$fields = $this->xml->xpath('//header[@name="' . $name . '"]');
|
||||
|
||||
// Make sure something was found.
|
||||
if (!$fields)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search through the fields for the right one.
|
||||
foreach ($fields as &$field)
|
||||
{
|
||||
// If we find an ancestor fields element with a group name then it isn't what we want.
|
||||
if ($field->xpath('ancestor::headerfields[@name]'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Found it!
|
||||
else
|
||||
{
|
||||
$element = &$field;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to load, setup and return a F0FFormHeader object based on field data.
|
||||
*
|
||||
* @param string $element The XML element object representation of the form field.
|
||||
* @param string $group The optional dot-separated form group path on which to find the field.
|
||||
* @param mixed $value The optional value to use as the default for the field.
|
||||
*
|
||||
* @return mixed The F0FFormHeader object for the field or boolean false on error.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
protected function loadHeader($element, $group = null, $value = null)
|
||||
{
|
||||
// Make sure there is a valid SimpleXMLElement.
|
||||
if (!($element instanceof SimpleXMLElement))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the field type.
|
||||
$type = $element['type'] ? (string) $element['type'] : 'field';
|
||||
|
||||
// Load the JFormField object for the field.
|
||||
$field = $this->loadHeaderType($type);
|
||||
|
||||
// If the object could not be loaded, get a text field object.
|
||||
if ($field === false)
|
||||
{
|
||||
$field = $this->loadHeaderType('field');
|
||||
}
|
||||
|
||||
// Setup the F0FFormHeader object.
|
||||
$field->setForm($this);
|
||||
|
||||
if ($field->setup($element, $value, $group))
|
||||
{
|
||||
return $field;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to remove a header from the form definition.
|
||||
*
|
||||
* @param string $name The name of the form field for which remove.
|
||||
* @param string $group The optional dot-separated form group path on which to find the field.
|
||||
*
|
||||
* @return boolean True on success, false otherwise.
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function removeHeader($name, $group = null)
|
||||
{
|
||||
// Make sure there is a valid JForm XML document.
|
||||
if (!($this->xml instanceof SimpleXMLElement))
|
||||
{
|
||||
throw new UnexpectedValueException(sprintf('%s::getFieldAttribute `xml` is not an instance of SimpleXMLElement', get_class($this)));
|
||||
}
|
||||
|
||||
// Find the form field element from the definition.
|
||||
$element = $this->findHeader($name, $group);
|
||||
|
||||
// If the element exists remove it from the form definition.
|
||||
if ($element instanceof SimpleXMLElement)
|
||||
{
|
||||
$dom = dom_import_simplexml($element);
|
||||
$dom->parentNode->removeChild($dom);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for {@link F0FFormHelper::loadFieldType()}.
|
||||
*
|
||||
* @param string $type The field type.
|
||||
* @param boolean $new Flag to toggle whether we should get a new instance of the object.
|
||||
*
|
||||
* @return mixed F0FFormField object on success, false otherwise.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
protected function loadFieldType($type, $new = true)
|
||||
{
|
||||
return F0FFormHelper::loadFieldType($type, $new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for {@link F0FFormHelper::loadHeaderType()}.
|
||||
*
|
||||
* @param string $type The field type.
|
||||
* @param boolean $new Flag to toggle whether we should get a new instance of the object.
|
||||
*
|
||||
* @return mixed F0FFormHeader object on success, false otherwise.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
protected function loadHeaderType($type, $new = true)
|
||||
{
|
||||
return F0FFormHelper::loadHeaderType($type, $new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for {@link F0FFormHelper::loadRuleType()}.
|
||||
*
|
||||
* @param string $type The rule type.
|
||||
* @param boolean $new Flag to toggle whether we should get a new instance of the object.
|
||||
*
|
||||
* @return mixed JFormRule object on success, false otherwise.
|
||||
*
|
||||
* @see F0FFormHelper::loadRuleType()
|
||||
* @since 2.0
|
||||
*/
|
||||
protected function loadRuleType($type, $new = true)
|
||||
{
|
||||
return F0FFormHelper::loadRuleType($type, $new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for {@link F0FFormHelper::addFieldPath()}.
|
||||
*
|
||||
* @param mixed $new A path or array of paths to add.
|
||||
*
|
||||
* @return array The list of paths that have been added.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function addFieldPath($new = null)
|
||||
{
|
||||
return F0FFormHelper::addFieldPath($new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for {@link F0FFormHelper::addHeaderPath()}.
|
||||
*
|
||||
* @param mixed $new A path or array of paths to add.
|
||||
*
|
||||
* @return array The list of paths that have been added.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function addHeaderPath($new = null)
|
||||
{
|
||||
return F0FFormHelper::addHeaderPath($new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for F0FFormHelper::addFormPath().
|
||||
*
|
||||
* @param mixed $new A path or array of paths to add.
|
||||
*
|
||||
* @return array The list of paths that have been added.
|
||||
*
|
||||
* @see F0FFormHelper::addFormPath()
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function addFormPath($new = null)
|
||||
{
|
||||
return F0FFormHelper::addFormPath($new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy for F0FFormHelper::addRulePath().
|
||||
*
|
||||
* @param mixed $new A path or array of paths to add.
|
||||
*
|
||||
* @return array The list of paths that have been added.
|
||||
*
|
||||
* @see F0FFormHelper::addRulePath()
|
||||
* @since 2.0
|
||||
*/
|
||||
public static function addRulePath($new = null)
|
||||
{
|
||||
return F0FFormHelper::addRulePath($new);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user