29
0
mirror of https://github.com/joomla/joomla-cms.git synced 2024-08-26 13:09:46 +00:00

[#31844] Rapid Application Framework (Joomla! RAD) (Fix #1911)

This commit is contained in:
Nicholas K. Dionysopoulos 2013-09-05 16:39:33 -05:00 committed by Michael Babker
parent 14e99a0176
commit f236dab9e1
150 changed files with 38130 additions and 12 deletions

View File

@ -102,6 +102,7 @@ class JoomlaInstallerScript
$extensions[] = array('library', 'phputf8', '', 0);
$extensions[] = array('library', 'joomla', '', 0);
$extensions[] = array('library', 'idna_convert', '', 0);
$extensions[] = array('library', 'fof', '', 0);
// Modules site
// Site

View File

@ -16,8 +16,8 @@ CREATE TABLE IF NOT EXISTS `#__ucm_history` (
INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES
(30, 'com_contenthistory', 'component', 'com_contenthistory', '', 1, 1, 1, 0, '{"name":"com_contenthistory","type":"component","creationDate":"May 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved.\\n\\t","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_CONTENTHISTORY_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0),
(31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 1, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0);
(31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 1, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0),
(105, 'FOF', 'library', 'lib_fof', '', 0, 1, 1, 1, '{"legacy":false,"name":"FOF","type":"library","creationDate":"2013-09-03","author":"Nicholas K. Dionysopoulos \/ Akeeba Ltd","copyright":"(C)2011-2013 Nicholas K. Dionysopoulos","authorEmail":"nicholas@akeebabackup.com","authorUrl":"https:\/\/www.akeebabackup.com","version":"2.1.rc2","description":"Framework-on-Framework (FOF) - A rapid component development framework for Joomla!","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0);
ALTER TABLE `#__content_types` ADD COLUMN `content_history_options` VARCHAR(5120) NOT NULL COMMENT 'JSON string for com_contenthistory options';
@ -26,3 +26,9 @@ UPDATE `#__content_types` SET `content_history_options` = '{"form_file":"adminis
UPDATE `#__content_types` SET `content_history_options` = '{"form_file":"administrator\/components\/com_contact\/models\/forms\/contact.xml", "hide_fields":["default_con","checked_out","checked_out_time","version","xreference"], "display_lookup":[{"source_column":"created_by","target_table":"#__users","target_column":"id","display_column":"name"}, {"source_column":"catid","target_table":"#__categories","target_column":"id","display_column":"title"}, {"source_column":"modified_by","target_table":"#__users","target_column":"id","display_column":"name"}, {"source_column":"access","target_table":"#__viewlevels","target_column":"id","display_column":"title"},{"source_column":"user_id","target_table":"#__users","target_column":"id","display_column":"name"}]}' WHERE `type_alias` = 'com_contact.contact';
UPDATE `#__content_types` SET `content_history_options` = '{"form_file":"administrator\\/components\\/com_categories\\/models\\/forms\\/category.xml", "hide_fields":["asset_id","checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "display_lookup":[{"source_column":"created_user_id","target_table":"#__users","target_column":"id","display_column":"name"}, {"source_column":"access","target_table":"#__viewlevels","target_column":"id","display_column":"title"}, {"source_column":"modified_user_id","target_table":"#__users","target_column":"id","display_column":"name"},{"source_column":"parent_id","target_table":"#__categories","target_column":"id","display_column":"title"}]}' WHERE `type_alias` IN ('com_content.category', 'com_contact.category', 'com_newsfeeds.category', 'com_weblinks.category');
INSERT INTO `#__update_sites` (`name`, `type`, `location`, `enabled`, `last_check_timestamp`) VALUES
('FOF Updates (official releases)', 'extension', 'http://cdn.akeebabackup.com/updates/fof.xml', 1, 0);
INSERT INTO `#__update_sites_extensions` (`update_site_id`, `extension_id`) VALUES
(LAST_INSERT_ID(), 105);

View File

@ -1,2 +1,9 @@
INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES
(31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 0, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0);
(31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 0, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0),
(105, 'FOF', 'library', 'lib_fof', '', 0, 1, 1, 1, '{"legacy":false,"name":"FOF","type":"library","creationDate":"2013-09-03","author":"Nicholas K. Dionysopoulos \/ Akeeba Ltd","copyright":"(C)2011-2013 Nicholas K. Dionysopoulos","authorEmail":"nicholas@akeebabackup.com","authorUrl":"https:\/\/www.akeebabackup.com","version":"2.1.rc2","description":"Framework-on-Framework (FOF) - A rapid component development framework for Joomla!","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0);
INSERT INTO #__update_sites ("name", "type", "location", "enabled", "last_check_timestamp") VALUES
('FOF Updates (official releases)', 'extension', 'http://cdn.akeebabackup.com/updates/fof.xml', 1, 0);
INSERT INTO #__update_sites_extensions ("update_site_id", "extension_id") VALUES
(LASTVAL(), 105);

View File

@ -1,6 +1,14 @@
SET IDENTITY_INSERT #__extensions ON;
INSERT INTO #__extensions (extension_id, name, type, element, folder, client_id, enabled, access, protected, manifest_cache, params, custom_data, system_data, checked_out, checked_out_time, ordering, state)
SELECT 31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 0, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0;
SELECT 31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 0, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2013 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0
UNION ALL
SELECT 105, 'FOF', 'library', 'lib_fof', '', 0, 1, 1, 1, '{"legacy":false,"name":"FOF","type":"library","creationDate":"2013-09-03","author":"Nicholas K. Dionysopoulos \/ Akeeba Ltd","copyright":"(C)2011-2013 Nicholas K. Dionysopoulos","authorEmail":"nicholas@akeebabackup.com","authorUrl":"https:\/\/www.akeebabackup.com","version":"2.1.rc2","description":"Framework-on-Framework (FOF) - A rapid component development framework for Joomla!","group":""}', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0;
SET IDENTITY_INSERT #__extensions OFF;
INSERT INTO #__update_sites (name, type, location, enabled, last_check_timestamp) VALUES
('FOF Updates (official releases)', 'extension', 'http://cdn.akeebabackup.com/updates/fof.xml', 1, 0);
INSERT INTO #__update_sites_extensions (update_site_id, extension_id) VALUES
(SCOPE_IDENTITY(), 105);

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="library" version="2.5" method="upgrade">
<name>FOF</name>
<libraryname>fof</libraryname>
<description>Framework-on-Framework (FOF) - A rapid component development framework for Joomla!</description>
<creationDate>2013-09-03</creationDate>
<author>Nicholas K. Dionysopoulos / Akeeba Ltd</author>
<authorEmail>nicholas@akeebabackup.com</authorEmail>
<authorUrl>https://www.akeebabackup.com</authorUrl>
<copyright>(C)2011-2013 Nicholas K. Dionysopoulos</copyright>
<license>GNU GPLv2 or later</license>
<version>2.1.rc2</version>
<packager>Akeeba Ltd</packager>
<packagerurl>https://www.AkeebaBackup.com/download.html</packagerurl>
<files folder="fof">
<folder>autoloader</folder>
<folder>config</folder>
<folder>controller</folder>
<folder>dispatcher</folder>
<folder>encrypt</folder>
<folder>form</folder>
<folder>hal</folder>
<folder>inflector</folder>
<folder>input</folder>
<folder>less</folder>
<folder>model</folder>
<folder>platform</folder>
<folder>query</folder>
<folder>render</folder>
<folder>string</folder>
<folder>table</folder>
<folder>template</folder>
<folder>toolbar</folder>
<folder>view</folder>
<file>LICENSE.txt</file>
<file>include.php</file>
<file>index.html</file>
<file>version.txt</file>
</files>
<updateservers>
<server type="extension" priority="1" name="FOF Updates (official releases)">http://cdn.akeebabackup.com/updates/fof.xml</server>
</updateservers>
</extension>

View File

@ -25,6 +25,9 @@ $ -> Language fix or change
- -> Removed
! -> Note
05-Sep-2013 Michael Babker
+ [#31844] Rapid Application Framework (Joomla! RAD). Thanks Nicholas Dionysopoulos
03-Sep-2013 Michael Babker
+ [#31800] Add Joomla Ajax Interface to core. Thanks Matt Thomas
# [#31915] *Strict Standards: Only variables should be passed by reference when saving/deleting lang override. Thanks Jean-Marie Simonet

View File

@ -504,6 +504,7 @@ INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`
(102, 'phputf8', 'library', 'phputf8', '', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0),
(103, 'Joomla! Platform', 'library', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"Joomla! Platform","type":"library","creationDate":"2008","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2013 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"http:\\/\\/www.joomla.org","version":"13.1","description":"LIB_JOOMLA_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0),
(104, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0),
(105, 'FOF', 'library', 'lib_fof', '', 0, 1, 1, 1, '{"legacy":false,"name":"FOF","type":"library","creationDate":"2013-09-03","author":"Nicholas K. Dionysopoulos \/ Akeeba Ltd","copyright":"(C)2011-2013 Nicholas K. Dionysopoulos","authorEmail":"nicholas@akeebabackup.com","authorUrl":"https:\/\/www.akeebabackup.com","version":"2.1.rc2","description":"Framework-on-Framework (FOF) - A rapid component development framework for Joomla!","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0),
(200, 'mod_articles_archive', 'module', 'mod_articles_archive', '', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0),
(201, 'mod_articles_latest', 'module', 'mod_articles_latest', '', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0),
(202, 'mod_articles_popular', 'module', 'mod_articles_popular', '', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0),
@ -1725,7 +1726,8 @@ CREATE TABLE IF NOT EXISTS `#__update_sites` (
INSERT INTO `#__update_sites` (`update_site_id`, `name`, `type`, `location`, `enabled`, `last_check_timestamp`) VALUES
(1, 'Joomla Core', 'collection', 'http://update.joomla.org/core/list.xml', 1, 0),
(2, 'Joomla Extension Directory', 'collection', 'http://update.joomla.org/jed/list.xml', 1, 0),
(3, 'Accredited Joomla! Translations','collection','http://update.joomla.org/language/translationlist_3.xml', 1 ,0);
(3, 'Accredited Joomla! Translations','collection','http://update.joomla.org/language/translationlist_3.xml', 1 ,0),
(4, 'FOF Updates (official releases)','extension','http://cdn.akeebabackup.com/updates/fof.xml',1,0);
-- --------------------------------------------------------
@ -1746,7 +1748,8 @@ CREATE TABLE IF NOT EXISTS `#__update_sites_extensions` (
INSERT INTO `#__update_sites_extensions` (`update_site_id`, `extension_id`) VALUES
(1, 700),
(2, 700),
(3, 600);
(3, 600),
(4, 105);
-- --------------------------------------------------------

View File

@ -528,7 +528,8 @@ INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder"
(101, 'SimplePie', 'library', 'simplepie', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0),
(102, 'phputf8', 'library', 'phputf8', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0),
(103, 'Joomla! Platform', 'library', 'joomla', '', 0, 1, 1, 1, '{"legacy":false,"name":"Joomla! Platform","type":"library","creationDate":"2008","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2013 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"http:\\/\\/www.joomla.org","version":"13.1","description":"LIB_JOOMLA_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0),
(104, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0);
(104, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0),
(105, 'FOF', 'library', 'lib_fof', '', 0, 1, 1, 1, '{"legacy":false,"name":"FOF","type":"library","creationDate":"2013-09-03","author":"Nicholas K. Dionysopoulos \/ Akeeba Ltd","copyright":"(C)2011-2013 Nicholas K. Dionysopoulos","authorEmail":"nicholas@akeebabackup.com","authorUrl":"https:\/\/www.akeebabackup.com","version":"2.1.rc2","description":"Framework-on-Framework (FOF) - A rapid component development framework for Joomla!","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0);
-- Modules
-- Site
@ -2323,11 +2324,13 @@ COMMENT ON TABLE "#__update_sites" IS 'Update Sites';
--
INSERT INTO "#__update_sites" ("update_site_id", "name", "type", "location", "enabled", "last_check_timestamp") VALUES
(1, 'Joomla Core', 'collection', 'http://update.joomla.org/core/list.xml', 1, 0),
(2, 'Joomla Extension Directory', 'collection', 'http://update.joomla.org/jed/list.xml', 1, 0);
(2, 'Joomla Extension Directory', 'collection', 'http://update.joomla.org/jed/list.xml', 1, 0),
(3, 'Accredited Joomla! Translations','collection','http://update.joomla.org/language/translationlist_3.xml', 1 ,0),
(4, 'FOF Updates (official releases)','extension','http://cdn.akeebabackup.com/updates/fof.xml',1,0);
SELECT nextval('#__update_sites_update_site_id_seq');
SELECT setval('#__update_sites_update_site_id_seq', 3, false);
SELECT setval('#__update_sites_update_site_id_seq', 5, false);
--
@ -2346,7 +2349,9 @@ COMMENT ON TABLE "#__update_sites_extensions" IS 'Links extensions to update sit
--
INSERT INTO "#__update_sites_extensions" ("update_site_id", "extension_id") VALUES
(1, 700),
(2, 700);
(2, 700),
(3, 400),
(4, 105);
--

View File

@ -800,7 +800,9 @@ SELECT 102, 'phputf8', 'library', 'phputf8', '', 0, 1, 1, 1, '', '', '', '', 0,
UNION ALL
SELECT 103, 'Joomla! Platform', 'library', 'joomla', '', 0, 1, 1, 1, 'a:11:{s:6:"legacy";b:0;s:4:"name";s:16:"Joomla! Platform";s:4:"type";s:7:"library";s:12:"creationDate";s:4:"2008";s:6:"author";s:6:"Joomla";s:9:"copyright";s:67:"Copyright (C) 2005 - 2013 Open Source Matters. All rights reserved.";s:11:"authorEmail";s:16:"admin@joomla.org";s:9:"authorUrl";s:21:"http://www.joomla.org";s:7:"version";s:4:"13.1";s:11:"description";s:26:"LIB_JOOMLA_XML_DESCRIPTION";s:5:"group";s:0:"";}', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0
UNION ALL
SELECT 104, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0;
SELECT 104, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0
UNION ALL
SELECT 105, 'FOF', 'library', 'lib_fof', '', 0, 1, 1, 1, '{"legacy":false,"name":"FOF","type":"library","creationDate":"2013-09-03","author":"Nicholas K. Dionysopoulos \/ Akeeba Ltd","copyright":"(C)2011-2013 Nicholas K. Dionysopoulos","authorEmail":"nicholas@akeebabackup.com","authorUrl":"https:\/\/www.akeebabackup.com","version":"2.1.rc2","description":"Framework-on-Framework (FOF) - A rapid component development framework for Joomla!","group":""}', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0;
INSERT INTO #__extensions (extension_id, name, type, element, folder, client_id, enabled, access, protected, manifest_cache, params, custom_data, system_data, checked_out, checked_out_time, ordering, state)
SELECT 200, 'mod_articles_archive', 'module', 'mod_articles_archive', '', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0
@ -2651,6 +2653,7 @@ SET IDENTITY_INSERT #__update_sites ON;
INSERT INTO #__update_sites (update_site_id,name,type,location,enabled,last_check_timestamp) VALUES (1, 'Joomla Core', 'collection', 'http://update.joomla.org/core/list.xml', 1, 0);
INSERT INTO #__update_sites (update_site_id,name,type,location,enabled,last_check_timestamp) VALUES (2, 'Joomla Extension Directory', 'collection', 'http://update.joomla.org/jed/list.xml', 1, 0);
INSERT INTO #__update_sites (update_site_id,name,type,location,enabled,last_check_timestamp) VALUES (3, 'Accredited Joomla! Translations', 'collection', 'http://update.joomla.org/language/translationlist_3.xml', 1, 0);
INSERT INTO #__update_sites (update_site_id,name,type,location,enabled,last_check_timestamp) VALUES (4, 'FOF Updates (official releases)','extension','http://cdn.akeebabackup.com/updates/fof.xml',1,0);
SET IDENTITY_INSERT #__update_sites OFF;
@ -2685,7 +2688,9 @@ SELECT 1, 700
UNION ALL
SELECT 2, 700
UNION ALL
SELECT 3, 600;
SELECT 3, 600
UNION ALL
SELECT 4, 105;
/****** Object: Table [#__updates] ******/
SET QUOTED_IDENTIFIER ON;

347
libraries/fof/LICENSE.txt Normal file
View File

@ -0,0 +1,347 @@
================================================================================
Historical note
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On February 21st, 2013 FOF changed its license to GPLv2 or later (instead of v3
or later) so that it can be distributed with the Joomla! CMS without causing
licensing issues.
================================================================================
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.

View File

@ -0,0 +1,816 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage autoloader
* @copyright Copyright (c)2010-2012 Nicholas K. Dionysopoulos
* @license GNU General Public License version 2, or later
*/
defined('FOF_INCLUDED') or die();
/**
* An autoloader for FOF-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
* @since 2.1
*/
class FOFAutoloaderComponent
{
/**
* An instance of this autoloader
*
* @var FOFAutoloaderComponent
*/
public static $autoloader = null;
/**
* The path to the FOF root directory
*
* @var string
*/
public static $fofPath = null;
/**
* An array holding component names and their FOF-ness status
*
* @var array
*/
protected static $fofComponents = array();
/**
* Initialise this autoloader
*
* @return FOFAutoloaderComponent
*/
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 FOF-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 isFOFComponent($component)
{
if (!isset($fofComponents[$component]))
{
$componentPaths = FOFPlatform::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)
{
JLog::add(__METHOD__ . "() autoloading $class_name", JLog::DEBUG, 'fof');
static $isCli = null, $isAdmin = null;
if (is_null($isCli) && is_null($isAdmin))
{
list($isCli, $isAdmin) = FOFDispatcher::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 FOF 2.1 or later component?
if (!$this->isFOFComponent($component))
{
return;
}
// Get the alternate view and class name (opposite singular/plural name)
$alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
$alt_class = FOFInflector::camelize($component_raw . '_controller_' . $alt_view);
// Get the component's paths
$componentPaths = FOFPlatform::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 FOFController
elseif (!class_exists($class_name))
{
if ($view != 'default')
{
$defaultClass = FOFInflector::camelize($component_raw . '_controller_default');
$this->class_alias($defaultClass, $class_name);
}
else
{
$this->class_alias('FOFController', $class_name);
}
}
}
/**
* Autoload Models
*
* @param string $class_name The name of the class to load
*
* @return void
*/
public function autoload_fof_model($class_name)
{
JLog::add(__METHOD__ . "() autoloading $class_name", JLog::DEBUG, 'fof');
static $isCli = null, $isAdmin = null;
if (is_null($isCli) && is_null($isAdmin))
{
list($isCli, $isAdmin) = FOFDispatcher::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 FOF 2.1 or later component?
if (!$this->isFOFComponent($component))
{
return;
}
// Get the alternate view and class name (opposite singular/plural name)
$alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
$alt_class = FOFInflector::camelize($component_raw . '_model_' . $alt_view);
// Get the proper and alternate paths and file names
$componentPaths = FOFPlatform::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 FOFModel
elseif (!class_exists($class_name))
{
if ($view != 'default')
{
$defaultClass = FOFInflector::camelize($component_raw . '_model_default');
$this->class_alias($defaultClass, $class_name);
}
else
{
$this->class_alias('FOFModel', $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)
{
JLog::add(__METHOD__ . "() autoloading $class_name", JLog::DEBUG, 'fof');
static $isCli = null, $isAdmin = null;
if (is_null($isCli) && is_null($isAdmin))
{
list($isCli, $isAdmin) = FOFDispatcher::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 FOFInput;
$format = $input->getCmd('format', 'html', 'cmd');
}
// Is this an FOF 2.1 or later component?
if (!$this->isFOFComponent($component))
{
return;
}
// Get the alternate view and class name (opposite singular/plural name)
$alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
$alt_class = FOFInflector::camelize($component_raw . '_view_' . $alt_view);
// Get the proper and alternate paths and file names
$componentPaths = FOFPlatform::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 FOFModel
elseif (!class_exists($class_name))
{
if ($view != 'default')
{
$defaultClass = FOFInflector::camelize($component_raw . '_view_default');
$this->class_alias($defaultClass, $class_name);
}
else
{
if (!file_exists(self::$fofPath . '/view/' . $format . '.php'))
{
$default_class = 'FOFView';
}
else
{
$default_class = 'FOFView' . 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)
{
JLog::add(__METHOD__ . "() autoloading $class_name", JLog::DEBUG, 'fof');
static $isCli = null, $isAdmin = null;
if (is_null($isCli) && is_null($isAdmin))
{
list($isCli, $isAdmin) = FOFDispatcher::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 FOF 2.1 or later component?
if (!$this->isFOFComponent($component))
{
return;
}
// Get the alternate view and class name (opposite singular/plural name)
$alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
$alt_class = FOFInflector::camelize($component_raw . '_table_' . $alt_view);
// Get the proper and alternate paths and file names
$componentPaths = FOFPlatform::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 FOFModel
elseif (!class_exists($class_name))
{
if ($view != 'default')
{
$defaultClass = FOFInflector::camelize($component_raw . '_table_default');
$this->class_alias($defaultClass, $class_name);
}
else
{
$this->class_alias('FOFTable', $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)
{
JLog::add(__METHOD__ . "() autoloading $class_name", JLog::DEBUG, 'fof');
static $isCli = null, $isAdmin = null;
if (is_null($isCli) && is_null($isAdmin))
{
list($isCli, $isAdmin) = FOFDispatcher::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 FOF 2.1 or later component?
if (!$this->isFOFComponent($component))
{
return;
}
// Get the alternate view and class name (opposite singular/plural name)
$alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
$alt_class = FOFInflector::camelize($component_raw . '_helper_' . $alt_view);
// Get the proper and alternate paths and file names
$componentPaths = FOFPlatform::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)
{
JLog::add(__METHOD__ . "() autoloading $class_name", JLog::DEBUG, 'fof');
static $isCli = null, $isAdmin = null;
if (is_null($isCli) && is_null($isAdmin))
{
list($isCli, $isAdmin) = FOFDispatcher::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];
// Get the proper and alternate paths and file names
$file = "/components/$component/toolbar.php";
$path = ($isAdmin || $isCli) ? JPATH_ADMINISTRATOR : JPATH_SITE;
$altPath = ($isAdmin || $isCli) ? JPATH_SITE : JPATH_ADMINISTRATOR;
// 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 FOFToolbar
if (!class_exists($class_name))
{
$this->class_alias('FOFToolbar', $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)
{
JLog::add(__METHOD__ . "() autoloading $class_name", JLog::DEBUG, 'fof');
// @todo
}
}

View File

@ -0,0 +1,115 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage autoloader
* @copyright Copyright (c)2010-2012 Nicholas K. Dionysopoulos
* @license GNU General Public License version 2, or later
*/
defined('FOF_INCLUDED') or die();
/**
* The main class autoloader for FOF itself
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFAutoloaderFof
{
/**
* An instance of this autoloader
*
* @var FOFAutoloaderFof
*/
public static $autoloader = null;
/**
* The path to the FOF root directory
*
* @var string
*/
public static $fofPath = null;
/**
* Initialise this autoloader
*
* @return FOFAutoloaderFof
*/
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 FOF prefix
if (substr($class_name, 0, 3) != 'FOF')
{
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;
}
}
}
}

View File

@ -0,0 +1,74 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage config
* @copyright Copyright (c)2010-2012 Nicholas K. Dionysopoulos
* @license GNU General Public License version 2, or later
*/
defined('FOF_INCLUDED') or die();
/**
* Configuration parser for the dispatcher-specific settings
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFConfigDomainDispatcher implements FOFConfigDomainInterface
{
/**
* 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;
}
}
}

View File

@ -0,0 +1,41 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage config
* @copyright Copyright (c)2010-2012 Nicholas K. Dionysopoulos
* @license GNU General Public License version 2, or later
*/
defined('FOF_INCLUDED') or die();
/**
* The Interface of an FOFConfigDomain class. The methods are used to parse and
* privision sensible information to consumers. FOFConfigProvider acts as an
* adapter to the FOFConfigDomain classes.
*
* @package FrameworkOnFramework
* @since 2.1
*/
interface FOFConfigDomainInterface
{
/**
* 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);
}

View File

@ -0,0 +1,189 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage config
* @copyright Copyright (c)2010-2012 Nicholas K. Dionysopoulos
* @license GNU General Public License version 2, or later
*/
defined('FOF_INCLUDED') or die();
/**
* Configuration parser for the tables-specific settings
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFConfigDomainTables implements FOFConfigDomainInterface
{
/**
* 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();
$fieldData = $aTable->xpath('field');
if (!empty($fieldData))
{
foreach ($fieldData as $field)
{
$k = (string) $field['name'];
$ret['tables'][$key]['fields'][$k] = (string) $field;
}
}
}
}
/**
* 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 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 getBehaviors($table, &$configuration, $params, $default = '')
{
$behaviors = $default;
if (isset($configuration['tables']['*'])
&& isset($configuration['tables']['*']['behaviors'])
&& isset($configuration['tables']['*']['behaviors']))
{
$behaviors = (string) $configuration['tables']['*']['behaviors'];
}
if (isset($configuration['tables'][$table])
&& isset($configuration['tables'][$table]['behaviors'])
&& isset($configuration['tables'][$table]['behaviors']))
{
$behaviors = (string) $configuration['tables'][$table]['behaviors'];
}
return $behaviors;
}
}

View File

@ -0,0 +1,281 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage config
* @copyright Copyright (c)2010-2012 Nicholas K. Dionysopoulos
* @license GNU General Public License version 2, or later
*/
defined('FOF_INCLUDED') or die();
/**
* Configuration parser for the view-specific settings
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFConfigDomainViews implements FOFConfigDomainInterface
{
/**
* 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();
$toolBar = $aView->xpath('toolbar');
if (!empty($toolBar))
{
$toolbarAttributes = $toolBar[0]->attributes();
// If a toolbar title is specified, create a title element.
if (isset($toolbarAttributes['title']))
{
$ret['views'][$key]['toolbar']['title'] = array(
'value' => (string) $toolbarAttributes['title']
);
}
// Parse the toolbar buttons data
$toolbarData = $aView->xpath('toolbar/button');
if (!empty($toolbarData))
{
foreach ($toolbarData as $button)
{
$k = (string) $button['type'];
$ret['views'][$key]['toolbar'][$k] = current($button->attributes());
$ret['views'][$key]['toolbar'][$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']))
{
$toolbar = $configuration['views']['*']['toolbar'];
}
if (isset($configuration['views'][$view]) && isset($configuration['views'][$view]['toolbar']))
{
$toolbar = array_merge($toolbar, $configuration['views'][$view]['toolbar']);
}
if (empty($toolbar))
{
return $default;
}
return $toolbar;
}
}

View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1,212 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage config
* @copyright Copyright (c)2010-2012 Nicholas K. Dionysopoulos
* @license GNU General Public License version 2, or later
*/
defined('FOF_INCLUDED') or die();
/**
* Reads and parses the fof.xml file in the back-end of a FOF-powered component,
* provisioning the data to the rest of the FOF framework
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFConfigProvider
{
/**
* Cache of FOF 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 (FOFPlatform::getInstance()->isCli())
{
$order = array('cli', 'backend');
}
elseif (FOFPlatform::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 = 'FOFConfigDomain' . 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 = FOFPlatform::getInstance()->getComponentBaseDirs($component);
// Check that the path exists
JLoader::import('joomla.filesystem.folder');
$path = $componentPaths['admin'];
$path = JPath::check($path);
if (!JFolder::exists($path))
{
return $ret;
}
// Read the filename if it exists
$filename = $path . '/fof.xml';
JLoader::import('joomla.filesystem.file');
if (!JFile::exists($filename))
{
return $ret;
}
$data = JFile::read($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 = 'FOFConfigDomain' . 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))
{
JLoader::import('joomla.filesystem.folder');
$files = JFolder::files(__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;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1,734 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* FrameworkOnFramework dispatcher class
*
* FrameworkOnFramework is a set of classes whcih 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.Dispatcher
* @since 1.0
*/
class FOFDispatcher extends JObject
{
/** @var array Configuration variables */
protected $config = array();
/** @var FOFInput Input variables */
protected $input = array();
/** @var string The name of the default view, in case none is specified */
public $defaultView = 'cpanel';
// Variables for FOF's transparent user authentication. You can override them
// in your Dispatcher's __construct() method.
/** @var int The Time Step for the TOTP used in FOF'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 FOF knows about
*
* @return FOFDispatcher
*/
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 FOFDispatcher
*/
public static function &getTmpInstance($option = null, $view = null, $config = array())
{
if (array_key_exists('input', $config))
{
if ($config['input'] instanceof FOFInput)
{
$input = $config['input'];
}
else
{
if (!is_array($config['input']))
{
$config['input'] = (array) $config['input'];
}
$config['input'] = array_merge($_REQUEST, $config['input']);
$input = new FOFInput($config['input']);
}
}
else
{
$input = new FOFInput;
}
$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 = FOFPlatform::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']);
}
JLoader::import('joomla.filesystem.path');
$path = JPath::find(
$searchPaths, 'dispatcher.php'
);
if ($path)
{
require_once $path;
}
}
if (!class_exists($className))
{
$className = 'FOFDispatcher';
}
$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 FOFInput;
}
// 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 FOFConfigProvider;
$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);
}
/**
* The main code of the Dispatcher. It spawns the necessary controller and
* runs it.
*
* @return null|Exception
*/
public function dispatch()
{
if (!FOFPlatform::getInstance()->authorizeAdmin($this->input->getCmd('option', 'com_foobar')))
{
if (FOFPlatform::getInstance()->checkVersion(JVERSION, '3.0', 'ge'))
{
throw new Exception(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403);
}
else
{
return JError::raiseError('403', JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'));
}
}
$this->transparentAuthentication();
// Merge English and local translations
FOFPlatform::getInstance()->loadTranslations($this->component);
$canDispatch = true;
if (FOFPlatform::getInstance()->isCli())
{
$canDispatch = $canDispatch && $this->onBeforeDispatchCLI();
}
$canDispatch = $canDispatch && $this->onBeforeDispatch();
if (!$canDispatch)
{
JResponse::setHeader('Status', '403 Forbidden', true);
if (FOFPlatform::getInstance()->checkVersion(JVERSION, '3.0', 'ge'))
{
throw new Exception(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403);
}
else
{
return JError::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 = FOFInflector::singularize($view);
}
elseif (in_array($task, array('browse')))
{
$view = FOFInflector::pluralize($view);
}
$this->input->set('view', $view);
$this->input->set('task', $task);
$config = $this->config;
$config['input'] = $this->input;
$controller = FOFController::getTmpInstance($option, $view, $config);
$status = $controller->execute($task);
if (!$this->onAfterDispatch())
{
JResponse::setHeader('Status', '403 Forbidden', true);
if (FOFPlatform::getInstance()->checkVersion(JVERSION, '3.0', 'ge'))
{
throw new Exception(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403);
}
else
{
return JError::raiseError('403', JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'));
}
}
$format = $this->input->get('format', 'html', 'cmd');
$format = empty($format) ? 'html' : $format;
if ($format == 'html')
{
// In HTML views perform a redirection
if ($controller->redirect())
{
return;
}
}
else
{
// In non-HTML views just exit the application with the proper HTTP headers
if ($controller->hasRedirect())
{
$headers = JResponse::sendHeaders();
jexit();
}
}
}
/**
* 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 = FOFInflector::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') && FOFPlatform::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 = FOFPlatform::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)
{
return FOFPlatform::getInstance()->logoutUser();
}
return true;
}
/**
* Transparently authenticates a user
*
* @return void
*/
public function transparentAuthentication()
{
// Only run when there is no logged in user
if (!FOFPlatform::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 = FOFPlatform::getInstance()->loginUser($authInfo);
}
}
/**
* Decrypts a transparent authentication message using a TOTP
*
* @param string $encryptedData The encrypted data
*
* @return array The decrypted data
*/
private function _decryptWithTOTP($encryptedData)
{
if (empty($this->fofAuth_Key))
{
$this->_fofAuth_CryptoKey = null;
return null;
}
$totp = new FOFEncryptTotp($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 FOFEncryptAes($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
*
* @return string THe encryption key
*/
private function _createDecryptionKey($time = null)
{
$totp = new FOFEncryptTotp($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 = FOFPlatform::getInstance()->isCli();
$isAdmin = FOFPlatform::getInstance()->isBackend();
}
return array($isCLI, $isAdmin);
}
}

View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1,238 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* A simple implementation of AES-128, AES-192 and AES-256 encryption using the
* high performance mcrypt library.
*
* @package FrameworkOnFramework
* @since 1.0
*/
class FOFEncryptAES
{
/** @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;
}
}

View File

@ -0,0 +1,221 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* FOFEncryptBase32
*
* @package FrameworkOnFramework
* @since 1.0
*/
class FOFEncryptBase32
{
/**
* 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));
}
}

View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1,170 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') 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 FOFEncryptTotp
{
private $_passCodeLength = 6;
private $_pinModulo;
private $_secretLength = 10;
private $_timeStep = 30;
/**
* 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).
*/
public function __construct($timeStep = 30, $passCodeLength = 6, $secretLength = 10)
{
$this->_timeStep = $timeStep;
$this->_passCodeLength = $passCodeLength;
$this->_secretLength = $secretLength;
$this->_pinModulo = pow(10, $this->_passCodeLength);
}
/**
* 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) == $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);
$base32 = new FOFEncryptBase32;
$secret = $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 FOFEncryptBase32;
return $base32->encode($secret);
}
}

View File

@ -0,0 +1,37 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Generic interface that a FOF form field class must implement
*
* @package FrameworkOnFramework
* @since 2.0
*/
interface FOFFormField
{
/**
* 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();
}

View File

@ -0,0 +1,151 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldAccessLevel'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/accesslevel.php';
}
/**
* Form Field class for FOF
* Joomla! access levels
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldAccesslevel extends JFormFieldAccessLevel implements FOFFormField
{
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->static;
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 = JFactory::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(FOFFormFieldList::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 = JFactory::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(FOFFormFieldList::getOptionName($options, $this->value), ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,249 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldList'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/list.php';
}
/**
* Form Field class for FOF
* Supports a generic list of options.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldActions extends JFormFieldList implements FOFFormField
{
protected $static;
protected $repeatable;
/** @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->static;
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'] = FOFStringUtils::toBool($this->element['show_published']);
}
if (isset($this->element['show_unpublished']))
{
$config['unpublished'] = FOFStringUtils::toBool($this->element['show_unpublished']);
}
if (isset($this->element['show_archived']))
{
$config['archived'] = FOFStringUtils::toBool($this->element['show_archived']);
}
if (isset($this->element['show_trash']))
{
$config['trash'] = FOFStringUtils::toBool($this->element['show_trash']);
}
if (isset($this->element['show_all']))
{
$config['all'] = FOFStringUtils::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 FOFFormFieldPublished 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 FOFFormFieldPublished($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 FOFTable))
{
throw new Exception(__CLASS__ . ' needs a FOFTable 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 FOFFormFieldPublished 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;
}
}

View File

@ -0,0 +1,101 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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('text');
/**
* Form Field class for the FOF framework
* Supports a button input.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldButton extends FOFFormFieldText implements FOFFormField
{
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->static;
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 getInput()
{
$this->label = '';
$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'] . '"' : '';
$this->value = JText::_($text);
if ($icon)
{
$icon = '<span class="icon ' . $icon . '"></span>';
}
return '<button id="' . $this->id . '" class="btn ' . $class . '" ' .
$onclick . '>' .
$icon .
htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') .
'</button>';
}
/**
* Method to get the field title.
*
* @return string The field title.
*/
protected function getTitle()
{
return null;
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldCacheHandler'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/cachehandler.php';
}
/**
* Form Field class for FOF
* Joomla! cache handlers
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldCachehandler extends JFormFieldCacheHandler implements FOFFormField
{
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->static;
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(FOFFormFieldList::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(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,171 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldCalendar'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/calendar.php';
}
/**
* Form Field class for the FOF framework
* Supports a calendar / date field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldCalendar extends JFormFieldCalendar implements FOFFormField
{
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->static;
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()
{
// Initialize some field attributes.
$format = $this->element['format'] ? (string) $this->element['format'] : '%Y-%m-%d';
$class = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
// Get some system objects.
$config = JFactory::getConfig();
$user = JFactory::getUser();
// 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 = JFactory::getDate($this->value, 'UTC');
$date->setTimezone(new DateTimeZone($config->get('offset')));
// Transform the date string.
$this->value = $date->format('Y-m-d H:i:s', true, false);
}
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 = JFactory::getDate($this->value, 'UTC');
$date->setTimezone(new DateTimeZone($user->getParam('timezone', $config->get('offset'))));
// Transform the date string.
$this->value = $date->format('Y-m-d H:i:s', true, false);
}
break;
}
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()
{
// Initialize some field attributes.
$format = $this->element['format'] ? (string) $this->element['format'] : '%Y-%m-%d';
$class = $this->element['class'] ? (string) $this->element['class'] : '';
// Get some system objects.
$config = JFactory::getConfig();
$user = JFactory::getUser();
// 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 = JFactory::getDate($this->value, 'UTC');
$date->setTimezone(new DateTimeZone($config->get('offset')));
// Transform the date string.
$this->value = $date->format('Y-m-d H:i:s', true, false);
}
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 = JFactory::getDate($this->value, 'UTC');
$date->setTimezone(new DateTimeZone($user->getParam('timezone', $config->get('offset'))));
// Transform the date string.
$this->value = $date->format('Y-m-d H:i:s', true, false);
}
break;
}
return '<span class="' . $this->id . ' ' . $class . '">' .
htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,86 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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('text');
/**
* Form Field class for the FOF framework
* Supports a captcha field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldCaptcha extends JFormFieldCaptcha implements FOFFormField
{
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->static;
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();
}
}

View File

@ -0,0 +1,121 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldCheckbox'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/checkbox.php';
}
/**
* Form Field class for the FOF framework
* A single checkbox
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldCheckbox extends JFormFieldCheckbox implements FOFFormField
{
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->static;
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';
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 . ' />' .
'</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';
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 . ' />' .
'</span>';
}
}

View File

@ -0,0 +1,231 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2013 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;
if (!class_exists('JFormFieldList'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/list.php';
}
/**
* Form Field class for FOF
* Components installed on the site
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFFormFieldComponents extends JFormFieldList implements FOFFormField
{
protected $static;
protected $repeatable;
public $client_ids = null;
/**
* 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->static;
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(FOFFormFieldList::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(FOFFormFieldList::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 = JFactory::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)
{
// 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 = JFactory::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;
}
}

View File

@ -0,0 +1,96 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldEditor'))
{
if (!include_once JPATH_LIBRARIES . '/joomla/form/fields/editor.php')
{
require_once JPATH_LIBRARIES . '/cms/form/field/editor.php';
}
}
/**
* Form Field class for the FOF framework
* An editarea field for content creation and formatted HTML display
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldEditor extends JFormFieldEditor implements FOFFormField
{
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->static;
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>';
}
}

View File

@ -0,0 +1,169 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldEMail'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/email.php';
}
/**
* Form Field class for the FOF framework
* Supports a one line text field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldEmail extends JFormFieldEMail implements FOFFormField
{
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->static;
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;
}
}

View File

@ -0,0 +1,181 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldGroupedList'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/groupedlist.php';
}
/**
* Form Field class for FOF
* Supports a generic list of options.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldGroupedlist extends JFormFieldGroupedList implements FOFFormField
{
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->static;
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->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()
{
$class = $this->element['class'] ? (string) $this->element['class'] : '';
$selected = self::getOptionName($this->getOptions(), $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 = FOFFormFieldList::getOptionName($data, $selected, $optKey, $optText);
if (!is_null($match))
{
$ret = array(
'group' => $label,
'item' => $match
);
break;
}
}
return $ret;
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldHidden'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/hidden.php';
}
/**
* Form Field class for the FOF framework
* A hidden field
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldHidden extends JFormFieldHidden implements FOFFormField
{
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->static;
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();
}
}

View File

@ -0,0 +1,19 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Form Field class for the FOF framework
* Media selection field. This is an alias of the "media" field type.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldImage extends FOFFormFieldMedia
{
}

View File

@ -0,0 +1,149 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldImagelist'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/imagelist.php';
}
/**
* Form Field class for the FOF framework
* Media selection field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldImagelist extends JFormFieldImageList implements FOFFormField
{
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->static;
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 = JURI::root() . '/' . $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();
}
}

View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1,97 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldInteger'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/integer.php';
}
/**
* Form Field class for the FOF framework
* Supports a one line text field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldInteger extends JFormFieldInteger implements FOFFormField
{
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->static;
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(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,118 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldLanguage'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/language.php';
}
/**
* Form Field class for FOF
* Available site languages
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldLanguage extends JFormFieldLanguage implements FOFFormField
{
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->static;
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(FOFFormFieldList::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(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,352 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldList'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/list.php';
}
/**
* Form Field class for FOF
* Supports a generic list of options.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldList extends JFormFieldList implements FOFFormField
{
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->static;
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 FOFTable))
{
// 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;
$link_url = str_replace('[ITEM:ID]', $replace, $link_url);
// Replace other field variables in the URL
$fields = $this->item->getFields();
foreach ($fields as $fielddata)
{
$fieldname = $fielddata->Field;
if (empty($fieldname))
{
$fieldname = $fielddata->column_name;
}
$search = '[ITEM:' . strtoupper($fieldname) . ']';
$replace = $this->item->$fieldname;
$link_url = str_replace($search, $replace, $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 FOF 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');
JArrayHelper::sortObjects($sortOptions, $order, $order_dir == 'asc' ? 1 : -1, $order_case_sensitive, false);
}
// Initialise the options
$options = array();
// 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;
if ($source_class && $source_method)
{
// Maybe we have to load a file?
if (!empty($source_file))
{
$source_file = FOFTemplateUtils::parsePath($source_file, true);
JLoader::import('joomla.filesystem.file');
if (JFile::exists($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
$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');
}
}
}
}
// 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;
}
reset($options);
return $options;
}
}

View File

@ -0,0 +1,146 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldMedia'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/media.php';
}
/**
* Form Field class for the FOF framework
* Media selection field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldMedia extends JFormFieldMedia implements FOFFormField
{
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->static;
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 = JURI::root() . $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();
}
}

View File

@ -0,0 +1,273 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldSql'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/sql.php';
}
/**
* Form Field class for FOF
* Generic list from a model's results
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldModel extends FOFFormFieldList implements FOFFormField
{
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->static;
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(FOFFormFieldList::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 FOFTable))
{
// 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;
$link_url = str_replace('[ITEM:ID]', $replace, $link_url);
// Replace other field variables in the URL
$fields = $this->item->getFields();
foreach ($fields as $fielddata)
{
$fieldname = $fielddata->Field;
if (empty($fieldname))
{
$fieldname = $fielddata->column_name;
}
$search = '[ITEM:' . strtoupper($fieldname) . ']';
$replace = $this->item->$fieldname;
$link_url = str_replace($search, $replace, $link_url);
}
}
else
{
$show_link = false;
}
if ($this->element['empty_replacement'])
{
$empty_replacement = (string) $this->element['empty_replacement'];
}
$value = FOFFormFieldList::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', JText::_($nonePlaceholder), null);
}
// Process field atrtibutes
$applyAccess = strtolower($applyAccess);
$applyAccess = in_array($applyAccess, array('yes', 'on', 'true', '1'));
// Explode model name into model name and prefix
$parts = FOFInflector::explode($modelName);
$mName = ucfirst(array_pop($parts));
$mPrefix = FOFInflector::implode($parts);
// Get the model object
$config = array('savestate' => 0);
$model = FOFModel::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;
}
}

View File

@ -0,0 +1,156 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Form Field class for FOF
* Renders the row ordering interface checkbox in browse views
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldOrdering extends JFormField implements FOFFormField
{
protected $static;
protected $repeatable;
/**
* A monotonically increasing number, denoting the row number in a repeatable view
*
* @var integer
*/
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->static;
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 FOFTable))
{
throw new Exception(__CLASS__ . ' needs a FOFTable to act upon');
}
$html = '';
$viewObject = $this->form->getView();
$ordering = $viewObject->getLists()->order == 'ordering';
if (!$viewObject->hasAjaxOrderingSupport())
{
// Ye olde Joomla! 2.5 method
$disabled = $ordering ? '' : 'disabled="disabled"';
$html .= '<span>';
$html .= $viewObject->pagination->orderUpIcon($this->rowid, true, 'orderup', 'Move Up', $ordering);
$html .= '</span><span>';
$html .= $viewObject->pagination->orderDownIcon($this->rowid, $viewObject->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" style="text-align: center" />';
}
else
{
// The modern drag'n'drop method
if ($viewObject->getPerms()->editstate)
{
$disableClassName = '';
$disabledLabel = '';
$hasAjaxOrderingSupport = $viewObject->hasAjaxOrderingSupport();
if (!$hasAjaxOrderingSupport['saveOrder'])
{
$disabledLabel = JText::_('JORDERINGDISABLED');
$disableClassName = 'inactive tip-top';
}
$html .= '<span class="sortable-handler ' . $disableClassName . '" title="' . $disabledLabel . '" rel="tooltip">';
$html .= '<i class="icon-menu"></i>';
$html .= '</span>';
$html .= '<input type="text" style="display:none" name="order[]" size="5"';
$html .= 'value="' . $this->value . '" class="input-mini text-area-order " />';
}
else
{
$html .= '<span class="sortable-handler inactive" >';
$html .= '<i class="icon-menu"></i>';
$html .= '</span>';
}
}
return $html;
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldPassword'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/password.php';
}
/**
* Form Field class for the FOF framework
* Supports a one line text field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldPassword extends JFormFieldPassword implements FOFFormField
{
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->static;
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(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldPlugins'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/plugins.php';
}
/**
* Form Field class for FOF
* Plugins installed on the site
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldPlugins extends JFormFieldPlugins implements FOFFormField
{
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->static;
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(FOFFormFieldList::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(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,188 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldList'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/list.php';
}
/**
* Form Field class for FOF
* Supports a generic list of options.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldPublished extends JFormFieldList implements FOFFormField
{
protected $static;
protected $repeatable;
/** @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->static;
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,
);
$stack = array();
if ($this->element['show_published'] == 'false')
{
$config['published'] = 0;
}
if ($this->element['show_unpublished'] == 'false')
{
$config['unpublished'] = 0;
}
if ($this->element['show_archived'] == 'true')
{
$config['archived'] = 1;
}
if ($this->element['show_trash'] == 'true')
{
$config['trash'] = 1;
}
if ($this->element['show_all'] == 'true')
{
$config['all'] = 1;
}
return JHtml::_('jgrid.publishedOptions', $config);
}
/**
* 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(FOFFormFieldList::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 FOFTable))
{
throw new Exception(__CLASS__ . ' needs a FOFTable 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);
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldRadio'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/radio.php';
}
/**
* Form Field class for FOF
* Radio selection list
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldRadio extends JFormFieldRadio implements FOFFormField
{
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->static;
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(FOFFormFieldList::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(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,81 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldRules'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/rules.php';
}
/**
* Form Field class for FOF
* Joomla! ACL Rules
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFFormFieldRules extends JFormFieldRules implements FOFFormField
{
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)
{
// 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 '';
}
}

View File

@ -0,0 +1,123 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Form Field class for FOF
* Renders the checkbox in browse views which allows you to select rows
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldSelectrow extends JFormField implements FOFFormField
{
protected $static;
protected $repeatable;
/**
* A monotonically increasing number, denoting the row number in a repeatable view
*
* @var integer
*/
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->static;
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 FOFTable))
{
throw new Exception(__CLASS__ . ' needs a FOFTable to act upon');
}
// Is this record checked out?
$checked_out = false;
$locked_by_field = $this->item->getColumnAlias('locked_by');
if (property_exists($this->item, $locked_by_field))
{
$locked_by = $this->item->$locked_by_field;
$checked_out = ($locked_by != 0);
}
// 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);
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldSessionHandler'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/sessionhandler.php';
}
/**
* Form Field class for FOF
* Joomla! session handlers
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldSessionhandler extends JFormFieldSessionHandler implements FOFFormField
{
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->static;
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(FOFFormFieldList::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(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,89 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldSpacer'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/spacer.php';
}
/**
* Form Field class for the FOF framework
* Spacer used between form elements
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldSpacer extends JFormFieldSpacer implements FOFFormField
{
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->static;
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();
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldSql'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/sql.php';
}
/**
* Form Field class for FOF
* Radio selection listGeneric list from an SQL statement
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldSql extends JFormFieldSql implements FOFFormField
{
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->static;
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(FOFFormFieldList::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(FOFFormFieldList::getOptionName($this->getOptions(), $this->value), ENT_COMPAT, 'UTF-8') .
'</span>';
}
}

View File

@ -0,0 +1,148 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldAccessLevel'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/accesslevel.php';
}
/**
* Form Field class for FOF
* Tag Fields
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFFormFieldTag extends JFormFieldTag implements FOFFormField
{
/**
* 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);
$name = (string) $this->element['name'];
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id AS value, a.path, a.title AS text, a.level, a.published')
->from('#__tags AS a')
->join('LEFT', $db->quoteName('#__tags') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt');
$item = $this->form->getModel()->getItem();
if ($item instanceof FOFTable)
{
// 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();
}
// Ajax tag only loads assigned values
if (!$this->isNested())
{
// Only item assigned values
$values = (array) $this->value;
JArrayHelper::toInteger($values);
$query->where('a.id IN (' . implode(',', $values) . ')');
}
// Filter language
if (!empty($this->element['language']))
{
$query->where('a.language = ' . $db->quote($this->element['language']));
}
$query->where($db->quoteName('a.alias') . ' <> ' . $db->quote('root'));
// 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))
{
JArrayHelper::toInteger($published);
$query->where('a.published IN (' . implode(',', $published) . ')');
}
$query->group('a.id, a.title, a.level, a.lft, a.rgt, a.parent_id, a.published, a.path')
->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()
{
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 '';
}
}

View File

@ -0,0 +1,161 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldTel'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/tel.php';
}
/**
* Form Field class for the FOF framework
* Supports a URL text field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldTel extends JFormFieldTel implements FOFFormField
{
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->static;
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;
}
}

View File

@ -0,0 +1,236 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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('text');
/**
* Form Field class for the FOF framework
* Supports a one line text field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldText extends JFormFieldText implements FOFFormField
{
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->static;
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 FOFTable))
{
$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 other field variables in the URL
$fields = $this->item->getFields();
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;
}
}

View File

@ -0,0 +1,93 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldTextarea'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/textarea.php';
}
/**
* Form Field class for the FOF framework
* Supports a text area
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldTextarea extends JFormFieldTextarea implements FOFFormField
{
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->static;
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();
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldTimezone'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/timezone.php';
}
/**
* Form Field class for FOF
* Supports a generic list of options.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldTimezone extends JFormFieldTimezone implements FOFFormField
{
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->static;
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 = FOFFormFieldGroupedlist::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();
}
}

View File

@ -0,0 +1,63 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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('text');
/**
* Form Field class for the FOF framework
* Supports a title field with an optional slug display below it.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldTitle extends FOFFormFieldText implements FOFFormField
{
/**
* 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_field = 'slug';
$slug_format = '(%s)';
$slug_class = 'small';
// Get field parameters
if ($this->element['slug_field'])
{
$slug_field = (string) $this->element['slug_field'];
}
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;
}
}

View File

@ -0,0 +1,161 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldUrl'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/url.php';
}
/**
* Form Field class for the FOF framework
* Supports a URL text field.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldUrl extends JFormFieldUrl implements FOFFormField
{
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->static;
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;
}
}

View File

@ -0,0 +1,345 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldUser'))
{
require_once JPATH_LIBRARIES . '/cms/form/field/user.php';
}
/**
* Form Field class for the FOF framework
* A user selection box / display field
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormFieldUser extends JFormFieldUser implements FOFFormField
{
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->static;
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 (FOFPlatform::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
FOFPlatform::getInstance()->importPlugin('user');
$jResponse = FOFPlatform::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 (FOFPlatform::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;
}
}

618
libraries/fof/form/form.php Normal file
View File

@ -0,0 +1,618 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* FOFForm 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 FOFForm extends JForm
{
/**
* The model attached to this view
*
* @var FOFModel
*/
protected $model;
/**
* The view used to render this form
*
* @var FOFView
*/
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 string $replace Flag to toggle whether form fields should be replaced if a field
* already exists with the same group/name.
* @param string $xpath An optional xpath to search for the fields.
*
* @return object FOFForm 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('FOFForm::getInstance(name, *%s*)', gettype($data)));
}
// Instantiate the form.
$forms[$name] = new FOFForm($name, $options);
// Load the data.
if (substr(trim($data), 0, 1) == '<')
{
if ($forms[$name]->load($data, $replace, $xpath) == false)
{
throw new RuntimeException('FOFForm::getInstance could not load form');
}
}
else
{
if ($forms[$name]->loadFile($data, $replace, $xpath) == false)
{
throw new RuntimeException('FOFForm::getInstance could not load file');
}
}
}
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)
{
FOFTemplateUtils::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;
FOFTemplateUtils::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)
{
FOFTemplateUtils::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 FOFModel to this form
*
* @param FOFModel &$model The model to attach to the form
*
* @return void
*/
public function setModel(FOFModel &$model)
{
$this->model = $model;
}
/**
* Returns the FOFModel attached to this form
*
* @return FOFModel
*/
public function &getModel()
{
return $this->model;
}
/**
* Attaches a FOFView to this form
*
* @param FOFView &$view The view to attach to the form
*
* @return void
*/
public function setView(FOFView &$view)
{
$this->view = $view;
}
/**
* Returns the FOFView attached to this form
*
* @return FOFView
*/
public function &getView()
{
return $this->view;
}
/**
* Method to get an array of FOFFormHeader objects in the headerset.
*
* @return array The array of FOFFormHeader 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 FOFFormHeader 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 FOFFormHeader 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 FOFForm 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 FOFFormHeader 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 FOFFormHeader 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 FOFFormHeader object.
$field->setForm($this);
if ($field->setup($element, $value, $group))
{
return $field;
}
else
{
return false;
}
}
/**
* Proxy for {@link FOFFormHelper::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 FOFFormField object on success, false otherwise.
*
* @since 2.0
*/
protected function loadFieldType($type, $new = true)
{
return FOFFormHelper::loadFieldType($type, $new);
}
/**
* Proxy for {@link FOFFormHelper::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 FOFFormHeader object on success, false otherwise.
*
* @since 2.0
*/
protected function loadHeaderType($type, $new = true)
{
return FOFFormHelper::loadHeaderType($type, $new);
}
/**
* Proxy for {@link FOFFormHelper::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 FOFFormHelper::loadRuleType()
* @since 2.0
*/
protected function loadRuleType($type, $new = true)
{
return FOFFormHelper::loadRuleType($type, $new);
}
/**
* Proxy for {@link FOFFormHelper::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 FOFFormHelper::addFieldPath($new);
}
/**
* Proxy for {@link FOFFormHelper::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 FOFFormHelper::addHeaderPath($new);
}
/**
* Proxy for FOFFormHelper::addFormPath().
*
* @param mixed $new A path or array of paths to add.
*
* @return array The list of paths that have been added.
*
* @see FOFFormHelper::addFormPath()
* @since 2.0
*/
public static function addFormPath($new = null)
{
return FOFFormHelper::addFormPath($new);
}
/**
* Proxy for FOFFormHelper::addRulePath().
*
* @param mixed $new A path or array of paths to add.
*
* @return array The list of paths that have been added.
*
* @see FOFFormHelper::addRulePath()
* @since 2.0
*/
public static function addRulePath($new = null)
{
return FOFFormHelper::addRulePath($new);
}
}

View File

@ -0,0 +1,578 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* An interface for FOFFormHeader fields, used to define the filters and the
* elements of the header row in repeatable (browse) views
*
* @package FrameworkOnFramework
* @since 2.0
*/
abstract class FOFFormHeader
{
/**
* The description text for the form field. Usually used in tooltips.
*
* @var string
* @since 2.0
*/
protected $description;
/**
* The SimpleXMLElement object of the <field /> XML element that describes the header field.
*
* @var SimpleXMLElement
* @since 2.0
*/
protected $element;
/**
* The FOFForm object of the form attached to the header field.
*
* @var FOFForm
* @since 2.0
*/
protected $form;
/**
* The label for the header field.
*
* @var string
* @since 2.0
*/
protected $label;
/**
* The header HTML.
*
* @var string|null
* @since 2.0
*/
protected $header;
/**
* The filter HTML.
*
* @var string|null
* @since 2.0
*/
protected $filter;
/**
* The buttons HTML.
*
* @var string|null
* @since 2.0
*/
protected $buttons;
/**
* The options for a drop-down filter.
*
* @var array|null
* @since 2.0
*/
protected $options;
/**
* The name of the form field.
*
* @var string
* @since 2.0
*/
protected $name;
/**
* The name of the field.
*
* @var string
* @since 2.0
*/
protected $fieldname;
/**
* The group of the field.
*
* @var string
* @since 2.0
*/
protected $group;
/**
* The form field type.
*
* @var string
* @since 2.0
*/
protected $type;
/**
* The value of the filter.
*
* @var mixed
* @since 2.0
*/
protected $value;
/**
* The intended table data width (in pixels or percent).
*
* @var mixed
* @since 2.0
*/
protected $tdwidth;
/**
* The key of the filter value in the model state.
*
* @var mixed
* @since 2.0
*/
protected $filterSource;
/**
* Is this a sortable column?
*
* @var bool
* @since 2.0
*/
protected $sortable = false;
/**
* Method to instantiate the form field object.
*
* @param FOFForm $form The form to attach to the form field object.
*
* @since 2.0
*/
public function __construct(FOFForm $form = null)
{
// If there is a form passed into the constructor set the form and form control properties.
if ($form instanceof FOFForm)
{
$this->form = $form;
}
}
/**
* 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 'description':
case 'name':
case 'type':
case 'fieldname':
case 'group':
case 'tdwidth':
return $this->$name;
break;
case 'label':
if (empty($this->label))
{
$this->label = $this->getLabel();
}
return $this->label;
case 'value':
if (empty($this->value))
{
$this->value = $this->getValue();
}
return $this->value;
break;
case 'header':
if (empty($this->header))
{
$this->header = $this->getHeader();
}
return $this->header;
break;
case 'filter':
if (empty($this->filter))
{
$this->filter = $this->getFilter();
}
return $this->filter;
break;
case 'buttons':
if (empty($this->buttons))
{
$this->buttons = $this->getButtons();
}
return $this->buttons;
break;
case 'options':
if (empty($this->options))
{
$this->options = $this->getOptions();
}
return $this->options;
break;
case 'sortable':
if (empty($this->sortable))
{
$this->sortable = $this->getSortable();
}
return $this->sortable;
break;
}
return null;
}
/**
* Method to attach a JForm object to the field.
*
* @param FOFForm $form The JForm object to attach to the form field.
*
* @return FOFFormHeader The form field object so that the method can be used in a chain.
*
* @since 2.0
*/
public function setForm(FOFForm $form)
{
$this->form = $form;
return $this;
}
/**
* Method to attach a FOFForm object to the field.
*
* @param SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object.
* @param mixed $value The form field value to validate.
* @param string $group The field name group control value. This acts as as an array container for the field.
* For example if the field has name="foo" and the group value is set to "bar" then the
* full field name would end up being "bar[foo]".
*
* @return boolean True on success.
*
* @since 2.0
*/
public function setup(SimpleXMLElement $element, $value, $group = null)
{
// Make sure there is a valid JFormField XML element.
if ((string) $element->getName() != 'header')
{
return false;
}
// Reset the internal fields
$this->label = null;
$this->header = null;
$this->filter = null;
$this->buttons = null;
$this->options = null;
$this->value = null;
$this->filterSource = null;
// Set the XML element object.
$this->element = $element;
// Get some important attributes from the form field element.
$class = (string) $element['class'];
$id = (string) $element['id'];
$name = (string) $element['name'];
$filterSource = (string) $element['filter_source'];
$tdwidth = (string) $element['tdwidth'];
// Set the field description text.
$this->description = (string) $element['description'];
// Set the group of the field.
$this->group = $group;
// Set the td width of the field.
$this->tdwidth = $tdwidth;
// Set the field name and id.
$this->fieldname = $this->getFieldName($name);
$this->name = $this->getName($this->fieldname);
$this->id = $this->getId($id, $this->fieldname);
$this->filterSource = $this->getFilterSource($filterSource);
// Set the field default value.
$this->value = $this->getValue();
return true;
}
/**
* Method to get the id used for the field input tag.
*
* @param string $fieldId The field element id.
* @param string $fieldName The field element name.
*
* @return string The id to be used for the field input tag.
*
* @since 2.0
*/
protected function getId($fieldId, $fieldName)
{
$id = '';
// If the field is in a group add the group control to the field id.
if ($this->group)
{
// If we already have an id segment add the group control as another level.
if ($id)
{
$id .= '_' . str_replace('.', '_', $this->group);
}
else
{
$id .= str_replace('.', '_', $this->group);
}
}
// If we already have an id segment add the field id/name as another level.
if ($id)
{
$id .= '_' . ($fieldId ? $fieldId : $fieldName);
}
else
{
$id .= ($fieldId ? $fieldId : $fieldName);
}
// Clean up any invalid characters.
$id = preg_replace('#\W#', '_', $id);
return $id;
}
/**
* Method to get the name used for the field input tag.
*
* @param string $fieldName The field element name.
*
* @return string The name to be used for the field input tag.
*
* @since 2.0
*/
protected function getName($fieldName)
{
$name = '';
// If the field is in a group add the group control to the field name.
if ($this->group)
{
// If we already have a name segment add the group control as another level.
$groups = explode('.', $this->group);
if ($name)
{
foreach ($groups as $group)
{
$name .= '[' . $group . ']';
}
}
else
{
$name .= array_shift($groups);
foreach ($groups as $group)
{
$name .= '[' . $group . ']';
}
}
}
// If we already have a name segment add the field name as another level.
if ($name)
{
$name .= '[' . $fieldName . ']';
}
else
{
$name .= $fieldName;
}
return $name;
}
/**
* Method to get the field name used.
*
* @param string $fieldName The field element name.
*
* @return string The field name
*
* @since 2.0
*/
protected function getFieldName($fieldName)
{
return $fieldName;
}
/**
* Method to get the field label.
*
* @return string The field label.
*
* @since 2.0
*/
protected function getLabel()
{
// Get the label text from the XML element, defaulting to the element name.
$title = $this->element['label'] ? (string) $this->element['label'] : '';
if (empty($title))
{
$view = $this->form->getView();
$params = $view->getViewOptionAndName();
$title = $params['option'] . '_' .
FOFInflector::pluralize($params['view']) . '_FIELD_' .
(string) $this->element['name'];
$title = strtoupper($title);
$result = JText::_($title);
if ($result === $title)
{
$title = ucfirst((string) $this->element['name']);
}
}
return $title;
}
/**
* Get the filter value for this header field
*
* @return mixed The filter value
*/
protected function getValue()
{
$model = $this->form->getModel();
return $model->getState($this->filterSource);
}
/**
* Return the key of the filter value in the model state or, if it's not set,
* the name of the field.
*
* @param string $filterSource The filter source value to return
*
* @return string
*/
protected function getFilterSource($filterSource)
{
if ($filterSource)
{
return $filterSource;
}
else
{
return $this->name;
}
}
/**
* Is this a sortable field?
*
* @return boolean True if it's sortable
*/
protected function getSortable()
{
$sortable = ($this->element['sortable'] != 'false');
if ($sortable)
{
if (empty($this->header))
{
$this->header = $this->getHeader();
}
$sortable = !empty($this->header);
}
return $sortable;
}
/**
* Returns the HTML for the header row, or null if this element should
* render no header element
*
* @return string|null HTML code or null if nothing is to be rendered
*
* @since 2.0
*/
protected function getHeader()
{
return null;
}
/**
* Returns the HTML for a text filter to be rendered in the filter row,
* or null if this element should render no text input filter.
*
* @return string|null HTML code or null if nothing is to be rendered
*
* @since 2.0
*/
protected function getFilter()
{
return null;
}
/**
* Returns the HTML for the buttons to be rendered in the filter row,
* next to the text input filter, or null if this element should render no
* text input filter buttons.
*
* @return string|null HTML code or null if nothing is to be rendered
*
* @since 2.0
*/
protected function getButtons()
{
return null;
}
/**
* Returns the JHtml options for a drop-down filter. Do not include an
* empty option, it is added automatically.
*
* @return array The JHtml options for a drop-down filter
*
* @since 2.0
*/
protected function getOptions()
{
return array();
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Access level field header
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderAccesslevel extends FOFFormHeaderFieldselectable
{
/**
* Method to get the list of access levels
*
* @return array A list of access levels.
*
* @since 2.0
*/
protected function getOptions()
{
$db = JFactory::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();
return $options;
}
}

View File

@ -0,0 +1,43 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Generic field header, without any filters
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderField extends FOFFormHeader
{
/**
* Get the header
*
* @return string The header HTML
*/
protected function getHeader()
{
$sortable = ($this->element['sortable'] != 'false');
$label = $this->getLabel();
if ($sortable)
{
$view = $this->form->getView();
return JHTML::_('grid.sort', $label, $this->name,
$view->getLists()->order_Dir, $view->getLists()->order,
$this->form->getModel()->task
);
}
else
{
return JText::_($label);
}
}
}

View File

@ -0,0 +1,126 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Generic field header, with text input (search) filter
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderFielddate extends FOFFormHeaderField
{
/**
* Get the filter field
*
* @return string The HTML
*/
protected function getFilter()
{
// Initialize some field attributes.
$format = $this->element['format'] ? (string) $this->element['format'] : '%Y-%m-%d';
$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['filterclass'])
{
$attributes['class'] = (string) $this->element['filterclass'];
}
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'];
}
else
{
$onchange = 'document.adminForm.submit()';
}
if ((string) $this->element['placeholder'])
{
$attributes['placeholder'] = JText::_((string) $this->element['placeholder']);
}
$name = $this->element['searchfieldname'] ? $this->element['searchfieldname'] : $this->name;
if ($this->element['searchfieldname'])
{
$model = $this->form->getModel();
$searchvalue = $model->getState((string) $this->element['searchfieldname']);
}
else
{
$searchvalue = $this->value;
}
// Get some system objects.
$config = JFactory::getConfig();
$user = JFactory::getUser();
// 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 = JFactory::getDate($searchvalue, 'UTC');
$date->setTimezone(new DateTimeZone($config->get('offset')));
// Transform the date string.
$searchvalue = $date->format('Y-m-d H:i:s', true, false);
}
break;
case 'USER_UTC':
// Convert a date to UTC based on the user timezone.
if ((int) $searchvalue)
{
// Get a date object based on the correct timezone.
$date = JFactory::getDate($this->value, 'UTC');
$date->setTimezone(new DateTimeZone($user->getParam('timezone', $config->get('offset'))));
// Transform the date string.
$searchvalue = $date->format('Y-m-d H:i:s', true, false);
}
break;
}
return JHtml::_('calendar', $searchvalue, $name, $name, $format, $attributes);
}
/**
* Get the buttons HTML code
*
* @return string The HTML
*/
protected function getButtons()
{
return '';
}
}

View File

@ -0,0 +1,84 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Generic field header, with text input (search) filter
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderFieldsearchable extends FOFFormHeaderField
{
/**
* Get the filter field
*
* @return string The HTML
*/
protected function getFilter()
{
// Initialize some field attributes.
$size = $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : '';
$maxLength = $this->element['maxlength'] ? ' maxlength="' . (int) $this->element['maxlength'] . '"' : '';
$filterclass = $this->element['filterclass'] ? ' class="' . (string) $this->element['filterclass'] . '"' : '';
$placeholder = $this->element['placeholder'] ? $this->element['placeholder'] : $this->getLabel();
$name = $this->element['searchfieldname'] ? $this->element['searchfieldname'] : $this->name;
$placeholder = 'placeholder="' . JText::_($placeholder) . '"';
if ($this->element['searchfieldname'])
{
$model = $this->form->getModel();
$searchvalue = $model->getState((string) $this->element['searchfieldname']);
}
else
{
$searchvalue = $this->value;
}
// Initialize JavaScript field attributes.
if ($this->element['onchange'])
{
$onchange = ' onchange="' . (string) $this->element['onchange'] . '"';
}
else
{
$onchange = ' onchange="document.adminForm.submit();"';
}
return '<input type="text" name="' . $name . '" id="' . $this->id . '"' . ' value="'
. htmlspecialchars($searchvalue, ENT_COMPAT, 'UTF-8') . '"' . $filterclass . $size . $placeholder . $onchange . $maxLength . '/>';
}
/**
* Get the buttons HTML code
*
* @return string The HTML
*/
protected function getButtons()
{
$buttonclass = $this->element['buttonclass'] ? ' class="' . (string) $this->element['buttonclass'] . '"' : '';
$buttonsState = strtolower($this->element['buttons']);
$show_buttons = !in_array($buttonsState, array('no', 'false', '0'));
if (!$show_buttons)
{
return '';
}
$html = '';
$html .= '<button ' . $buttonclass . ' onclick="this.form.submit();">' . "\n";
$html .= "\t" . JText::_('JSEARCH_FILTER') . "\n";
$html .= '</button>' . "\n";
$html .= '<button ' . $buttonclass . ' onclick="document.adminForm.' . $this->id . '.value=\'\';this.form.submit();">' . "\n";
$html .= "\t" . JText::_('JSEARCH_RESET') . "\n";
$html .= '</button>' . "\n";
return $html;
}
}

View File

@ -0,0 +1,102 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Generic field header, with drop down filters
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderFieldselectable extends FOFFormHeaderField
{
/**
* Create objects for the options
*
* @return array The array of option objects
*/
protected function getOptions()
{
$options = array();
// 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;
if ($source_class && $source_method)
{
// Maybe we have to load a file?
if (!empty($source_file))
{
$source_file = FOFTemplateUtils::parsePath($source_file, true);
JLoader::import('joomla.filesystem.file');
if (JFile::exists($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
$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');
}
}
}
}
// Get the field $options
foreach ($this->element->children() as $option)
{
// Only add <option /> elements.
if ($option->getName() != 'option')
{
continue;
}
// Create a new option object based on the <option /> element.
$options[] = JHtml::_(
'select.option',
(string) $option['value'],
JText::alt(
trim((string) $option),
preg_replace('/[^a-zA-Z0-9_\-]/', '_', $this->fieldname)
),
'value', 'text', ((string) $option['disabled'] == 'true')
);
}
reset($options);
return $options;
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Generic field header, with drop down filters based on a SQL query
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderFieldsql extends FOFFormHeaderFieldselectable
{
/**
* Create objects for the options
*
* @return array The array of 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;
$query = (string) $this->element['query'];
// Get the database object.
$db = JFactory::getDBO();
// Set the query and get the result list.
$db->setQuery($query);
$items = $db->loadObjectlist();
// 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;
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Generic filter, text box entry with optional buttons
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderFiltersearchable extends FOFFormHeaderFieldsearchable
{
/**
* Get the header
*
* @return string The header HTML
*/
protected function getHeader()
{
return '';
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Generic filter, drop-down based on fixed options
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderFilterselectable extends FOFFormHeaderFieldselectable
{
/**
* Get the header
*
* @return string The header HTML
*/
protected function getHeader()
{
return '';
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Generic filter, drop-down based on SQL query
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderFiltersql extends FOFFormHeaderFieldsql
{
/**
* Get the header
*
* @return string The header HTML
*/
protected function getHeader()
{
return '';
}
}

View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1,42 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Language field header
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderLanguage extends FOFFormHeaderFieldselectable
{
/**
* Method to get the filter options.
*
* @return array The filter option objects.
*
* @since 2.0
*/
protected function getOptions()
{
// Initialize some field attributes.
$client = (string) $this->element['client'];
if ($client != 'site' && $client != 'administrator')
{
$client = 'site';
}
// Merge any additional options in the XML definition.
$options = array_merge(
parent::getOptions(), JLanguageHelper::createLanguageList($this->value, constant('JPATH_' . strtoupper($client)), true, true)
);
return $options;
}
}

View File

@ -0,0 +1,103 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
if (!class_exists('JFormFieldSql'))
{
require_once JPATH_LIBRARIES . '/joomla/form/fields/sql.php';
}
/**
* Form Field class for FOF
* Generic list from a model's results
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderModel extends FOFFormHeaderFieldselectable
{
/**
* 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', JText::_($nonePlaceholder), null);
}
// Process field atrtibutes
$applyAccess = strtolower($applyAccess);
$applyAccess = in_array($applyAccess, array('yes', 'on', 'true', '1'));
// Explode model name into model name and prefix
$parts = FOFInflector::explode($modelName);
$mName = ucfirst(array_pop($parts));
$mPrefix = FOFInflector::implode($parts);
// Get the model object
$config = array('savestate' => 0);
$model = FOFModel::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;
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Ordering field header
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderOrdering extends FOFFormHeader
{
/**
* Get the header
*
* @return string The header HTML
*/
protected function getHeader()
{
$sortable = ($this->element['sortable'] != 'false');
$view = $this->form->getView();
$model = $this->form->getModel();
$hasAjaxOrderingSupport = $view->hasAjaxOrderingSupport();
if (!$sortable)
{
// Non sortable?! I'm not sure why you'd want that, but if you insist...
return JText::_('JGRID_HEADING_ORDERING');
}
if (!$hasAjaxOrderingSupport)
{
// Ye olde Joomla! 2.5 method
$html = JHTML::_('grid.sort', 'JFIELD_ORDERING_LABEL', 'ordering', $view->getLists()->order_Dir, $view->getLists()->order, 'browse');
$html .= JHTML::_('grid.order', $model->getList());
return $html;
}
else
{
// The new, drag'n'drop ordering support
return JHtml::_(
'grid.sort',
'<i class="icon-menu-2"></i>',
'ordering',
$view->getLists()->order_Dir,
$view->getLists()->order,
null,
'asc',
'JGRID_HEADING_ORDERING'
);
}
}
}

View File

@ -0,0 +1,66 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Field header for Published (enabled) columns
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderPublished extends FOFFormHeaderFieldselectable
{
/**
* Create objects for the options
*
* @return array The array of option objects
*/
protected function getOptions()
{
$config = array(
'published' => 1,
'unpublished' => 1,
'archived' => 0,
'trash' => 0,
'all' => 0,
);
$stack = array();
if ($this->element['show_published'] == 'false')
{
$config['published'] = 0;
}
if ($this->element['show_unpublished'] == 'false')
{
$config['unpublished'] = 0;
}
if ($this->element['show_archived'] == 'true')
{
$config['archived'] = 1;
}
if ($this->element['show_trash'] == 'true')
{
$config['trash'] = 1;
}
if ($this->element['show_all'] == 'true')
{
$config['all'] = 1;
}
$options = JHtml::_('jgrid.publishedOptions', $config);
reset($options);
return $options;
}
}

View File

@ -0,0 +1,29 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Row selection checkbox
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHeaderRowselect extends FOFFormHeader
{
/**
* Get the header
*
* @return string The header HTML
*/
protected function getHeader()
{
return '<input type="checkbox" name="checkall-toggle" value="" title="'
. JText::_('JGLOBAL_CHECK_ALL')
. '" onclick="Joomla.checkAll(this)" />';
}
}

View File

@ -0,0 +1,230 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
JLoader::import('joomla.form.helper');
/**
* FOFForm's helper class.
* Provides a storage for filesystem's paths where FOFForm's entities reside and
* methods for creating those entities. Also stores objects with entities'
* prototypes for further reusing.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFFormHelper extends JFormHelper
{
/**
* Method to load a form field object given a type.
*
* @param string $type The field type.
* @param boolean $new Flag to toggle whether we should get a new instance of the object.
*
* @return mixed JFormField object on success, false otherwise.
*
* @since 11.1
*/
public static function loadFieldType($type, $new = true)
{
return self::loadType('field', $type, $new);
}
/**
* Method to load a form field object given a type.
*
* @param string $type The field type.
* @param boolean $new Flag to toggle whether we should get a new instance of the object.
*
* @return mixed JFormField object on success, false otherwise.
*
* @since 11.1
*/
public static function loadHeaderType($type, $new = true)
{
return self::loadType('header', $type, $new);
}
/**
* Method to load a form entity object given a type.
* Each type is loaded only once and then used as a prototype for other objects of same type.
* Please, use this method only with those entities which support types (forms don't support them).
*
* @param string $entity The entity.
* @param string $type The entity type.
* @param boolean $new Flag to toggle whether we should get a new instance of the object.
*
* @return mixed Entity object on success, false otherwise.
*
* @since 11.1
*/
protected static function loadType($entity, $type, $new = true)
{
// Reference to an array with current entity's type instances
$types = &self::$entities[$entity];
$key = md5($type);
// Return an entity object if it already exists and we don't need a new one.
if (isset($types[$key]) && $new === false)
{
return $types[$key];
}
$class = self::loadClass($entity, $type);
if ($class !== false)
{
// Instantiate a new type object.
$types[$key] = new $class;
return $types[$key];
}
else
{
return false;
}
}
/**
* Attempt to import the JFormField class file if it isn't already imported.
* You can use this method outside of JForm for loading a field for inheritance or composition.
*
* @param string $type Type of a field whose class should be loaded.
*
* @return mixed Class name on success or false otherwise.
*
* @since 11.1
*/
public static function loadFieldClass($type)
{
return self::loadClass('field', $type);
}
/**
* Attempt to import the FOFFormHeader class file if it isn't already imported.
* You can use this method outside of JForm for loading a field for inheritance or composition.
*
* @param string $type Type of a field whose class should be loaded.
*
* @return mixed Class name on success or false otherwise.
*
* @since 11.1
*/
public static function loadHeaderClass($type)
{
return self::loadClass('header', $type);
}
/**
* Load a class for one of the form's entities of a particular type.
* Currently, it makes sense to use this method for the "field" and "rule" entities
* (but you can support more entities in your subclass).
*
* @param string $entity One of the form entities (field or rule).
* @param string $type Type of an entity.
*
* @return mixed Class name on success or false otherwise.
*
* @since 2.0
*/
public static function loadClass($entity, $type)
{
if (strpos($type, '.'))
{
list($prefix, $type) = explode('.', $type);
$altPrefix = $prefix;
}
else
{
$prefix = 'FOF';
$altPrefix = 'J';
}
$class = JString::ucfirst($prefix, '_') . 'Form' . JString::ucfirst($entity, '_') . JString::ucfirst($type, '_');
$altClass = JString::ucfirst($altPrefix, '_') . 'Form' . JString::ucfirst($entity, '_') . JString::ucfirst($type, '_');
if (class_exists($class))
{
return $class;
}
elseif (class_exists($altClass))
{
return $altClass;
}
// Get the field search path array.
$paths = self::addPath($entity);
// If the type is complex, add the base type to the paths.
if ($pos = strpos($type, '_'))
{
// Add the complex type prefix to the paths.
for ($i = 0, $n = count($paths); $i < $n; $i++)
{
// Derive the new path.
$path = $paths[$i] . '/' . strtolower(substr($type, 0, $pos));
// If the path does not exist, add it.
if (!in_array($path, $paths))
{
$paths[] = $path;
}
}
// Break off the end of the complex type.
$type = substr($type, $pos + 1);
}
// Try to find the class file.
$type = strtolower($type) . '.php';
foreach ($paths as $path)
{
if ($file = JPath::find($path, $type))
{
require_once $file;
if (class_exists($class))
{
break;
}
elseif (class_exists($altClass))
{
break;
}
}
}
// Check for all if the class exists.
if (class_exists($class))
{
return $class;
}
elseif (class_exists($altClass))
{
return $altClass;
}
else
{
return false;
}
}
/**
* Method to add a path to the list of header include paths.
*
* @param mixed $new A path or array of paths to add.
*
* @return array The list of paths that have been added.
*/
public static function addHeaderPath($new = null)
{
return self::addPath('header', $new);
}
}

View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1,229 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage hal
* @copyright Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Implementation of the Hypertext Application Language document in PHP. It can
* be used to provide hypermedia in a web service context.
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFHalDocument
{
/**
* The collection of links of this document
*
* @var FOFHalLinks
*/
private $_links = null;
/**
* The data (resource state or collection of resource state objects) of the
* document.
*
* @var array
*/
private $_data = null;
/**
* Embedded documents. This is an array of FOFHalDocument instances.
*
* @var array
*/
private $_embedded = array();
/**
* When $_data is an array we'll output the list of data under this key
* (JSON) or tag (XML)
*
* @var string
*/
private $_dataKey = '_list';
/**
* Public constructor
*
* @param mixed $data The data of the document (usually, the resource state)
*/
public function __construct($data = null)
{
$this->_data = $data;
$this->_links = new FOFHalLinks;
}
/**
* Add a link to the document
*
* @param string $rel The relation of the link to the document.
* See RFC 5988 http://tools.ietf.org/html/rfc5988#section-6.2.2 A document MUST always have
* a "self" link.
* @param FOFHalLink $link The actual link object
* @param boolean $overwrite When false and a link of $rel relation exists, an array of links is created. Otherwise the
* existing link is overwriten with the new one
*
* @see FOFHalLinks::addLink
*
* @return boolean True if the link was added to the collection
*/
public function addLink($rel, FOFHalLink $link, $overwrite = true)
{
return $this->_links->addLink($rel, $link, $overwrite);
}
/**
* Add links to the document
*
* @param string $rel The relation of the link to the document. See RFC 5988
* @param array $links An array of FOFHalLink objects
* @param boolean $overwrite When false and a link of $rel relation exists, an array of
* links is created. Otherwise the existing link is overwriten
* with the new one
*
* @see FOFHalLinks::addLinks
*
* @return boolean
*/
public function addLinks($rel, array $links, $overwrite = true)
{
return $this->_links->addLinks($rel, $links, $overwrite);
}
/**
* Add data to the document
*
* @param stdClass $data The data to add
* @param boolean $overwrite Should I overwrite existing data?
*
* @return void
*/
public function addData($data, $overwrite = true)
{
if (is_array($data))
{
$data = (object) $data;
}
if ($overwrite)
{
$this->_data = $data;
}
else
{
if (!is_array($this->_data))
{
$this->_data = array($this->_data);
}
$this->_data[] = $data;
}
}
/**
* Add an embedded document
*
* @param string $rel The relation of the embedded document to its container document
* @param FOFHalDocument $document The document to add
* @param boolean $overwrite Should I overwrite existing data with the same relation?
*
* @return boolean
*/
public function addEmbedded($rel, FOFHalDocument $document, $overwrite = true)
{
if (!array_key_exists($rel, $this->_embedded) || !$overwrite)
{
$this->_embedded[$rel] = $document;
}
elseif (array_key_exists($rel, $this->_embedded) && !$overwrite)
{
if (!is_array($this->_embedded[$rel]))
{
$this->_embedded[$rel] = array($this->_embedded[$rel]);
}
$this->_embedded[$rel][] = $document;
}
else
{
return false;
}
}
/**
* Returns the collection of links of this document
*
* @param string $rel The relation of the links to fetch. Skip to get all links.
*
* @return array
*/
public function getLinks($rel = null)
{
return $this->_links->getLinks($rel);
}
/**
* Returns the collection of embedded documents
*
* @param string $rel Optional; the relation to return the embedded documents for
*
* @return array|FOFHalDocument
*/
public function getEmbedded($rel = null)
{
if (empty($rel))
{
return $this->_embedded;
}
elseif (isset($this->_embedded[$rel]))
{
return $this->_embedded[$rel];
}
else
{
return array();
}
}
/**
* Return the data attached to this document
*
* @return array|stdClass
*/
public function getData()
{
return $this->_data;
}
/**
* Instantiate and call a suitable renderer class to render this document
* into the specified format.
*
* @param string $format The format to render the document into, e.g. 'json'
*
* @return string The rendered document
*
* @throws RuntimeException If the format is unknown, i.e. there is no suitable renderer
*/
public function render($format = 'json')
{
$class_name = 'FOFHalRender' . ucfirst($format);
if (!class_exists($class_name, true))
{
throw new RuntimeException("Unsupported HAL Document format '$format'. Render aborted.");
}
$renderer = new $class_name($this);
return $renderer->render(
array(
'data_key' => $this->_dataKey
)
);
}
}

137
libraries/fof/hal/link.php Normal file
View File

@ -0,0 +1,137 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage hal
* @copyright Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Implementation of the Hypertext Application Language link in PHP.
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFHalLink
{
/**
* For indicating the target URI. Corresponds with the Target IRI as
* defined in Web Linking (RFC 5988). This attribute MAY contain a URI
* Template (RFC6570) and in which case, SHOULD be complemented by an
* additional templated attribtue on the link with a boolean value true.
*
* @var string
*/
protected $_href = '';
/**
* This attribute SHOULD be present with a boolean value of true when the
* href of the link contains a URI Template (RFC6570).
*
* @var boolean
*/
protected $_templated = false;
/**
* For distinguishing between Resource and Link elements that share the
* same relation
*
* @var string
*/
protected $_name = null;
/**
* For indicating what the language of the result of dereferencing the link should be.
*
* @var string
*/
protected $_hreflang = null;
/**
* For labeling the destination of a link with a human-readable identifier.
*
* @var string
*/
protected $_title = null;
/**
* Public constructor of a FOFHalLink object
*
* @param string $href See $this->_href
* @param boolean $templated See $this->_templated
* @param string $name See $this->_name
* @param string $hreflang See $this->_hreflang
* @param string $title See $this->_title
*
* @throws RuntimeException If $href is empty
*/
public function __construct($href, $templated = false, $name = null, $hreflang = null, $title = null)
{
if (empty($href))
{
throw new RuntimeException('A HAL link must always have a non-empty href');
}
$this->_href = $href;
$this->_templated = $templated;
$this->_name = $name;
$this->_hreflang = $hreflang;
$this->_title = $title;
}
/**
* Is this a valid link? Checks the existence of required fields, not their
* values.
*
* @return boolean
*/
public function check()
{
return !empty($this->_href);
}
/**
* Magic getter for the protected properties
*
* @param string $name The name of the property to retrieve, sans the underscore
*
* @return mixed Null will always be returned if the property doesn't exist
*/
public function __get($name)
{
$property = '_' . $name;
if (property_exists($this, $property))
{
return $this->$property;
}
else
{
return null;
}
}
/**
* Magic setter for the protected properties
*
* @param string $name The name of the property to set, sans the underscore
* @param mixed $value The value of the property to set
*
* @return void
*/
public function __set($name, $value)
{
if (($name == 'href') && empty($value))
{
return;
}
$property = '_' . $name;
if (property_exists($this, $property))
{
$this->$property = $value;
}
}
}

114
libraries/fof/hal/links.php Normal file
View File

@ -0,0 +1,114 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage hal
* @copyright Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Implementation of the Hypertext Application Language links in PHP. This is
* actually a collection of links.
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFHalLinks
{
/**
* The collection of links, sorted by relation
*
* @var array
*/
private $_links = array();
/**
* Add a single link to the links collection
*
* @param string $rel The relation of the link to the document. See RFC 5988
* http://tools.ietf.org/html/rfc5988#section-6.2.2 A document
* MUST always have a "self" link.
* @param FOFHalLink $link The actual link object
* @param boolean $overwrite When false and a link of $rel relation exists, an array of
* links is created. Otherwise the existing link is overwriten
* with the new one
*
* @return boolean True if the link was added to the collection
*/
public function addLink($rel, FOFHalLink $link, $overwrite = true)
{
if (!$link->check())
{
return false;
}
if (!array_key_exists($rel, $this->_links) || !$overwrite)
{
$this->_links[$rel] = $link;
}
elseif (array_key_exists($rel, $this->_links) && !$overwrite)
{
if (!is_array($this->_links[$rel]))
{
$this->_links[$rel] = array($this->_links[$rel]);
}
$this->_links[$rel][] = $link;
}
else
{
return false;
}
}
/**
* Add multiple links to the links collection
*
* @param string $rel The relation of the links to the document. See RFC 5988.
* @param array $links An array of FOFHalLink objects
* @param boolean $overwrite When false and a link of $rel relation exists, an array
* of links is created. Otherwise the existing link is
* overwriten with the new one
*
* @return boolean True if the link was added to the collection
*/
public function addLinks($rel, array $links, $overwrite = true)
{
if (empty($links))
{
return false;
}
foreach ($links as $link)
{
if ($link instanceof FOFHalLink)
{
$this->addLink($rel, $link, $overwrite);
}
}
}
/**
* Returns the collection of links
*
* @param string $rel Optional; the relation to return the links for
*
* @return array|FOFHalLink
*/
public function getLinks($rel = null)
{
if (empty($rel))
{
return $this->_links;
}
elseif (isset($this->_links[$rel]))
{
return $this->_links[$rel];
}
else
{
return array();
}
}
}

View File

@ -0,0 +1,26 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage hal
* @copyright Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Interface for HAL document renderers
*
* @package FrameworkOnFramework
* @since 2.1
*/
interface FOFHalRenderInterface
{
/**
* Render a HAL document into a representation suitable for consumption.
*
* @param array $options Renderer-specific options
*
* @return void
*/
public function render($options = array());
}

View File

@ -0,0 +1,177 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage hal
* @copyright Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Implements the HAL over JSON renderer
*
* @package FrameworkOnFramework
* @since 2.1
*/
class FOFHalRenderJson implements FOFHalRenderInterface
{
/**
* When data is an array we'll output the list of data under this key
*
* @var string
*/
private $_dataKey = '_list';
/**
* The document to render
*
* @var FOFHalDocument
*/
protected $_document;
/**
* Public constructor
*
* @param FOFHalDocument &$document The document to render
*/
public function __construct(&$document)
{
$this->_document = $document;
}
/**
* Render a HAL document in JSON format
*
* @param array $options Rendering options. You can currently only set json_options (json_encode options)
*
* @return string The JSON representation of the HAL document
*/
public function render($options = array())
{
if (isset($options['data_key']))
{
$this->_dataKey = $options['data_key'];
}
if (isset($options['json_options']))
{
$jsonOptions = $options['json_options'];
}
else
{
$jsonOptions = 0;
}
$serialiseThis = new stdClass;
// Add links
$collection = $this->_document->getLinks();
$serialiseThis->_links = new stdClass;
foreach ($collection as $rel => $links)
{
if (!is_array($links))
{
$serialiseThis->_links->$rel = $this->_getLink($links);
}
else
{
$serialiseThis->_links->$rel = array();
foreach ($links as $link)
{
array_push($serialiseThis->_links->$rel, $this->_getLink($link));
}
}
}
// Add embedded documents
$collection = $this->_document->getEmbedded();
if (!empty($collection))
{
$serialiseThis->_embedded->$rel = new stdClass;
foreach ($collection as $rel => $embeddeddocs)
{
if (!is_array($embeddeddocs))
{
$embeddeddocs = array($embeddeddocs);
}
foreach ($embeddeddocs as $embedded)
{
$renderer = new FOFHalRenderJson($embedded);
array_push($serialiseThis->_embedded->$rel, $renderer->render($options));
}
}
}
// Add data
$data = $this->_document->getData();
if (is_object($data))
{
if ($data instanceof FOFTable)
{
$data = $data->getData();
}
else
{
$data = (array) $data;
}
if (!empty($data))
{
foreach ($data as $k => $v)
{
$serialiseThis->$k = $v;
}
}
}
elseif (is_array($data))
{
$serialiseThis->{$this->_dataKey} = $data;
}
return json_encode($serialiseThis, $jsonOptions);
}
/**
* Converts a FOFHalLink object into a stdClass object which will be used
* for JSON serialisation
*
* @param FOFHalLink $link The link you want converted
*
* @return stdClass The converted link object
*/
protected function _getLink(FOFHalLink $link)
{
$ret = array(
'href' => $link->href
);
if ($link->templated)
{
$ret['templated'] = 'true';
}
if (!empty($link->name))
{
$ret['name'] = $link->name;
}
if (!empty($link->hreflang))
{
$ret['hreflang'] = $link->hreflang;
}
if (!empty($link->title))
{
$ret['title'] = $link->title;
}
return (object) $ret;
}
}

26
libraries/fof/include.php Normal file
View File

@ -0,0 +1,26 @@
<?php
/**
* @package FrameworkOnFramework
* @subpackage include
* @copyright Copyright (c)2010-2012 Nicholas K. Dionysopoulos
* @license GNU General Public License version 2, or later
*
* Initializes FOF
*/
defined('_JEXEC') or die();
if (!defined('FOF_INCLUDED'))
{
define('FOF_INCLUDED', '2.1.rc2');
// Register a debug log
if (defined('JDEBUG') && JDEBUG)
{
JLog::addLogger(array('text_file' => 'fof.log.php'), JLog::ALL, array('fof'));
}
// Register the FOF autoloader
require_once __DIR__ . '/autoloader/fof.php';
FOFAutoloaderFof::init();
}

1
libraries/fof/index.html Normal file
View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1,434 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* The FOFInflector is an adaptation of the Akelos PHP Inflector which is a PHP
* port from a Ruby on Rails project.
*/
/**
* FOFInflector to pluralize and singularize English nouns.
*
* @package FrameworkOnFramework
* @since 1.0
*/
class FOFInflector
{
/**
* Rules for pluralizing and singularizing of nouns.
*
* @var array
*/
protected static $_rules = array
(
'pluralization' => array(
'/move$/i' => 'moves',
'/sex$/i' => 'sexes',
'/child$/i' => 'children',
'/man$/i' => 'men',
'/foot$/i' => 'feet',
'/person$/i' => 'people',
'/taxon$/i' => 'taxa',
'/(quiz)$/i' => '$1zes',
'/^(ox)$/i' => '$1en',
'/(m|l)ouse$/i' => '$1ice',
'/(matr|vert|ind|suff)ix|ex$/i' => '$1ices',
'/(x|ch|ss|sh)$/i' => '$1es',
'/([^aeiouy]|qu)y$/i' => '$1ies',
'/(?:([^f])fe|([lr])f)$/i' => '$1$2ves',
'/sis$/i' => 'ses',
'/([ti]|addend)um$/i' => '$1a',
'/(alumn|formul)a$/i' => '$1ae',
'/(buffal|tomat|her)o$/i' => '$1oes',
'/(bu)s$/i' => '$1ses',
'/(alias|status)$/i' => '$1es',
'/(octop|vir)us$/i' => '$1i',
'/(gen)us$/i' => '$1era',
'/(ax|test)is$/i' => '$1es',
'/s$/i' => 's',
'/$/' => 's',
),
'singularization' => array(
'/cookies$/i' => 'cookie',
'/moves$/i' => 'move',
'/sexes$/i' => 'sex',
'/children$/i' => 'child',
'/men$/i' => 'man',
'/feet$/i' => 'foot',
'/people$/i' => 'person',
'/taxa$/i' => 'taxon',
'/databases$/i' => 'database',
'/(quiz)zes$/i' => '\1',
'/(matr|suff)ices$/i' => '\1ix',
'/(vert|ind)ices$/i' => '\1ex',
'/^(ox)en/i' => '\1',
'/(alias|status)es$/i' => '\1',
'/(tomato|hero|buffalo)es$/i' => '\1',
'/([octop|vir])i$/i' => '\1us',
'/(gen)era$/i' => '\1us',
'/(cris|^ax|test)es$/i' => '\1is',
'/(shoe)s$/i' => '\1',
'/(o)es$/i' => '\1',
'/(bus)es$/i' => '\1',
'/([m|l])ice$/i' => '\1ouse',
'/(x|ch|ss|sh)es$/i' => '\1',
'/(m)ovies$/i' => '\1ovie',
'/(s)eries$/i' => '\1eries',
'/([^aeiouy]|qu)ies$/i' => '\1y',
'/([lr])ves$/i' => '\1f',
'/(tive)s$/i' => '\1',
'/(hive)s$/i' => '\1',
'/([^f])ves$/i' => '\1fe',
'/(^analy)ses$/i' => '\1sis',
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
'/([ti]|addend)a$/i' => '\1um',
'/(alumn|formul)ae$/i' => '$1a',
'/(n)ews$/i' => '\1ews',
'/(.*)ss$/i' => '\1ss',
'/(.*)s$/i' => '\1',
),
'countable' => array(
'aircraft',
'cannon',
'deer',
'equipment',
'fish',
'information',
'money',
'moose',
'rice',
'series',
'sheep',
'species',
'swine',
)
);
/**
* Cache of pluralized and singularized nouns.
*
* @var array
*/
protected static $_cache = array(
'singularized' => array(),
'pluralized' => array()
);
/**
* Constructor
*
* Prevent creating instances of this class by making the contructor private
*/
private function __construct()
{
}
/**
* Add a word to the cache, useful to make exceptions or to add words in other languages.
*
* @param string $singular word.
* @param string $plural word.
*
* @return void
*/
public static function addWord($singular, $plural)
{
self::$_cache['pluralized'][$singular] = $plural;
self::$_cache['singularized'][$plural] = $singular;
}
/**
* Singular English word to plural.
*
* @param string $word word to pluralize.
*
* @return string Plural noun.
*/
public static function pluralize($word)
{
// Get the cached noun of it exists
if (isset(self::$_cache['pluralized'][$word]))
{
return self::$_cache['pluralized'][$word];
}
// Create the plural noun
if (in_array($word, self::$_rules['countable']))
{
$_cache['pluralized'][$word] = $word;
return $word;
}
foreach (self::$_rules['pluralization'] as $regexp => $replacement)
{
$matches = null;
$plural = preg_replace($regexp, $replacement, $word, -1, $matches);
if ($matches > 0)
{
$_cache['pluralized'][$word] = $plural;
return $plural;
}
}
return $word;
}
/**
* Plural English word to singular.
*
* @param string $word Word to singularize.
*
* @return string Singular noun.
*/
public static function singularize($word)
{
// Get the cached noun of it exists
if (isset(self::$_cache['singularized'][$word]))
{
return self::$_cache['singularized'][$word];
}
// Create the singular noun
if (in_array($word, self::$_rules['countable']))
{
$_cache['singularized'][$word] = $word;
return $word;
}
foreach (self::$_rules['singularization'] as $regexp => $replacement)
{
$matches = null;
$singular = preg_replace($regexp, $replacement, $word, -1, $matches);
if ($matches > 0)
{
$_cache['singularized'][$word] = $singular;
return $singular;
}
}
return $word;
}
/**
* Returns given word as CamelCased.
*
* Converts a word like "foo_bar" or "foo bar" to "FooBar". It
* will remove non alphanumeric characters from the word, so
* "who's online" will be converted to "WhoSOnline"
*
* @param string $word Word to convert to camel case.
*
* @return string UpperCamelCasedWord
*/
public static function camelize($word)
{
$word = preg_replace('/[^a-zA-Z0-9\s]/', ' ', $word);
$word = str_replace(' ', '', ucwords(strtolower(str_replace('_', ' ', $word))));
return $word;
}
/**
* Converts a word "into_it_s_underscored_version"
*
* Convert any "CamelCased" or "ordinary Word" into an "underscored_word".
*
* @param string $word Word to underscore
*
* @return string Underscored word
*/
public static function underscore($word)
{
$word = preg_replace('/(\s)+/', '_', $word);
$word = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $word));
return $word;
}
/**
* Convert any "CamelCased" word into an array of strings
*
* Returns an array of strings each of which is a substring of string formed
* by splitting it at the camelcased letters.
*
* @param string $word Word to explode
*
* @return array Array of strings
*/
public static function explode($word)
{
$result = explode('_', self::underscore($word));
return $result;
}
/**
* Convert an array of strings into a "CamelCased" word.
*
* @param array $words Array to implode
*
* @return string UpperCamelCasedWord
*/
public static function implode($words)
{
$result = self::camelize(implode('_', $words));
return $result;
}
/**
* Returns a human-readable string from $word.
*
* Returns a human-readable string from $word, by replacing
* underscores with a space, and by upper-casing the initial
* character by default.
*
* @param string $word String to "humanize"
*
* @return string Human-readable word
*/
public static function humanize($word)
{
$result = ucwords(strtolower(str_replace("_", " ", $word)));
return $result;
}
/**
* Converts a class name to its table name according to Koowa
* naming conventions.
*
* Converts "Person" to "people"
*
* @param string $className Class name for getting related table_name.
*
* @return string plural_table_name
*
* @see classify
*/
public static function tableize($className)
{
$result = self::underscore($className);
if (!self::isPlural($className))
{
$result = self::pluralize($result);
}
return $result;
}
/**
* Converts a table name to its class name according to Koowa naming conventions.
*
* @param string $tableName Table name for getting related ClassName.
*
* @return string SingularClassName
*
* @example Converts "people" to "Person"
* @see tableize
*/
public static function classify($tableName)
{
$result = self::camelize(self::singularize($tableName));
return $result;
}
/**
* Returns camelBacked version of a string. Same as camelize but first char is lowercased.
*
* @param string $string String to be camelBacked.
*
* @return string
*
* @see camelize
*/
public static function variablize($string)
{
$string = self::camelize(self::underscore($string));
$result = strtolower(substr($string, 0, 1));
$variable = preg_replace('/\\w/', $result, $string, 1);
return $variable;
}
/**
* Check to see if an English word is singular
*
* @param string $string The word to check
*
* @return boolean
*/
public static function isSingular($string)
{
// Check cache assuming the string is plural.
$singular = isset(self::$_cache['singularized'][$string]) ? self::$_cache['singularized'][$string] : null;
$plural = $singular && isset(self::$_cache['pluralized'][$singular]) ? self::$_cache['pluralized'][$singular] : null;
if ($singular && $plural)
{
return $plural != $string;
}
// If string is not in the cache, try to pluralize and singularize it.
return self::singularize(self::pluralize($string)) == $string;
}
/**
* Check to see if an Enlish word is plural.
*
* @param string $string String to be checked.
*
* @return boolean
*/
public static function isPlural($string)
{
// Check cache assuming the string is singular.
$plural = isset(self::$_cache['pluralized'][$string]) ? self::$_cache['pluralized'][$string] : null;
$singular = $plural && isset(self::$_cache['singularized'][$plural]) ? self::$_cache['singularized'][$plural] : null;
if ($plural && $singular)
{
return $singular != $string;
}
// If string is not in the cache, try to singularize and pluralize it.
return self::pluralize(self::singularize($string)) == $string;
}
/**
* Gets a part of a CamelCased word by index.
*
* Use a negative index to start at the last part of the word (-1 is the
* last part)
*
* @param string $string Word
* @param integer $index Index of the part
* @param string $default Default value
*
* @return string
*/
public static function getPart($string, $index, $default = null)
{
$parts = self::explode($string);
if ($index < 0)
{
$index = count($parts) + $index;
}
return isset($parts[$index]) ? $parts[$index] : $default;
}
}

View File

@ -0,0 +1 @@
<html><head><title></title></head><body></body></html>

View File

@ -0,0 +1,300 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* FrameworkOnFramework input handling class. Extends upon the JInput class.
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFInput extends JInput
{
/**
* Public constructor. Overriden to allow specifying the global input array
* to use as a string and instantiate from an objetc holding variables.
*
* @param array|string|object|null $source Source data; set null to use $_REQUEST
* @param array $options Filter options
*/
public function __construct($source = null, array $options = array())
{
$hash = null;
if (is_string($source))
{
$hash = strtoupper($source);
switch ($hash)
{
case 'GET':
$source = $_GET;
break;
case 'POST':
$source = $_POST;
break;
case 'FILES':
$source = $_FILES;
break;
case 'COOKIE':
$source = $_COOKIE;
break;
case 'ENV':
$source = $_ENV;
break;
case 'SERVER':
$source = $_SERVER;
break;
default:
$source = $_REQUEST;
$hash = 'REQUEST';
break;
}
}
elseif (is_object($source))
{
try
{
$source = (array) $source;
}
catch (Exception $exc)
{
$source = null;
}
}
elseif (is_array($source))
{
// Nothing, it's already an array
}
else
{
// Any other case
$source = $_REQUEST;
$hash = 'REQUEST';
}
// Magic quotes GPC handling (something JInput simply can't handle at all)
if (($hash == 'REQUEST') && get_magic_quotes_gpc() && class_exists('JRequest', true))
{
$source = JRequest::get('REQUEST', 2);
}
parent::__construct($source, $options);
}
/**
* Gets a value from the input data. Overriden to allow specifying a filter
* mask.
*
* @param string $name Name of the value to get.
* @param mixed $default Default value to return if variable does not exist.
* @param string $filter Filter to apply to the value.
* @param int $mask The filter mask
*
* @return mixed The filtered input value.
*/
public function get($name, $default = null, $filter = 'cmd', $mask = 0)
{
if (isset($this->data[$name]))
{
return $this->_cleanVar($this->data[$name], $mask, $filter);
}
return $default;
}
/**
* Returns a copy of the raw data stored in the class
*
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* Old static methods are now deprecated. This magic method makes sure there
* is a continuity in our approach. The downside is that it's only compatible
* with PHP 5.3.0. Sorry!
*
* @param string $name Name of the method we're calling
* @param array $arguments The arguments passed to the method
*
* @return mixed
*/
public static function __callStatic($name, $arguments)
{
JLog::add('FOFInput: static getXXX() methods are deprecated. Use the input object\'s methods instead.', JLog::WARNING, 'deprecated');
if (substr($name, 0, 3) == 'get')
{
// Initialise arguments
$key = array_shift($arguments);
$default = array_shift($arguments);
$input = array_shift($arguments);
$type = 'none';
$mask = 0;
$type = strtolower(substr($name, 3));
if ($type == 'var')
{
$type = array_shift($arguments);
$mask = array_shift($arguments);
}
if (is_null($type))
{
$type = 'none';
}
if (is_null($mask))
{
$mask = 0;
}
if (!($input instanceof FOFInput) && !($input instanceof JInput))
{
$input = new FOFInput($input);
}
return $input->get($key, $default, $type, $mask);
}
return false;
}
/**
* Magic method to get filtered input data.
*
* @param mixed $name Name of the value to get.
* @param string $arguments Default value to return if variable does not exist.
*
* @return boolean The filtered boolean input value.
*/
public function __call($name, $arguments)
{
if (substr($name, 0, 3) == 'get')
{
$filter = substr($name, 3);
$default = null;
$mask = 0;
if (isset($arguments[1]))
{
$default = $arguments[1];
}
if (isset($arguments[2]))
{
$mask = $arguments[2];
}
return $this->get($arguments[0], $default, $filter, $mask);
}
}
/**
* Sets an input variable. WARNING: IT SHOULD NO LONGER BE USED!
*
* @param string $name The name of the variable to set
* @param mixed $value The value to set it to
* @param array &$input The input array or FOFInput object
* @param boolean $overwrite Should I overwrite existing values (default: true)
*
* @return string Previous value
*
* @deprecated
*/
public static function setVar($name, $value = null, &$input = array(), $overwrite = true)
{
JLog::add('FOFInput::setVar() is deprecated. Use set() instead.', JLog::WARNING, 'deprecated');
if (empty($input))
{
return JRequest::setVar($name, $value, 'default', $overwrite);
}
elseif (is_string($input))
{
return JRequest::setVar($name, $value, $input, $overwrite);
}
else
{
if (!$overwrite && array_key_exists($name, $input))
{
return $input[$name];
}
$previous = array_key_exists($name, $input) ? $input[$name] : null;
if (is_array($input))
{
$input[$name] = $value;
}
elseif ($input instanceof FOFInput)
{
$input->set($name, $value);
}
return $previous;
}
}
/**
* Custom filter implementation. Works better with arrays and allows the use
* of a filter mask.
*
* @param mixed $var The variable (value) to clean
* @param integer $mask The clean mask
* @param string $type The variable type
*
* @return mixed
*/
protected function _cleanVar($var, $mask = 0, $type = null)
{
if (is_array($var))
{
$temp = array();
foreach ($var as $k => $v)
{
$temp[$k] = self::_cleanVar($v, $mask);
}
return $temp;
}
// If the no trim flag is not set, trim the variable
if (!($mask & 1) && is_string($var))
{
$var = trim($var);
}
// Now we handle input filtering
if ($mask & 2)
{
// If the allow raw flag is set, do not modify the variable
$var = $var;
}
elseif ($mask & 4)
{
// If the allow HTML flag is set, apply a safe HTML filter to the variable
$safeHtmlFilter = JFilterInput::getInstance(null, null, 1, 1);
$var = $safeHtmlFilter->clean($var, $type);
}
else
{
$var = $this->filter->clean($var, $type);
}
return $var;
}
}

View File

@ -0,0 +1,65 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Base class for rendering a display layout
* loaded from from a layout file
*
* This class searches for Joomla! version override Layouts. For example,
* if you have run this under Joomla! 3.0 and you try to load
* mylayout.default it will automatically search for the
* layout files default.j30.php, default.j3.php and default.php, in this
* order.
*
* @package FrameworkOnFramework
* @since 1.0
*/
class FOFLayoutFile extends JLayoutFile
{
/**
* Method to finds the full real file path, checking possible overrides
*
* @return string The full path to the layout file
*/
protected function getPath()
{
jimport('joomla.filesystem.path');
if (is_null($this->fullPath) && !empty($this->layoutId))
{
$parts = explode('.', $this->layoutId);
$file = array_pop($parts);
$filePath = implode('/', $parts);
$suffixes = FOFPlatform::getInstance()->getTemplateSuffixes();
foreach ($suffixes as $suffix)
{
$files[] = $file . $suffix . '.php';
}
$files[] = $file . '.php';
$possiblePaths = array(
JPATH_THEMES . '/' . JFactory::getApplication()->getTemplate() . '/html/layouts/' . $filePath,
$this->basePath . '/' . $filePath
);
reset($files);
while ((list(, $fileName) = each($files)) && is_null($this->fullPath))
{
$r = JPath::find($possiblePaths, $fileName);
$this->fullPath = $r === false ? null : $r;
}
}
return $this->fullPath;
}
}

View File

@ -0,0 +1,38 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* Helper to render a FOFLayout object, storing a base path
*
* @package FrameworkOnFramework
* @since x.y
*/
class FOFLayoutHelper extends JLayoutHelper
{
/**
* Method to render the layout.
*
* @param string $layoutFile Dot separated path to the layout file, relative to base path
* @param object $displayData Object which properties are used inside the layout file to build displayed output
* @param string $basePath Base path to use when loading layout files
*
* @return string
*/
public static function render($layoutFile, $displayData = null, $basePath = '')
{
$basePath = empty($basePath) ? self::$defaultBasePath : $basePath;
// Make sure we send null to FOFLayoutFile if no path set
$basePath = empty($basePath) ? null : $basePath;
$layout = new FOFLayoutFile($layoutFile, $basePath);
$renderedLayout = $layout->render($displayData);
return $renderedLayout;
}
}

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,189 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* This class is taken verbatim from:
*
* lessphp v0.3.8
* http://leafo.net/lessphp
*
* LESS css compiler, adapted from http://lesscss.org
*
* Copyright 2012, Leaf Corcoran <leafot@gmail.com>
* Licensed under MIT or GPLv3, see LICENSE
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFLessFormatterClassic
{
public $indentChar = " ";
public $break = "\n";
public $open = " {";
public $close = "}";
public $selectorSeparator = ", ";
public $assignSeparator = ":";
public $openSingle = " { ";
public $closeSingle = " }";
public $disableSingle = false;
public $breakSelectors = false;
public $compressColors = false;
/**
* Public constructor
*/
public function __construct()
{
$this->indentLevel = 0;
}
/**
* Indent a string by $n positions
*
* @param integer $n How many positions to indent
*
* @return string The indented string
*/
public function indentStr($n = 0)
{
return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
}
/**
* Return the code for a property
*
* @param string $name The name of the porperty
* @param string $value The value of the porperty
*
* @return string The CSS code
*/
public function property($name, $value)
{
return $name . $this->assignSeparator . $value . ";";
}
/**
* Is a block empty?
*
* @param stdClass $block The block to check
*
* @return boolean True if the block has no lines or children
*/
protected function isEmpty($block)
{
if (empty($block->lines))
{
foreach ($block->children as $child)
{
if (!$this->isEmpty($child))
{
return false;
}
}
return true;
}
return false;
}
/**
* Output a CSS block
*
* @param stdClass $block The block definition to output
*
* @return void
*/
public function block($block)
{
if ($this->isEmpty($block))
{
return;
}
$inner = $pre = $this->indentStr();
$isSingle = !$this->disableSingle &&
is_null($block->type) && count($block->lines) == 1;
if (!empty($block->selectors))
{
$this->indentLevel++;
if ($this->breakSelectors)
{
$selectorSeparator = $this->selectorSeparator . $this->break . $pre;
}
else
{
$selectorSeparator = $this->selectorSeparator;
}
echo $pre .
implode($selectorSeparator, $block->selectors);
if ($isSingle)
{
echo $this->openSingle;
$inner = "";
}
else
{
echo $this->open . $this->break;
$inner = $this->indentStr();
}
}
if (!empty($block->lines))
{
$glue = $this->break . $inner;
echo $inner . implode($glue, $block->lines);
if (!$isSingle && !empty($block->children))
{
echo $this->break;
}
}
foreach ($block->children as $child)
{
$this->block($child);
}
if (!empty($block->selectors))
{
if (!$isSingle && empty($block->children))
{
echo $this->break;
}
if ($isSingle)
{
echo $this->closeSingle . $this->break;
}
else
{
echo $pre . $this->close . $this->break;
}
$this->indentLevel--;
}
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
* @package FrameworkOnFramework
* @copyright Copyright (C) 2010 - 2012 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;
/**
* This class is taken verbatim from:
*
* lessphp v0.3.8
* http://leafo.net/lessphp
*
* LESS css compiler, adapted from http://lesscss.org
*
* Copyright 2012, Leaf Corcoran <leafot@gmail.com>
* Licensed under MIT or GPLv3, see LICENSE
*
* @package FrameworkOnFramework
* @since 2.0
*/
class FOFLessFormatterCompressed extends FOFLessFormatterClassic
{
public $disableSingle = true;
public $open = "{";
public $selectorSeparator = ",";
public $assignSeparator = ":";
public $break = "";
public $compressColors = true;
/**
* Indent a string by $n positions
*
* @param integer $n How many positions to indent
*
* @return string The indented string
*/
public function indentStr($n = 0)
{
return "";
}
}

Some files were not shown because too many files have changed in this diff Show More