diff --git a/deployed/icagenda/administrator/components/com_icagenda/CHANGELOG.php b/deployed/icagenda/administrator/components/com_icagenda/CHANGELOG.php new file mode 100644 index 00000000..479737d6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/CHANGELOG.php @@ -0,0 +1,4381 @@ + + +
iCagenda
ChangeLog
+================================================================================ +?
Welcome to iCagenda 3.7.15 release!

Bug Fix Release.

Update and take advantage of all the improvements done in lastest version of iCagenda!

Stay safe!


+================================================================================ +: !important +added -removed ~changed #fixed
Info: access to the beta versions and pre-releases are reserved to users with a valid pro subscription.
iCagenda™ is distributed under the terms of the GNU General Public License version 3 or later; see LICENSE.txt. +================================================================================ + + + +iCagenda 3.7.15 (2020.08.29) +================================================================================ +# [LOW] Fixed : Missing default utf-8 title formatting if no option set. +# [LOW] Fixed : Category filter interaction with module list. +# [LOW] Fixed : Add next date control in admin list and event view. + +* Changed files in 3.7.15 +~ admin/models/events.php +~ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/render/render.php +~ site/add/elements/icevent_vars.php + + +iCagenda 3.7.14 (2020.04.27) Security & Bug Fix Release +================================================================================ +# [SECURITY][LOW] Exploit type: Blind SQLi +1 Severity: Low +1 Versions: 3.6.0 through 3.7.13 +1 Description: The lack of type casting of a variable in SQL statement leads to a SQL injection vulnerability in the events list view. ++ Added : Search in custom fields value with the frontend global search field. +# [LOW] Fixed : Missing custom cancellation label in detailled view of event. +# [LOW] Fixed : Showon display of custom label options (should be hidden if default label). +# [LOW] Fixed : Removed not used asset_id. + +* Changed files in 3.7.14 +~ admin/access.xml +~ admin/models/forms/event.xml +~ admin/sql/install/mysql/icagenda.install.sql +~ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ site/models/submit.php +~ site/models/forms/submit.xml +~ site/views/list/tmpl/default_filters.php + + +iCagenda 3.7.13 (2020.04.02) +================================================================================ ++ Added : custom Cancelled label options (text + style). +# [LOW] Fixed : module language missing string. +# [LOW] Fixed : missing redirection on Registration form if closed. +# [LOW][PLUGIN] Fixed : search routing on multilanguages site. + +* Changed files in 3.7.13 +~ admin/models/forms/event.xml +~ admin/utilities/event/event.php +~ [PLUGIN] plugins/search/icagenda/icagenda.php +~ [PLUGIN] plugins/search/icagenda/icagenda.xml +~ site/views/registration/view.html.php + + +iCagenda 3.7.12 (2020.03.28) +================================================================================ ++ Added : Event cancellation feature to inform your visitors of events cancelled. ++ Added : Possibility to create custom language constants (Language Overrides) for translation of custom fields (Label and value). ++ Added : Falang custom fields element content xml files (version 2.0). +# [LOW] Fixed : Participants access view for organizers. +# [LOW] Fixed : JCE image input width. +# [LOW] Fixed : Event Title "h" tag in default theme for event details view. + +* Changed files in 3.7.12 +~ admin/models/event.php +~ admin/models/registrations.php +~ admin/models/forms/event.xml +~ admin/utilities/event/data.php +~ admin/utilities/event/event.php +~ admin/utilities/registration/participants.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/registrations/tmpl/default.php +~ [MEDIA] media/css/icagenda-back.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ site/add/elements/icevent_vars.php +~ site/models/registration.php +~ [THEME] site/themes/packs/default/default_event.php +~ [THEME] site/themes/packs/default/css/default_component.css +~ [THEME] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ site/views/event/tmpl/default_top.php +~ site/views/registration/view.html.php + + +iCagenda 3.7.11 (2019.12.19) +================================================================================ +~ [THEME] Changed : Remove css max-height for image in event details view +# [LOW] Fixed : missing alt text for images. + +* Changed files in 3.7.11 +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [THEME] site/themes/packs/default/css/default_component.css +~ [THEME] site/themes/packs/ic_rounded/css/ic_rounded_component.css + + +iCagenda 3.7.10 (2019.08.31) +================================================================================ ++ Added : Prefixe for Search in registrations admin list. EVENTID: to search for an event ID. ++ Added : Missing no results message for Search in admin events list. ++ [GLOBALIZATION] Added : zh-CN Chinese (Simplified) date formats. ++ [MODULE] Added : Chinese languages zh-CN and zh-TW as year before month used for date display of the calendar header. +~ [THEME] Changed : Removed not needed max-width CSS applied on module calendar for ic_rounded theme + +* Changed files in 3.7.10 +~ admin/models/registrations.php +~ admin/views/events/tmpl/default.php +~ admin/views/icagenda/tmpl/default.php ++ [LIBRARY] libraries/ic_library/globalize/culture/zh-CN.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [THEME] site/themes/packs/ic_rounded/css/ic_rounded_module.css + + +iCagenda 3.7.9 (2019.06.13) +================================================================================ ++ Added : character encoding Windows-1256 for registrations export. ++ [GLOBALIZATION] Added : de-CH German (Switzerland) date formats. +# [LOW] Fixed : admin events list search with non-Latin characters. +# [LOW] Fixed : zero "0" value not saved if used as an option value in dropdown list type custom field. +# [LOW] Fixed : x-small thumbnail crop option not saved if disabled. +# [LOW] Fixed : default published state for registrations export when not firstly filtered. + +* Changed files in 3.7.9 +~ admin/controllers/registrations.raw.php +~ admin/models/events.php +~ admin/models/fields/modal/thumbs.php +~ admin/models/forms/download.xml +~ admin/utilities/customfields/customfields.php ++ [LIBRARY] libraries/ic_library/globalize/culture/de-CH.php +~ site/models/registration.php +~ site/models/forms/registration.xml + + +iCagenda 3.7.8 (2019.01.10) +================================================================================ +# [LOW] Fixed : while adding a patch for old Joomla 3 versions, Published state control was broken with Joomla 3.9 in release 3.7.7 of iCagenda. + +* Changed files in 3.7.8 +~ admin/tables/category.php +~ admin/tables/customfield.php +~ admin/tables/event.php +~ admin/tables/feature.php +~ admin/tables/registration.php + + +iCagenda 3.7.7 (2019.01.09) +================================================================================ ++ Added : column indexes to improve sql queries performance. ++ Added : search in dates/period (admin). +# [LOW] Fixed : for Joomla version before 3.7: do not set column alias. +# [LOW] Fixed : COM_ICAGENDA_REGISTRATION_REGISTER_BTN string override +# [LOW] Fixed : missing Export button Joomla before 3.7 +# [LOW] Fixed : gravatar on mobile display. + +* Changed files in 3.7.7 +~ admin/models/events.php +~ admin/sql/install/mysql/icagenda.install.sql +~ admin/tables/category.php +~ admin/tables/customfield.php +~ admin/tables/event.php +~ admin/tables/feature.php +~ admin/tables/registration.php +~ admin/views/registrations/view.html.php +~ admin/views/registrations/tmpl/default.php +~ site/icagenda.php +~ site/views/registration/tmpl/default.php + + +iCagenda 3.7.6 (2018.11.28) +================================================================================ +# [LOW] Patch for Joomla 3.9.1: Due to a change in Published state control in Joomla core, the side-effect is published toggle/change state is broken in iCagenda. +1 This affects too a few parts of Joomla core: com_banners Clients, com_users Notes, com_finder Filters and com_messages. I've created PRs to fix this in next Joomla 3.9.2 + +* Changed files in 3.7.6 +~ admin/tables/category.php +~ admin/tables/customfield.php +~ admin/tables/event.php +~ admin/tables/feature.php +~ admin/tables/registration.php + + +iCagenda 3.7.5 (2018.10.30) +================================================================================ +! Privacy Tools part.2 : integration with Joomla 3.9 Privacy Tools Suite +! Joomla! Integration: +1 - Action logs include user actions in iCagenda extension. (Enable "Action Log - iCagenda" plugin). +1 - iCagenda will include events, registrations and related custom fields to the user data exported on privacy information requests. (Enable "Privacy - iCagenda" plugin). +1 - iCagenda reports its privacy related capabilities to the Joomla Privacy system. ++ Added : Plugin Privacy - iCagenda. ++ Added : Plugin Action Log - iCagenda. +~ [MODULE][PRO] Changed : Improve module font color when image background. +# [LOW] Fixed : Fix the registrations csv export zip file not unzippable. +# [LIBRARY][LOW] Fixed : Fix de-DE date formats missing dot. +# [THEME][LOW] Fixed : Add missing ic-details-cat class default theme. + +* Changed files in 3.7.5 +~ script.icagenda.php +~ admin/models/registrations.php +~ admin/utilities/registration/registration.php +~ [LIBRARY] libraries/ic_library/globalize/culture/de-DE.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php ++ [PLUGIN][ACTIONLOG] plugins/actionlog/icagenda/icagenda.php ++ [PLUGIN][ACTIONLOG] plugins/actionlog/icagenda/icagenda.xml ++ [PLUGIN][PRIVACY] plugins/privacy/icagenda/icagenda.php ++ [PLUGIN][PRIVACY] plugins/privacy/icagenda/icagenda.xml +~ site/themes/packs/default/default_event.php + + +iCagenda 3.7.4 (2018.09.26) Security Release +================================================================================ +# [SECURITY][MEDIUM] Exploit type: XSS +1 Severity: Low +1 Versions: 3.6.7 through 3.7.3 +1 Description: Inadequate input filtering on the list of events page, when frontend search filters enable. This may lead to reflective XSS via injection of arbitrary parameters and/or values on the current page url. + + +iCagenda 3.7.3 (2018.08.23) +================================================================================ +~ Changed : improve category color brightness control to set font color for date (https://www.w3.org/TR/AERT/#color-contrast). +~ Changed : a few code clean, minor reviews and deprecated code removal. +~ Changed : improve words breaking on Chrome for event details information. +# [LOW] Fixed : Google Maps embed api script broken for a few languages using quotes in translation strings (French...). +# [LOW] Fixed : Google maps embed iframe url. +# [LOW] Fixed : php warning on email cloaking if Joomla EmailCloaking plugin is disabled. +# [LOW] Fixed : frontend search filters Month and Year not displaying events with period on a single month. +# [LOW] Fixed : missing https ssl url for external calendars and usage stats. + +* Changed files in 3.7.3 +~ script.icagenda.php +~ admin/assets/jcms/info.php +~ admin/utilities/addtocal/addtocal.php +~ admin/utilities/events/data.php +~ admin/utilities/googlemaps/googlemaps.php +~ admin/utilities/info/info.php +~ admin/utilities/render/render.php +~ admin/views/event/tmpl/edit.php +~ [LIBRARY] libraries/ic_library/color/color.php +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ site/helpers/iCicons.class.php +~ site/models/event.php +~ site/models/registration.php +~ [THEME] site/themes/packs/default/css/default_component.css +~ [THEME] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ site/views/list/view.feed.php +~ site/views/submit/view.html.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.7.2 (2018.06.11) +================================================================================ +! New Google Maps Platform +1 - Starting June 11th, 2018, Google Maps API no longer support keyless access. +1 - Starting July 16th, 2018, the billing requirement will be enforced. +1 - All projects must be associated with a billing account, or will not be able to make Javascript API requests over $200/mo. +1 - However it is advised to use new option Google Maps Embed API for Maps Service, that remains free with unlimited usage. ++ Added : Google Maps Embed API (New option for Maps Service). ++ Added : Privacy consent information (badge) in admin registrations list. ++ Added : Prefixes for Search in registrations. USERID: to search for a user ID and EMAIL: to search for a user Email address. +~ Changed : Option for Name Consent allows now to require name visibility consent even if List of Participants is disabled. + +* Changed files in 3.7.2 +~ script.icagenda.php +~ admin/config.xml +~ admin/models/registrations.php +~ admin/utilities/googlemaps/googlemaps.php +~ admin/views/event/tmpl/edit.php +~ admin/views/registrations/tmpl/default.php +~ site/models/registration.php +~ site/views/registration/tmpl/default.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.7.1 (2018.05.28) +================================================================================ ++ Added : option to set Gravatar consent on Registration form: 'Auto' (as for 3.7.0, if list of participants is enabled), 'Require Explicite Consent' (even if list of participants hidden), 'Disabled' (not ask for consent, but never use Gravatar to show avatar. Future options will be developed for 'Avatar', to enable upload or other avatar system integration like Community Builder). +# [LOW] Fixed PHP 7.2 : count returns php warning when no registration (if Error Reporting is enabled. Don't forget to keep this Joomla configuration option turn off or on default when site is in production). +# [PLUGIN][SEARCH][LOW] Fixed : global search in private events not returning results even if user logged-in with access permissions. + +* Changed files in 3.7.1 +~ script.icagenda.php +~ admin/config.xml +~ admin/utilities/registration/registration.php +~ [PLUGIN][SEARCH] plugins/search/icagenda/icagenda.php +~ [PLUGIN][SEARCH] plugins/search/icagenda/icagenda.xml +~ site/models/registration.php +~ site/views/registration/tmpl/default.php + + +iCagenda 3.7.0 (2018.05.25) +================================================================================ +! Privacy Tools part.1 : GDPR REGULATION (EU) 2016/679. +! New separated database table 'icagenda_user_actions' to store all explicit consents as required by GDPR. +1 - Registration form: name visibility, Gravatar, Organiser, Terms. +1 - Submit an Event form: Terms of Service (tos). +! Fresh New Installation (only!): new default settings +1 - Event view: participants list hidden by default. +1 - Registration form: 'Terms & Conditions' consent checkbox enabled by default. +1 - Registration form: 'Phone' core field disabled by default. +! Update Installation: new options preset to Privacy by default +1 - Event view: participant name and gravatar not public by default (require explicite consent). +1 - Registration form: improved 'Terms & Conditions' consent checkbox. +1 - Registration form: new 'Name Visibility' consent checkbox (enabled by a new config option in 'Registration' tab). +1 - Registration form: new 'Gravatar' consent checkbox (auto-enabled if list of participants is active). +1 - Registration form: new 'Consent to Organiser' consent checkbox (new config option in 'Registration' tab). +! Announcement : First version to support Joomla 3 only (support for J2.5 has ended). +~ Changed UX : integrates showon feature in global options of component (showon was introduced in Joomla 3.2.4). +~ [MEDIA] Changed : iCicons font updated. +# [LOW] Fixed : Google Maps initialize possible conflict with other extensions using maps. +# [MODULE][LOW] Fixed : escape div html tags in calendar script to prevent unexpected manipulation of generated content by a third party extension. + +* Changed files in 3.7.0 +~ script.icagenda.php +~ admin/config.xml +~ admin/models/registration.php +~ admin/utilities/customfields/customfields.php ++ admin/utilities/form/field/configtermsdefault.php ++ admin/utilities/form/field/terms.php +~ admin/utilities/googlemaps/googlemaps.php +~ admin/utilities/registration/participants.php +~ [MEDIA] media/css/icagenda-front.css +~ [MEDIA] media/icicons/style.css +~ [MEDIA] media/icicons/fonts/iCicons.eot +~ [MEDIA] media/icicons/fonts/iCicons.svg +~ [MEDIA] media/icicons/fonts/iCicons.ttf +~ [MEDIA] media/icicons/fonts/iCicons.woff +~ [MEDIA] media/js/icmap-front.js +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ site/models/registration.php +~ site/models/submit.php +~ site/models/forms/registration.xml +~ [THEME] site/themes/packs/default/css/default_component.css +~ [THEME] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ site/views/registration/tmpl/default.php + + +iCagenda 3.6.14 (2018.05.04) +================================================================================ +! Cleanup : Spring cleaning time ;-) +1 - Replace Joomla Framework commonly used but deprecated functions from iCagenda. +1 - Code Standards review (part 1). +# [HIGH] Fixed : Permissions Access levels for registration form broken in version 3.6.13. +# [LOW] Fixed : syntax error, unexpected T_OBJECT_OPERATOR on PHP 5.3 and below (Please, ask your hoster to upgrade your PHP version! Recommended: Joomla 3 + PHP 7). +# [LOW] Fixed : event's contact email not receiving notification email when new registration. +# [LOW] Fixed : missing integer control for title characters limit. +# [MODULE][LOW] Fixed PHP 7.2 : refactory deprecated php code. +# [MODULE][PRO][LOW] Fixed : PHP Notice in backend log for module template layout icrounded. + +* Changed files in 3.6.14 +~ script.icagenda.php +~ admin/config.xml +~ admin/controller.php +~ admin/icagenda.php +~ admin/assets/jcms/info.php +~ admin/controllers/event.php +~ admin/controllers/events.php +~ admin/controllers/mail.php +~ admin/controllers/registrations.raw.php +~ admin/controllers/themes.php +~ admin/helpers/icagenda.php +~ admin/models/categories.php +~ admin/models/customfields.php +~ admin/models/download.php +~ admin/models/event.php +~ admin/models/events.php +~ admin/models/mail.php +~ admin/models/registrations.php +~ admin/models/themes.php +~ admin/models/fields/icmap/lat.php +~ admin/models/fields/icmap/lng.php +~ admin/models/fields/modal/coordinate.php +~ admin/models/fields/modal/date.php +~ admin/models/fields/modal/evt_date.php +~ admin/models/fields/modal/ic_password.php +~ admin/models/fields/modal/icfile.php +~ admin/models/fields/modal/iclink_article.php +~ admin/models/fields/modal/iclink_type.php +~ admin/models/fields/modal/iclink_url.php +~ admin/models/fields/modal/ictext_placeholder.php +~ admin/models/fields/modal/ictxt_article.php +~ admin/models/fields/modal/media.php +~ admin/models/fields/modal/menulink.php +~ admin/models/fields/modal/multicat.php +~ admin/models/fields/modal/param_place.php +~ admin/models/fields/modal/ph_regbt.php +~ admin/models/fields/modal/tos_article.php +~ admin/tables/category.php +~ admin/tables/customfield.php +~ admin/tables/event.php +~ admin/tables/feature.php +~ admin/tables/registration.php +~ admin/utilities/addtocal/addtocal.php +~ admin/utilities/ajax/ajax.php +~ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/form/field/customfieldgroups.php +~ admin/utilities/form/field/customform.php +~ admin/utilities/form/field/registrationdates.php +~ admin/utilities/form/field/registrationpeople.php +~ admin/utilities/form/field/registrationterms.php +~ admin/utilities/list/list.php +~ admin/utilities/manager/manager.php +~ admin/utilities/menus/menus.php +~ admin/utilities/params/params.php +~ admin/utilities/registration/registration.php +~ admin/views/categories/view.html.php +~ admin/views/category/view.html.php +~ admin/views/customfield/view.html.php +~ admin/views/customfields/view.html.php +~ admin/views/download/view.html.php +~ admin/views/event/view.html.php +~ admin/views/events/view.html.php +~ admin/views/events/tmpl/default.php +~ admin/views/feature/view.html.php +~ admin/views/features/view.html.php +~ admin/views/icagenda/view.html.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/view.html.php +~ admin/views/mail/view.html.php +~ admin/views/registration/view.html.php +~ admin/views/registrations/view.html.php +~ admin/views/registrations/tmpl/default.php +~ admin/views/themes/view.html.php +~ admin/views/themes/tmpl/default.php +~ [LIBRARY] libraries/ic_library/globalize/convert.php +~ [LIBRARY] libraries/ic_library/globalize/globalize.php +~ [LIBRARY] libraries/ic_library/globalize/culture/cs-CZ.php +~ [LIBRARY] libraries/ic_library/globalize/culture/de-DE.php +~ [LIBRARY] libraries/ic_library/globalize/culture/el-GR.php +~ [LIBRARY] libraries/ic_library/globalize/culture/en-GB.php +~ [LIBRARY] libraries/ic_library/globalize/culture/en-US.php +~ [LIBRARY] libraries/ic_library/globalize/culture/es-ES.php +~ [LIBRARY] libraries/ic_library/globalize/culture/fa-IR.php +~ [LIBRARY] libraries/ic_library/globalize/culture/fi-FI.php +~ [LIBRARY] libraries/ic_library/globalize/culture/fo-FO.php +~ [LIBRARY] libraries/ic_library/globalize/culture/fr-FR.php +~ [LIBRARY] libraries/ic_library/globalize/culture/hr-HR.php +~ [LIBRARY] libraries/ic_library/globalize/culture/hu-HU.php +~ [LIBRARY] libraries/ic_library/globalize/culture/iso.php +~ [LIBRARY] libraries/ic_library/globalize/culture/it-IT.php +~ [LIBRARY] libraries/ic_library/globalize/culture/lv-LV.php +~ [LIBRARY] libraries/ic_library/globalize/culture/nb-NO.php +~ [LIBRARY] libraries/ic_library/globalize/culture/nl-NL.php +~ [LIBRARY] libraries/ic_library/globalize/culture/pl-PL.php +~ [LIBRARY] libraries/ic_library/globalize/culture/pt-BR.php +~ [LIBRARY] libraries/ic_library/globalize/culture/pt-PT.php +~ [LIBRARY] libraries/ic_library/globalize/culture/ru-RU.php +~ [LIBRARY] libraries/ic_library/globalize/culture/sk-SK.php +~ [LIBRARY] libraries/ic_library/globalize/culture/sv-SE.php +~ [LIBRARY] libraries/ic_library/globalize/culture/tr-TR.php +~ [LIBRARY] libraries/ic_library/globalize/culture/uk-UA.php +~ [LIBRARY] libraries/ic_library/globalize/culture/zh-TW.php +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ [PLUGIN] plugins/search/icagenda/icagenda.php +~ [PLUGIN] plugins/search/icagenda/icagenda.xml +~ [PLUGIN] plugins/system/ic_autologin/ic_autologin.php +~ [PLUGIN] plugins/system/ic_autologin/ic_autologin.xml +~ site/controller.php +~ site/icagenda.php +~ site/controllers/registration.php +~ site/models/event.php +~ site/models/events.php +~ site/models/icagenda.php +~ site/models/list.php +~ site/models/registration.php +~ site/models/submit.php +~ site/models/fields/categories.php +~ [THEME] site/themes/default.xml +~ [THEME] site/themes/ic_rounded.xml +~ [THEME] site/themes/packs/default/default_calendar.php +~ [THEME] site/themes/packs/default/default_day.php +~ [THEME] site/themes/packs/default/default_event.php +~ [THEME] site/themes/packs/default/default_events.php +~ [THEME] site/themes/packs/default/default_registration.php +~ [THEME] site/themes/packs/ic_rounded/ic_rounded_calendar.php +~ [THEME] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME] site/themes/packs/ic_rounded/ic_rounded_events.php +~ [THEME] site/themes/packs/ic_rounded/ic_rounded_registration.php +~ site/views/event/view.html.php +~ site/views/list/view.html.php +~ site/views/registration/view.html.php +~ site/views/submit/view.html.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.6.13 (2018.04.17) +================================================================================ +! New : integrates iCagenda component in Joomla extensions updater (LiveUpdate kept for install on J2.5). ++ Added : integrate Falang into frontend search results. ++ Added : character encoding option for registration csv exported file. ++ [PLUGIN] Added : integrate Falang into search plugin. +~ Changed : moves iCagendaOnListPrepare sooner for a better retrieving of data by plugin event. +~ Changed : improve registration export modal on Joomla 3. +~ Changed : improve year frontend filter. +~ Changed : update snippets (title, meta description) length according to new Google limits (December 2017). +~ Changed : improve pagination html/css. +- [MODULE] Removed : Ctrl+Alt+C shortcut to focus on calendar module, to prevent conflict with Polish language shortcut alt+C Ć. +# [LOW] Fixed : multiple groups select in custom field admin edition. +# [LOW] Fixed : naming issue with JHtml select.genericlist for people and date form field. Default Joomla api returns not well formed ID : should be jform_people instead of jformpeople (missing underscore). +# [LOW] Fixed : only positive integer allowed for 'Number/page' in menu options. +# [LOW] Fixed : missing context in description content.prepare (event view). +# [LOW] Fixed : full month too large in date box with default theme pack. +# [LOW] Fixed : first day of the week option for datetime picker. +# [LOW] Fixed : time display (show/hide option not working properly) in RSS feeds. +# [LOW] Fixed : back button routing after click on calendar icon was broken. +# [LOW] Fixed : missing selected date in url on Cancel registration routing back to event view. +# [LOW] Fixed : print preview error 404 when event title starts with a numeric. +# [LOW] Fixed : approval error in admin on some server. +# [LOW] Fixed : conflict with JCE media manager in the feature form field to select an image (files not displayed). +# [LOW] Fixed : frontend search for ongoing full periods sometimes missing in results. +# [LOW] Fixed : missing control if no selected single date in registration admin form. +# [MODULE][LOW] Fixed PHP 7.2 : count returns php warning when null. +# [MODULE][PRO][LOW] Fixed : module width not 100% when only 1 event, and minor flexbox css improvements. +# [MODULE][PRO][LOW] Fixed : time format am/pm broken in module iC Event List. + +* Changed files in 3.6.13 +~ admin/config.xml +~ admin/models/event.php +~ admin/models/registration.php +~ admin/models/registrations.php +~ admin/models/fields/modal/evt.php +~ admin/models/fields/modal/ictextarea_counter.php +~ admin/models/forms/customfield.xml +~ admin/models/forms/download.xml +~ admin/models/forms/event.xml +~ admin/models/forms/feature.xml +~ admin/utilities/ajax/ajax.php +~ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/form/field/customfieldgroups.php +~ admin/utilities/form/field/customform.php +~ admin/utilities/form/field/registrationdates.php +~ admin/utilities/form/field/registrationpeople.php +~ admin/utilities/form/field/registrationterms.php +~ admin/utilities/list/list.php +~ admin/utilities/render/render.php +~ admin/views/download/tmpl/default.php +~ admin/views/event/tmpl/edit.php +~ admin/views/registrations/view.html.php +~ admin/views/registrations/view.raw.php +~ admin/views/registrations/tmpl/default.php +~ icagenda.xml +~ [MEDIA] media/css/icagenda-front.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php ++ [PLUGIN] plugins/installer/icagenda/icagenda.php ++ [PLUGIN] plugins/installer/icagenda/icagenda.xml ++ [PLUGIN] plugins/installer/icagenda/LICENSE.txt ++ [PLUGIN] plugins/installer/icagenda/language/en-GB/en-GB.plg_installer_icagenda.ini ++ [PLUGIN] plugins/installer/icagenda/language/en-GB/en-GB.plg_installer_icagenda.sys.ini +~ [PLUGIN] plugins/quickicon/icagendaupdate/icagendaupdate.php +~ [PLUGIN] plugins/search/icagenda/icagenda.php +~ [PLUGIN] plugins/search/icagenda/icagenda.xml +~ [PLUGIN] plugins/system/ic_autologin/ic_autologin.php +~ script.icagenda.php +~ site/router.php +~ site/add/elements/icevent_vars.php +~ site/add/elements/iclist_vars.php +~ site/controllers/registration.php +~ site/helpers/iCicons.class.php +~ site/models/list.php +~ site/models/registration.php +~ site/models/fields/year.php +~ site/views/event/view.html.php +~ site/views/event/tmpl/default_top.php +~ site/views/list/view.feed.php +~ site/views/list/view.html.php +~ site/views/list/tmpl/default.xml +~ site/views/registration/view.html.php +~ site/views/registration/tmpl/actions.php ++ site/views/registration/tmpl/cancel.php +~ site/views/registration/tmpl/complete.php +~ site/views/registration/tmpl/default.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.6.12 (2017.07.27) +================================================================================ ++ Added : filter by approval state in admin list of events. +~ [MODULE][PRO] Changed : added flexbox CSS to improve multiple columns display in module iC Event list. +~ [THEMES] Changed : minor improvement of frontend search field height on some site templates. +~ [THEME][ic_rounded] Changed : in list view, date boxes use now category color for background if no event image. +# [MEDIUM] Fixed : entering past single date(s) and no period for one event returning a no valid date error warning. +# [LOW] Fixed : missing Joomla api getMaxUploadSize in J3.6.x (file field type), but if you have kept your Joomla 3 installation safe and up-to-date you didn't have the issue of a broken 'Submit an Event' frontend form. + +* Changed files in 3.6.12 +~ admin/models/events.php +~ admin/tables/event.php +~ admin/views/events/view.html.php +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ site/layouts/joomla/form/field/file.php +~ [THEME] site/themes/packs/default/css/default_component.css +~ [THEME] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME] site/themes/packs/ic_rounded/ic_rounded_events.php + + +iCagenda 3.6.11 (2017.07.20) +================================================================================ +~ Changed : minor improvements of the frontend search results (more accurate when Search Mode is Current List). +# [LOW] Fixed : iCalcreator library php7 issue, rename constructor to __construct. +# [LOW] Fixed : full period (no weekdays) not displayed when display all dates turned-off. +# [LOW] Fixed : wrong alert message in admin event edit, if no start and end date for period, and weekday(s) selected. +# [MODULE][LOW] Patched : possible issue with inconstant "null" date saved by new Joomla calendar picker (since J. 3.7.0), preventing the module calendar to auto-load on current month (This happened when a valid date was previously selected, then by removing date from "Load on date" option field and saving the module, it saved in database a null datetime. A second save of module with this option field empty was needed to remove not expected null datetime saved in database by new joomla calendar picker. The patch included in module does not fix Joomla bug, but fixes possible issue of not loading on current month the iCagenda calendar module). + +* Changed files in 3.6.11 +~ admin/tables/event.php +~ admin/utilities/events/data.php +~ [LIBRARY] libraries/ic_library/iCalcreator/iCalcreator.class.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php + + +iCagenda 3.6.10 (2017.07.06) +================================================================================ +# [MEDIUM] Fixed : datetime picker returning wrong value when empty (period start/end dates and/or single date(s)) that can prevent possibility to save event. +# [LOW] Fixed : filtering by date broken when 'Display all Dates' option is set on 'no'. + +* Changed files in 3.6.10 +~ admin/models/event.php +~ admin/models/fields/modal/date.php +~ admin/tables/event.php +~ admin/utilities/events/data.php +~ [LIBRARY] libraries/ic_library/date/date.php +~ script.icagenda.php +~ site/models/submit.php + + +iCagenda 3.6.9 (2017.07.05) +================================================================================ ++ Added : global option to select if the search filters apply as a global search or only to the current list. ++ Added : menu options for frontend search filters (not available on Joomla 2.5). ++ Added : [DESC], [SHORTDESC] and [METADESC] tags for email notification (frontend 'Registration' and 'Submit an Event' forms). ++ Added : set datetime picker for event dates in am/pm mode when option enabled for am/pm time. +# [Joomla 2.5][HIGH] Fixed : list of events white screen of death (Catchable fatal error : JInput::getArray()). +# [Joomla][LOW] Patched : minimum digits for phone number validation is 7 in Joomla api. Adds a custom rule for phone check to allow a minimum of 6 digits (New Caledonia). +# [Joomla 3.7][LOW] Fixed : display of Max Server upload limit in frontend file type field, not accurate with iCagenda settings (Joomla! api issue on this new feature, where Joomla layout forces to display the server max upload limit...). +# [Joomla 3.7][LOW] Fixed : width of the "override" label when selected in dropdown list of custom field types. +# [MODULE][LOW] Fixed : Hungarian hu-HU year before month in calendar module. +# [THEME][LOW] Fixed : z-index added to class .ic-share, for AddThis sharing buttons in float position (minor issue with a few site templates screen sizes). + +* Changed files in 3.6.9 +~ admin/config.xml +~ admin/assets/elements/title.php +~ admin/assets/elements/titleimg.php +~ admin/models/event.php ++ admin/models/fields/list.php +~ admin/tables/event.php +~ admin/utilities/events/data.php +~ admin/utilities/list/list.php +~ admin/views/customfield/tmpl/edit.php +~ admin/views/event/tmpl/edit.php +~ [LIBRARY] libraries/ic_library/form/field/sortablefields.php ++ [LIBRARY] libraries/ic_library/form/rule/positiveinteger.php ++ [LIBRARY] libraries/ic_library/form/rule/tel.php +- [LIBRARY][FOLDER] libraries/ic_library/form/rules +~ [MEDIA] media/css/icagenda-back.css +~ [MEDIA] media/css/icagenda-back.j25.css +~ [MEDIA] media/js/icdates.js +~ [MODULE] modules/mod_iccalendar/helper.php +~ [PLUGIN] plugins/system/ic_library/ic_library.php +~ script.icagenda.php ++ site/layouts/joomla/form/field/file.php +~ site/models/fields/categories.php +~ site/models/fields/year.php +~ site/models/registration.php +~ site/models/submit.php +~ [THEME] site/themes/packs/default/css/default_component.css +~ [THEME] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/default_filters.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.6.8 (2017.05.03) +================================================================================ ++ Added : get mode option from Joomla plugin email.cloak to set contact email as linkable mailto address (default) or not. +# [LOW] Fixed : missing addslashes for event stats labels in control panel (broken when double-quotes in event/category title). +# [LOW] Fixed : issue with counting of events to be displayed when filter by Features is used in main list of events, resulting in extra pages with no events (bug introduced since patch for module in 3.6.7). +# [LOW] Fixed : URLs after frontend search filters submit and reset click when SEF enable. +# [LOW] Fixed : [STARTDATETIME] and [ENDDATETIME] tags in registration custom notification email broken if only one period and no single date for the event. + +* Changed files in 3.6.8 +~ admin/utilities/events/data.php +~ admin/utilities/render/render.php +~ admin/views/icagenda/tmpl/default.php +~ site/add/elements/icevent_vars.php +~ site/models/registration.php +~ site/views/list/tmpl/default.php + + +iCagenda 3.6.7 (2017.04.27) +================================================================================ +! Joomla 3.7 Ready ++ Added : icagenda plugin event 'iCagendaOnNewEvent' (When a new event is first published and approved. In plugin group 'icagenda'). ++ Added : content plugin event 'iCagendaOnEventPrepare' (Preparing content for output. To modify 'event' data). ++ Added : content plugin event 'iCagendaOnEventBeforeDisplay' (Before the generated content of the 'event details' view). ++ Added : content plugin event 'iCagendaOnEventAfterDisplay' (After the generated content of the 'event details' view). ++ Added : content plugin event 'iCagendaOnListPrepare' (Preparing content for output. To modify 'list of events' data). ++ Added : content plugin event 'iCagendaOnListBeforeDisplay' (Before the generated content of the 'list of events' view). ++ Added : content plugin event 'iCagendaOnListAfterDisplay' (After the generated content of the 'list of events' view). ++ Added : content plugin event 'iCagendaOnRegistrationPrepare' (Preparing content for output. To modify 'event/registration' data). ++ Added : content plugin event 'iCagendaOnRegistrationBeforeDisplay' (Before the generated form of the 'registration' view). ++ Added : content plugin event 'iCagendaOnRegistrationAfterDisplay' (After the generated form of the 'registration' view). ++ Added : content plugin event 'iCagendaOnSubmitPrepare' (Preparing content for output. To modify 'submit an event' data). ++ Added : content plugin event 'iCagendaOnSubmitBeforeDisplay' (Before the generated form of the 'submit an event' view). ++ Added : content plugin event 'iCagendaOnSubmitAfterDisplay' (After the generated form of the 'submit an event' view). +~ Changed : extends Frontend search results. Add search in Short Description and Address. +~ Changed : frontend search filters improvement (form method changed from 'post' to 'get', and search enhancement). +~ Changed : update copyright 2017. +~ [THEMES] Changed : minor improvements to be more friendly with dark site templates. +- Removed : hardcoded 'input-large' class from custom form input field type text (to be constant with core fields) +# [MEDIUM] Fixed : alert message on registration after submit, blocking redirect to confirmation page (registration correctly processed), due to new Joomla Custom Fields system plugin (loading admin helper in frontend). +# [LOW] Fixed : button style issue with Joomla 3.7. +# [LOW] Fixed : missing dropdown selection of available dates for register button. +# [LOW] Fixed : access to complete view if no tickets available after registration. +# [LOW] Fixed : thumbnails generation from distant url. +# [LOW] Fixed : registration counter when option 'Display All Dates' is turned off. +# [LOW] Fixed : custom fields required failled to be checked if form validation is set only on 'Server' for 'Submit an event' form. +# [LOW] Fixed : html tags error in admin category edit view. +# [LOW] Fixed : should not display date (wrong format because null) in registration custom notification email when using tags [DATE] and [TIME] and registration mode is 'for all dates'. +# [MODULE][PRO][LOW] Fixed : wrong counting of events to be displayed when filter by Features is used. +# [THEMES][LOW] Fixed : frontend search input height on some site templates. + +* Changed files in 3.6.7 +~ admin/models/event.php +~ admin/models/forms/event.xml +~ admin/utilities/customfields/customfields.php +~ admin/utilities/events/data.php +~ admin/utilities/list/list.php +~ admin/utilities/manager/manager.php +~ admin/utilities/registration/registration.php +~ admin/utilities/render/render.php +~ admin/views/category/tmpl/edit.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/themes/tmpl/default.php +~ [LIBRARY] libraries/ic_library/url/url.php +~ [MEDIA] media/css/icagenda-front.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ script.icagenda.php +~ site/add/elements/iclist_vars.php +~ site/models/events.php +~ site/models/registration.php +~ site/models/submit.php +~ [THEME] site/themes/packs/default/css/default_component.css +~ [THEME] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ site/views/event/tmpl/default.php +~ site/views/event/view.html.php +~ site/views/list/tmpl/default_filters.php +~ site/views/list/tmpl/default.php +~ site/views/list/view.html.php +~ site/views/registration/tmpl/default.php +~ site/views/registration/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/view.html.php + + +iCagenda 3.6.6 (2016.12.20) +================================================================================ ++ [LIBRARY] Added : form field positive integer. +~ Changed : improved session management for current date of the event. +~ Changed : improved registrations status (number of tickets booked/available). +~ [VIEW] Changed : simplifies event/default_top view file. +~ [VIEW] Changed : removed header param control in list/default.php view file. +~ [VIEW] Changed : removed registration type control for custom fields in registration/default.php view file. +~ [MODULES] Changed : improves routing to event details view. +# [MEDIUM] Fixed : access to registration form not possible for languages where joomla transliteration returns empty value (Asian languages...). +# [LOW] Fixed : disallow zero value for number of tickets per registration. +# [LOW] Fixed : empty space for values of options in custom field type 'List', when no usage of value/label pairs. +# [LOW] Fixed : time displayed in list of all dates in event details view, even if display time option turned off. +# [LOW] Fixed : code tags {} inside Short Description should be removed. +# [LOW] Fixed : do not display a dropdown list of dates if only one option. +# [LOW] Fixed : no event message not displayed if header subtitle not enabled. + +* Changed files in 3.6.6 +~ admin/config.xml +~ admin/utilities/customfields/customfields.php +~ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/events/events.php +~ admin/utilities/form/field/registrationdates.php +~ admin/utilities/list/list.php +~ admin/utilities/registration/participants.php +~ admin/utilities/registration/registration.php ++ [LIBRARY] libraries/ic_library/form/rules/positiveinteger.php +~ [MEDIA] media/css/icagenda-back.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ site/add/elements/icevent_vars.php +~ site/models/event.php +~ site/models/list.php +~ site/models/registration.php +~ site/router.php +~ [VIEW] site/views/event/tmpl/default_top.php +~ [VIEW] site/views/list/tmpl/default.php +~ [VIEW] site/views/registration/tmpl/default.php +~ site/views/registration/view.html.php + + +iCagenda 3.6.5 (2016.11.23) +================================================================================ ++ Added : Ajax refresh of number of tickets in the frontend registration form, depending of the date selected. ++ Added : new css classes to able custom styles on period dates in event details view 'List of Dates'. +~ Changed : refactory of the functions to count number of registrations booked/available for component and modules. +~ Changed : default status is set to 'published' in status filter when accessing the registrations list in admin (and for export csv). +~ Changed : improve telephone field type check if valid phone number (registration form). +# [LOW] Fixed : dates display in admin registrations list, after adding a new registetration using admin, and event registration type is for all dates. +# [LOW] Fixed : control maximum of available tickets when creating a registration in admin. +# [LOW] Fixed : control maximum of available tickets in frontend registration form was broken if less available places than selected number of tickets. +# [LOW] Fixed : missing required attribute when using a custom field of type override name. +# [LOW] Fixed : submission of empty required custom fields filled with space (missing trim spaces). +# [LOW] Fixed : search in frontend with from/to the same day returned no event even if events exist for this date. +# [LOW] Fixed : image select input width when using JCE media field type. +# [LOW] Fixed : possible wrong date display in event view (when multiple dates). +# [LOW] Fixed : bugs in RSS feeds (missing category, wrong date...) and minor improvement (using global joomla RSS feeds limit). +# [MODULE][PRO][LOW] Fixed : introduction text broken (short description). + +* Changed files in 3.6.5 +~ admin/models/fields/modal/evt.php +~ admin/models/fields/modal/icmulti_checkbox.php +~ admin/models/forms/registration.xml +~ admin/models/registration.php +~ admin/models/registrations.php +~ admin/tables/registration.php +~ admin/utilities/ajax/ajax.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/form/field/registrationdates.php +~ admin/utilities/form/field/registrationpeople.php +~ admin/utilities/registration/participants.php +~ admin/utilities/registration/registration.php +~ admin/views/registration/tmpl/edit.php +~ admin/views/registrations/view.html.php +~ [LIBRARY] libraries/ic_library/form/field/sortablefields.php +~ [MEDIA] media/css/icagenda-back.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ script.icagenda.php +~ site/add/elements/icevent_vars.php +~ site/controller.php +~ site/controllers/registration.php +~ site/models/event.php +~ site/models/events.php +~ site/models/forms/registration.xml +~ site/models/list.php +~ site/models/registration.php +~ site/views/event/tmpl/default_top.php +~ site/views/list/view.feed.php +~ site/views/registration/tmpl/default.php +~ site/views/registration/view.html.php + + +iCagenda 3.6.4.1 (patch Joomla 2.5) (2016.10.18) +================================================================================ +# [Joomla 2.5] Fixed : empty list of events in component List Events view (patch for iCagenda 3.6.4). + +* Changed files in 3.6.4.1 +~ admin/utilities/events/data.php + + +iCagenda 3.6.4 (2016.10.15) +================================================================================ ++ [MODULE][CALENDAR] Added : option to display an event only if a menu item of type 'List Events' (or the selected menu item in the 'Link to Menu Item' option) matches the event depending on the menu options and event settings. +~ [MODULE][PRO] Changed : code improvement. +# [LOW] Fixed : https for gravatar on ssl server. +# [LOW][MODULES] Fixed : alert message for admins in frontend (and improvement of events to be displayed controls). +# [LOW] Fixed : issue with multiple xml attribute due to a bug with 'showon' in Joomla 3.2.4 > 3.4.1 (custom field admin edit). +# [LOW] Fixed : event individual option to show or hide AddThis on event details view. +# [LOW] Fixed : custom fields input width with site templates not supporting Joomla core fields layouts. +# [LOW] Fixed : global registrations counter. + +* Changed files in 3.6.4 +~ admin/config.xml +~ admin/models/event.php +~ admin/models/fields/modal/menulink.php +~ admin/models/forms/customfield.xml +~ admin/tables/event.php +~ admin/utilities/addthis/addthis.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/events/data.php +~ admin/utilities/form/field/customfieldgroups.php +~ admin/utilities/menus/menus.php +~ admin/utilities/registration/participants.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ site/models/event.php +~ site/models/forms/registration.xml +~ site/views/list/tmpl/default.php + + +iCagenda 3.6.3 (2016.09.26) +================================================================================ ++ [MODULE][PRO] Added : options to filter events by Feature(s) in Module iC Event List. ++ Added : plugin event handler on Event Prepare (to allow individually by event, enabling/disabling jComments integration by using JComments tag {jcomments off} in event full description editor. Needs version 1.1.0 of iC JComments plugin: http://icagenda.joomlic.com/resources/addons/jcomments-content-plugin) +~ [MODULES] Changed : Mode 'auto' for Menu Item Link option now will allow to display events even if no menu item link set properly to display this event (will generate a standard sef url using the home menu item (Joomla! routing system), in the identical way Joomla Articles modules behave). +~ [THEME PACKS] Changed : Responsive improvements for Frontend Search Filters buttons. +~ Changed : 'complete' view (landing page after registration with a bit more information on user's registration). +~ Changed : a bit of code clean-up and minor improvements as well as css corrections to prevent possible css conflict with a few site templates. +# [LOW][MODULE] Fixed : Registration status fixes in module Calendar (could return close when still open). +# [LOW][MODULE] Fixed : Events disappearing in module Calendar (issue with date control). +# [LOW] Fixed : Registration dates if Type is set for registration to all the dates (fix on registration process and update database to fix issue). +# [LOW] Fixed : Missing event state control if access through event's direct url. +# [LOW] Fixed : Missing one translation string in confirmation page after registration has been processed ('Registration Information'). +# [LOW] Fixed : Missing checkbox label for Terms and Conditions in Registration form. +# [LOW] Fixed : Hits only on published events (could have counts on other status). +# [LOW] Fixed : Script error from a deprecated script (not used anymore) in registration complete view. +# [LOW] Fixed : Script error in menu item options. + +* Changed files in 3.6.3 +~ admin/models/fields/modal/icmulti_opt.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/form/field/registrationdates.php +~ admin/utilities/form/field/registrationterms.php +~ admin/utilities/registration/participants.php +~ [MEDIA] media/css/icagenda-front.css +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ [INSTALL] script.icagenda.php +~ site/models/event.php +~ site/models/events.php +~ site/models/forms/registration.xml +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_component_medium.css +~ [THEME PACKS] site/themes/packs/default/css/default_component_small.css +~ [THEME PACKS] site/themes/packs/default/css/default_component_xsmall.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_medium.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_small.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_xsmall.css +~ site/views/event/view.html.php +~ site/views/registration/tmpl/complete.php +~ site/views/registration/tmpl/default.php +~ site/views/registration/view.html.php + + +iCagenda 3.6.2 (2016.09.01) +================================================================================ +# [LOW] Fixed : Custom fields not saved in 3.6.1 in admin event edit (issue due to frontend fix). +# [LOW] Fixed : Approval icon in frontend broken (no effect). +# [LOW] Fixed : Registration button type if no other dates, and period registration complete. +# [LOW] Fixed : Search input filter not returning past events in search results. + +* Changed files in 3.6.2 +~ admin/utilities/customfields/customfields.php +~ admin/utilities/events/data.php +~ admin/utilities/form/field/registrationdates.php +~ admin/utilities/manager/manager.php +~ admin/utilities/registration/registration.php + + +iCagenda 3.6.1 (2016.08.29) +================================================================================ ++ Added : force system slugs for overrides of core fields and protect from usage in other custom field types. +~ Changed : minor UI improvement of custom field edition. +~ Changed : set properly required column setting in Custom Fields admin list. +~ Changed : don't show 'slug' option if type is a core field override in custom field edition form (needs minimum Joomla 3.2.4 for showon feature). +~ Changed : Check if user ID exists to prevent alert message in events admin list. This Joomla alert message is kept for the event edition where user does not exist anymore, but hidden in the admin list of events to prevent misunderstanding. +# [MEDIUM] Fixed : Custom fields data not saved in frontend 'Submit an Event' form. +# [LOW] Fixed : event add to cal in .ics format (iCal and Outlook). +# [LOW] Fixed : warning message if error reporting turn on, and no custom fields set for Submit an Event form. +# [LOW] Fixed : usage of core_* slug names in not-core field types. +# [LOW] Fixed : required option broken for core field 'Phone' in registration form. +# [LOW] Fixed : search filter of type calendar better adjustment to fit with site template not managing well Joomla core calendar picker input field. +# [LOW] Fixed : advanced email check options in registration form broken. +# [LOW] Fixed : RSS feeds broken. + +* Changed files in 3.6.1 +~ admin/models/events.php +~ admin/models/forms/customfield.xml +~ admin/tables/customfield.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/event/data.php +~ admin/views/customfield/tmpl/edit.php +~ admin/views/customfields/tmpl/default.php +~ admin/views/customfields/view.html.php +~ [MEDIA] media/css/icagenda-front.css +~ site/models/registration.php +~ site/views/event/tmpl/default_vcal.php +~ site/views/list/tmpl/default_filters.php +~ site/views/list/view.feed.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.6.0 (2016.08.19) +================================================================================ +! New : Frontend Search Filters +1 - Global Options: Component Options > List tab. +1 - Drag & drop filters options to change frontend ordering. +1 - Options of display (responsive, full width, show or hide 'Search' label...). +! Refactory : List of events +1 - The list view is now divided into 3 separate views: list, event and registration. +1 - Performance improvement: up to 10 times faster to load the main list of events! +! Refactory : Registration Form +1 - A full new view HTML structure, to load all fields with a maximum of flexibility +1   and performance (see custom field groups) +! New : Admin Custom Fields List and Edition Reviewed +1 - List: useful info directly in the list of custom fields. +1 - Edition: Will show option(s) depending on selected parent form and field type +1   (minimum Joomla 3.2.4 to get this functionnality). +! New : Custom Field Groups +1 - Create and manage groups for custom fields (directly in Custom Field edition). +1 - Set individually in each event edition (Registration tab) the groups of custom fields to use for the registration form. +! New : Custom Field Types +1 - New field types: date (calendar), url, email +1 - New field type "label (separator)": to add label headings inside form (with custom CSS class option) +1 - New field type "description (separator)": to add a description text inside form (with custom CSS class option) +1 - Override field types: name, email, phone, date and tickets +1   (replace the core iCagenda fields, to allow ordering inside custom fields as you want!) +! New : Statistics +1 - Hits on events. +1 - Charts for category and event hits, displayed in the control panel of iCagenda. +! Anonymous Usage Statistics +1 Usage statistics or 'Telemetry' is a feature in iCagenda that sends anonymously and automatically your system information (Similar to the Joomla! Statistics plugin introduced in Joomla 3.5). +1 This will only submit the Joomla! version, PHP version, database engine and version, and iCagenda version. Usage statistics are collected during the update, and help us improve future versions of iCagenda. +1 The code used for this anonymous data submission can be read in the install script file of the extension (script.icagenda.php). +1 You can disable this feature in global options of iCagenda component, 'General Settings' tab. +! New : Module iC Event List (PRO) +1 - Option to display all dates. ++ Added : option to set month format in the date box (list of events). ++ Added : missing options in filter by custom field type (admin list of custom fields). ++ Added : control for current page in list pagination before rendering. ++ Added : select user in registration edition, with auto-filled name and email (depending on your global settings). ++ Added : admin filter (dropdown) to select custom fields by group. ++ Added : landing page for registration form in frontend. +- Removed : all not needed anymore rel="nofollow" in modules event links. +~ Changed : date drop down in registration form is auto selected on the date clicked. +~ [THEME PACKS] Changed : in THEME_events.php, variable $EVENT_MONTHSHORT replaced by $EVENT_MONTH (to use new month format option). +~ Changed : includes all fixes and improvements of versions 3.5.14 and 3.5.21 (see releases notes for additional info). + +* Changed files in 3.6.0 +~ admin/config.xml +~ admin/controllers/customfield.php +~ admin/controllers/registration.php +~ admin/icagenda.php +~ admin/liveupdate/liveupdate.php +~ admin/models/category.php +~ admin/models/customfield.php +~ admin/models/customfields.php +~ admin/models/event.php +~ admin/models/events.php +~ admin/models/fields/modal/cat.php +~ admin/models/fields/modal/checkdnsrr.php +~ admin/models/fields/modal/ic_editor.php +~ admin/models/fields/modal/ictext_placeholder.php ++ admin/models/fields/spacer/description.php ++ admin/models/fields/spacer/label.php +~ admin/models/forms/customfield.xml +~ admin/models/forms/event.xml +~ admin/models/forms/registration.xml +~ admin/models/icagenda.php +~ admin/models/registrations.php +~ admin/sql/install/mysql/icagenda.install.sql +~ admin/sql/uninstall/mysql/icagenda.uninstall.sql +~ admin/tables/customfield.php +~ admin/tables/event.php ++ [FOLDER] admin/utilities/addthis/ ++ admin/utilities/addthis/addthis.php ++ [FOLDER] admin/utilities/addtocal/ ++ admin/utilities/addtocal/addtocal.php +~ admin/utilities/ajax/ajax.php ++ admin/utilities/ajax/filter.php +~ admin/utilities/customfields/customfields.php ++ [FOLDER] admin/utilities/event/ ++ admin/utilities/event/data.php ++ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/events/events.php ++ [FOLDER] admin/utilities/form/field/ ++ admin/utilities/form/field/customfieldgroups.php ++ admin/utilities/form/field/customform.php ++ admin/utilities/form/field/registrationdates.php ++ admin/utilities/form/field/registrationpeople.php ++ admin/utilities/form/field/registrationterms.php +~ admin/utilities/form/form.php ++ [FOLDER] admin/utilities/googlemaps/ ++ admin/utilities/googlemaps/googlemaps.php ++ [FOLDER] admin/utilities/list/ ++ admin/utilities/list/list.php ++ [FOLDER] admin/utilities/manager/ ++ admin/utilities/manager/manager.php ++ [FOLDER] admin/utilities/registration/ ++ admin/utilities/registration/participants.php ++ admin/utilities/registration/registration.php ++ [FOLDER] admin/utilities/render/ ++ admin/utilities/render/render.php ++ admin/utilities/theme/joomla25.php ++ admin/utilities/theme/style.php +~ admin/utilities/theme/theme.php +~ admin/views/customfield/tmpl/edit.php +~ admin/views/customfields/tmpl/default.php +~ admin/views/customfields/view.html.php +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php +~ admin/views/events/tmpl/default.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/icagenda/view.html.php +~ admin/views/info/tmpl/default.php +~ admin/views/registration/tmpl/edit.php +~ admin/views/registrations/tmpl/default.php +~ icagenda.xml +~ [LIBRARY] libraries/ic_library/date/date.php +~ [LIBRARY] libraries/ic_library/filter/output.php ++ [LIBRARY][FOLDER] libraries/ic_library/form/ ++ [LIBRARY][FOLDER] libraries/ic_library/form/field/ ++ [LIBRARY]libraries/ic_library/form/field/sortablefields.php +~ [LIBRARY] libraries/ic_library/globalize/culture/cs-CZ.php +~ [LIBRARY] libraries/ic_library/globalize/culture/en-GB.php ++ [LIBRARY][FOLDER] libraries/ic_library/iCalcreator/ ++ [LIBRARY]libraries/ic_library/iCalcreator/iCalcreator.class.php ++ [LIBRARY][FOLDER] libraries/ic_library/render/ ++ [LIBRARY] libraries/ic_library/render/render.php +~ [LIBRARY] libraries/ic_library/url/url.php +~ [MEDIA] media/css/icagenda-back.css +~ [MEDIA] media/css/icagenda-front.css +~ [MEDIA] media/css/icagenda-front.j25.css +~ [MEDIA][iCicons] media/icicons/fonts +~ [MEDIA][iCicons] media/icicons/style.css +- [MEDIA] media/images/video_poster_icagenda.jpg +- [MEDIA] media/images/youtube_iCagenda.png ++ [MEDIA] media/js/Chart.js ++ [MEDIA] media/js/Chart.min.js +~ [MEDIA] media/js/icagenda.js +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [PLUGIN] plugins/search/icagenda/icagenda.php +~ [PLUGIN] plugins/system/ic_library/ic_library.php +~ script.icagenda.php ++ site/add/elements/icevent_vars.php ++ site/add/elements/iclist_vars.php +- site/add/elements/icsetvar.php +~ site/controller.php ++ [FOLDER] site/controllers/ ++ site/controllers/registration.php +- site/helpers/iCalcreator.class.php +- site/helpers/ichelper.php +- site/helpers/icmodel.php +- site/helpers/media_css.class.php +~ site/icagenda.php ++ site/models/event.php +~ site/models/events.php ++ [FOLDER] site/models/fields/ ++ site/models/fields/categories.php ++ site/models/fields/month.php ++ site/models/fields/year.php +~ site/models/forms/registration.xml +~ site/models/forms/submit.xml +~ site/models/list.php ++ site/models/registration.php +~ site/models/submit.php +~ site/router.php +~ [THEME PACK] site/themes/packs/default/css/default_component.css +~ [THEME PACK] site/themes/packs/default/css/default_component_medium.css +~ [THEME PACK] site/themes/packs/default/css/default_component_small.css +~ [THEME PACK] site/themes/packs/default/css/default_component_xsmall.css +~ [THEME PACK] site/themes/packs/default/default_day.php +~ [THEME PACK] site/themes/packs/default/default_events.php +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component_medium.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component_small.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component_xsmall.css +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_events.php ++ [FOLDER] site/views/event/ ++ [FOLDER] site/views/event/tmpl/ ++ site/views/event/tmpl/default.php ++ site/views/event/tmpl/default_top.php ++ site/views/event/tmpl/default_vcal.php ++ site/views/event/view.html.php +- site/views/list/tmpl/actions.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/default_categories.php ++ site/views/list/tmpl/default_filters.php +- site/views/list/tmpl/default_vcal.php +- site/views/list/tmpl/event.php +- site/views/list/tmpl/registration.php +~ site/views/list/view.feed.php +~ site/views/list/view.html.php ++ [FOLDER] site/views/registration/ ++ [FOLDER] site/views/registration/tmpl/ ++ site/views/registration/tmpl/actions.php ++ site/views/registration/tmpl/complete.php ++ site/views/registration/tmpl/default.php ++ site/views/registration/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/view.html.php + + +iCagenda 3.5.21 (2016.08.04) +================================================================================ +# [HIGH] Fixed : Fresh install and udpate could fail with a broken admin (only free version). +# [LOW] Fixed : warning if library disabled in control panel + +* Changed files in 3.5.21 +~ admin/icagenda.php +~ icagenda.xml + + +$ iCagenda 3.6.0-rc1 (2016.07.30) +================================================================================ +! Anonymous Usage Statistics +1 Usage statistics or 'Telemetry' is a feature in iCagenda that sends anonymously and automatically your system information (Similar to the Joomla! Statistics plugin introduced in Joomla 3.5). +1 This will only submit the Joomla! version, PHP version, database engine and version, and iCagenda version. Usage statistics are collected during the update, and help us improve future versions of iCagenda. +1 The code used for this anonymous data submission can be read in the install script file of the extension (script.icagenda.php). +1 You can disable this feature in global options of iCagenda component, 'General Settings' tab. +# [LOW] Fixed : default setting for new option DateBox Month Format +# [LOW] Fixed : warning if library disabled in control panel +# [LOW] Fixed : warning if no custom fields in registration form + +* Changed files in 3.6.0-rc1 +~ admin/config.xml +~ admin/icagenda.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ [MEDIA] media/icicons/style.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ script.icagenda.php +~ site/add/elements/iclist_vars.php +~ site/views/registration/tmpl/default.php + + +iCagenda 3.5.20 (2016.07.28) +================================================================================ +# [LOW] Fixed : missing Google API Key when set, in frontend 'Submit an Event' form. +# [LOW] Fixed : missing some current dates (single dates) when 'Current and upcoming events' filtering. +# [LOW] Fixed : possible issue of css conflict between iCagenda icons font and site template icons font. + +* Changed files in 3.5.20 +~ admin/utilities/events/data.php +~ [MEDIA] media/icicons/style.css +~ site/views/submit/tmpl/default.php + + +$ iCagenda 3.6.0-beta1 (2016.07.13) +================================================================================ +! Refactory : Custom Fields admin list +1 - improve Custom Fields admin list usability and readability. +! New : Custom Field Types +1 - new field type "label (separator)": to add label headings inside form (with custom CSS class option) +1 - new field type "description (separator)": to add a description text inside form (with custom CSS class option) ++ Added : option to set month format in the date box (list of events). ++ Added : missing options in filter by custom field type (admin list of custom fields). ++ Added : control for current page in list pagination before rendering. +- Removed : all not needed anymore rel="nofollow" in modules event links. +~ Changed : includes all fixes and improvements of versions 3.5.18 and 3.5.19 (see releases notes for additional info). +~ [THEME PACKS] Changed : in THEME_events.php, variable $EVENT_MONTHSHORT replaced by $EVENT_MONTH (to use new month format option). +# Fixed : event individual option to set registration deadline. +# Fixed : missing custom fields filled in admin registration edit page. +# Fixed : minor search filters grid css adjustement. +# Fixed : Error page if page searched does not exist. + +* Changed files in 3.6.0-beta1 +~ admin/config.xml +~ admin/models/category.php +~ admin/models/customfield.php +~ admin/models/customfields.php +~ admin/models/event.php +~ admin/models/fields/modal/cat.php ++ admin/models/fields/spacer/description.php ++ admin/models/fields/spacer/label.php +~ admin/models/forms/customfield.xml +~ admin/tables/customfield.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/events/events.php +~ admin/utilities/form/field/registrationdates.php +~ admin/utilities/googlemaps/googlemaps.php +~ admin/utilities/list/list.php +~ admin/utilities/registration/registration.php +~ admin/views/customfield/tmpl/edit.php +~ admin/views/customfields/tmpl/default.php +~ admin/views/event/tmpl/edit.php +~ admin/views/registration/tmpl/edit.php +~ [LIBRARY] libraries/ic_library/date/date.php +~ [MEDIA] media/css/icagenda-front.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [PLUGIN] plugins/quickicon/icagendaupdate/icagendaupdate.php +~ site/add/elements/iclist_vars.php +~ site/models/list.php +~ site/models/registration.php +~ site/models/submit.php + + +iCagenda 3.5.19 (2016.06.30) +================================================================================ +! Since June 22, 2016, Google Maps API no longer support keyless access. +1 Active domains created before June 22, 2016, continue to be able to access the Google Maps JavaScript API, Static Maps API, and Street View Image API without an API key. They are not affected by keyless access being unavailable for new domains. +1 However it is advised to use a key in order to guarantee the quality of service. ++ Added : Option to set Google Maps browser API key (Global Options > General Settings). +# [LOW] Fixed : Error sql 00000 in event edition and registration form on PDO sql server. +# [LOW] Fixed : error page not found if sh404sef extension installed. +# [LOW][THEME PACK default] Fixed : size of Date Box conteneur when a site template declares a 'box-sizing: border-box' style to all div. + +* Changed files in 3.5.19 +~ admin/config.xml +~ admin/utilities/customfields/customfields.php +~ admin/views/event/tmpl/edit.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ [THEME PACK] site/themes/packs/default/css/default_component.css + + +iCagenda 3.5.18 (2016.06.19) Security Release [J! 2.5] +================================================================================ ++ Added : username of the user who has submitted event in frontend (event admin edition, Publishing tab). +~ Changed : a few minor code cleaning. +# [SECURITY][MEDIUM][Joomla 2.5.x ONLY!] Fixed : possible non-persistent (or reflected) cross-site scripting vulnerability (Note: if you have a Joomla 3 website, you DON'T have this security vulnerability. If you use iCagenda 3.6.0-alpha, NO ISSUE on both Joomla versions 2.5 and 3). A reflected attack is typically delivered via email or a neutral web site. The bait is an innocent-looking URL, pointing to a trusted site but containing the XSS vector. If the trusted site is vulnerable to the vector, clicking the link can cause the victim's browser to execute the injected script (your joomla 2.5 site is not directly compromised, but your visitor could be... please, update!). Again, it's recommended for all users still using Joomla 2.5, to upgrade to Joomla 3 as soon as possible! (Joomla 2.5 is not updated and end of life since December 2014. iCagenda will stop support Joomla 2.5 after iCagenda 3.6 release.) +# [LOW] Fixed : alias generation if unicode enabled in Joomla global configuration. +# [LOW] Fixed : user name display in list of events when created_by not set. +# [LOW] Fixed : possible issue on multiple clicks on submit button (frontend form) resulting in duplicated data. +# [LOW] Fixed : ordering by username in admin events list. +# [LOW] Fixed : white page in admin control panel on pdo-mysql database. +# [LOW] Fixed : issue with some date formats in en-US language. +# [LOW] Fixed : issue with quick icon plugin on iCagenda uninstall (Joomla admin control panel white page). +# [LOW] Fixed : 'Place' name translation with Falang. +# [LOW] Fixed & improved : Image name control (space replacement) and renaming if needed, in frontend 'Submit an Event' form. +# [LOW][MODULE][PRO] Fixed : missing events if date filter is set to display only past events. + +* Changed files in 3.5.18 +~ admin/models/category.php +~ admin/models/event.php +~ admin/models/events.php +~ admin/models/forms/event.xml +~ admin/utilities/categories/categories.php +~ admin/utilities/events/data.php +~ admin/utilities/form/form.php +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php +~ admin/views/events/tmpl/default.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ [LIBRARY] libraries/ic_library/globalize/culture/en-US.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [PLUGIN] plugins/quickicon/icagendaupdate/icagendaupdate.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ site/models/submit.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php + + +$ iCagenda 3.6.0-alpha2.1 (2016.06.02) +================================================================================ ++ Added : missing files of alpha2 (Thanks to the first beta-testers report!) + +* Changed files in 3.6.0-alpha2.1 +~ admin/utilities/customfields/customfields.php +~ admin/utilities/event/data.php +~ admin/utilities/event/event.php + + +$ iCagenda 3.6.0-alpha2 (2016.05.31) +================================================================================ +! New : Registration Form Refactory +1 - a full new view HTML structure, to load all fields with a maximum of flexibility +1   and performance (see custom field groups) +! New : Custom Field Types +1 - new field types: date (calendar), url, email (new ones will be added in beta1!) +1 - override field types: name, email, phone, date and tickets +1   (replace the core iCagenda fields, to allow ordering inside custom fields as you want!) +! New : Admin Custom Field List and Edition Reviewed +1 - List: useful info directly in the list of custom fields. +1 - Edition: Will show option(s) depending on selected parent form and field type +1   (minimum Joomla 3.2.4 to get this functionnality). +! And a lot of code improvements! ;-) ++ Added : select user in registration edition, with auto-filled name and email (depending on your global settings). ++ Added : admin filter (dropdown) to select custom fields by group. ++ Added : landing page for registration form in frontend. +~ Changed : includes all fixes and improvements of versions 3.5.14 to 3.5.17 (see releases notes for additional info). +# [J2.5][MEDIUM] Fixed (alpha1) : was broken on Joomla 2.5 +# [LOW] Fixed (alpha1) : redirection on successfull registration. +# [LOW] Fixed (alpha1) : multiple words search in frontend. +# [LOW] Fixed (alpha1) : pagination issue on Chrome when search filters disabled. + +* Changed files in 3.6.0-alpha2 +~ admin/config.xml +~ admin/controllers/registration.php +~ admin/controllers/registrations.raw.php +~ admin/icagenda.php +~ admin/liveupdate/liveupdate.php +~ admin/models/category.php +~ admin/models/customfield.php +~ admin/models/customfields.php +~ admin/models/event.php +~ admin/models/events.php +~ admin/models/forms/customfield.xml +~ admin/models/forms/download.xml +~ admin/models/forms/event.xml +~ admin/models/forms/registration.xml +~ admin/models/mail.php +~ admin/models/registrations.php +~ admin/tables/customfield.php +~ admin/utilities/ajax/ajax.php +~ admin/utilities/categories/categories.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/form/field/customfieldgroups.php ++ admin/utilities/form/field/registrationdates.php ++ admin/utilities/form/field/registrationpeople.php ++ admin/utilities/form/field/registrationterms.php +~ admin/utilities/form/form.php +~ admin/utilities/list/list.php +~ admin/utilities/registration/participants.php +~ admin/utilities/registration/registration.php +~ admin/utilities/theme/joomla25.php +~ admin/utilities/theme/theme.php +~ admin/views/customfield/tmpl/edit.php +~ admin/views/customfields/tmpl/default.php +~ admin/views/customfields/view.html.php +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php +~ admin/views/events/tmpl/default.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ admin/views/registration/tmpl/edit.php +~ admin/views/registrations/tmpl/default.php +~ icagenda.xml +~ [LIBRARY] libraries/ic_library/filter/output.php +~ [LIBRARY] libraries/ic_library/form/field/sortablefields.php +~ [LIBRARY] libraries/ic_library/globalize/culture/cs-CZ.php +~ [LIBRARY] libraries/ic_library/globalize/culture/en-GB.php +~ [LIBRARY] libraries/ic_library/globalize/culture/en-US.php +~ [LIBRARY] libraries/ic_library/globalize/culture/fa-IR.php ++ [LIBRARY] libraries/ic_library/globalize/culture/fo-FO.php +~ [LIBRARY] libraries/ic_library/globalize/globalize.php +~ [LIBRARY] libraries/ic_library/lib_ic_library.xml ++ [LIBRARY] libraries/ic_library/render/render.php +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [LIBRARY] libraries/ic_library/url/url.php +~ [MEDIA] media/css/icagenda-back.css +~ [MEDIA] media/css/icagenda-front.css +~ [MEDIA] media/css/icagenda-front.j25.css +~ [MEDIA] media/js/icagenda.js +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml ++ [PLUGIN] plugins/quickicon/icagendaupdate/icagendaupdate.php ++ [PLUGIN] plugins/quickicon/icagendaupdate/icagendaupdate.xml ++ [PLUGIN] plugins/quickicon/icagendaupdate/language/ +~ [PLUGIN] plugins/system/ic_library/ic_library.php +~ script.icagenda.php +~ site/add/elements/icevent_vars.php +~ site/controllers/registration.php +~ site/icagenda.php +~ site/models/event.php +~ site/models/events.php +~ site/models/forms/registration.xml +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/registration.php +~ site/models/submit.php +~ site/router.php +~ [THEME PACK] site/themes/packs/default/css/default_component.css +~ [THEME PACK] site/themes/packs/default/css/default_module.css +~ [THEME PACK] site/themes/packs/default/default_day.php +~ [THEME PACK] site/themes/packs/default/default_event.php +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/event/tmpl/default.php +~ site/views/event/view.html.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default_categories.php +~ site/views/list/view.html.php +~ site/views/registration/tmpl/complete.php +~ site/views/registration/tmpl/default.php +~ site/views/registration/view.html.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.5.17 (2016.04.12) +================================================================================ ++ Added : Patches and controls for Joomla 3.5.1 mail issues, returning a "0 - Invalid address: " error depending of your settings and server. +~ Changed : admin module options minor UI change, with replacement of icon image (in info message) by iCagenda font icons. +# [LIBRARY][LOW] Fixed : error if uploaded image is too big for php thumbnails generator (control was broken). +# [MODULE iC Calendar][J2.5][LOW] Fixed : All categories option select bug on Joomla 2.5 +# [MODULE iC Event List][PRO][LOW] Fixed : wrong info message for admin logged-in on frontend. + +* Changed files in 3.5.17 +~ admin/models/mail.php +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ site/helpers/icmodel.php +~ site/models/submit.php + + +iCagenda 3.5.16 (2016.03.19) +================================================================================ +! New : Quick Icon plugin for update notification +1 - Checks for iCagenda updates and notifies you when you visit the Control Panel page of Joomla! administration. +! Info : iCagenda 3.5 is Joomla! 3.5 and PHP 7 READY! ++ [GLOBALIZATION] Added : fo-FO Faroese (Faroe Islands) date formats. +# [MODULE iC Calendar][LOW] Fixed : time loading when a lot of past events. +# [MODULE iC Event List][PRO][MEDIUM] Fixed : issue with number of events option (not always displaying all the events as set by this option). + +* Changed files in 3.5.16 +~ admin/models/events.php +~ icagenda.xml +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ script.icagenda.php +~ site/models/events.php ++ [LIBRARY] libraries/ic_library/globalize/culture/fo-FO.php ++ plugins/quickicon/icagendaupdate/icagendaupdate.php ++ plugins/quickicon/icagendaupdate/icagendaupdate.xml ++ [FOLDER] plugins/quickicon/icagendaupdate/language/ + + +iCagenda 3.5.15 (2016.02.19) +================================================================================ +# [Registrations CSV Export][LOW] Fixed : html tags in 'Notes' when this field was filled in admin registration edition. +# [Registrations CSV Export][LOW] Fixed : missing period dates (when registration for a full period) in 'date' column. +# [MODULE iC Event List][PRO][MEDIUM] Fixed : category filter was broken in 3.5.14. +# [MODULE iC Event List][PRO][LOW] Fixed : some events not displayed, depending on your settings. +# [MODULE iC Event List][PRO][LOW] Fixed : direct url to event when full period with no weekdays selected. +# [MODULE iC Calendar][LOW] Fixed : conflict on windows with Ctrl+C and the a11y shortcut keyaccess used for direct-focus on module calendar (replaced by Ctrl+Alt+C). + +* Changed files in 3.5.15 +~ admin/models/registrations.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php + + +iCagenda 3.5.14 (2016.01.23) +================================================================================ ++ [MODULE iC Event List][PRO] Added : option to display all dates. ++ [Registrations CSV Export] Added : option to export registration ID (disabled by default). ++ [a11y](experimental) : keyboard accessibility for navigation in the calendar module on focus. ++ [THEME PACKS] Added : additional class names for each information fields, to allow individual css styling (ic-info-email, ic-info-website,... and for custom fields, ic-info-[slug]). +~ Changed : improvement of file renaming on upload of file attachment. +~ Changed : allow to show registration options in 'Submit an Event' frontend form, even if registrations are disabled in global options, and will set to OFF by default in the form field option. +~ [THEME PACKS] Changed : review of clearfix in event details view, to allow custom CSS flexibility for floating positions. +# [LOW] Fixed : if 'Display all dates' option is set to NO, do not show an event in past events, if at least this event has one current/upcoming date. +# [LOW] Fixed : do not display time in frontend confirmation message after a successful registration, if display time option for this event is set to off. +# [LOW] Fixed : depending on your site, possibility of an invalid date format (1 January 1970) for registrations notification on a full period (from ... to ...). +# [LOW] Fixed : remove sup html tags in notification emails, if the date format includes exposant suffix for day (en-US). + +* Changed files in 3.5.14 +~ admin/controllers/registrations.raw.php +~ admin/models/event.php +~ admin/models/forms/download.xml +~ admin/models/registrations.php +~ admin/utilities/events/data.php +~ admin/utilities/menus/menus.php +~ [LIBRARY] libraries/ic_library/filter/output.php +~ [LIBRARY] libraries/ic_library/globalize/globalize.php +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ site/add/elements/icsetvar.php +~ site/helpers/icmodel.php +~ site/models/events.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/list/tmpl/registration.php +~ site/views/submit/tmpl/default.php + + +$ iCagenda 3.6.0-alpha1 (2015.12.28) +================================================================================ +! New : Frontend Search Filters +1 - Global Options: Component Options > List tab. +1 - Drag & drop filters options to change frontend ordering. +1 - Options of display (responsive, full width, show or hide 'Search' label...). +! New : Statistics +1 - Hits on events. +1 - Charts for category and event hits, displayed in the control panel of iCagenda. +! New : Custom Field Groups +1 - Create and manage groups for custom fields (directly in Custom Field edition). +1 - Set individually in each event edition (Registration tab) the groups of custom fields to use for the registration form. +! New : Module iC Event List (PRO) +1 - Option to display all dates. +~ Changed : the list view is now divided into 3 separated views: list, event and registration. +~ Changed : date drop down in registration form is auto selected on the date clicked. + +* Changed files in 3.6.0-alpha1 +~ admin/config.xml +~ admin/controllers/customfield.php +~ admin/icagenda.php +~ admin/models/customfield.php +~ admin/models/event.php +~ admin/models/events.php +~ admin/models/fields/modal/checkdnsrr.php +~ admin/models/fields/modal/ic_editor.php +~ admin/models/forms/customfield.xml +~ admin/models/forms/event.xml +~ admin/models/icagenda.php +~ admin/sql/install/mysql/icagenda.install.sql +~ admin/sql/uninstall/mysql/icagenda.uninstall.sql +~ admin/tables/customfield.php +~ admin/tables/event.php ++ [FOLDER] admin/utilities/addthis/ ++ admin/utilities/addthis/addthis.php ++ [FOLDER] admin/utilities/addtocal/ ++ admin/utilities/addtocal/addtocal.php ++ admin/utilities/ajax/filter.php +~ admin/utilities/customfields/customfields.php ++ [FOLDER] admin/utilities/event/ ++ admin/utilities/event/data.php ++ admin/utilities/event/event.php +~ admin/utilities/events/data.php +~ admin/utilities/events/events.php ++ [FOLDER] admin/utilities/form/field/ ++ admin/utilities/form/field/customfieldgroups.php ++ admin/utilities/form/field/customform.php ++ [FOLDER] admin/utilities/googlemaps/ ++ admin/utilities/googlemaps/googlemaps.php ++ [FOLDER] admin/utilities/list/ ++ admin/utilities/list/list.php ++ [FOLDER] admin/utilities/manager/ ++ admin/utilities/manager/manager.php ++ [FOLDER] admin/utilities/registration/ ++ admin/utilities/registration/participants.php ++ admin/utilities/registration/registration.php ++ [FOLDER] admin/utilities/render/ ++ admin/utilities/render/render.php ++ admin/utilities/theme/joomla25.php ++ admin/utilities/theme/style.php +~ admin/utilities/theme/theme.php +~ admin/views/customfield/tmpl/edit.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/icagenda/view.html.php +~ admin/views/info/tmpl/default.php +~ admin/views/registrations/tmpl/default.php +~ icagenda.xml ++ [LIBRARY][FOLDER] libraries/ic_library/form/ ++ [LIBRARY][FOLDER] libraries/ic_library/form/field/ ++ [LIBRARY]libraries/ic_library/form/field/sortablefields.php ++ [LIBRARY][FOLDER] libraries/ic_library/iCalcreator/ ++ [LIBRARY]libraries/ic_library/iCalcreator/iCalcreator.class.php +~ [MEDIA] media/css/icagenda-back.css +~ [MEDIA] media/css/icagenda-front.css +~ [MEDIA][iCicons] media/icicons/ ++ [MEDIA] media/js/Chart.js ++ [MEDIA] media/js/Chart.min.js +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [PLUGIN] plugins/search/icagenda/icagenda.php +~ script.icagenda.php ++ site/add/elements/icevent_vars.php ++ site/add/elements/iclist_vars.php +- site/add/elements/icsetvar.php +~ site/controller.php ++ [FOLDER] site/controllers/ ++ site/controllers/registration.php +- site/helpers/iCalcreator.class.php +- site/helpers/ichelper.php +- site/helpers/icmodel.php +- site/helpers/media_css.class.php +~ site/icagenda.php ++ site/models/event.php +~ site/models/events.php ++ [FOLDER] site/models/fields/ ++ site/models/fields/categories.php ++ site/models/fields/month.php ++ site/models/fields/year.php +~ site/models/forms/registration.xml +~ site/models/list.php ++ site/models/registration.php +~ site/models/submit.php +~ site/router.php +~ [THEME PACK] site/themes/packs/default/css/default_component.css +~ [THEME PACK] site/themes/packs/default/css/default_component_medium.css +~ [THEME PACK] site/themes/packs/default/css/default_component_small.css +~ [THEME PACK] site/themes/packs/default/css/default_component_xsmall.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component_medium.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component_small.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component_xsmall.css ++ [FOLDER] site/views/event/ ++ [FOLDER] site/views/event/tmpl/ ++ site/views/event/tmpl/default.php ++ site/views/event/tmpl/default_top.php ++ site/views/event/tmpl/default_vcal.php ++ site/views/event/view.html.php +- site/views/list/tmpl/actions.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/default_categories.php ++ site/views/list/tmpl/default_filters.php +- site/views/list/tmpl/default_vcal.php +- site/views/list/tmpl/event.php +- site/views/list/tmpl/registration.php +~ site/views/list/view.feed.php +~ site/views/list/view.html.php ++ [FOLDER] site/views/registration/ ++ [FOLDER] site/views/registration/tmpl/ ++ site/views/registration/tmpl/actions.php ++ site/views/registration/tmpl/complete.php ++ site/views/registration/tmpl/default.php ++ site/views/registration/view.html.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.5.13 (2015.12.05) +================================================================================ ++ Added : in registrations csv export, new option to display 'created date' (when the user registered). +# [MEDIUM] Fixed : error getimagesize if original image deleted. +# [MEDIUM] Fixed : not able to get user groups after logged-in user changed his password in frontend (return error message in component and modules). +# [LOW] Fixed : issue since Joomla 3.4.5 with upload of custom Theme Packs. +# [LOW] Fixed : issue with date and DST (Day Saving Time) with export to Outlook. +# [LOW] Fixed : private access level for event information was broken if custom fields. +# [LOW] Fixed : admin language ordering in events list. +# [LOW] Fixed : category and search list filters with no effect in registration csv export. +# [MODULE iC calendar][LOW] Fixed : Loading calendar on defined month/year not working in some cases. + +* Changed files in 3.5.13 +~ admin/controllers/registrations.raw.php +~ admin/models/events.php +~ admin/models/forms/download.xml +~ admin/models/registrations.php +~ admin/models/themes.php +~ admin/utilities/events/data.php +~ admin/utilities/events/events.php +~ admin/utilities/menus/menus.php +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [PLUGIN] plugins/search/icagenda/icagenda.php +~ site/helpers/icmodel.php +~ site/models/events.php +~ site/models/submit.php +~ site/themes/packs/default/default_day.php +~ site/themes/packs/default/default_event.php +~ site/themes/packs/ic_rounded/ic_rounded_day.php +~ site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/list/tmpl/default_vcal.php +~ site/views/list/tmpl/event.php + +iCagenda 3.5.12 (2015.10.12) +================================================================================ ++ Added : option field 'Time display' in 'Submit an event' form. ++ Added : global option to Select if 'Time Display' option is set by default on 'Show' or 'hide' when creating a new event ('General Settings' tab of the Global Options of the component). ++ Added : missing separator option in global options for date format. ++ [MODULE iC calendar] Added : option to set custom limit for auto-intro description. ++ [MODULE iC Event List][PRO] Added : option to set HTML filtering for auto-intro description. +~ Changed : use global date format option in registrations list, and display start and end date when registration for a period. +# [MODULE iC calendar][LOW] Fixed : display of "booking closed" when events only singles dates, and all upcoming, but registration type option for this event is set to "for all dates of the event". +# [MODULE iC calendar][LOW] Fixed : in "auto" mode for option "Link to Menu Item", the global option for filter by dates was not defined, if not on a list of events page ("auto" not working properly in this case, in a few cases, depending of your settings, if one at least of the menu item(s) to a list of events was set to use global options for Filter by dates). +# [MODULE iC calendar][LOW] Fixed : option for filtering HTML tags of intro-text not working in tooltip if not on list of events page. +# [LOW] Fixed : not displaying full address if country and/or city included in the place name. +# [LOW] Fixed : display of long content in registrations admin list (overlap in data display). + +* Changed files in 3.5.12 +~ admin/config.xml +~ admin/models/event.php +~ admin/models/forms/event.xml +~ admin/models/registrations.php +~ admin/utilities/events/events.php +~ admin/utilities/menus/menus.php +~ admin/views/registrations/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ script.icagenda.php +~ site/add/elements/icsetvar.php +~ site/helpers/icmodel.php +~ site/models/forms/submit.xml +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/default.xml +~ site/views/submit/view.html.php + + +iCagenda 3.5.11 (2015.09.05) +================================================================================ +# [LOW] Fixed : date format with short month broken (in 3.5.10). +# [LOW] Fixed : date format with separator broken (since 3.5.6). +# [MODULE iC calendar][LOW] Fixed : display of current month, whereas option 'Loading on Date' is set on a day of the previous month. + +* Changed files in 3.5.11 +~ [LIBRARY] libraries/ic_library/globalize/culture/en-GB.php +~ [LIBRARY] libraries/ic_library/globalize/culture/en-US.php +~ [LIBRARY] libraries/ic_library/globalize/culture/fa-IR.php +~ [LIBRARY] libraries/ic_library/globalize/globalize.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php + + +iCagenda 3.5.10 (2015.09.01) +================================================================================ ++ Added : Compatible with Jalali/Persian calendar in admin (use of Joomla calendar for datetime picker). ++ Added : missing field to select 'Registration type' in the 'Submit an event' form, if registration options displayed. ++ Added : function to disable the submit button in frontend forms, after first click (to prevent multiple clicks during data process). +~ Changed : Asynchronous Loading of the AddThis widget script +~ Changed : auto-detect if https/ssl server for loading the AddThis widget script. +~ [MODULE iC calendar] Changed : you can now select one of the seven days of the week, as the first day of the calendar. +~ [THEME PACK] Changed : registration header is simplified, and use now its own css classes (ic-reg + suffix) +~ [THEME PACK] Changed : new ic-current-period class used to replace inline css when for the overline when period started and current (box date in list of events) +# [LOW] Fixed : a few issues with Jalali calendar in frontend (day 31 of a period not dislayed in calendar, possible datetime contruct error if no single dates in event details view). +# [LOW] Fixed : if only single dates with no period, and registration type option set to "for all dates of event", the date in registration email notifications was wrong. +# [LOW] Fixed : loading of event custom fields in registrations list if same id (missing parent_form control). +# [LOW] Fixed : date could include non-breaking space ( ) in notification email. +# [MODULE iC Event List][LOW] Fixed : display of month in the date box, on last day of a month (eg. 31 August) was next month, and not current month. + +* Changed files in 3.5.10 +~ admin/models/fields/modal/date.php +~ admin/models/fields/modal/enddate.php +~ admin/models/fields/modal/startdate.php +~ admin/tables/event.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/events/events.php +~ admin/utilities/form/form.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/registrations/tmpl/default.php ++ [LIBRARY] libraries/ic_library/globalize/convert.php +~ [LIBRARY] libraries/ic_library/globalize/globalize.php ++ [MEDIA] media/images/loader.gif +~ [MEDIA] media/js/icdates.js +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ site/add/elements/icsetvar.php +~ site/helpers/icmodel.php +~ site/models/forms/submit.xml +~ site/models/submit.php +~ [THEME PACK] site/themes/packs/default/css/default_component.css +~ [THEME PACK] site/themes/packs/default/default_registration.php +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_events.php +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_registration.php +~ site/views/list/tmpl/registration.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.5.9 (2015.08.01) +================================================================================ +! Added options for export in csv of a list of registrations (select info to be exported, and select between comma or semicolon as separator for values) +! You can now send a newsletter for all users registered for an event (all dates), or only for users registered to only one date (or period) of the event. +~ Changed : dropdowns for event and date in registration form, as well as for newsletter now use ajax for updating the date depending of the selected event, without reloading the page. +~ Changed : set 'All Events' as default value for 'Filter by Dates' global option (on new install). +~ [THEME PACK] Changed : ic_rounded module calendar css for table, by addition of class ic-table (minor change to prevent some possible css conflict with site template). +~ Changed : minimum joomla 3 release is now 3.2.3 (for websites using iCagenda on Joomla 3). +# [MEDIUM] Fixed : when trying to change state of a registration (broken since 3.5.7) the event state was sometimes changed in the same time (but not removed from database). Sorry for any inconvenience. +# [LOW] Fixed : change state not working in admin registrations list (not possible to trash or unpublished a registration entry). +# [LOW] Fixed : lost of changes if changing event in registration admin edition (fixed by using ajax to generate the date list). +# [MODULES][LOW] Fixed : 'Filter by dates' could be broken for modules, if set in all menus to 'Use Global', and set to 'All Events' in global options. +# [MODULE iC Event List][LOW] Fixed : notice error if no events to be displayed (undefined variable). + +* Changed files in 3.5.9 +~ admin/config.xml +~ admin/controllers/mail.php +~ admin/controllers/registration.php +~ admin/controllers/registrations.php +~ admin/controllers/registrations.raw.php +~ admin/models/fields/modal/evt.php +~ admin/models/fields/modal/evt_date.php +- admin/models/fields/modal/mailinglist.php +~ admin/models/forms/download.xml +~ admin/models/forms/mail.xml +~ admin/models/forms/registration.xml +~ admin/models/mail.php +~ admin/models/registration.php +~ admin/models/registrations.php +- admin/tables/mail.php +~ admin/tables/registration.php ++ admin/utilities/ajax/ajax.php +~ admin/utilities/events/events.php +~ admin/utilities/menus/menus.php +~ admin/views/mail/tmpl/edit.php +~ admin/views/mail/view.html.php +~ admin/views/registration/tmpl/edit.php +~ admin/views/registrations/tmpl/default.php +~ admin/views/registrations/view.html.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ script.icagenda.php +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_module.css + + +iCagenda 3.5.8 (2015.07.17) +================================================================================ +# [MODULE iC Calendar][LOW] Fixed : no events displayed in the calendar if menus option 'Filter by dates' is set to 'Use Global' (Sorry for any inconvenience). + +* Changed files in 3.5.8 +~ admin/utilities/menus/menus.php + + +iCagenda 3.5.7 (2015.07.16) +================================================================================ ++ Added : publishing info for registrations; Created date/by (null if registration processed before update to 3.5.7 or later) and Modified date/by. ++ [MODULES] Added: alert message with number of events not displayed, when a user with admin permissions is logged-in in frontend (see current fix in modules for events with no menu link to allow the display.). +~ Changed : end time for single dates is now assumed to be midnight, when filtering today's events. +~ [THEME PACK] Changed : remove inline css used before to display Terms of Service, and use new names for the css classes. +# [MODULES][LOW] Fixed : no display of events if no menu link allows the display. +# [MODULE iC Calendar][LOW] Fixed : possible script conflict if joomla timezone or server timezone selected (highlightToday issue). +# [MODULE iC Calendar][LOW] Fixed : no display of December events. +# [LOW] Fixed : filtering of space for dates in notification emails if mail received in plain text. +# [LOW] Fixed : possible notice 'Undefined variable: dateglobalize_#' in backend, related to date format option (depends on your admin language). +# [LOW] Fixed : wrong place of a closing div in list of events (3.5.6). +# [LOW] Fixed : edit own access for registrations (user with only edit own access permissions, will see only its own registrations in the list). +# [LOW] Fixed : JS notice empty value if Terms of Services not displayed in registration form. + +* Changed files in 3.5.7 +~ admin/controllers/registration.php +~ admin/controllers/registrations.php +~ admin/models/fields/iclist/globalization.php +~ admin/models/forms/customfield.xml +~ admin/models/forms/event.xml +~ admin/models/forms/registration.xml +~ admin/models/registration.php +~ admin/models/registrations.php +~ admin/sql/install/mysql/icagenda.install.sql +~ admin/utilities/events/data.php +~ admin/utilities/events/events.php +~ admin/utilities/form/form.php +~ admin/utilities/menus/menus.php +~ admin/views/event/tmpl/edit.php +~ admin/views/registration/tmpl/edit.php +~ admin/views/registrations/tmpl/default.php +~ [LIBRARY] libraries/ic_library/globalize/globalize.php +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ site/helpers/icmodel.php +~ site/models/events.php +~ site/models/submit.php +~ [THEME PACK] site/themes/packs/default/css/default_component.css +~ [THEME PACK] site/themes/packs/default/css/default_module.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/registration.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.5.6 (2015.06.29) +================================================================================ ++ Added : Compatible with Jalali/Persian calendar in frontend. +~ Changed : Update of Info page (addition of credits: languages and external libraries). +~ Changed : Improvement of add to cal function for a better export to external calendars. +~ Changed : Improvement of valid dates control in frontend submit an event form. +~ Changed : migration of globalize date format function to the iC Library, and improvement. +# [MEDIUM] Fixed : delete custom fields data of an event if this one is deleted. +# [LOW] Fixed : add to cal issue when hide time selected. +# [LOW] Fixed : date/dates display in event details depending of number of dates for a period. +# [LOW] Fixed : registration button was not active when event with a past period, but upcoming single dates. +# [LOW] Fixed : line return in Notes field, when exporting list of registrations to csv. +# [LOW] Fixed : confirmed email field (registration form) was not removed from the session. +# [LOW] Fixed : no display of a few dates in today's events filtering (when period with weekdays, and event running). + +* Changed files in 3.5.6 +~ admin/add/ renamed admin/assets/ ++ admin/assets/jcms/info.php +~ admin/config.xml +~ admin/controller.php +- [FOLDER] admin/globalization/ +~ admin/icagenda.php +~ admin/models/event.php +~ admin/models/events.php +~ admin/models/fields/iclist/globalization.php +~ admin/models/fields/modal/date.php +~ admin/models/fields/modal/evt_date.php +~ admin/models/forms/event.xml +~ admin/models/registration.php +~ admin/models/registrations.php +~ admin/sql/install/mysql/icagenda.install.sql +~ admin/tables/registration.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/events/data.php +~ admin/utilities/events/events.php ++ admin/utilities/info/info.php +~ admin/views/category/tmpl/edit.php +~ admin/views/customfield/tmpl/edit.php +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php +~ admin/views/events/tmpl/default.php +~ admin/views/events/view.html.php +~ admin/views/feature/tmpl/edit.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/icagenda/view.html.php +~ admin/views/info/tmpl/default.php +~ admin/views/info/view.html.php +~ admin/views/mail/tmpl/edit.php +~ admin/views/registration/tmpl/edit.php +~ admin/views/registration/view.html.php +~ admin/views/registrations/view.html.php +~ admin/views/themes/tmpl/default.php +~ icagenda.xml +~ [LIBRARY] libraries/ic_library/date/date.php ++ [LIBRARY][FOLDER] libraries/ic_library/globalize/ ++ [LIBRARY] libraries/ic_library/globalize/culture/fa-IR.php ++ [LIBRARY] libraries/ic_library/globalize/globalize.php +~ [LIBRARY] libraries/ic_library/lib_ic_library.xml +~ [LIBRARY] libraries/ic_library/library/library.php +~ [LIBRARY] libraries/ic_library/string/string.php +~ [MEDIA] media/css/icagenda-back.css +~ [MEDIA] media/css/icagenda-front.css +~ [MEDIA] media/css/icagenda-front.j25.css +~ [MEDIA] media/js/icdates.js +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ script.icagenda.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/models/events.php +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACK] site/themes/packs/default/css/default_component.css +~ [THEME PACK] site/themes/packs/default/css/default_module.css +~ [THEME PACK] site/themes/packs/default/default_calendar.php +~ [THEME PACK] site/themes/packs/default/default_day.php +~ [THEME PACK] site/themes/packs/default/default_event.php +~ [THEME PACK] site/themes/packs/default/default_events.php +~ [THEME PACK] site/themes/packs/default/default_registration.php +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_calendar.php +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_events.php +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_registration.php +~ site/views/list/tmpl/actions.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/default_vcal.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/default.xml +~ site/views/submit/tmpl/send.php +~ site/views/submit/view.html.php + + +iCagenda 3.5.5 (2015.04.27) +================================================================================ +~ Changed : removal of v1 and v2 release notes (link to online change log for these versions). +# [MEDIUM] Fixed : issue with admin event edition on IE (script error only on Internet Explorer). +# [LOW] Fixed : wrong file jquery.tipTip.js was included in 3.5.4. This version includes the correct new one with tooltip position fix (as announced in previous release). + +* Changed files in 3.5.5 +~ admin/CHANGELOG.php +~ [MEDIA] media/js/icdates.js +~ [MEDIA] media/js/jquery.tipTip.js + + +iCagenda 3.5.4 (2015.04.24) +================================================================================ +! JComments ready : You can download the free iC JComments plugin to enable comments on events (http://icagenda.joomlic.com/resources/addons). ++ [GLOBALIZATION] Added : fa-IR Persan (Iran) date formats. ++ Added : global option to set text transformation of the event title (Global Options > General Settings tab). ++ Added : check image name in frontend 'Submit an Event form', and if file extension is missing, add the correct one. +~ Changed : location of css and js core files (removed from admin and site folder, and moved to media). +~ Changed : improve datetime picker validation (no need to click on validate button to be sure date entered is saved). +# [MEDIUM] Fixed : missing 404 error page, when SEF is enabled, and event alias in url doesn't exist (was returning the first event found). +# [MEDIUM] Fixed : Persan language issue, fixed date construct fatal error. +# [LOW] Fixed : possible iCtip position issue (add to cal, print... tooltip) if another script is changing window top offset(). +# [LOW] Fixed : broken url to event details view in registration form header. +# [LOW] Fixed : broken approval icon function in admin list of events. +# [LOW] Fixed : special characters in breadcrumbs. +# [LOW] Fixed : Nb of registered user, if only one single date, and registration type is changed after a few registrations occured. + +* Changed files in 3.5.4 +- [FOLDER] admin/add/css/ +~ admin/add/elements/desc.php +~ admin/add/elements/title.php ++ admin/add/elements/titleheader.php +~ admin/add/elements/titleimg.php +- [FOLDER] admin/add/image/ +~ admin/config.xml ++ admin/globalization/fa-IR.php +~ admin/models/event.php +~ admin/models/forms/event.xml +~ admin/tables/feature.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/events/data.php +~ admin/utilities/events/events.php +~ admin/utilities/form/form.php +~ admin/views/categories/view.html.php +~ admin/views/category/tmpl/edit.php +~ admin/views/customfield/tmpl/edit.php +~ admin/views/customfields/view.html.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/events/view.html.php +~ admin/views/feature/tmpl/edit.php +~ admin/views/feature/view.html.php +~ admin/views/features/view.html.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/icagenda/view.html.php +~ admin/views/info/tmpl/default.php +~ admin/views/info/view.html.php +~ admin/views/mail/view.html.php +~ admin/views/registration/tmpl/edit.php +~ admin/views/registrations/view.html.php +~ admin/views/themes/tmpl/default.php +~ icagenda.xml +~ [LIBRARY] libraries/ic_library/date/period.php +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [MEDIA] media/css/icagenda-back.css ++ [MEDIA] media/css/icagenda-back.j25.css +~ [MEDIA] media/css/icagenda-front.css ++ [MEDIA] media/css/icagenda-front.j25.css +~ [MEDIA] media/css/icagenda.css ++ [MEDIA][FOLDER] media/css/images/ ++ [MEDIA] media/css/jquery-ui-1.8.17.custom.css ++ [MEDIA] media/css/template.j25.css +~ [MEDIA][ICICONS][UPDATE] media/icicons/ +~ [MEDIA][IMAGES][UPDATE] media/images/ +~ [MEDIA] media/js/icdates.js ++ [MEDIA] media/js/icmap-front.js +~ [MEDIA] media/js/jquery.tipTip.js +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ script.icagenda.pro.php +- [FOLDER] site/add/css/ +~ site/add/elements/icsetvar.php +- [FOLDER] site/add/image/ +~ site/controller.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +- [FOLDER] site/js/ +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ site/router.php +~ [THEME PACK] site/themes/packs/default/css/default_component.css +~ [THEME PACK] site/themes/packs/default/default_events.php +~ [THEME PACK] site/themes/packs/default/default_registration.php +~ [THEME PACK] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_events.php +~ [THEME PACK] site/themes/packs/ic_rounded/ic_rounded_registration.php ++ site/views/list/tmpl/actions.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default_categories.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/send.php +~ site/views/submit/view.html.php + + +iCagenda 3.5.3 (2015.03.25) +================================================================================ ++ Added : Confirm Email field in frontend Registration form, for not logged-in user. ++ Added : BOM utf-8 to csv export file (special characters). +~ Changed : improvement of the model for admin event edition. +~ Changed : postal code is now displayed (if available) in frontend address field. +# [MEDIUM] Fixed : saving of custom fields and features when new event (with not yet an ID) was broken (no data saved). +# [THEME PACKS][LOW] Fixed : display of empty participants list when registration not enabled. +# [LOW] Fixed : display of information details in event details view, was not always displayed depending of options and data filled. +# [LOW] Fixed : register button when only a single date, and the list display type is not set to display all dates. +# [LOW] Fixed : added back the alert message on Joomla 2.5 about the impossibility of trashing frontend submitted events if not edited (the issue with trash and empty asset_id is fixed in latest version of Joomla 3). + +* Changed files in 3.5.3 +~ admin/config.xml +~ admin/models/event.php +~ admin/models/fields/modal/ictext_placeholder.php +~ admin/models/forms/event.xml +~ admin/models/registrations.php +~ admin/tables/event.php +~ admin/utilities/events/data.php +~ admin/views/events/tmpl/default.php +~ admin/views/registrations/view.raw.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ site/add/elements/icsetvar.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php + + +iCagenda 3.5.2 (2015.03.13) +================================================================================ +~ Changed : name/username allows now numeric characters (server-side iCagenda validator), and addition of joomla client-side username validation. +~ Changed : minor re-ordering of period options in admin edition of an event, with info text for weekdays. +# [MEDIUM] Fixed : function to generate small icons in Features was broken. +# [LOW] Fixed : Custom fields data broken in csv export of registrations. +# [LOW] Fixed : Number of registered users, for events over a period with no weekdays selected. +# [LOW] Fixed : List of participants was broken if 'Avatar' and/or 'Username' list display option was selected (option 'Full' was working as expected). +# [LOW] Fixed : Url to event details view could return a wrong number of registered user if a period with no weekdays selected (component list of events). +# [LOW] Fixed : notice error when php function dateInterval does not exist on your server. +# [LOW] Fixed : improvement of the function to get the current layout. +# [LOW] Fixed : a few date format buggy depending of your settings, and the current language used. +# [LOW] Fixed : notice error $translator not defined in control panel (language issue) only on free version. +# [LOW] Fixed : filters display issue in registration admin list on Joomla 2.5 when event title length too high. +# [MODULE iC Event List][LOW] Fixed : blur x-small thumbs when created in admin. + +* Changed files in 3.5.2 +~ admin/add/css/icagenda.j25.css +~ admin/models/fields/modal/thumbs.php +~ admin/models/forms/event.xml +~ admin/models/registrations.php +~ admin/tables/feature.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/registrations/tmpl/default.php +~ [LIBRARY] libraries/ic_library/date/period.php +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ site/add/elements/icsetvar.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/models/forms/submit.xml +~ site/models/list.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/view.html.php + + +iCagenda 3.5.1 (2015.03.01) +================================================================================ +~ [MODULE iC calendar] Cleaned : not needed data attributs in arrows navigation. +# [MEDIUM] Fixed : no display of events if access registered, and user logged-in is not a Super User. +# [LOW] Fixed : possible issue with Joomla 3.4.0 (not saving event due to a script conflict), if admin module 'Multilanguage status' published (change of the modal for this module, using now Bootstrap). +# [LOW] Fixed : minor error issue in script used in edit form (admin) for link option on register button. +# [LOW] Fixed : 'No tickets are available for this date' displayed if no registration done for an event. +# [LOW] Fixed : incorrect count of available and booked tickets when Registration Type is set to 'all dates of the period'. +# [LOW] Fixed : link to view event after registration, not linking to registered date event view. + +* Changed files in 3.5.1 +~ admin/models/event.php +~ admin/models/fields/modal/iclink_article.php +~ admin/models/fields/modal/iclink_type.php +~ admin/models/fields/modal/iclink_url.php +~ admin/utilities/events/data.php +~ admin/utilities/form/form.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/view.html.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ site/add/elements/icsetvar.php +~ site/helpers/icmodel.php +~ site/models/events.php +~ site/views/list/tmpl/registration.php + + +iCagenda 3.5.0 (2015.02.25) +================================================================================ +! [EXPORT CSV][Registrations] : integration of CSV exportation for a list of registrations. Use the filter dropdowns to select state, event and/or date, and export the list of registered users by clicking on the 'Export' button in the toolbar. +! [Registrations] : the max number of tickets is now applied to each individual date of an event, if registration per date is selected. +! [MODULES] Added : event url goes directly to the date selected in the event details view. +! [FORMS] Improvement in Form Validation. By default, the form validation is process first client-side, using now the joomla core form-validate, and in second validation is server-side, processed by iCagenda. You have option both for the 'Registration' and 'Submit an Event' forms, to select default (2 controls) or only server-side form validation (the most advanced and secured one. The client-side validation adds a more user-friendly way which is faster for user (page not reloaded) to know when a field or more are invalid). ++ Added : Admin filter by registered date in registrations list. ++ Added : Admin filter by category in registrations list. ++ [RSS] Added : get current menu options to filter the RSS feeds (Filter by date, ordering...). ++ [MODULE iC calendar] Added : option to close automatically the tooltip on Mouseout. ++ [PLUGIN Search] Added : Search in shortdesc and metadesc text. +~ [MODULE iC calendar] Changed : improvement of the tool tip design, and addition of auto vertical scrolling inside tooltip. +~ [MODULE iC calendar] Changed : All mktime php function changed to be standardized with component refactory. +~ Many code improvements and minor bugs fixed. +# [MEDIUM] Fixed : Possible blank page in frontend, or very slow loading of iCagenda. The issue was not identified (seems to be related to php 5.4.37), but the new release 3.5.0 fixes this problem. +# [MEDIUM] Fixed : Slow loading in frontend, when using distant images, the parent image to generate thumbnails was always controlled, and should not if thumb already existed. +# [LOW] Fixed : W3C validation. +# [LOW] Fixed : issue in checking menu item if published (could return a 404 error page if menu item not published). +# [LOW] Fixed : missing displaytime checking in list of dates rendering (could not display an event over a period, with week days selected, if time not set). +# [LOW] Fixed : when only single dates filled in 'Submit an Event' form, the event was unpublished. +# [LOW] Fixed : "Notice: Undefined index:" if some fields are not filled when captcha solution was incorrect in registration form. +# [LOW] Fixed : issue if captcha plugin option is not set correctly, and set to be shown in form options. +# [LOW] Fixed : do not display event not approved in RSS feeds. +# [LOW] Fixed : no display of toolbar in list of events (admin) if no category created (display issue hiding page header). +# [LOW] Fixed : infotips in registration form not working on Joomla 2.5 (bug introduced in 3.4.1). +# [LOW][PRO MODULE iC Event List] Fixed : wrong date if period has a start date before today, and end date after today (was displaying tomorrow). +# [LOW][PRO MODULE iC Event List] Fixed : missing ic- prefix for columns classes in default layout, and rtl files. +# [SQL] Fixed : possible issue when update from an old version of iCagenda (before 3.2.14 and 3.2.0), with sql updating using the joomla core sql updates system. + +* Changed files in 3.5.0 +- admin/add/css/icmap.css +~ admin/config.xml ++ admin/controllers/registrations.raw.php +~ admin/globalization/en-GB.php ++ admin/models/download.php +~ admin/models/events.php +~ admin/models/fields/icmap/city.php +~ admin/models/fields/icmap/country.php +~ admin/models/fields/icmap/lat.php +~ admin/models/fields/icmap/lng.php +~ admin/models/fields/modal/date.php +~ admin/models/fields/modal/ictextarea_counter.php +~ admin/models/fields/modal/thumbs.php ++ admin/models/forms/download.xml +~ admin/models/forms/event.xml +~ admin/models/registrations.php +~ admin/sql/updates/3.2.0.sql +~ admin/sql/updates/3.2.14.sql +~ admin/sql/updates/3.2.sql +~ admin/utilities/customfields/customfields.php ++ admin/utilities/events/data.php +~ admin/utilities/events/events.php +~ admin/utilities/form/form.php +~ admin/utilities/menus/menus.php +~ admin/utilities/thumb/thumb.php +~ admin/views/categories/view.html.php ++ admin/views/download/tmpl/default.php ++ admin/views/download/view.html.php +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php +~ admin/views/events/tmpl/default.php +~ admin/views/events/view.html.php +~ admin/views/registrations/tmpl/default.php +~ admin/views/registrations/view.html.php ++ admin/views/registrations/view.raw.php +~ [LIBRARY] libraries/ic_library/date/date.php +~ [LIBRARY] libraries/ic_library/thumb/create.php +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [MEDIA] media/css/icagenda-back.css +~ [MEDIA] media/css/icagenda-front.css ++ [MEDIA] media/css/icagenda.css +~ [MEDIA] media/icicons/style.css +~ [MEDIA] media/js/icdates.js +~ [MEDIA] media/js/icform.js +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style-rtl.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style-rtl.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ [PLUGIN] plugins/search/icagenda/icagenda.php +~ script.icagenda.php +- site/add/css/icmap.css +~ site/add/elements/icsetvar.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/models/events.php +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_component_xsmall.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/default/default_events.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_xsmall.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_events.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default_categories.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/view.html.php + +iCagenda 3.4.1 (2015.01.30) +================================================================================ +! Changed : To fix an issue when using a custom captcha plugin (not joomla core reCaptcha plugin), the options has been changed. Now, there's only one place where you can set the captcha plugin used in iCagenda: 'General Settings' tab of the Global Options of the component. And you have individual option to show/hide captcha in 'Registration' and 'Submit an Event' forms. The update script will try to migrate your settings, but it's possible that you will have to set again this option in the menu options of 'Submit en Event' menu item type. +! Fixed : the 404 error page on multi-language site (when clicking on a module link). ++ Added : Get menu id and title of an event submitted in frontend (notification email, and filter in admin list of events). ++ Added : Options to show/hide period, weekdays and single dates in 'Submit an Event' form. ++ Added : Filter RSS feeds by category filter set in the menu options. ++ Added : Tooltip legends to pagination. ++ Added : Option to show/hide time in date box (list of events). ++ Added : Global Option to set access level to registration form. ++ [Plugin Search] Added : Next date added in search result (after title of the event). +~ Changed : You can now enter date before 1970/1/1 and after 2038/1/19 (no more unix limitation due to mktime php function, removed from date functions). +~ Changed : pageclass_sfx moved from id icagenda to a class (ic-list, ic-event, ic-registration, ic-submit, ic-send) to follow joomla standard. +~ Changed : Google Maps script checking (if api not loaded, iCagenda will load it). +~ Changed : Main list of events filter by date is improved (full recoding of the dates filtering functions). +~ Changed : The option 'list of all dates/only next/last date' is changed into 'Display All Dates' yes/no option. +~ [PRO MODULE iC Event List] Changed : ic- prefix added to section, group and col class names (to prevent class names CSS conflict). +~ Changed : Many code improvements. +# [MEDIUM] Fixed : 'auto' mode for menu link in modules was not well filtering language when joomla multi-language enabled. Improvement of the language detection for the menu items to retrieve the correct url. +# [LOW] Fixed : do not send user notification email after an event submission in frontend, if user has permissions to approve an event. +# [LOW] Fixed : no thumbnails were generated when '.' found in the image filename (eg. image.name.jpg). +# [LOW] Fixed : detects if an image file is too large, depending of server memory_limit setting, to prevent a blank page in admin when thumbnails cannot be generated (alert message displayed when a file is too large). +# [LOW] Fixed : filtering by category in events admin list was broken. +# [LOW] Fixed : Minor warning message in admin 'Themes manager' page (don't worry, nothing is broken!), 'Error loading component: COM_ICAGENDA, Component not found'. +# [LOW] Fixed : a few minor issue in admin list of events (date in current language, notice error $list var, ...). +# [LOW] Fixed : no display of events if category is unpublished. +# [LOW] Fixed : Keep in session Terms and Conditions checked, when reCaptcha is not correct. +# [LOW] Fixed : alias not generated when latin and non-latin characters in title (no datetime url safe alias, depending of unicode slug joomla global config setting). +# [LOW] Fixed : wrong display of menu option 'Features' on Joomla 2.5. +# [LOW] Fixed : if click on cancel on registration form, and when back to event details view, the back arrow was returning to registration form (now returns to parent list of events). + +* Changed files in 3.4.1 +~ admin/add/css/jquery-ui-1.8.17.custom.css +~ admin/config.xml +~ admin/globalization/uk-UA.php +~ admin/models/events.php +~ admin/models/fields/modal/cat.php +~ admin/models/fields/modal/date.php +~ admin/models/fields/modal/enddate.php +~ admin/models/fields/modal/ictextarea_counter.php +~ admin/models/fields/modal/startdate.php +~ admin/models/fields/modal/template.php +~ admin/models/forms/event.xml +~ admin/tables/event.php +~ admin/utilities/events/events.php +~ admin/utilities/form/form.php +~ admin/utilities/menus/menus.php +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php +~ admin/views/events/tmpl/default.php +~ admin/views/events/view.html.php +~ admin/views/themes/tmpl/default.php +~ admin/views/themes/view.html.php +~ [LIBRARY] libraries/ic_library/date/date.php +~ [LIBRARY] libraries/ic_library/date/period.php +~ [LIBRARY] libraries/ic_library/thumb/create.php +~ [LIBRARY] libraries/ic_library/thumb/get.php +~ [MEDIA] media/css/icagenda-front.css +~ [MEDIA] media/js/icdates.js +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [PLUGIN] plugins/search/icagenda/icagenda.php +~ script.icagenda.php +~ site/add/css/jquery-ui-1.8.17.custom.css +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/models/events.php ++ site/models/forms/registration.xml +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/default/default_events.php +~ [THEME PACKS] site/themes/packs/default/default_registration.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_events.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_registration.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml ++ site/views/list/tmpl/default_categories.php +~ site/views/list/tmpl/default_vcal.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.feed.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/default.xml +~ site/views/submit/tmpl/send.php +~ site/views/submit/view.html.php + + +iCagenda 3.4.0 (2014.12.22) +================================================================================ +! New : Custom fields. +1 - Available in registration and event edition forms. +1 - Field types : text, list, radio buttons. +! New : Feature Icons. +1 - Create icons for each feature. +1 - Attribute one or more features individually for each event. +1 - Feature can be for example: Parking, Refreshments, Restaurant, Hotel, Free, TV, Toilets, Swimming, Airport... (no limit of usage!). +! New : Librairies +1 - iC Library : standalone library (loaded by a plugin). +1 - iCagenda Utilities : integrated library of iCagenda. +! New : Full Thumbnails generator +1 - Options for 4 predetermined sizes : large, medium, small, xsmall. +1 - For each thumbnail size, individual options : width, height, quality, crop. +! Improvement and new options: +1 - Captcha option added in 'Registration' and 'Submit an event' forms. +1 - RTL integration (component and modules) +1 - SQL requests improvement (faster process of database queries) +1 - Link to event details from modules and search plugin now detect the category filter setting from each menu items. +1 - Notification email to user who has submitted an event in frontend, with an Event Reference Number. +1 - ... +! Please check all release notes since 3.4.0-alpha1 to review all the changes and new options added since 3.3.8 + +* Release Notes 3.4.0 +~ Changed : 'btn' class renamed in 'ic-btn' for frontend (mainly used for buttons). +~ Changed : a few css improvement (ic_rounded theme, liveupdate design...), and new classes added for a few core functions (date time display...). +# [LOW] Fixed : minor issues with 3.4.0-rc. + +* Changed files in 3.4.0 +~ admin/config.xml +~ admin/icagenda.php +~ admin/liveupdate/assets/liveupdate.css +~ admin/liveupdate/classes/abstractconfig.php +~ admin/liveupdate/classes/tmpl/nagscreen.php +~ admin/liveupdate/classes/tmpl/overview.php +~ admin/liveupdate/classes/updatefetch.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/events/events.php ++ admin/utilities/params/params.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ [LIBRARY] libraries/ic_library/date/date.php ++ [LIBRARY] libraries/ic_library/date/period.php +~ [MEDIA] media/css/icagenda-front.css ++ [MEDIA] media/js/icagenda.js +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [PLUGIN] plugins/system/ic_library/ic_library.php +~ script.icagenda.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/helpers/media_css.class.php +~ site/models/events.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_component_xsmall.css +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_medium.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_small.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_xsmall.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/send.php +~ site/views/submit/view.html.php + + +$ iCagenda 3.4.0-rc (2014.12.14) +================================================================================ +! RTL integration (component and modules) +! SQL requests improvement (faster process of database queries) +! [MODULES & PLUGIN] Link to event details from modules and search plugin now detect the category filter setting from each menu items. +! Notification email to user who has submitted an event in frontend, with an Event Reference Number (of type YYYYMMDDID where YYYY is year, MM is month, DD is day and ID is event id). ++ Added : form fields saved to session to keep data after submission of the form if a wrong captcha value was entered. ++ Added : nofollow for 'registration' and 'submit an event' form links (to not been read by search engine). ++ Added : option to set ordering of categories in drop-down field. ++ Added : option to set a category as default in drop-down field. +~ Changed : auto-generation of alias improved. +~ Changed : default order of categories in drop-down field by title (previously by id). +# [LOW] Fixed : issue with single date before 1999-11-30. +# [LOW] Fixed : tooltip not working in 'Submit an Event' form on Joomla 3.3.6 (fixed since alpha-1). +# [LOW] Fixed : pixelated event image in details view, if original image is too small. +# [LOW] Fixed : notice error 'DS' in admin and frontend after Joomla upgrade from 2.5 to 3.3. +# [LOW] Fixed : text counter bug in frontend 'Submit an Event' form on IE11. + +* Changed files in 3.4.0-rc +~ admin/config.xml +~ admin/icagenda.php +~ admin/models/category.php +~ admin/models/event.php +~ admin/models/events.php +~ admin/models/feature.php +~ admin/models/fields/icmap/city.php +~ admin/models/fields/icmap/country.php +~ admin/models/fields/icmap/lat.php +~ admin/models/fields/icmap/lng.php +~ admin/models/fields/modal/cat.php +~ admin/models/fields/modal/date.php +~ admin/models/fields/modal/iclink_type.php +~ admin/models/fields/modal/ictextarea_counter.php +~ admin/models/fields/modal/multicat.php +~ admin/models/forms/feature.xml +~ admin/tables/category.php +~ admin/tables/customfield.php +~ admin/tables/event.php +~ admin/tables/feature.php +~ admin/tables/registration.php +~ admin/utilities/customfields/customfields.php +~ admin/utilities/events/events.php +~ admin/utilities/form/form.php ++ admin/utilities/menus/menus.php +~ admin/utilities/thumb/thumb.php +~ libraries/ic_library/filter/output.php +~ libraries/ic_library/url/url.php +~ media/css/icagenda-front.css +~ media/js/icform.js ++ [MODULE][PRO] modules/mod_ic_event_list/css/default_style-rtl.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css ++ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style-rtl.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ site/add/css/style.css +~ site/add/elements/icsetvar.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/icagenda.php ++ site/models/events.php +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php ++ [THEME PACKS] site/themes/packs/default/css/default_component-rtl.css +~ [THEME PACKS] site/themes/packs/default/css/default_component.css ++ [THEME PACKS] site/themes/packs/default/css/default_module-rtl.css +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/default/default_registration.php ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component-rtl.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module-rtl.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_events.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_registration.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/default.xml +~ site/views/submit/tmpl/send.php +~ site/views/submit/view.html.php + + +$ iCagenda 3.4.0-beta2 (2014.11.09) +================================================================================ ++ Captcha option added in 'Registration' and 'Submit an event' forms. You can select the joomla captcha plugin that will be used in the form. ++ Added : Custom fields filled added in the registration notification emails. ++ Added : 3 tags in registration notification emails : [CUSTOMFIELDS] (list of custom fields), [DATE] (only date) and [TIME] (only time). ++ Added : Option to redirect after validation of the frontend 'Submit an Event' form (default, article or url). ++ Added : Option to set a characters limit for Title in List of Events. ++ Added : Option to create custom CSS stylesheets to add to the iCagenda styles or to override existing CSS styles and classes (Global Options). ++ [PRO MODULE iC Event List] Added : Options to set a header and/or footer custom text. ++ [MODULE iC Calendar] Added : Option to select the date on which the calendar will load (month and year). ++ [MODULE iC Calendar] Added : Option to show/hide Month and/or Year navigation. +~ Changed : display of "LiveUpdate" button only to user with component global options permissions. +~ [MODULE iC Calendar] Changed : navigation routing improved in calendar (now compatible with Advanced Module Manager by NoNumber). +~ [Theme Packs] Changed : load animated png is replaced by a animated gif (to prevent not working on not compatible browsers). +# [LOW] Fixed : 'view event' redirect link, after registration submission. +# [LOW] Fixed : nofollow for 'print' and 'add to cal' icons links. +# [LOW] Fixed : issue with custom field type 'list' if set to 'required'. Field was not checked properly if 'alias' and 'slug' identical. +# [LOW] Fixed : Add to iCal if SEF not activated (wrong url). +# [LOW] Fixed : displays users registered depending on the date (when 'All dates of each event' option is selected in menu options). +# [LOW] Fixed : possibility to edit or removed a registered user when the event is not published. +# [LOW] Fixed : changed 'all period' to 'all dates' in registration option, and fix an issue in data saved when no period for an event. +# [LOW] Fixed : possible issues with "edit own" permission for event edition. +# [LOW] Fixed : auto-increment of image name in frontend submit an event form, if image name already exists. +# [LOW] Fixed : error when searching in event with special characters (ą ę ć ś ź ł ż ó ż ń). +# [PRO MODULE iC Event List] [LOW] Fixed : wrong date depending of the time zone (only if datetime or date display is selected). + +* Changed files in 3.4.0-beta2 +~ admin/config.xml +~ admin/models/events.php +~ admin/models/fields/modal/evt.php +~ admin/models/fields/modal/evt_date.php +~ admin/models/fields/modal/iclink_type.php +~ admin/models/fields/modal/thumbs.php +~ admin/models/forms/event.xml +~ admin/models/forms/registration.xml +~ admin/utilities/customfields/customfields.php ++ admin/utilities/events/events.php +~ admin/utilities/form/form.php +~ admin/views/events/tmpl/default.php +~ admin/views/events/view.html.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/registrations/tmpl/default.php ++ libraries/ic_library/date/date.php +~ libraries/ic_library/lib_ic_library.xml +~ libraries/ic_library/thumb/create.php +~ libraries/ic_library/url/url.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ [PLUGIN] plugins/system/ic_library/ic_library.php +~ site/add/elements/icsetvar.php +~ site/helpers/iCicons.class.php +~ site/helpers/icmodel.php +~ site/helpers/media_css.class.php +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css ++ [THEME PACKS] site/themes/packs/default/images/ic_load.gif +- [THEME PACKS] site/themes/packs/default/images/ic_load.png +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php ++ [THEME PACKS] site/themes/packs/ic_rounded/images/ic_load.gif +- [THEME PACKS] site/themes/packs/ic_rounded/images/ic_load.png +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default_vcal.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/default.xml +~ site/views/submit/view.html.php + + +$ iCagenda 3.4.0-beta1 (2014.07.23) +================================================================================ ++ Added : Short Description field (you can now enter a special short description, to be used in the list of events as Intro Text). ++ Added : Limit options for Short Description, Auto-Introtext and Meta Description. Addition of a live counter of remaining characters both in admin event edit and submit an event forms. ++ Added : Option for maximum size of the uploaded image in frontend 'submit an event' form. This new function controls the file before upload, check the size and file type, and display a preview if the file is conformed. ++ Added : image added to rss feeds ++ [SQL] Added : 'shortdesc' in '#__icagenda_events' table +~ Changed : 'Meta' is replaced by 'Auto-Introtext' in Intro Text option (global component and modules options). +~ [THEME PACKS] Changed : Begin of renaming of existing CSS classes of ic_rounded theme pack (to use standardized naming, and prevent CSS conflicts with site templates and other third party extensions. Don't forget to update your custom theme pack if needed!) +~ Changed : a few code improvements, and control alert messages added. +# [LOW] Fixed : possible issue on a fresh install, with a wrong installation of the iC Library. +# [LOW] Fixed : wrong display in frontend of radio buttons, when using a Gantry Template. + +* Changed files in 3.4.0-beta1 +~ admin/add/css/icagenda.j25.css +~ admin/config.xml ++ admin/models/fields/modal/ictextarea_counter.php +~ admin/models/forms/event.xml +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php +~ admin/views/icagenda/tmpl/color.php +~ icagenda.xml +~ libraries/ic_library/lib_ic_library.xml +~ media/css/icagenda-back.css +~ media/css/icagenda-front.css ++ media/js/icform.js +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ script.icagenda.pro.php +~ site/add/css/icagenda.j25.css +~ site/add/elements/icsetvar.php +~ site/helpers/icmodel.php +~ site/icagenda.php +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/default.xml +~ site/views/submit/view.html.php + + +$ iCagenda 3.4.0-alpha2 (2014.07.16) +================================================================================ ++ Added : Alert message with list of custom theme packs not updated to be compatible with custom fields and feature icons. ++ Added : Check if at least 1 category is published before adding/editing an event. ++ Added : Option to show/hide custom fields in frontend 'Submit an event' form (Menu Item params and Global Options). ++ Added : Own server for Testing Updates (alpha & beta). +# [MEDIUM] Fixed : SQL error 1064 in event edit if no custom fields exists. +# [LOW] Fixed : bug in checking if a slug already exists (custom fields) (could display multiple times the custom field in event details view). +# [LOW] Fixed : bug in display of information option in Event Details view. +# [LOW] Fixed : bug in fields display options in the form to submit an event in frontend. +# [LOW][PRO][MODULE iC Event List] Fixed : today date was not always properly set depending on your hosting location (now uses Joomla config offset). + +* Changed files in 3.4.0-alpha2 +~ admin/config.xml +~ admin/liveupdate/classes/abstractconfig.php +~ admin/liveupdate/config.php +~ admin/models/customfields.php ++ admin/sql/install/mysql/icagenda.install.sql +- admin/sql/install.mysql.utf8.sql ++ admin/sql/uninstall/mysql/icagenda.uninstall.sql +- admin/sql/uninstall.mysql.utf8.sql +~ admin/tables/customfield.php +~ admin/utilities/categories/categories.php +~ admin/utilities/customfields/customfields.php ++ admin/utilities/theme/theme.php +~ admin/views/customfields/tmpl/default.php +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php +~ admin/views/events/view.html.php +~ admin/views/features/tmpl/default.php +~ admin/views/icagenda/tmpl/color.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ admin/views/themes/tmpl/default.php +~ icagenda.xml ++ [iC Library] libraries/ic_library/file/file.php +~ [iC Library] libraries/ic_library/lib_ic_library.xml +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [PLUGIN][iC Library] plugins/system/ic_library/ic_library.php +~ script.icagenda.pro.php +~ site/add/elements/icsetvar.php +~ site/helpers/icmodel.php +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/default.xml +~ site/views/submit/view.html.php + + +$ iCagenda 3.4.0-alpha1 (2014.07.11) +================================================================================ +! New : Custom fields. +1 Available in registration and event edition forms. +1 Field types : text, list, radio buttons. +! New : Feature Icons. +1 Create icons for each feature. +1 Attribute one or more features individually for each event. +1 Feature can be for example: Parking, Refreshments, Restaurant, Hotel, Free, TV, Toilets, Swimming, Airport... (no limit of usage!). +! New : Librairies +1 iC Library : standalone library (loaded by a plugin). +1 iCagenda Utilities : integrated library of iCagenda. +! New : Full Thumbnails generator +1 Options for 4 predetermined sizes : large, medium, small, xsmall. +1 For each thumbnail size, individual options : width, height, quality, crop. +! Many code lines cleaned up, and global improvement. (zip is now 0,4 mb lighter!) ++ Added : Modified Date and Modified By fields in admin event edit form. ++ [PRO][MODULE iC Event List] Added : Detection of the categor(y)ies set in the menu items to generate link of an event. ++ [PRO][MODULE iC Event List] Added : Show/Hide venue name +~ [PRO][MODULE iC Event List] Changed : Improved design of icrounded layout. +~ Changed : default ordering of admin list of events is now ID descendant (latest created event in first position). +~ Changed : default ordering of admin list of registered users is now ID descendant (latest registered user in first position). +~ Changed : option to set 'Intro Text'; auto, hide, short desc or meta (global options and modules params). +# [LOW] Fixed : created date was missing in old versions of iCagenda (before 3.1.5). This version update database to set a valid created date for events created with versions of iCagenda < 3.1.5, and set in this order : modified date if valid or next/last date if valid or, at the end, will use current date. (this fix is to prevent wrong 'Created on 30 November -0001' in search results) + +* Changed files in 3.4.0-alpha1 +~ admin/access.xml +~ admin/add/elements/title.php +~ admin/add/elements/titleimg.php +~ admin/config.xml ++ admin/controllers/customfield.php ++ admin/controllers/customfields.php +~ admin/controllers/event.php ++ admin/controllers/feature.php ++ admin/controllers/features.php +~ admin/helpers/icagenda.php +~ admin/icagenda.php ++ admin/models/customfield.php ++ admin/models/customfields.php +~ admin/models/event.php +~ admin/models/events.php ++ admin/models/feature.php ++ admin/models/features.php +~ admin/models/fields/modal/date.php ++ admin/models/fields/modal/thumbs.php ++ admin/models/forms/customfield.xml +~ admin/models/forms/event.xml ++ admin/models/forms/feature.xml +~ admin/models/forms/registration.xml +~ admin/models/icagenda.php +~ admin/models/registration.php +~ admin/models/registrations.php ++ admin/tables/customfield.php +~ admin/tables/event.php ++ admin/tables/feature.php +~ admin/tables/icagenda.php +~ admin/tables/registration.php ++ admin/utilities/categories/categories.php ++ admin/utilities/class/class.php ++ admin/utilities/customfields/customfields.php ++ admin/utilities/form/form.php ++ admin/utilities/thumb/thumb.php +~ admin/views/category/tmpl/edit.php ++ admin/views/customfield/tmpl/edit.php ++ admin/views/customfield/view.html.php ++ admin/views/customfields/tmpl/default.php ++ admin/views/customfields/view.html.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/events/view.html.php ++ admin/views/feature/tmpl/edit.php ++ admin/views/feature/view.html.php ++ admin/views/features/tmpl/default.php ++ admin/views/features/view.html.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/icagenda/view.html.php +~ admin/views/info/tmpl/default.php +~ admin/views/registration/tmpl/edit.php +~ admin/views/registrations/tmpl/default.php +~ icagenda.xml ++ media/css/icagenda-back.css ++ media/css/icagenda-front.css +~ [iCicons][New icons] media/icicons/ ++ media/images/customfields-16.png ++ media/images/customfields-48.png ++ media/images/features-16.png ++ media/images/features-48.png ++ media/images/panel_denied/customfields-48.png ++ media/images/panel_denied/features-48.png +~ [IMAGES][All png optimized] media/images/ +~ media/js/icdates.js +- [FOLDER] media/scripts/ +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +- [FOLDER] plugins/search/plg_icagenda/ ++ [FOLDER] plugins/search/icagenda/ +- [FOLDER] plugins/system/plg_ic_autologin/ ++ [FOLDER] plugins/system/ic_autologin/ ++ plugins/system/ic_library/ic_library.php ++ plugins/system/ic_library/ic_library.xml +~ script.icagenda.pro.php +~ site/add/elements/icsetvar.php +~ site/helpers/ichelper.php +~ site/helpers/iCicons.class.php +~ site/helpers/icmodel.php +~ site/icagenda.php +~ site/js/icmap.js +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ site/router.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/default/default_events.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_small.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_xsmall.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_events.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.feed.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php ++ [iC Library] libraries/ic_library/color/color.php ++ [iC Library] libraries/ic_library/filter/output.php ++ [iC Library] libraries/ic_library/lib_ic_library.xml ++ [iC Library] libraries/ic_library/library/library.php ++ [iC Library] libraries/ic_library/string/string.php ++ [iC Library] libraries/ic_library/thumb/create.php ++ [iC Library] libraries/ic_library/thumb/get.php ++ [iC Library] libraries/ic_library/thumb/image.php ++ [iC Library] libraries/ic_library/url/url.php ++ [SQL] #__icagenda_customfields_data ++ [SQL] #__icagenda_feature ++ [SQL] #__icagenda_feature_xref + + +iCagenda 3.3.8 (2014.07.04) +================================================================================ ++ Added : Events RSS feeds integrated to Joomla (This is a partial integration, displaying all events. An advanced integration with options, and events image in the RSS feed, will be added in 3.4.0 version, thanks to the new iC Library not yet implemented). +~ Changed : ChangeLog design +# [HIGH] Fixed : did not save the date selected during registration in datetime database format , depending on date format settings (was not working properly with name of the day of the week display displayed, eg. Saturday, 21 June 2014, or if AM/PM selected). +# [LOW] Fixed : quote issue in short description when sharing on facebook. + +* Changed files in 3.3.8 +~ admin/add/css/icagenda.css ++ admin/CHANGELOG.php +- admin/UPDATELOGS.php +~ admin/models/fields/modal/evt_date.php +~ admin/views/icagenda/tmpl/color.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/icagenda/view.html.php +~ icagenda.xml +~ script.icagenda.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php ++ site/views/list/view.feed.php + + +iCagenda 3.3.7 (2014.05.29) +================================================================================ +! New : Custom notification emails to a user after registration to an event can be edit in html using your favorite editor. ++ Added : individual options for the display of fields in menu "Submit an event". +~ Changed : New registration button (uses icons, colors, and a redirect to login with return page, if user has no permission). +# [MEDIUM] Fixed : link to past event if "only next/last date" selected in the menu option, returned a view with no data, depending of value set in option 'Selection of events'. +# [LOW] Fixed : bug if 'today' and 'all dates' selected, could display no events (missing offset in date controls). +# [LOW] Fixed : in iCagenda 3.3.6, the notification emails to a user after registration to an event, do not account for newlines. +# [LOW] Fixed : Print popup view, if SEF disabled. + +* Changed files in 3.3.7 +~ admin/add/css/icagenda.j25.css +~ admin/config.xml ++ admin/models/fields/modal/ic_editor.php +~ [iCicons][Update] media/icicons/ +~ site/helpers/icmodel.php +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/default.xml +~ site/views/submit/view.html.php + + +iCagenda 3.3.6 (2014.05.16) +================================================================================ ++ Added : Option for Intro Text : hide, the short description (generated from full description) or the meta description (Global Options of the component, and options of the modules). ++ [GLOBALIZATION] Added : tr-TR Turkish (Turkey) date formats. ++ [MODULE Calendar] Added : ID is added next to title of the menu, in option to select 'link to menu'. ++ [PRO] Added : Option to set minimum release stability for update notifications. (PRO OPTIONS tab in global options of iCagenda Pro) +~ [Optimization] : SQL request filtering improved in order to fix an issue, and speed up loading (more optimization to come concerning speed of page loading). +~ Changed : Division of the events tab in the global configuration into 2 tabs : Events (list of events options) and Event (details view options). +~ Changed : Updated addthis script (v300). +# [Optimization] Fixed : the list model was running the loading of data twice, and with this issue fixed the execution time for displaying a list is now halved (Thanks doorknob!). +# [HIGH]Fixed : Access to registration form if registration not activated in options. +# [LOW] Fixed : (only on Joomla 2.5) wrong display of print page if 'All Dates for each event' is selected in menu option. +# [LOW][MODULE Calendar][JS] Fixed : It was correctly deleting and adding the class style_Today but not the reverse for style_Day (by doorknob). +# [LOW]Fixed : Issue with Turkish language in admin events list (due to setlocale function, not used anymore). +# [LOW]Fixed : wrong closing select tags in 2 fields of the registration form. +# [LOW]Fixed : missing div tag in registration form. + +* Changed files in 3.3.6 +~ admin/config.xml +~ admin/globalization/iso.php ++ admin/globalization/tr-TR.php +~ admin/models/fields/modal/menulink.php +~ admin/views/events/tmpl/default.php +~ admin/views/events/view.html.php +~ media/scripts/icthumb.php +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/js/jQuery.highlightToday.js +~ [MODULE] modules/mod_iccalendar/js/jQuery.highlightToday.min.js +~ site/add/elements/icsetvar.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php + + +iCagenda 3.3.5-1 (patch) (2014.04.29) +================================================================================ +# Fixed : possible issue with uploaded files (image and/or file) not attached correctly in frontend submission form. + +* Changed files in 3.3.5-1 +~ site/views/submit/tmpl/default.php + + +iCagenda 3.3.5 (2014.04.27) +================================================================================ ++ Added : Control if event is published before editing a user registered for an event. (prevent error if user is registered to an unpublished event) ++ Added : Control if registered date still exists when editing a user registered for an event. +~ Changed : can convert date format depending on the option setting for date format (menu or global), when registration saved since version 3.3.3. +# [MEDIUM] Fixed : Date selection in Registration edition. +# [LOW] Fixed : missing loading of template.js on registration edition (Joomla 2.5). +# [LOW] Fixed : wrong css styling of pagination (Joomla 2.5). + +* Changed files in 3.3.5 +~ admin/add/css/template.css +~ admin/models/fields/modal/evt_date.php +~ admin/models/fields/modal/evt.php +~ admin/models/registrations.php +~ admin/views/registration/tmpl/edit.php +~ admin/views/registrations/tmpl/default.php +~ site/helpers/icmodel.php + + +iCagenda 3.3.4 (2014.04.25) +================================================================================ +! Joomla 3.3 Ready! This version has been tested on 3.3.0 rc, and a few improvements has been done to run well on the new Joomla 3.3 available soon ! ++ Added : Displays 'Home Page' and 'Submit a New Event' buttons, after validation of the event submission form, if user is logged in (was only displayed when user not logged in). ++ Added : Show 'Registration Options' in frontend submission form, only if registration is activated in global options. +~ Changed : Hide User ID when logged-in in registration form (was visible only for registered user). +~ Changed : no more 'onload' to initialize Google Maps (could prevent onload conflict with other extensions). +# [MEDIUM][Joomla 3.2.x & 3.3-beta] Fixed : in the frontend submission form, when user logged-in, 'disabled' changed to 'readonly' for user name and email, as it will not be submitted on a Joomla 3.3 website, and was giving the bug of double-click-needed on the submit button on J3.2. +# [MEDIUM][Joomla 2.5] Fixed : Global Options BUG with options not accessible -> Not correct path for js files in admin (after change of location for the scripts files in 3.3.3), on Joomla 2.5. +# [LOW] Fixed : Possible missing close div in submission form, if registration not displayed. +# [LOW][MODULE Calendar] Fixed : time was displayed even if the option to show time in event edition was disabled. Control missing in default theme pack. + +* Changed files in 3.3.4 +~ admin/add/elements/desc.php +~ admin/add/elements/title.php +~ admin/icagenda.php +- admin/models/fields/modal/time.php +~ admin/models/forms/event.xml +~ admin/views/event/tmpl/edit.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/icagenda/view.html.php +~ script.icagenda.php +~ site/helpers/icmodel.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ site/views/list/tmpl/registration.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/send.php +~ site/views/submit/view.html.php ++ media/js/jquery.noconflict.js + + +iCagenda 3.3.3 (2014.04.20) +================================================================================ +! New : Edition in admin of a user registered for an event, and possibility to create a new registered user. +! New : Advanced options for Registration Button. You can now replace individually for each event, the link on the button by an external url or an article ('Options' tab, in admin event edition). Another option is added for browser target of the registration button. ++ Added : Global option to set a default date format (general settings tab). ++ [MODULE Calendar] Added : Option to display a custom text in header of calendar. (Thanks doorknob) ++ [MODULE Calendar] Added : Option to set a padding for the tooltip, on mobile devices. (Thanks doorknob) +~ Changed : Date selected during a registration will be saved in database without formatting. +~ Changed : IcoMoon replaced by iCicon font (iCagenda vector icons font), for print and calendar icons on Joomla 3. +~ Changed : forms (Submission and Registration): uses iCtip script to generate information tooltips (replaces css3 tooltips, and adds responsive behaviour to detect screen border). +~ Changed : folder 'add/js' moved from admin and site folders to media folder. +~ [THEME PACKS] Changed : in THEME_day.php file, 'cal_date' changed to 'data-cal-date' (to avoid possible future conflicts as html5 is developed). +~ [ROUTER SEF] Changed : "event_registration" to "registration" at the end of url to registration form (when SEF enabled). +~ Code : many code cleaned and/or improved (Thank you Doorknob for your precious contribution!). +- [ROUTER SEF] Removed : "event_details" at the end of url to event details view (when SEF enabled) and provides a better SEO score. +- [MODULE] Removed : br tags after date/close header in calendar tooltip. +# [MEDIUM] Fixed : error in a php function which changes event time (winter/summer time) when event over a period starting before daylight saving, and finishing after daylight saving. +# [MEDIUM] Fixed : displaying of today, and/or upcoming, or past events are now using Joomla config time zone, to prevent issue with server timezone. +# [LOW] Fixed : ordering of categories (admin). +# [LOW] Fixed : possibility of a PHP Warning: Invalid argument supplied for foreach() in /components/com_icagenda/views/list/tmpl/event.php on line 48, in your site error log. +# [LOW] Fixed : Not sending notification to the user who registers for an event, if email is not set as required. +# [LOW] Fixed : Error if no events, with Addthis button. +# [LOW] Fixed : Bug in All Dates, when only sunday for period (wrong display : "Sunday & Sunday"). +# [LOW] Fixed : It was not loading Google Maps script if only coordinates were indicated (empty address). +# [LOW][PLUGIN Search] Fixed : Display of events not filtered by current language. +# [LOW][PRO][MODULE iC Event List] Fixed : Possible missing thumbnail, if no leading "/" in image url. + +* Changed files in 3.3.3 +~ admin/add/css/icagenda.css +~ admin/add/image/joomlic_iCagenda.png +~ admin/add/image/logo_icagenda.png +- [FOLDER] admin/add/js/ +~ admin/config.xml +~ admin/controllers/categories.php +~ admin/controllers/event.php ++ admin/controllers/registration.php +~ admin/helpers/icagenda.php +~ admin/liveupdate/liveupdate.php +~ admin/models/event.php +~ admin/models/events.php +~ admin/models/fields/modal/date.php ++ admin/models/fields/modal/evt.php ++ admin/models/fields/modal/evt_date.php +~ admin/models/fields/modal/icalert_msg.php ++ admin/models/fields/modal/iclink_article.php ++ admin/models/fields/modal/iclink_type.php ++ admin/models/fields/modal/iclink_url.php +~ admin/models/forms/event.xml ++ admin/models/forms/registration.xml ++ admin/models/registration.php +~ admin/tables/category.php +~ admin/tables/event.php ++ admin/tables/registration.php +~ admin/views/categories/tmpl/default.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php ++ admin/views/registration/tmpl/edit.php ++ admin/views/registration/tmpl/index.html ++ admin/views/registration/view.html.php +~ admin/views/registrations/tmpl/default.php +~ admin/views/registrations/view.html.php +~ admin/views/themes/tmpl/default.php +~ media/scripts/icthumb.php +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/js/jQuery.highlightToday.js +~ [MODULE] modules/mod_iccalendar/js/jQuery.highlightToday.min.js +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ [PLUGIN] plugins/search/plg_icagenda/icagenda.php +~ script.icagenda.php +~ site/add/css/icagenda.css +~ site/add/css/style.css +~ site/add/elements/icsetvar.php +- [FOLDER] site/add/js/ +~ site/helpers/ichelper.php +~ site/helpers/iCicons.class.php +~ site/helpers/icmodel.php +~ site/router.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_component_xsmall.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/default/default_registration.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_xsmall.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module_small.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_registration.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.3.2 (2014.03.17) +================================================================================ +! [PLUGIN] New plugin iCagenda search, enables searching in events. +- Removed : option 'All options' (by individual date and for all period) in 'Registration type' (not logical). +# [MEDIUM] Fixed : Not displaying singles dates in registration form. +# [LOW] Fixed : Not setting default value correctly for new global options: show/hide venue's name, city, country and short description. +# [LOW][THEME PACKS] Fixed : Missing ic-box-date class in ic_rounded xsmall media css file. +# [LOW][MODULE] Fixed : possibility of a notice message related to the jquery checking. + +* Changed files in 3.3.2 +~ admin/models/forms/event.xml +~ admin/tables/event.php +~ icagenda.xml +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php ++ [PLUGIN] plugins/search/plg_icagenda/icagenda.php ++ [PLUGIN] plugins/search/plg_icagenda/icagenda.xml ++ [PLUGIN] plugins/search/plg_icagenda/index.html ++ [PLUGIN][FOLDER] language +~ script.icagenda.php +~ site/add/elements/icsetvar.php +~ site/helpers/icmodel.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_xsmall.css +~ site/views/list/view.html.php + + +iCagenda 3.3.1 (2014.03.14) +================================================================================ ++ Added : Global options to show/hide information in list of events (venue's name, city, country, short description). ++ Added : Global options to show/hide day, month and/or year in date box of the list of events. ++ Added : Global option to set HTML filtering in Short Description (All italicized, No HTML or Authorized tags:
, , , , , ). ++ Added : Global option to set first day of the week (used when list of weekdays is displayed). ++ [MODULE iC Calendar] Added : Options to select a background color for days with only one event or more than one event. ++ [MODULE iC Calendar] Added : HTML Filtering Option for Short Description in tooltip. +~ Changed : redirect to login page if user has no access to submission form or is not logged-in. +~ [THEME PACKS] Changed : display order of Venue's name, city and country in tooltip of the calendar (now on the same line). +~ [THEME PACKS][ic_rounded] Changed class names for day, month and year in date box. +- [THEME PACKS] Removed, module iC calendar : tags for short description in tooltip. +# [MEDIUM] Fixed : Duplicate display of alert message, and not display of event details, if event not approved, and user logged-in with approval permissions. +# [MODULE iC Calendar][LOW] Fixed : Not displaying events in module calendar on Joomla 2.5, if all categories selected. + +* Changed files in 3.3.1 +~ admin/config.xml +~ admin/models/registrations.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ site/add/elements/icsetvar.php +~ site/helpers/icmodel.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/default/default_events.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_events.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/event.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.3.0 (2014.03.06) +================================================================================ +! [Theme Packs] Added media css files for Responsive Design. +! [SQL] Creates table #__icagenda_customfields database to prepare future Custom Fields System. ++ Added : Options to show/hide the fields in Event Submission Form. ++ Added : Option "Contact's email" in Admin notification mailing list for registrations. ++ Added : Filter by Upcoming/Past/Today events (Admin Events List). ++ Added : Filter by event (Admin Registrations List). ++ [MODULE iC Calendar] Added : Multi-selection of categories. ++ [MODULE iC Calendar] Added : Option to select a default font color for calendar. ++ [SQL] Added : 'metadesc' field to store an event meta-description (if not set, uses the new function to generate a short meta-description based on full description (limited to 160 characters to give the best SEO performance). ++ [SQL] Added : 'custom_fields' field to store data from custom fields (not yet available). +~ [Theme Pack] DEFAULT : major changes in event details view (default_event.php) and list view (default_events.php) by removing table tags, and using div to display content. Many class names changed with a leading prefix 'ic-' added to prevent possible conflict of naming with site templates css files. +~ Updated : iCalcreator updated from v2.16.12 to v2.18 (Add to iCal and Outlook). +~ Changed : limited length for url when adding an event to Yahoo and Google calendar (to prevent errors). +~ Changed : Updating preview of event image in edit admin when mouseover preview link. +~ Changed : Removal of the 404 block in order to prevent double display of an error page (depending of the site template used). +~ [SEO] Changed and enhanced : meta title and description are improved, better filtering, and give the best possible SEO performance. +~ [PRO][MODULE iC Event List] Changed : Using user timezone or if not set, Joomla server time zone, to set today time. +# [HIGH] Security : Fixed access to registration form when an event is unpublished or finished (prevents spamming). +# [MEDIUM] Fixed : conflict with module login, when a user log-in or log-out on the event details view, if 'add to cal' activated (loading iCal/outlook .ics file). +# [MEDIUM] Fixed : redirect to login page if user has no access to registration form and event details page (if direct visit to this page). +# [LOW] Fixed : not sending if missing space after comma, in custom list of emails for notification email. +# [LOW] Fixed : add to outlook calendar if no end date. +# [LOW] Fixed : Error introduced in a previous version with 'add to cal' function, concerning Windows live and yahoo calendars (url broken). +# [LOW] Fixed : Error to get show_page_heading from menu, when not set. +# [LOW] Fixed : conflict of 'date' variable between event details view and calendar (renamed 'iccaldate' in calendar). +# [LOW] Fixed : Error in setting next date if only one date (and/or only sunday) selected as weekday (period events). +# Many minor bugs fixed, and many code improvement. + +* Changed files in 3.3.0 +~ admin/config.xml +~ admin/models/category.php +~ admin/models/event.php +~ admin/models/events.php +~ admin/models/forms/event.xml +~ admin/models/mail.php +~ admin/models/registrations.php +~ admin/sql/install.mysql.utf8.sql +~ admin/sql/uninstall.mysql.utf8.sql +~ admin/tables/event.php +~ admin/views/categories/tmpl/default.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/events/view.html.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ admin/views/registrations/tmpl/default.php +~ admin/views/registrations/view.html.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ script.icagenda.php +~ site/add/css/icagenda.css +~ site/add/css/style.css +~ site/add/elements/icsetvar.php +~ site/helpers/iCalcreator.class.php +~ site/helpers/ichelper.php +~ site/helpers/iCicons.class.php +~ site/helpers/icmodel.php ++ site/helpers/media_css.class.php +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css ++ [THEME PACKS] site/themes/packs/default/css/default_component_large.css ++ [THEME PACKS] site/themes/packs/default/css/default_component_medium.css ++ [THEME PACKS] site/themes/packs/default/css/default_component_small.css ++ [THEME PACKS] site/themes/packs/default/css/default_component_xsmall.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css ++ [THEME PACKS] site/themes/packs/default/css/default_module_large.css ++ [THEME PACKS] site/themes/packs/default/css/default_module_medium.css ++ [THEME PACKS] site/themes/packs/default/css/default_module_small.css ++ [THEME PACKS] site/themes/packs/default/css/default_module_xsmall.css +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/default/default_events.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_large.css ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_medium.css ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_small.css ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component_xsmall.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module_large.css ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module_medium.css ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module_small.css ++ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module_xsmall.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_events.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/default_vcal.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/view.html.php ++ SQL : Adding 'metadesc' column to table #__icagenda_events ++ SQL : Adding 'custom_fields' column to table #__icagenda_registration ++ SQL : Create table #__icagenda_customfields + + + +iCagenda 3.2.13 (2014.02.01) +================================================================================ +! [COMPONENT] Advanced Admin ACL (manage access permissions in iCagenda Backend). +! [MODULE iC Calendar] Enhancement of tooltip display on mobile device. Addition of new options in params of the module. (Thanks doorknob!) +! [MODULE iC Calendar] Beta timezone options removed. A new script, developped by doorknob, is now setting "today" highlight according to visitor local time. You keep option to use Joomla Server Time Zone, and you can set highlight on UTC time zone. +! [GNU/GLP License] Update license to version 3 (or later). ++ Added : Category filtering in administration list of events. ++ Added : Category ordering in administration list of events. +~ [Source Language] Fixed of a few errors in english (en-GB British) source translations files (centre, information...). (Thanks Phil Winsor!) +# [LOW] Fixed : limited length to 2068 bytes of the url to add an event to Google Calendar, to prevent 404 error (url length limitation). +# [LOW] Fixed : missing [...] for short description, in default Theme Pack. +# [LOW] Fixed : attachment field in event form (mouseover). +# [LOW] Fixed : Some global styling error in main css files, and some other needed replacements. +# [LOW] Fixed : Conflict Bootstrap/Google Maps, on Zoom Control and street view button (Joomla 3.2). +# [LOW][THEME PACKS] Fixed : Email cloacking click in 'Default' Theme Pack. +# [LOW][MODULE iC Calendar] Fixed : Missing tags in week days thead. +# [MEDIUM][MODULE iC Calendar] Fixed : Removed limit of sql request. + +* Changed files in 3.2.13 +! [GNU/GLP License v3] LICENSE.txt +~ admin/access.xml +~ admin/add/css/icagenda.css +~ admin/helpers/icagenda.php +~ admin/icagenda.php +~ admin/liveupdate/classes/tmpl/nagscreen.php +~ admin/models/events.php +~ admin/models/fields/modal/icalert_msg.php +~ admin/models/fields/modal/icfile.php +~ admin/tables/event.php +~ admin/views/categories/tmpl/default.php +~ admin/views/category/tmpl/edit.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/events/view.html.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ admin/views/mail/tmpl/edit.php +~ admin/views/registrations/tmpl/default.php +~ admin/views/themes/tmpl/default.php ++ media/images/global_options-48.png ++ [Folder] media/images/panel_denied/ ++ [MODULE][PRO] modules/mod_ic_event_list/LICENSE.txt +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +- [MODULE] modules/mod_iccalendar/js/function.js +- [MODULE] modules/mod_iccalendar/js/function_312.js +- [MODULE] modules/mod_iccalendar/js/function_316.js +- [MODULE] modules/mod_iccalendar/js/ictip.js ++ [MODULE] modules/mod_iccalendar/js/jQuery.highlightToday.js ++ [MODULE] modules/mod_iccalendar/js/jQuery.highlightToday.min.js ++ [MODULE] modules/mod_iccalendar/LICENSE.txt +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ [PLUGIN] plugins/plg_ic_autologin/ic_autologin.php ++ [PLUGIN] plugins/plg_ic_autologin/LICENSE.txt +~ script.icagenda.php +~ site/add/css/icagenda.css +~ site/add/css/style.css +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/icagenda.php +~ site/js/icmap.js +- site/js/map.js +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/default/default_events.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ site/views/list/tmpl/event.php + + +iCagenda 3.2.12 (2014.01.08) +================================================================================ +! [MODULE iC Calendar] Disabling by default the function detecting the visitor time zone in module calendar, in order to highlight 'today'. This script function was giving some issue depending of your server, settings, and joomla version. You can now find an option in parameters of the module calendar, where you can use the visitor time zone to set 'today' highlight. If option 'Beta 1 - Visitor Time Zone' selected, when a new visitor comes to your website, it sets a variable containing his time zone in session cookies (so could slow a little when first visit of this user, as it reloads the page one time). And it keeps this information in browser cookies. If option 'Beta 2 - Visitor Time Zone' selected, retrieves the time zone of the visitor each time a page with a calendar module is loaded. If you encounter an error or problem during loading of a page where a module calendar is displayed, select 'Joomla - Server Time Zone' to use the global configuration Time Zone set for your website, and clean your cookies. A better and more advanced solution will be developped to set the detection of visitor time zone. +~ Minor enhancements and corrections in code. +~ [iCicons] Update of iCagenda iCicons font. +# [LOW][MODULE iC Event List][PRO] Fixed : Issue on joomla 2.5 with option 'All' in multi-select of categories resulting in an empty list. +# [LOW] Fixed : missing strip_tags in event.php tmpl view file. + +* Changed files in 3.2.12 +~ [FOLDER][iCicons] media/icicons ++ media/js/detect_timezone.js ++ media/js/jquery.detect_timezone.js +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ script.icagenda.php +~ site/helpers/icmodel.php +~ site/models/forms/submit.xml +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/default_registration.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css + + +iCagenda 3.2.11 FIX for 3.2.10 (2014.01.04) +================================================================================ +! The function detecting the visitor time zone, in order to highlight 'today', and introduced in version 3.2.10, is now disabled on Joomla 2.5 website due to a possible alert message (no error on Joomla 3). This feature needs more developpement and testing before being introduced again for Joomla 2.5 sites, because of all possible script conflicts that happen on this platform (Joomla 3.2.1 is much more fluid!). +# [HIGH][MODULE iC Calendar] Fixed : Possible issue with calendar (redirecting to home page if script for setting visitor time zone failed). +# [MEDIUM] Fixed : Issue when 'All Dates' selected, and SEF not activated, in opening event details (error 404). + +* Changed files in 3.2.11 +~ [MODULE] modules/mod_iccalendar/helper.php +~ site/views/list/tmpl/default.php + + +iCagenda 3.2.10 (2014.01.03) +================================================================================ ++ Added : Options for emails of notification and confirmation - Registration form. ++ [MODULE iC Event List][PRO] Added : 'Upcoming & Today' and 'Today' filter options. ++ [MODULE iC Event List][PRO] Added : Multi-selection of categories. ++ [MODULE iC Calendar] Added : Option to display 'country'. +~ Updated : Translation Credits and Contributors informations. +~ [MODULE iC Calendar] Enhancement : get visitor timezone and set it to session using javascript (client side) to highlight correctly 'today'. +~ [MODULE iC Calendar] Changed : get option 'display time' and global setting 'time format', in tooltip. +# [LOW] Fixed : Filtering of html content of the tip related to 'Add to Cal' button. +# [LOW][MODULE iC Calendar] Fixed : Error on a php 5.2 server, because of the new function to order events per hour in the tooltip (We really recommend switching to minimum php 5.3). +# [LOW][THEME PACKS] Fixed : Link on title in default theme pack. + +* Changed files in 3.2.10 +~ admin/config.xml ++ admin/models/fields/modal/ictext_placeholder.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ script.icagenda.php +~ site/helpers/iCicons.class.php +~ site/helpers/icmodel.php +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php + + +iCagenda 3.2.9 (2013.12.28) +================================================================================ ++ Added : Add to calendar icon (iCal, Google, Yahoo, Windows Live and Outlook calendars) in event details view. ++ Added : Print icon in event details view. ++ [MODULE Calendar] Added : Time for each event, in infotip. ++ [MODULE Calendar] Added : Option to used the text 'Close' in the infotip, translated in your current language, or use of a custom value. ++ [MODULE iC Event List][PRO] Added : Option to display list in columns (1 to 4 columns per row). +~ [THEME PACKS] Changed : style class 'content' renamed in 'ic-content'. +~ [THEME PACKS] Removed : Back button from Theme Packs, and added it in view file (to add future options for this button). +# [LOW] Fixed : Missing date in url, when clicking on [...] in short description, if 'All Dates' option selected for the list of events page view. +# [MEDIUM] Fixed : Change og tag description to full description, for sharing on social networks (remove html tags). +# [MEDIUM][MODULES] Fixed : Date display in Event details view after click on module links, was wrong if 'All Dates' option selected for the list of events page view. +# [MEDIUM][MODULE CALENDAR] Fixed : missing closing div in loading html (may in a rare cases give an error in displaying script code). + +* Changed files in 3.2.9 +~ admin/config.xml +~ admin/models/fields/modal/ictxt_default.php +~ admin/models/fields/modal/icvalue_opt.php +~ admin/views/info/tmpl/default.php ++ [FOLDER] media/images/cal/ +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ site/add/css/style.css +~ site/add/elements/icsetvar.php +~ site/controller.php ++ site/helpers/iCalcreator.class.php +~ site/helpers/ichelper.php ++ site/helpers/iCicons.class.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/default/default_events.php +~ [THEME PACKS] site/themes/packs/default/default_registration.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_events.php +~ site/views/list/tmpl/default.php ++ site/views/list/tmpl/default_vcal.php +~ site/views/list/tmpl/event.php +~ site/views/list/view.html.php + + +iCagenda 3.2.8 (2013.12.15) +================================================================================ +! New : Option to display All Dates for each event (or Next/last date of each event as it was before this release). +! [THEME PACKS] Important : New file THEME_events.php to replace THEME_list.php, and new names of data variables. ++ Added : Globalization Date Format file for Ukrainian uk-UA ++ Added : Localization of Google-maps based on the current language of the site. (Thanks SLV!) +~ [MODULE iC Event List][PRO] Changed : Enhancement of Date and Time option. +~ Changed : Enhancement of css of Submission form on J2.5 websites. +# [LOW] Fixed : alone div tag, which can give problem of display of submission form page. +# [LOW] Fixed : issue in style display of category title. +# [LOW] Fixed : category title and description in header of list of events sometimes in double. +# [THEME PACKS][LOW] Fixed : css missing style for category name in header of the list of events. +# [MODULE iC Event List][PRO][LOW] Fixed : Possible issue with module display. +# [MODULE Calendar][MEDIUM] Fixed : Possible issue with module changing months, due to a bug in text "loading...". + +* Changed files in 3.2.8 +~ admin/add/css/icagenda.css +~ admin/config.xml ++ admin/globalization/uk-UA.php ++ admin/models/fields/modal/icalert_msg.php +~ admin/views/event/tmpl/edit.php +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ script.icagenda.php +~ site/add/css/icagenda.j25.css +- site/add/css/template.css ++ site/add/elements/icsetvar.php +~ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_event.php ++ [THEME PACKS] site/themes/packs/default/default_events.php +- [THEME PACKS] site/themes/packs/default/default_list.php +~ [THEME PACKS] site/themes/packs/default/default_registration.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php ++ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_events.php +- [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_list.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_registration.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/send.php + + +iCagenda 3.2.7 (2013.11.23) +================================================================================ +~ [MODULE iC calendar] Changed : minor edit in sql request of module iC calendar +# [LOW] Fixed : bug in breadcrumbs event details view. +# [THEME PACKS][LOW] Fixed : possible issue of display break when using ic_rounded theme (depending of your site template). + +* Changed files in 3.2.7 +~ [MODULE] modules/mod_iccalendar/helper.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_list.php +~ site/views/list/tmpl/event.php + + +iCagenda 3.2.6 (2013.11.21) +================================================================================ +! New : Option (menu and global) to display Category informations; title and/or description (in header of list of events). ++ Added : Event Details view added to Breadcrumbs. ++ Added : Option Top & Bottom for navigation arrows (list of events). +# [MODULE iC Event List][PRO] Fixed : time not displayed correctly in module iC Event List. +# [MODULE iC Event List][PRO] Fixed : clic to event details views was not working on IE 9 (and under) with icrounded layout. + +* Changed files in 3.2.6 +~ admin/config.xml ++ admin/models/fields/modal/icmulti_checkbox.php ++ admin/models/fields/modal/icmulti_opt.php +~ admin/models/forms/category.xml +~ admin/views/icagenda/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/event.php +~ site/views/list/view.html.php + + +iCagenda 3.2.5 (2013.11.11) +================================================================================ +! Terms and Conditions Option added to registration form. +! Design compatibility with Joomla 3.2.0 (admin header html) and enhancements in admin display. ++ [THEME PACKS] Added css and php integration of registration infos in calendar tooltip. ++ [MODULE iC Calendar] Added : Options to display city, name of venue, short description, and registration infos (number of seats, seats available and already registered). +~ [MODULE iC Calendar] Changed : 'today' day is now using joomla timezone (was server timezone before). + +* Changed files in 3.2.5 +~ admin/add/css/icagenda.css +~ admin/add/css/icagenda.j25.css +~ admin/config.xml +- admin/models/fields/eventtitle.php ++ admin/models/fields/modal/ictxt_article.php ++ admin/models/fields/modal/ictxt_content.php ++ admin/models/fields/modal/ictxt_default.php ++ admin/models/fields/modal/ictxt_type.php +~ admin/models/forms/category.xml +~ admin/models/forms/event.xml +~ admin/views/categories/view.html.php +~ admin/views/category/tmpl/edit.php +~ admin/views/category/view.html.php +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php +~ admin/views/events/view.html.php +~ admin/views/icagenda/view.html.php +~ admin/views/info/view.html.php +~ admin/views/mail/view.html.php +~ admin/views/registrations/view.html.php +~ admin/views/themes/view.html.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ script.icagenda.php +- site/add/js/address.js +- site/add/js/dates.js +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ site/views/list/tmpl/registration.php + + +iCagenda 3.2.4 (2013.10.29) +================================================================================ ++ [MODULE iC Event List][PRO] Added : category color as background of the date, in 'default' layout. +~ [MODULE iC Calendar] Changed : authorizes
and
html tags in Short Description. +# Fixed : Issue when only sunday selected for period events, all days of the week were displayed. +# Fixed : Not display of Google Maps (blank) after update to last release 3.2.3, when Google Maps Global Options were not set before. +# Fixed : safehtml filter from joomla not working in frontend (skipping html tags, as should not). Filter set now to raw to not skip tags. +# Fixed : issue when access levels to Event Submission Form set to multiple levels (was not filtering access levels as expected). +# [THEME PACKS] Fixed : Issue Alignement of editor buttons in submission form. +# [MODULE iC Event List][PRO] Fixed : wrong display of events in column, due to a conflict in some site templates. + +* Changed files in 3.2.4 +~ admin/views/event/tmpl/edit.php +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ site/helpers/icmodel.php +~ site/models/forms/submit.xml +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ site/views/list/tmpl/default.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/view.html.php + + +iCagenda 3.2.3 (2013.10.20) +================================================================================ +! [THEME PACKS] Updated : enhancements of ic_rounded theme pack, to give a better responsive experience. All table tags have been removed, and replace with div tags, and with addition of @media css styling depending of the device (mobile, tablet, desktop). This new version of ic_rounded theme pack will now have version number respectively to the component version. (to improve tracking updates by users creating their own theme. For your information, a website page is in preparation for you to get more information and documentation about creating and updating a personal Theme Pack, and new features for Theme Pack manager are in brainstorming!). +! No loading of Google Maps scripts, if no address is set, or if global option is set on Hide (to speed up loading when this files are not needed). ++ Added : missing Options Week Days in Frontend Submission Form. ++ [MODULE iC Event List][PRO] Added : Options to display date and time, city, short description, and registration infos (number of seats, seats available and already booked). +~ [THEME PACKS] Changed : enhancements of the back arrow to detect if a previous page has been visited. Code in themes php file is now simplified. +~ Changed : enhancements of Open Graph tags (title, type, image, url, description, sitename). +~ Changed : enhancements and changes in tags used in iCagenda, to able a better structural hierarchy of list of events. (auto-detect if page heading is displayed in content or not, to set properly the Hn tag). +~ Changed : views php files to speed up loading of iCagenda (list of events, event details and event registration). +# Fixed : Calendar Issue; Bug in some countries about the time change. If a date of an event over a period was the day of the time change, it was generated 2 times. The new feature integrates this setting to not double this day. + + +* Changed files in 3.2.3 ++ admin/models/fields/modal/icvalue_field.php ++ admin/models/fields/modal/icvalue_opt.php +~ [MODULE][PRO] modules/mod_ic_event_list/css/default_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/css/icrounded_style.css +~ [MODULE][PRO] modules/mod_ic_event_list/helper.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE][PRO] modules/mod_ic_event_list/mod_ic_event_list.xml +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/default.php +~ [MODULE][PRO] modules/mod_ic_event_list/tmpl/icrounded.php +~ [MODULE] modules/mod_iccalendar/helper.php ++ site/helpers/ichelper.php +~ site/helpers/icmodel.php +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_calendar.php +~ [THEME PACKS] site/themes/packs/default/default_day.php +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/default/default_list.php +~ [THEME PACKS] site/themes/packs/default/default_registration.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css ++ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_alldates.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_calendar.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_list.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_registration.php +~ site/views/list/tmpl/default.php +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/send.php + + +iCagenda 3.2.2 (2013.10.10) +================================================================================ +! [iCicons] Use of integrated vector icons 'iCicons' designed for iCagenda (will evolve!). +# Fixed : List of dates in registration form (was not filtering by weekdays). +# [iCicons] Fixed : Android not display of arrows in ascii code (calendar, back button, back/next navigation). +# [iCicons] Fixed : Iphone/Ipad, arrows were not clickable (calendar, back button, back/next navigation). +# Fixed : ACL access levels filtering for events in front-end. +# Fixed : Request of Itemid in submit form. +~ Changed : better filtering of Approval access. +~ Changed : clean-up of some php functions, and sql request in frontend. +~ [THEME PACKS] Changed : enhancements of module css, and adding vector icon for back button. + +* Changed files in 3.2.2 +~ admin/views/events/tmpl/default.php +~ icagenda.xml +~ [MODULE] modules/mod_iccalendar/helper.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.php +~ [MODULE] modules/mod_iccalendar/mod_iccalendar.xml +~ site/helpers/icmodel.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/default.xml +~ [THEME PACKS] site/themes/ic_rounded.xml +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php ++ [FOLDER] media/icicons/ ++ [FOLDER] media/icicons/fonts/ ++ media/icicons/fonts/iCicons.eot ++ media/icicons/fonts/iCicons.svg ++ media/icicons/fonts/iCicons.ttf ++ media/icicons/fonts/iCicons.woff ++ media/icicons/lte-ie7.js ++ media/icicons/style.css + + +iCagenda 3.2.1 (2013.10.07) +================================================================================ +! First Stable release with 'Submit an Event' feature. For Users of the free version, see all the Release Notes of previous RC versions (available for Pro). +~ Changed : Use of DATE_FORMAT_LC3 in list of events, admin (to get date in Russian on windows server). +# Fixed : Remove nowrap css class attribute, to prevent not wrapping to the next line for long title (this is solved in iCagenda, but you may have the same problem in Joomla 3 articles. Proposal of modification added on Joomla core Github). +# Fixed : Error message when updating from an older version, if category filter was set to one category (new option multiple-categories filtering). + +* Changed files in 3.2.1 +~ admin/views/events/tmpl/default.php +~ site/helpers/icmodel.php +~ site/models/list.php + + +iCagenda 3.2.0 RC4 (2013.10.04) +================================================================================ +! Added : New option, Multi-selection of categories, in parameters of the menu link to list of events. +! Changed : Updated Google Maps API to V3 https ++ Added : Notification email to a user when his event submitted has been approved by a manager. ++ Added : Redirect to login page if Approval Manager is not connected on event details page (replacing 404 page). ++ Added : New icons for 'Approve this event' (J2.5 using icons, and J3 using icomoon). ++ Added : New tooltip script for manager icons. ++ Added : Router SEF for Submit an Event. +# [LOW] Bug : inserting an extra number data at the end of the footer text line, in notification email send to Approval managers. +# [LOW] Bug : Number of events in header was not well set, when an Approval Manager is logged-in. +# [LOW] Display : Display of info tooltip when Phone Field not shown in registration form. +# [MEDIUM] Bug : display of 'sunday', when no days of the week selected for a period event, in event details view. +~ [THEME PACKS] Changed : Manager Icons are removed from theme packs (to prevent not display in personal theme pack) and added in event.php file. +~ Changed : Attachment opens now in a new window (target blank). + +* Changed files in 3.2.0 RC4 +~ admin/config.xml +~ admin/models/fields/modal/cat.php ++ admin/models/fields/modal/multicat.php +~ admin/models/forms/event.xml +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/info/tmpl/default.php +~ icagenda.xml +~ site/add/css/style.css +~ site/helpers/icmodel.php +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ site/router.php +~ [THEME PACKS] site/themes/default.xml +~ [THEME PACKS] site/themes/ic_rounded.xml +~ [THEME PACKS] site/themes/packs/default/css/default_component.css +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/default/default_list.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_list.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/send.php +~ site/views/submit/view.html.php ++ [FOLDER] media/css/ ++ media/css/tipTip.css ++ [FOLDER] media/css/manager/ ++ media/images/manager/approval_16.png ++ [FOLDER] media/js/ ++ media/js/jquery.tipTip.js + + + +iCagenda 3.2.0 RC3 (2013.09.26) +================================================================================ +! Changes in the display of Global Options (added General Settings Tab) +! Fixed : important issue in notification emails send to managers authorized to approve events (due to a bug if user is depending of more than one user groups) +! Changed : Approval can be processed directly in Frontend, at event preview page. ++ Added : Check if managers with Approval permissions are Enabled and Activated. ++ Added : Option to select Template in menu-item link 'Submit an Event'. ++ Added : Global option to enable or disable auto login in url links included in notification emails. ++ Added : implemented Page Header and page class suffix in 'Submit an Event' page. +~ Changed : Events submitted in Frontend by a user (manager) belonging to an authorized group will be automatically approved. +~ Changed : Back button in event details view return to list of events ( replace history.go(-1) ). + +* Changed files in 3.2.0 RC3 ++ admin/add/elements/desc.php +~ admin/config.xml +~ admin/models/forms/event.xml +~ script.icagenda.pro.php +~ site/helpers/icmodel.php +~ site/models/forms/submit.xml +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/list/tmpl/registration.php +~ site/views/submit/tmpl/default.php +~ site/views/submit/tmpl/default.xml +~ site/views/submit/tmpl/send.php +~ site/views/submit/view.html.php + + +iCagenda 3.2.0 RC2 (2013.09.22) +================================================================================ +# Fixed : Access Permissions to 'Submit an Event' form (missing global option). ++ Added : Options to customize the content when a user access to the 'Submit an Event' page, and this user is not connected, or connected but does not have sufficient rights. + +* Changed files in 3.2.0 RC2 +~ admin/config.xml ++ admin/models/fields/modal/ictext_content.php ++ admin/models/fields/modal/ictext_type.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ site/views/submit/tmpl/default.php + + +iCagenda 3.2.0 RC (2013.09.20) +================================================================================ +! NEW : Menu Type to 'Submit an Event' in frontend. +! NEW : Selection of days of the week for period events (additional options to come for dates settings!). +! NEW : Plugin iCagenda Autologin. + +* Changed files in 3.2.0 RC +~ admin/config.xml +~ admin/models/event.php +~ admin/models/events.php ++ admin/models/fields/modal/tos_article.php +~ admin/models/fields/modal/tos_content.php ++ admin/models/fields/modal/tos_default.php ++ admin/models/fields/modal/tos_type.php +~ admin/tables/event.php +~ admin/views/event/tmpl/edit.php +~ [MODULE PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [MODULE] modules/mod_iccalendar/helper.php +~ script.icagenda.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ site/models/submit.php +~ [THEME PACKS] site/themes/default.xml +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/default/default_list.php +~ [THEME PACKS] site/themes/ic_rounded.xml +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_list.php ++ site/views/submit/tmpl/default.php ++ site/views/submit/tmpl/default.xml ++ site/views/submit/tmpl/send.php ++ site/views/submit/view.html.php ++ [PLUGIN] plugins/plg_ic_autologin/ic_autologin.php ++ [PLUGIN] plugins/plg_ic_autologin/ic_autologin.xml ++ SQL : Adding 'daystime' column to table icagenda_events + + +iCagenda 3.1.13 (2013.09.20) +================================================================================ +# Fixed : display in frontend of the fake date 30 november 1999, if no single date is set. + +* Changed files in 3.1.13 +~ site/helpers/icmodel.php + + +iCagenda 3.1.12 (2013.09.17) +================================================================================ +# Fixed : A problem with the control of the upcoming date for events over a period (unpublished event and message 'no valid date'). This bug is present since version 3.1.5, and rarely appeared. +# Fixed : conflict CSS days font color in calendar module with some Shape5 templates. + +* Changed files in 3.1.12 +~ site/helpers/icmodel.php +~ [THEME PACKS] site/themes/default.xml +~ [THEME PACKS] site/themes/ic_rounded.xml +~ [THEME PACKS] site/themes/packs/default/css/default_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css + + +iCagenda 3.1.11 (2013.09.13) +================================================================================ +# Fixed : Italian bug in translation files, responsible of missing features in event edit (admin). +# Fixed : Error mktime when saving a new event (due to no filling of single dates). A fix should update in the same way events with this issue in the frontend. + +* Changed files in 3.1.11 +~ admin/models/fields/modal/date.php +~ admin/views/event/tmpl/edit.php +~ site/helpers/icmodel.php + + +iCagenda 3.1.10 (2013.09.12) +================================================================================ ++ added : control if allow_url_fopen and GD are enabled (thumbnails generator) ++ added : files to prepare the next release with Submit an Event feature! ++ added : Approval option in event edit (will be operating in release 3.2!). +~ Changed : new dates control when saving an event, display now an alert message for new event, and block saving of a new event if no valid date. +~ Changed : enhancement of period datepicker (not possible now to have end date before start date) +# Fixed : not generation of thumbs when extension of a file in caps. +# MODULE iC calendar : Fixed possible conflicts due to div tags enclosed within scripts (rare conflict, manifested by the appearance of a part of the script on the page, and the non-functioning of the calendar). +# THEME IC_ROUNDED : display of next date (Time 2 times), list of events. + +* Changed files in 3.1.10 +~ admin/add/js/icdates.js +~ admin/config.xml +~ admin/controllers/events.php ++ admin/helpers/html/events.php +~ admin/models/event.php +~ admin/models/fields/modal/date.php +~ admin/models/fields/modal/enddate.php +~ admin/models/fields/modal/startdate.php ++ admin/models/fields/modal/tos_content.php +~ admin/models/forms/event.xml +~ admin/tables/event.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ [PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ modules/mod_iccalendar/helper.php +~ modules/mod_iccalendar/mod_iccalendar.php +~ site/add/js/icdates.js +~ site/helpers/icmodel.php ++ site/models/forms/submit.xml +~ site/models/list.php ++ site/models/submit.php +~ [THEME PACKS] site/themes/ic_rounded.xml +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_list.php ++ SQL : Adding 'approval' column to table icagenda_events + + +iCagenda 3.1.9 (2013.09.06) +================================================================================ +! MODULE iC calendar : possibility now to publish many calendars on a single page. ++ Added : Extra-control if mime-type of the event's image is correct (in order to process thumbnails creation). ++ Added : Complete or not form fields 'Name' and 'Email' with the profile information of a Joomla user connected, in registration form. ++ Added : Option to enable or disable the thumbnail generator. ++ Added : 'Notes' field text area in Registration form (set disabled as default). ++ Added : Option Show/Hide 'Notes' in registration form. ++ Added : Option Show/Hide 'Phone' in registration form. ++ Added : Information and control of folder creation used by iCagenda (thumbnails, attachments). +~ THEME PACKS : version 2.0 (default and ic_rounded). +~ Changed : period of dates with start date the same day than end date is now displayed as 'date start time - end time' (eg. 23 April 2013 10:00-19:00) +~ Changed : list of date formats was without infos in Joomla 3 +# MODULE iC calendar : Fixed, Tooltip Close X button was not working on Apple mobile devices. +# Fixed : bugs in thumbnails generator if ROOT/images folder doesn't exist. Solve an issue if path to images is not 'images'. + +* Changed files in 3.1.9 +~ admin/config.xml +~ admin/models/event.php +~ admin/models/fields/iclist/globalization.php +~ admin/models/fields/modal/enddate.php +~ admin/models/fields/modal/startdate.php +~ admin/models/forms/event.xml +~ admin/models/registrations.php +~ admin/tables/event.php +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ admin/views/registrations/tmpl/default.php +~ media/scripts/icthumb.php +~ [PRO] modules/mod_ic_event_list/mod_ic_event_list.php +~ [PRO] modules/mod_ic_event_list/mod_ic_event_list.xml ++ modules/mod_iccalendar/helper.php +~ modules/mod_iccalendar/mod_iccalendar.php +~ modules/mod_iccalendar/mod_iccalendar.xml +~ script.icagenda.php +- site/helpers/icmodcalendar.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ [THEME PACKS] site/themes/default.xml +~ [THEME PACKS] site/themes/ic_rounded.xml +~ [THEME PACKS] site/themes/packs/default/default_event.php +~ [THEME PACKS] site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_day.php +~ [THEME PACKS] site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/views/list/tmpl/registration.php +~ site/views/list/view.html.php ++ SQL : Adding 'created_by_email' column to table icagenda_events ++ SQL : Adding 'weekdays' column to table icagenda_events ++ SQL : Adding 'notes' column to table icagenda_registration + + +iCagenda 3.1.8 (2013.08.30) +================================================================================ +# Fixed : Error message in liveupdate (developed by Nicholas from Akeeba) to work under php 5.2. I've added a php control to be able to load storage.php file. But, we truly recommend every user to upgrade their php version to a minimum of 5.3, as recommended by Joomla core, and as minimum to be able to install Joomla 3. In the future, you can encounter other such issue, or error message, if you're still in a PHP version lower than 5.3. ++ Added : Alert Message in control panel of the component, if PHP version is lower than 5.3. + +* Changed files in 3.1.8 +~ admin/liveupdate/classes/storage/storage.php +~ admin/views/icagenda/tmpl/default.php + + +iCagenda 3.1.7 (2013.08.29) +================================================================================ ++ Added : Created_by filter in list of registered users (admin). ++ Added : Option to use php function checkdnsrr in registration form, to check if email provider is valid (this option is now disabled by default). ++ Added : Options for event details view: show/hide dates, Google Maps, information... and set access level for some. ++ Added : Options to order by dates list of single dates, and display a vertical or horizontal list. ++ Added : Option for registration form : auto-filled name or username, in name's form field (was only name before). ++ MODULE iC calendar : Option to display only start date in the calendar, in case of an event over a period. +~ MODULE iC calendar : Changes in script code of function.js file to prevent some conflict. +~ Changed : Search in registrations list extended: username, name, email, date, phone, people... (only search in Title before this release) +~ Changed : Default value is now set to "by individual date" in 'Registration Type' field. +~ Changed : Upgraded files of LiveUpdate by Akeeba, updates system integrated in iCagenda. +# Fixed : sending notification email to author of an event, when new registration. Fixed of [AUTHOREMAIL] tag. +# Fixed : Error Debug of Google Maps (icmap.js). + +* Changed files in 3.1.7 +~ admin/config.xml +~ admin/liveupdate/ (All php files of this folder updated) ++ admin/models/fields/modal/checkdnsrr.php +~ admin/models/forms/event.xml +~ admin/models/registrations.php +~ admin/views/icagenda/tmpl/default.php +~ admin/views/registrations/tmpl/default.php +~ modules/mod_iccalendar/js/function.js +~ modules/mod_iccalendar/mod_iccalendar.xml +~ site/helpers/icmodcalendar.php +~ site/helpers/icmodel.php +~ site/js/icmap.js +~ site/themes/packs/default/default_event.php +~ site/views/list/tmpl/registration.php + + +iCagenda 3.1.6 (2013.08.20) +================================================================================ +# Fixed : NextDate control when event set on a period in the future. ++ Added : Control of time when event with a date in a period the same as a single date. ++ Added : On windows server and php version < 5.3, disable check function if provider of an email address during registration is valid, as checkdnsrr is implemented on windows server only since php 5.3.0 + +* Changed files in 3.1.6 +~ site/helpers/icmodel.php + + +iCagenda 3.1.5 Security Release and enhancements! (2013.08.19) +================================================================================ +! Security Release : fixed a XSS vulnerability discovered by Stefan Horlacher from Compass Security AG (www.csnc.ch) (many thanks Stefan to keep the web clean and secured!). Another issue was resolved, discovered by Giusebos, which allowed sending spam to the administrator and the creator of the event, using cookies via registration form. And that's not all! As we always want to add much more security, some filtering enhancements have been added to the registration form (see below). +! Change : Now, when an event over a period with an end date and its time set to 00:00:00, this end date is displayed in frontend (list of events, and modules). ++ Added : New options in filtering events in menuitem. Now you can display all events, upcoming events, past events, events of the day and upcoming, or today's events. ++ Added : Page 404 when event not found. ++ Added : Enhancement of Email control during registration. Test if provider is valid. ++ Added : Test of the Name during registration. Now, a name cannot start with a number and cannot contain any of the following characters: / \ < > "_QQ_" [ ] ( ) " ; = + &. ++ Added : Control in front-end if dates of events are valid (control was before only in admin edit) +# Fixed : was counted archived events in header of list of events, and should not. +# Fixed : if end time is lower or equal to start time of an event over a period, end date is displayed. +# Fixed : Author name and username were not correctly displayed in admin events list, and now display correctly the user selected in 'created by'. + +* Changed files in 3.1.5 +~ admin/models/events.php +~ admin/tables/event.php +~ admin/views/events/tmpl/default.php +~ site/helpers/icmodcalendar.php +~ site/helpers/icmodel.php +~ site/views/list/tmpl/default.xml +~ site/views/list/tmpl/event.php +~ site/views/list/tmpl/registration.php + + +iCagenda 3.1.4 (2013.08.13) +================================================================================ +# Fixed : bug in function for detecting wrong dates entered by user, which was not always working as expected, depending of time setting in joomla config +# Fixed : change in function for globalized date format of month and of day, to prevent some errors due to locale (Russian...) +# Fixed : Not sending notification email to the registered user (if his email address is entered and required) ++ Added : Control of event ID to prevent spamming emails to administrator by a robot (notification email admin) +~ Changed : Translation of Date in current language (admin - list of events) + +* Changed files in 3.1.4 +~ admin/tables/event.php +~ admin/views/events/tmpl/default.php +~ site/helpers/icmodcalendar.php +~ site/helpers/icmodel.php +~ site/themes/packs/default/css/default_module.css +~ site/themes/packs/ic_rounded/css/ic_rounded_module.css + + +iCagenda 3.1.3 (2013.08.09) +================================================================================ +# Fixed : global option to hide the participants list not working properly +# Fixed : notice message above registration option field, in event edit +~ MODULE iC calendar : changed, access levels control, to speed up loading of pages with calendar ++ MODULE iC calendar : loading picture when charging a new month + +* Changed files in 3.1.3 +~ admin/models/fields/modal/ph_regbt.php +~ modules/mod_iccalendar/js/function.js +~ modules/mod_iccalendar/mod_iccalendar.php +~ site/helpers/icmodcalendar.php +~ site/helpers/icmodel.php +~ site/themes/packs/default/css/default_module.css +~ site/themes/packs/ic_rounded/css/ic_rounded_module.css +~ (added) site/themes/packs/default/images/ic_load.png +~ (added) site/themes/packs/ic_rounded/images/ic_load.png + + +iCagenda 3.1.2 (2013.08.05) +================================================================================ +! Important editing of thumbnails generator (List of events in admin, Calendar module, and Event List module). Now, file renaming for thumbnails (remove all special caracters to get a clean url for image), and copy of distant pictures (to prevent broken link). Accepted as image extensions (File Types) for event image : jpg, jpeg, png, gif, bmp +# Fixed : Slow change of month of the calendar (thumbnail generator error function) +# Fixed : Slow display of events in module iC Event List (Pro Version) +~ changed : [J3 issue] jQuery UI version in admin, from 1.9.2 to 1.8.23 to prevent a conflict with description tooltip (appeared since joomla 3.1.4) + +* Changed files in 3.1.2 +~ admin/views/event/tmpl/edit.php +~ admin/views/events/tmpl/default.php +~ media/scripts/icthumb.php +~ script.icagenda.php +~ site/helpers/icmodcalendar.php + + +iCagenda 3.1.1 (2013.07.29) +================================================================================ +# Fixed : Wrong filtering of Viewing Access Levels in list of events page +# Fixed : error in modules (front-end), when url to image is broken or invalid +~ changed : url of image when sharing on facebook (other enhancements planned) + +* Changed files in 3.1.1 +~ admin/views/icagenda/view.html.php +~ script.icagenda.php +~ site/helpers/icmodcalendar.php +~ site/helpers/icmodel.php +~ site/views/list/tmpl/event.php + + +iCagenda 3.1.0 (2013.07.26) +================================================================================ +! New : Automatic thumbnails generator in modules (some options, and enhancements will be added later in theme packs) +# Fixed : Issues with J3 after upgrade from joomla 3.1.x to 3.1.4 (error 500 default layout missing, and JFile not found) +# Fixed : not sending admin notification email (error in 3.0.1 and 3.0 pre-releases) +# Fixed : No updating of Next Date when menu set to Upcoming Events +# Fixed : participant slide effect and display options not working ++ Added : Global Option for email field in frontend registration (required or not) +~ many code review + +* Changed files in 3.1.0 +~ admin/config.xml +~ admin/models/categories.php +~ admin/models/fields/modal/ph_regbt.php +~ admin/tables/event.php +~ admin/views/events/tmpl/default.php +~ admin/views/icagenda/view.html.php +~ media/scripts/icthumb.php +~ script.icagenda.php +~ site/helpers/icmodcalendar.php +~ site/helpers/icmodel.php +~ site/models/list.php +~ site/themes/packs/default/default_event.php +~ site/themes/packs/default/css/default_component.css +~ site/themes/packs/ic_rounded/ic_rounded_event.php +~ site/themes/packs/ic_rounded/css/ic_rounded_component.css +~ site/views/list/tmpl/registration.php + + +iCagenda 3.0.1 (2013.07.04) +================================================================================ +# Fixed : auto-play of the tutorial video on Chrome and Safari (the video should not autoplay) +# Fixed : missing admin pagination in categories list +# Fixed : buttons display over the datepicker (time show/hide button activated) + +* Changed files in 3.0.1 +~ admin/add/css/jquery-ui-1.8.17.custom.css +~ admin/views/categories/tmpl/default.php +~ admin/views/categories/view.html.php +~ admin/views/event/tmpl/edit.php +~ admin/views/event/view.html.php + + +iCagenda 3.0 RC (2013.06.30) +================================================================================ +# Fixed : Thumbnail generator in events list admin : error when using a distant url +# Fixed : Position and zooming in admin, in events created before update +# Fixed : Colors of options buttons in event admin edit : not always visible, in events created before update +# Fixed : Theme ic_rounded : problem of display with long title ++ Added : Custom text option for registration button ++ Added : Control if link to event picture is valid, in admin +~ updated : display in Global Options of the component and modules + + +iCagenda 3.0 beta 1 (2013.06.09) +================================================================================ +! First beta version compatible with Joomla 3 and Joomla 2.5 + +* Changed files in 3.0 +! Given that this new version brings compatibility with Joomla 3, all php files were reviewed to allow dual Joomla 2.5 / 3.x compatibility. Other files were also reviewed, with a major overhaul of logic and graphic structure of iCagenda. The list of modified files is reset with this new version 3.0 of iCagenda and the list of modified files will be detailed again from future release 3.0.1 + + +iCagenda v2 ChangeLog (2012.12.31 > 2013.05.29) +? http://icagenda.joomlic.com/docs/changelog/87-v2-changelog + +iCagenda v1 ChangeLog (2012.08.07 > 2012.08.29) +? http://icagenda.joomlic.com/docs/changelog/89-v1-changelog + +; diff --git a/deployed/icagenda/administrator/components/com_icagenda/access.xml b/deployed/icagenda/administrator/components/com_icagenda/access.xml new file mode 100644 index 00000000..eb9e6bbe --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/access.xml @@ -0,0 +1,26 @@ + + +
+ + + + + + + + + + + + + + +
+
diff --git a/deployed/icagenda/administrator/components/com_icagenda/assets/elements/desc.php b/deployed/icagenda/administrator/components/com_icagenda/assets/elements/desc.php new file mode 100644 index 00000000..6a3f38ae --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/assets/elements/desc.php @@ -0,0 +1,118 @@ +load('com_icagenda', JPATH_ADMINISTRATOR, 'en-GB', true); +$language->load('com_icagenda', JPATH_ADMINISTRATOR, null, true); + + +class JFormFieldDesc extends JFormField +{ + protected $type = 'Desc'; + + protected function getLabel() + { + return ' '; + } + + protected function getInput() + { + $html = array(); + + $document = JFactory::getDocument(); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::stylesheet('com_icagenda/template.j25.css', false, true); + JHtml::stylesheet('com_icagenda/icagenda-back.j25.css', false, true); + + JHTML::_('behavior.framework'); + + // load jQuery, if not loaded before + $scripts = array_keys($document->_scripts); + $scriptFound = false; + $scriptuiFound = false; + + for ($i = 0; $i < count($scripts); $i++) + { + if (stripos($scripts[$i], 'jquery.min.js') !== false) + { + $scriptFound = true; + } + // load jQuery, if not loaded before as jquery + if (stripos($scripts[$i], 'jquery.js') !== false) + { + $scriptFound = true; + } + if (stripos($scripts[$i], 'jquery-ui.min.js') !== false) + { + $scriptuiFound = true; + } + } + + // jQuery Library Loader + if (!$scriptFound) + { + // load jQuery, if not loaded before + if (!JFactory::getApplication()->get('jquery')) + { + JFactory::getApplication()->set('jquery', true); + // add jQuery + $document->addScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/jquery.noconflict.js' ); + } + } + + if (!$scriptuiFound) + { + $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); + } + + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/template.js' ); + } + + $label = $this->element['label']; + $label = $this->translateLabel ? JText::_($label) : $label; + + $style = $this->element['style']; + $style = $this->translateLabel ? JText::_($style) : $style; + + $class = $this->element['class']; + $class = $this->translateLabel ? JText::_($class) : $class; + + + // Contruction + $html[] = "
\ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/assets/elements/title.php b/deployed/icagenda/administrator/components/com_icagenda/assets/elements/title.php new file mode 100644 index 00000000..080e3b0a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/assets/elements/title.php @@ -0,0 +1,120 @@ +load('com_icagenda', JPATH_ADMINISTRATOR, 'en-GB', true); +$language->load('com_icagenda', JPATH_ADMINISTRATOR, null, true); + +JHtml::stylesheet('com_icagenda/icagenda-back.css', false, true); + + +class JFormFieldTitle extends JFormField +{ + protected $type = 'Title'; + + protected function getLabel() + { + return ' '; + } + + protected function getInput() + { + $html = array(); + + $document = JFactory::getDocument(); + $document->addStyleSheet( JURI::root( true ) . '/media/com_icagenda/icicons/style.css' ); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::stylesheet('com_icagenda/template.j25.css', false, true); + JHtml::stylesheet('com_icagenda/icagenda-back.j25.css', false, true); + + JHTML::_('behavior.framework'); + + // load jQuery, if not loaded before + $scripts = array_keys($document->_scripts); + $scriptFound = false; + $scriptuiFound = false; + + for ($i = 0; $i < count($scripts); $i++) + { + if (stripos($scripts[$i], 'jquery.min.js') !== false) + { + $scriptFound = true; + } + // load jQuery, if not loaded before as jquery + if (stripos($scripts[$i], 'jquery.js') !== false) + { + $scriptFound = true; + } + if (stripos($scripts[$i], 'jquery-ui.min.js') !== false) + { + $scriptuiFound = true; + } + } + + // jQuery Library Loader + if (!$scriptFound) + { + // load jQuery, if not loaded before + if (!JFactory::getApplication()->get('jquery')) + { + JFactory::getApplication()->set('jquery', true); + // add jQuery + $document->addScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/jquery.noconflict.js' ); + } + } + + if (!$scriptuiFound) + { + $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); + } + + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/template.js' ); + } + + $label = $this->element['label']; + $label = $this->translateLabel ? JText::_($label) : $label; + + $style = $this->element['style']; + $style = $this->translateLabel ? JText::_($style) : $style; + + $class = $this->element['class']; + $class = $this->translateLabel ? JText::_($class) : $class; + + + // Contruction + $html[] = "
element['label']; + $label = $this->translateLabel ? JText::_($label) : $label; + + $html = '

' . $label . '

'; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/assets/elements/titleimg.php b/deployed/icagenda/administrator/components/com_icagenda/assets/elements/titleimg.php new file mode 100644 index 00000000..4aab4509 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/assets/elements/titleimg.php @@ -0,0 +1,86 @@ +load('com_icagenda', JPATH_ADMINISTRATOR, 'en-GB', true); +$language->load('com_icagenda', JPATH_ADMINISTRATOR, null, true); + +JHtml::stylesheet('com_icagenda/icagenda-back.css', false, true); + + +class JFormFieldTitleImg extends JFormField +{ + protected $type = 'TitleImg'; + + protected function getLabel() + { + return ' '; + } + + protected function getInput() + { + $html = array(); + + // Affichage texte + + $label = $this->element['label']; + $label = $this->translateLabel ? JText::_($label) : $label; + + $style = $this->element['style']; + $style = $this->translateLabel ? JText::_($style) : $style; + + $class = $this->element['class']; + $class = $this->translateLabel ? JText::_($class) : $class; + + $icimage = $this->element['icimage']; + $image = '../media/com_icagenda/images/'. $icimage .''; + + $icicon = $this->element['icicon']; + + // Contruction + $html[] = '
\ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/assets/jcms/info.php b/deployed/icagenda/administrator/components/com_icagenda/assets/jcms/info.php new file mode 100644 index 00000000..47ccd10c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/assets/jcms/info.php @@ -0,0 +1,104 @@ +siteId = $siteId; + } + + /** + * Sets the value of a collected variable. Use NULL as value to unset it + * + * @param string $key Variable name + * @param string $value Variable value + */ + public function setValue($key, $value) + { + if (is_null($value) && isset($this->data[$key])) + { + unset($this->data[$key]); + } + else + { + $this->data[$key] = $value; + } + } + + /** + * Uploads collected data to the remote server + * + * @param bool $useIframe Should I create an iframe to upload data or should I use cURL/fopen? + * + * @return string|bool The HTML code if an iframe is requested or a boolean if we're using cURL/fopen + */ + public function sendInfo($useIframe = false) + { + // No site ID? Well, simply do nothing + if ( ! $this->siteId) + { + return ''; + } + + // First of all let's add the siteId + $this->setValue('sid', $this->siteId); + + // Then let's create the url + $url = array(); + + foreach ($this->data as $param => $value) + { + $url[] .= $param . '=' . $value; + } + + $url = $this->remoteUrl . '?' . implode('&', $url); + + // Should I create an iframe? + if ($useIframe) + { + return ''; + } + else + { + // Do we have cURL installed? + if (function_exists('curl_init')) + { + $ch = curl_init($url); + + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + + return curl_exec($ch); + } + else + { + // Nope, let's try with fopen and cross our fingers + return @fopen($url, 'r'); + } + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/config.xml b/deployed/icagenda/administrator/components/com_icagenda/config.xml new file mode 100644 index 00000000..ca695564 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/config.xml @@ -0,0 +1,2362 @@ + + + +
+ + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +
diff --git a/deployed/icagenda/administrator/components/com_icagenda/controller.php b/deployed/icagenda/administrator/components/com_icagenda/controller.php new file mode 100644 index 00000000..456e151b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controller.php @@ -0,0 +1,50 @@ +input; + + // Load the submenu. + iCagendaHelper::addSubmenu($jinput->get('view', 'icagenda')); + $view = $jinput->get('view', 'icagenda'); + $jinput->set('view', $view); + + parent::display(); + + return $this; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/categories.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/categories.php new file mode 100644 index 00000000..48995074 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/categories.php @@ -0,0 +1,39 @@ + true)); + + return $model; + } + +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/category.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/category.php new file mode 100644 index 00000000..e1ddb05b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/category.php @@ -0,0 +1,34 @@ +view_list = 'categories'; + parent::__construct(); + } + +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/customfield.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/customfield.php new file mode 100644 index 00000000..976c53be --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/customfield.php @@ -0,0 +1,63 @@ +view_list = 'customfields'; + parent::__construct(); + } + + /** + * Return Ajax to save a new custom field group + * + * @since 3.6.0 + */ + function newGroup() + { + icagendaAjaxFilter::saveCustomFieldGroup(); + } + + /** + * Return Ajax to check if a custom field group is set to any custom field + * + * @since 3.6.0 + */ + function checkGroup() + { + icagendaAjaxFilter::checkCustomFieldGroup(); + } + + /** + * Return Ajax to delete a custom field group + * + * @since 3.6.0 + */ + function deleteGroup() + { + icagendaAjaxFilter::deleteCustomFieldGroup(); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/customfields.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/customfields.php new file mode 100644 index 00000000..afa097f5 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/customfields.php @@ -0,0 +1,38 @@ + true)); + + return $model; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/event.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/event.php new file mode 100644 index 00000000..b104f3dc --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/event.php @@ -0,0 +1,144 @@ +view_list = 'events'; + + parent::__construct(); + } + + /** + * Method override to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since 1.0 + */ + protected function allowAdd($data = array()) + { + // Initialise variables. + $input = JFactory::getApplication()->input; + $user = JFactory::getUser(); + $categoryId = JArrayHelper::getValue($data, 'catid', $input->getInt('filter_category_id'), 'int'); + $allow = null; + + if ($categoryId) + { + // If the category has been passed in the data or URL check it. + $allow = $user->authorise('core.create', 'com_icagenda.category.' . $categoryId); + } + + if ($allow === null) + { + // In the absense of better information, revert to the component permissions. + return parent::allowAdd(); + } + else + { + return $allow; + } + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.0 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // Initialise variables. + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = JFactory::getUser(); + $userId = $user->get('id'); + + // Check general edit permission first. + if ($user->authorise('core.edit', 'com_icagenda.event.' . $recordId)) + { + return true; + } + + // Fallback on edit.own. + // First test if the permission is available. + if ($user->authorise('core.edit.own', 'com_icagenda.event.' . $recordId)) + { + // Now test the owner is the user. + $ownerId = (int) isset($data['created_by']) ? $data['created_by'] : 0; + + if (empty($ownerId) && $recordId) + { + // Need to do a lookup from the model. + $record = $this->getModel()->getItem($recordId); + + if (empty($record)) + { + return false; + } + + $ownerId = $record->created_by; + } + + // If the owner matches 'me' then do the test. + if ($ownerId == $userId) + { + return true; + } + } + + // Since there is no asset tracking, revert to the component permissions. + return parent::allowEdit($data, $key); + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 1.0 + */ + public function batch($model = null) + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Event', '', array()); + + // Preset the redirect + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=events' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/events.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/events.php new file mode 100644 index 00000000..6d3a504f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/events.php @@ -0,0 +1,118 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to save the submitted ordering values for records via AJAX. + * + * @return void + * + * @since 3.0 + */ + public function saveOrderAjax() + { + $app = JFactory::getApplication(); + $input = $app->input; + + $pks = $input->post->get('cid', array(), 'array'); + $order = $input->post->get('order', array(), 'array'); + + // Sanitize the input + JArrayHelper::toInteger($pks); + JArrayHelper::toInteger($order); + + // Get the model + $model = $this->getModel(); + + // Save the ordering + $return = $model->saveorder($pks, $order); + + if ($return) + { + echo "1"; + } + + // Close the application + $app->close(); + } + + public function __construct($config = array()) + { + parent::__construct($config); + + $this->registerTask('unapprove', 'approve'); + } + + /** + * Method to approve an event. + * + * @return void + * + * @since 3.2 + */ + public function approve() + { + // Check for request forgeries. + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $app = JFactory::getApplication(); + $input = $app->input; + + $ids = $input->post->get('cid', array(), 'array'); + + if (empty($ids)) + { + $app->enqueueMessage(JText::_('JERROR_NO_ITEMS_SELECTED'), 'warning'); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Change the state of the records. + if ( ! $model->approve($ids)) + { + $app->enqueueMessage($model->getError(), 'warning'); + } + else + { + $this->setMessage(JText::plural('COM_ICAGENDA_N_EVENTS_APPROVED', count($ids))); + } + } + + $this->setRedirect('index.php?option=com_icagenda&view=events'); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/feature.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/feature.php new file mode 100644 index 00000000..24b7dcb2 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/feature.php @@ -0,0 +1,34 @@ +view_list = 'features'; + + parent::__construct(); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/features.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/features.php new file mode 100644 index 00000000..40d43254 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/features.php @@ -0,0 +1,38 @@ + true)); + + return $model; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/icagenda.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/icagenda.php new file mode 100644 index 00000000..f40874c0 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/icagenda.php @@ -0,0 +1,38 @@ + true)); + return $model; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/index.html b/deployed/icagenda/administrator/components/com_icagenda/controllers/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/mail.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/mail.php new file mode 100644 index 00000000..de51ee8f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/mail.php @@ -0,0 +1,106 @@ +view_list = 'icagenda'; + + parent::__construct(); + } + + /** + * Return Ajax to load date select options + * + * @since 3.5.9 + */ + function dates() + { + icagendaAjax::getOptionsEventDates('mail'); + + // Cut the execution short +// JFactory::getApplication()->close(); + } + + /** + * Send the mail + * + * @return void + * + * @since 3.5.9 + */ + public function send() + { + // Check for request forgeries. + JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); + + $app = JFactory::getApplication(); + $jinput = $app->input; + $model = $this->getModel('Mail'); + + if ( ! $model->send()) + { + // Get the user data. + $requestData = $this->input->post->get('jform', array(), 'array'); + + // Save the data in the session. + $app->setUserState('com_icagenda.mail.data', $requestData); + + // Redirect back to the newsletter screen. + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=mail&layout=edit', false)); + + return false; + } + + // Flush the data from the session. + $app->setUserState('com_icagenda.mail.data', null); + + // Redirect back to the newsletter screen. + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=mail&layout=edit', false)); + + return true; + } + + /** + * Cancel the mail + * + * @return void + * + * @since 3.5.9 + */ + public function cancel($key = null) + { + // Check for request forgeries. + JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); + + $app = JFactory::getApplication(); + + // Flush the data from the session. + $app->setUserState('com_icagenda.mail.data', null); + + $this->setRedirect(JRoute::_('index.php?option=com_icagenda', false)); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/registration.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/registration.php new file mode 100644 index 00000000..182a6474 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/registration.php @@ -0,0 +1,115 @@ +view_list = 'registrations'; + parent::__construct(); + } + + /** + * Return Ajax to load date select options + * + * @since 3.5.9 + */ + function dates() + { + icagendaAjax::getOptionsEventDates('registration'); + + // Cut the execution short +// JFactory::getApplication()->close(); + } + + /** + * Return Full name/Username using Ajax (depending on Global Options) + * + * @since 3.6.0 + */ + function registrationName() + { + $userId = JFactory::getApplication()->input->get('userid', ''); + + icagendaAjax::getRegistrationName($userId); + +// $user = JFactory::getUser($userId); + +// return $user->name; + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 3.3.3 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // Initialise variables. + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = JFactory::getUser(); + $userId = $user->get('id'); + + // Check general edit permission first. + if ($user->authorise('core.edit', 'com_icagenda.registration.' . $recordId)) + { + return true; + } + + // Fallback on edit.own. + // First test if the permission is available. + if ($user->authorise('core.edit.own', 'com_icagenda.registration.' . $recordId)) + { + // Now test the owner is the user. + $ownerId = (int) isset($data['created_by']) ? $data['created_by'] : 0; + if (empty($ownerId) && $recordId) + { + // Need to do a lookup from the model. + $record = $this->getModel()->getItem($recordId); + + if (empty($record)) + { + return false; + } + + $ownerId = $record->created_by; + } + + // If the owner matches 'me' then do the test. + if ($ownerId == $userId) + { + return true; + } + } + + // Since there is no asset tracking, revert to the component permissions. + return parent::allowEdit($data, $key); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/registrations.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/registrations.php new file mode 100644 index 00000000..2f4d46ac --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/registrations.php @@ -0,0 +1,36 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/registrations.raw.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/registrations.raw.php new file mode 100644 index 00000000..191a1c9d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/registrations.raw.php @@ -0,0 +1,156 @@ + true)); + + return $model; + } + + /** + * Display method for the raw track data. + * + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}. + * + * @return JController This object to support chaining. + * + * @since 3.5.0 + */ + public function display($cachable = false, $urlparams = false) + { + // Get the document object. + $document = JFactory::getDocument(); + $vName = 'registrations'; + $vFormat = 'raw'; + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + // Get the model for the view. + $model = $this->getModel($vName); + + // Load the filter state. + $app = JFactory::getApplication(); + + $search = $app->getUserState($this->context . '.filter.search'); + $model->setState('filter.search', $search); + + $published = $app->getUserState($this->context . '.filter.state', '1'); + $model->setState('filter.state', $published); + + $categoryId = $app->getUserState($this->context . '.filter.categories'); + $model->setState('filter.categories', $categoryId); + + $eventId = $app->getUserState($this->context . '.filter.events'); + $model->setState('filter.events', $eventId); + + $date = $app->getUserState($this->context . '.filter.dates'); + $model->setState('filter.dates', $date); + + $model->setState('list.limit', 0); + $model->setState('list.start', 0); + + $input = JFactory::getApplication()->input; + $form = $input->get('jform', array(), 'array'); + + $model->setState('event_title', $form['event_title']); + $model->setState('date', $form['date']); + $model->setState('tickets', $form['tickets']); + $model->setState('name', $form['name']); + $model->setState('email', $form['email']); + $model->setState('phone', $form['phone']); + $model->setState('customfields', $form['customfields']); + $model->setState('notes', $form['notes']); + $model->setState('status', $form['status']); + $model->setState('created', $form['created']); + $model->setState('reg_id', $form['reg_id']); + + $model->setState('basename', $form['basename']); + $model->setState('separator', $form['separator']); + $model->setState('compressed', $form['compressed']); + + $config = JFactory::getConfig(); + $cookie_domain = $config->get('cookie_domain', ''); + $cookie_path = $config->get('cookie_path', '/'); + + // Joomla 3 + if (version_compare(JVERSION, '3.0', 'ge')) + { + setcookie(JApplicationHelper::getHash($this->context . '.event_title'), $form['event_title'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.date'), $form['date'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.tickets'), $form['tickets'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.name'), $form['name'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.email'), $form['email'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.phone'), $form['phone'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.customfields'), $form['customfields'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.notes'), $form['notes'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.status'), $form['status'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.created'), $form['created'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.reg_id'), $form['reg_id'], time() + 365 * 86400, $cookie_path, $cookie_domain); + + setcookie(JApplicationHelper::getHash($this->context . '.basename'), $form['basename'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.separator'), $form['separator'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplicationHelper::getHash($this->context . '.compressed'), $form['compressed'], time() + 365 * 86400, $cookie_path, $cookie_domain); + } + // Joomla 2.5 + else + { + setcookie(JApplication::getHash($this->context.'.basename'), $form['basename'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplication::getHash($this->context.'.separator'), $form['separator'], time() + 365 * 86400, $cookie_path, $cookie_domain); + setcookie(JApplication::getHash($this->context.'.compressed'), $form['compressed'], time() + 365 * 86400, $cookie_path, $cookie_domain); + } + + // Push the model into the view (as default). + $view->setModel($model, true); + + // Push document object into the view. + $view->document = $document; + + $view->display(); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/controllers/themes.php b/deployed/icagenda/administrator/components/com_icagenda/controllers/themes.php new file mode 100644 index 00000000..7c4024d5 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/controllers/themes.php @@ -0,0 +1,73 @@ +registerTask('themeinstall', 'themeinstall'); + } + + function themeinstall() + { + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $post = JFactory::getApplication()->input->post; + $theme = array(); + + if ($post->get('theme_component')) + { + $theme['component'] = 1; + } + + if (empty($theme)) + { + $ftp =& JClientHelper::setCredentialsFromRequest('ftp'); + + $model = &$this->getModel('themes'); + + if ($model->install($theme)) + { + $cache = JFactory::getCache('mod_menu'); + $cache->clean(); + + $msg = JText::_('COM_ICAGENDA_SUCCESS_THEME_INSTALLED'); + } + } + else + { + $msg = JText::_('COM_ICAGENDA_ERROR_THEME_APPLICATION_AREA'); + } + + $this->setRedirect('index.php?option=com_icagenda&view=themes', $msg); + } + + function cancel() + { + $this->setRedirect('index.php?option=com_icagenda'); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/helpers/html/events.php b/deployed/icagenda/administrator/components/com_icagenda/helpers/html/events.php new file mode 100644 index 00000000..56f3b76d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/helpers/html/events.php @@ -0,0 +1,57 @@ + array( + 'img' => 'tick.png', + 'task' => 'approve', + 'text' => '', + 'active_title' => 'COM_ICAGENDA_TOOLBAR_APPROVE', + 'inactive_title' => '', + 'tip' => true, + 'active_class' => 'unpublish', + 'inactive_class' => 'unpublish' + ), + 0 => array( + 'img' => 'publish_x.png', + 'task' => '', + 'text' => '', + 'active_title' => '', + 'inactive_title' => 'COM_ICAGENDA_APPROVED', + 'tip' => true, + 'active_class' => 'publish', + 'inactive_class' => 'publish' + ) + ); + return $states; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/helpers/html/index.html b/deployed/icagenda/administrator/components/com_icagenda/helpers/html/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/helpers/html/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/helpers/icagenda.php b/deployed/icagenda/administrator/components/com_icagenda/helpers/icagenda.php new file mode 100644 index 00000000..db33e664 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/helpers/icagenda.php @@ -0,0 +1,278 @@ +authorise('icagenda.access.categories', 'com_icagenda')) + { + JSubMenuHelper::addEntry( + JText::_('COM_ICAGENDA_TITLE_CATEGORIES'), + 'index.php?option=com_icagenda&view=categories', + $submenu == 'categories' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.events', 'com_icagenda')) + { + JSubMenuHelper::addEntry( + JText::_('COM_ICAGENDA_TITLE_EVENTS'), + 'index.php?option=com_icagenda&view=events', + $submenu == 'events' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.registrations', 'com_icagenda')) + { + JSubMenuHelper::addEntry( + JText::_('COM_ICAGENDA_TITLE_REGISTRATION'), + 'index.php?option=com_icagenda&view=registrations', + $submenu == 'registrations' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.newsletter', 'com_icagenda')) + { + JSubMenuHelper::addEntry( + JText::_('COM_ICAGENDA_TITLE_NEWSLETTER'), + 'index.php?option=com_icagenda&view=mail&layout=edit', + $submenu == 'newsletter' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.customfields', 'com_icagenda')) + { + JSubMenuHelper::addEntry( + JText::_('COM_ICAGENDA_TITLE_CUSTOMFIELDS'), + 'index.php?option=com_icagenda&view=customfields', + $submenu == 'customfields' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.features', 'com_icagenda')) + { + JSubMenuHelper::addEntry( + JText::_('COM_ICAGENDA_TITLE_FEATURES'), + 'index.php?option=com_icagenda&view=features', + $submenu == 'features' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.themes', 'com_icagenda')) + { + JSubMenuHelper::addEntry( + JText::_('COM_ICAGENDA_THEMES'), + 'index.php?option=com_icagenda&view=themes', + $submenu == 'themes' + ); + } + JSubMenuHelper::addEntry( + JText::_('COM_ICAGENDA_INFO'), + 'index.php?option=com_icagenda&view=info', + $submenu == 'info' + ); + + $document = JFactory::getDocument(); + + /** + * Set Titles iCagenda + */ + if ($submenu == 'icagenda') + { + $document->setTitle(JText::_('COM_ICAGENDA')); + } + if ($submenu == 'categories') + { + $document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_CATEGORIES')); + } + if ($submenu == 'events') + { + $document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_EVENTS')); + } + if ($submenu == 'registrations') + { + $document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_REGISTRATION')); + } + if ($submenu == 'newsletter') + { + $document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_NEWSLETTER')); + } + if ($submenu == 'customfields') + { + $document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_CUSTOMFIELDS')); + } + if ($submenu == 'features') + { + $document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_TITLE_FEATURES')); + } + if ($submenu == 'themes') + { + $document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_THEMES')); + } + if ($submenu == 'info') + { + $document->setTitle(JText::_('COM_ICAGENDA') . ' | ' . JText::_('COM_ICAGENDA_INFO')); + } + + $document->addStyleDeclaration(' + .icon48icagenda{background: url(../media/com_icagenda/images/XXX.png);} + .icon-48-events {background: url(../media/com_icagenda/images/all_events-48.png) no-repeat;} + .icon-48-event {background: url(../media/com_icagenda/images/new_event-48.png) no-repeat;} + .icon-48-registration {background: url(../media/com_icagenda/images/registration-48.png) no-repeat;} + .icon-48-categories {background: url(../media/com_icagenda/images/all_cats-48.png) no-repeat;} + .icon-48-category {background: url(../media/com_icagenda/images/new_cat-48.png) no-repeat;} + .icon-48-generic {background: url(../media/com_icagenda/images/iconicagenda48.png) no-repeat;} + .icon-48-mail {background: url(../media/com_icagenda/images/newsletter-48.png) no-repeat;} + .icon-48-themes {background: url(../media/com_icagenda/images/themes-48.png) no-repeat;} + .icon-48-customfields {background: url(../media/com_icagenda/images/customfields-48.png) no-repeat;} + .icon-48-info {background: url(../media/com_icagenda/images/info-48.png) no-repeat;} + '); + } + else + { + JHtmlSidebar::addEntry( + JText::_('COM_ICAGENDA_TITLE_ICAGENDA'), + 'index.php?option=com_icagenda&view=icagenda', + $submenu == 'icagenda' + ); + if (JFactory::getUser()->authorise('icagenda.access.categories', 'com_icagenda')) + { + JHtmlSidebar::addEntry( + JText::_('COM_ICAGENDA_TITLE_CATEGORIES'), + 'index.php?option=com_icagenda&view=categories', + $submenu == 'categories' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.events', 'com_icagenda')) + { + JHtmlSidebar::addEntry( + JText::_('COM_ICAGENDA_TITLE_EVENTS'), + 'index.php?option=com_icagenda&view=events', + $submenu == 'events' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.registrations', 'com_icagenda')) + { + JHtmlSidebar::addEntry( + JText::_('COM_ICAGENDA_TITLE_REGISTRATION'), + 'index.php?option=com_icagenda&view=registrations', + $submenu == 'registrations' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.newsletter', 'com_icagenda')) + { + JHtmlSidebar::addEntry( + JText::_('COM_ICAGENDA_TITLE_NEWSLETTER'), + 'index.php?option=com_icagenda&view=mail&layout=edit', + $submenu == 'newsletter' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.customfields', 'com_icagenda')) + { + JHtmlSidebar::addEntry( + JText::_('COM_ICAGENDA_TITLE_CUSTOMFIELDS'), + 'index.php?option=com_icagenda&view=customfields', + $submenu == 'customfields' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.features', 'com_icagenda')) + { + JHtmlSidebar::addEntry( + JText::_('COM_ICAGENDA_TITLE_FEATURES'), + 'index.php?option=com_icagenda&view=features', + $submenu == 'features' + ); + } + if (JFactory::getUser()->authorise('icagenda.access.themes', 'com_icagenda')) + { + JHtmlSidebar::addEntry( + JText::_('COM_ICAGENDA_THEMES'), + 'index.php?option=com_icagenda&view=themes', + $submenu == 'themes' + ); + } + JHtmlSidebar::addEntry( + JText::_('COM_ICAGENDA_INFO'), + 'index.php?option=com_icagenda&view=info', + $submenu == 'info' + ); + } + } + + /** + * Gets a list of the actions that can be performed. + */ + public static function getActions($messageId = 0) + { + $user = JFactory::getUser(); + $result = new JObject; + + if (empty($messageId)) + { + $assetName = 'com_icagenda'; + } + else + { + $assetName = 'com_icagenda.message.'.(int) $messageId; + } + + $actions = array( + 'core.admin', + 'core.manage', + 'core.create', + 'core.edit', + 'core.delete', + 'core.edit.state', + 'core.edit.own', + 'icagenda.access.categories', + 'icagenda.access.events', + 'icagenda.access.registrations', + 'icagenda.access.newsletter', + 'icagenda.access.customfields', + 'icagenda.access.features', + 'icagenda.access.themes' + ); + + foreach ($actions as $action) + { + $result->set($action, $user->authorise($action, $assetName)); + } + + return $result; + } + + /** + * Tests whether a string is serialized before attempting to unserialize it + * + * ( TO BE REMOVED WHEN ALL CALLS FROM IC LIBRARY !!! ) + */ + public static function isSerialized($str) + { + return ($str == serialize(false) || @unserialize($str) !== false); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/helpers/index.html b/deployed/icagenda/administrator/components/com_icagenda/helpers/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/helpers/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/icagenda.php b/deployed/icagenda/administrator/components/com_icagenda/icagenda.php new file mode 100644 index 00000000..839e91b8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/icagenda.php @@ -0,0 +1,182 @@ +. + * + * @since 1.0 + *---------------------------------------------------------------------------- +*/ + +defined('_JEXEC') or die; + +// Get Application +$app = JFactory::getApplication(); + +// Check Errors: iC Library & iCagenda Utilities +$UTILITIES_DIR = is_dir(JPATH_ADMINISTRATOR . '/components/com_icagenda/utilities'); + +if ( ( ! $UTILITIES_DIR) + || ( ! class_exists('iCLibrary')) ) +{ + $alert_message = JText::_('ICAGENDA_CAN_NOT_LOAD') . '
'; + $alert_message.= '
    '; + if ( ! class_exists('iCLibrary')) $alert_message.= '
  • ' . JText::_('IC_LIBRARY_NOT_LOADED') . '
  • '; + if ( ! $UTILITIES_DIR) $alert_message.= '
  • ' . JText::_('ICAGENDA_A_FOLDER_IS_MISSING') . '
  • '; + $alert_message.= '
'; + if ( ! $UTILITIES_DIR) $alert_message.= JText::_('ICAGENDA_IS_NOT_CORRECTLY_INSTALLED') . ' '; + if ( ! $UTILITIES_DIR) $alert_message.= JText::_('ICAGENDA_INSTALL_AGAIN') . '
'; + if ( ! $UTILITIES_DIR) $alert_message.= JText::_('IC_ALTERNATIVELY') . ':
    '; + if ($UTILITIES_DIR) $alert_message.= JText::_('IC_PLEASE') . ', '; + if ( ! class_exists('iCLibrary')) + { + if ( ! $UTILITIES_DIR) $alert_message.= '
  • '; + $alert_message.= JText::_('IC_LIBRARY_CHECK_PLUGIN_AND_LIBRARY'); + if ( ! $UTILITIES_DIR) $alert_message.= '
  • '; + } + if ( ! $UTILITIES_DIR) + { + $alert_message.= '
  • ' . JText::Sprintf('ICAGENDA_UTILITIES_FIX_MANUAL' + , 'admin/utilities' + , 'administrator/components/com_icagenda/'); + $alert_message.= '
'; + } + + // Get the message queue + $messages = $app->getMessageQueue(); + + $display_alert_message = false; + + // If we have messages + if (is_array($messages) && count($messages)) + { + // Check each message for the one we want + foreach ($messages as $key => $value) + { + if ($value['message'] == $alert_message) + { + $display_alert_message = true; + } + } + } + + if ( ! $display_alert_message) + { + $app->enqueueMessage($alert_message, 'error'); + + return; + } +} +else +{ + // Loads Utilities + JLoader::registerPrefix('icagenda', JPATH_ADMINISTRATOR . '/components/com_icagenda/utilities'); + + // Common fields + JFormHelper::addFieldPath(JPATH_ADMINISTRATOR . '/components/com_icagenda/utilities/form/field'); + + if ( ! defined('IC_LIBRARY')) + { + define('IC_LIBRARY', '1.3.0'); + } +} + +// Set Input J3 +$jinput = JFactory::getApplication()->input; + +// Load Live Update & Joomla import +require_once JPATH_ADMINISTRATOR . '/components/com_icagenda/liveupdate/liveupdate.php'; + +if ($jinput->get('view') == 'liveupdate') +{ + LiveUpdate::handleRequest(); + + return; +} + +if (version_compare(JVERSION, '3.0', 'lt')) +{ + jimport('joomla.application.component.controller'); + + $level = E_ALL & ~E_NOTICE & ~E_DEPRECATED; + + // Remove not-error message (only needed for Joomla 2.5) : Strict Standards + if (version_compare(PHP_VERSION, '5.4.0-dev', '>=')) + { + if ( ! defined('E_STRICT')) + { + define('E_STRICT', 2048); + } + + $level &= ~E_STRICT; + } + + error_reporting($level); +} + +// Set some css property +$document = JFactory::getDocument(); +$document->addStyleDeclaration('.icon-48-icagenda {background-image: none;}'); + +// Load Vector iCicons Font +JHtml::stylesheet( 'media/com_icagenda/icicons/style.css' ); + +// CSS files which could be overridden into your site template. (eg. /templates/my_template/css/com_icagenda/icagenda-back.css) +JHtml::stylesheet( 'com_icagenda/icagenda-back.css', false, true ); + +// Load translations +$language = JFactory::getLanguage(); +$language->load('com_icagenda', JPATH_ADMINISTRATOR, 'en-GB', true); +$language->load('com_icagenda', JPATH_ADMINISTRATOR, null, true); + +// Access check. +if ( ! JFactory::getUser()->authorise('core.manage', 'com_icagenda')) +{ + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + + return false; +} + +// Require helper file +JLoader::register('iCagendaHelper', dirname(__FILE__) . '/helpers/icagenda.php'); + +// Check config params +icagendaParams::encryptPassword(); + +// Get an instance of the controller prefixed by iCagenda +// Joomla 3.x / 2.5 SWITCH +if (version_compare(JVERSION, '3.0', 'ge')) +{ + $controller = JControllerLegacy::getInstance('iCagenda'); +} +else +{ + $controller = JController::getInstance('iCagenda'); +} + +// Perform the Request task +$controller->execute($jinput->get('task')); + +// Redirect if set by the controller +$controller->redirect(); diff --git a/deployed/icagenda/administrator/components/com_icagenda/icagenda.xml b/deployed/icagenda/administrator/components/com_icagenda/icagenda.xml new file mode 100644 index 00000000..eeb3ed70 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/icagenda.xml @@ -0,0 +1,133 @@ + + + iCagenda + Cyril Rezé / Jooml!C + 2020-08-29 + Copyright (c) 2012-2020 Jooml!C / Cyril Rezé. All rights reserved. + GNU General Public License version 3 or later; see LICENSE.txt + info@joomlic.com + www.joomlic.com + 3.7.15 + COM_ICAGENDA_DESC + + script.icagenda.php + + + + sql/install/mysql/icagenda.install.sql + sql/install/mysql/icagenda.install.sql + sql/install/mysql/icagenda.install.sql + sql/install/mysql/icagenda.install.sql + + + + + + sql/uninstall/mysql/icagenda.uninstall.sql + sql/uninstall/mysql/icagenda.uninstall.sql + sql/uninstall/mysql/icagenda.uninstall.sql + sql/uninstall/mysql/icagenda.uninstall.sql + + + + + + sql/updates + + + + + + + + + + + + + + + + + + + + + + + + index.html + icagenda.php + controller.php + router.php + + add + controllers + helpers + layouts + models + themes + views + + + + language/en-GB/en-GB.com_icagenda.ini + language/fr-FR/fr-FR.com_icagenda.ini + language/it-IT/it-IT.com_icagenda.ini + + + + index.html + css + icicons + images + js + + + + + COM_ICAGENDA_MENU + + COM_ICAGENDA_TITLE_ICAGENDA + COM_ICAGENDA_MENU_CATEGORIES + COM_ICAGENDA_EVENTS + COM_ICAGENDA_REGISTRATION + COM_ICAGENDA_MAIL + COM_ICAGENDA_MENU_CUSTOMFIELDS + COM_ICAGENDA_MENU_FEATURES + COM_ICAGENDA_THEMES + COM_ICAGENDA_INFO + + + + access.xml + CHANGELOG.php + config.xml + controller.php + index.html + icagenda.php + assets + controllers + helpers + liveupdate + models + sql + tables + utilities + views + + + language/en-GB/en-GB.com_icagenda.ini + language/en-GB/en-GB.com_icagenda.sys.ini + language/fr-FR/fr-FR.com_icagenda.ini + language/fr-FR/fr-FR.com_icagenda.sys.ini + language/it-IT/it-IT.com_icagenda.ini + language/it-IT/it-IT.com_icagenda.sys.ini + + + + + https://www.joomlic.com/icupdates/icagenda.xml + + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/index.html b/deployed/icagenda/administrator/components/com_icagenda/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/LICENSE.txt b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/LICENSE.txt new file mode 100644 index 00000000..cd63b9ea --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/LICENSE.txt @@ -0,0 +1,177 @@ +============================================================================== +Akeeba Live Update - One-click updates for Joomla! extensions +Copyright ©2011 Nicholas K. Dionysopoulos / AkeebaBackup.com + +Live Update is a sub-component to assist you in providing one-click updates +for your Joomla! 1.5 and Joomla! 1.6 extensions. It is licensed under the +GNU Lesser General Public License version 3 or, at your option, any later +version published by the Free Software Foundation. You can use it royalty- +free in any Joomla! extension, Free or Proprietary. The full text of its +license is provided below. +============================================================================== + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser 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 +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/current-32.png b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/current-32.png new file mode 100644 index 00000000..a896663e Binary files /dev/null and b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/current-32.png differ diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/fail-24.png b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/fail-24.png new file mode 100644 index 00000000..62ae36cd Binary files /dev/null and b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/fail-24.png differ diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/liveupdate-48.png b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/liveupdate-48.png new file mode 100644 index 00000000..077c1e05 Binary files /dev/null and b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/liveupdate-48.png differ diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/liveupdate.css b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/liveupdate.css new file mode 100644 index 00000000..f21bed1c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/liveupdate.css @@ -0,0 +1,161 @@ +/** + * @package LiveUpdate + * @copyright Copyright (c)2010-2012 Nicholas K. Dionysopoulos / AkeebaBackup.com + * @license GNU LGPLv3 or later + */ +@CHARSET "UTF-8"; + +.icon-48-liveupdate { background-image: url(liveupdate-48.png) } + +var { font-style: italic; font-weight: bold; } +p.liveupdate-url { font-family: "Lucida Sans Mono", "Courier New", Courier, monospace; } + +div.liveupdate-notsupported, +div.liveupdate-stuck { + border: thin solid #990000; + background: #fff0f0; + padding: 1em; + color: #330000; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + -o-border-radius: 10px; + border-radius: 10px; + -moz-box-shadow: 5px 5px 5px #f9f9f9; + -webkit-box-shadow: 5px 5px 5px #f9f9f9; + box-shadow: 5px 5px 5px #f9f9f9; +} +div.liveupdate-notsupported h3, +div.liveupdate-stuck h3 { +/* background: transparent url("fail-24.png") top left no-repeat; */ + text-align: center; + min-height: 24px; + padding: 2px 0 0 28px; + font-size: x-large; + color: red; + text-shadow: 1px 1px 6px #333; +} + +div.liveupdate-hasupdates { + border: thin solid #999900; + background: #2F96B4; + padding: 1em; + color: #333300; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + -o-border-radius: 10px; + border-radius: 10px; + -moz-box-shadow: 5px 5px 5px #f9f9f9; + -webkit-box-shadow: 5px 5px 5px #f9f9f9; + box-shadow: 5px 5px 5px #f9f9f9; +} + +div.liveupdate-hasupdates h3 { +/* background: transparent url("warn-24.png") top left no-repeat; */ + text-align: center; + min-height: 24px; + padding: 2px 0 12px 0; + font-size: x-large; + color: #fff; + text-shadow: 1px 1px 6px #333; +} + +div.liveupdate-noupdates { + border: thin solid #009900; + background: #51A351; + padding: 1em; + color: #003300; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + -o-border-radius: 10px; + border-radius: 10px; + -moz-box-shadow: 5px 5px 5px #d4d4d4; + -webkit-box-shadow: 5px 5px 5px #d4d4d4; + box-shadow: 5px 5px 5px #d4d4d4; +} + +div.liveupdate-noupdates h3 { +/* background: transparent url("ok-24.png") top left no-repeat; */ + text-align: center; + min-height: 24px; + padding: 2px 0 12px 0; + font-size: x-large; + color: #fff; + text-shadow: 1px 1px 6px #333; +} + +div.liveupdate-infotable { + width: 600px; + margin: auto auto; + padding: 10px; + border: thin solid #333; + background: #fefefe; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -o-border-radius: 5px; + border-radius: 5px; +} +div.liveupdate-infotable .row0 { background: #fcfcfc } +div.liveupdate-infotable .row1 { background: #f0f0f0 } +div.liveupdate-row { padding: 5px; } +span.liveupdate-label { display: inline-block; vertical-align: top; width: 160px; font-weight: bold; } +span.liveupdate-data { display: inline-block; vertical-align: top; max-width: 420px; overflow: none } + +p.liveupdate-buttons { text-align: center; margin: 1em; } + +p.liveupdate-error-needsauth { + margin: 1em; + background: #ffcccc; + border: medium solid #ff0000; + color: #660000; + font-size: large; + font-weight: bold; + padding: 1em; + text-align: center; + text-shadow: 1px 1px 2px white; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + -o-border-radius: 10px; + border-radius: 10px; + -moz-box-shadow: 5px 5px 5px #d4d4d4; + -webkit-box-shadow: 5px 5px 5px #d4d4d4; + box-shadow: 5px 5px 5px #d4d4d4; +} + +p.liveupdate-poweredby { font-size: 8pt; color: silver; margin: 1em 0 0.5em 0 } +p.liveupdate-poweredby a { color: silver; } +div.liveupdate-ftp p { margin: 1em 2em; line-height: 140%; border: thin solid #00c; padding: 0.5em; color: #006; background-color: #f0f0ff; font-size: 12pt; text-shadow: 1px 1px 3px silver } + +#nagscreen { + margin: 1em; + background: #BD362F; + color: #fff; + font-size: 14px; + font-weight: bold; + padding: 1em; + text-align: center; + text-shadow: 1px 1px 2px #333; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + -o-border-radius: 10px; + border-radius: 10px; + -moz-box-shadow: 5px 5px 5px #d4d4d4; + -webkit-box-shadow: 5px 5px 5px #d4d4d4; + box-shadow: 5px 5px 5px #d4d4d4; +} +.nagversioninfo { + font-size: 1em; + text-align: center; + margin: 20px 15% 30px 15%; +} +.nagtext { + font-weight: normal; + font-size: 1.2em; + text-align: center; + margin: 20px 15%; +} +.nagstability { + font-weight: normal; + font-size: 1em; + text-align: left; + margin: 10px 20% +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/nosupport-32.png b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/nosupport-32.png new file mode 100644 index 00000000..a3bf2a72 Binary files /dev/null and b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/nosupport-32.png differ diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/ok-24.png b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/ok-24.png new file mode 100644 index 00000000..f4d97a7b Binary files /dev/null and b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/ok-24.png differ diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/update-32.png b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/update-32.png new file mode 100644 index 00000000..5142dec7 Binary files /dev/null and b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/update-32.png differ diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/warn-24.png b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/warn-24.png new file mode 100644 index 00000000..b65a4930 Binary files /dev/null and b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/assets/warn-24.png differ diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/abstractconfig.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/abstractconfig.php new file mode 100644 index 00000000..29597f96 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/abstractconfig.php @@ -0,0 +1,234 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); + +/** + * This is the base class inherited by the config.php file in LiveUpdate's root. + * You may override it non-final members to customise its behaviour. + * @author Nicholas K. Dionysopoulos + * + */ +abstract class LiveUpdateAbstractConfig extends JObject +{ + /** @var string The extension name, e.g. com_foobar, plg_foobar, mod_foobar, tpl_foobar etc */ + protected $_extensionName = 'com_icagenda'; + /** @var string The human-readable name of your extension */ + protected $_extensionTitle = 'iCagenda - Events Management Extension for Joomla!'; + /** + * The filename of the XML manifest of your extension. Leave blank to use extensionname.xml. For example, + * if the extension is com_foobar, it will look for com_foobar.xml and foobar.xml in the component's + * directory. + * @var string + * */ + protected $_xmlFilename = ''; + + /** @var string The information storage adapter to use. Can be 'file' or 'component' */ + protected $_storageAdapter = 'file'; + /** @var array The configuration options for the storage adapter used */ + protected $_storageConfig = array('path' => JPATH_CACHE); + /** + * How to determine if a new version is available. 'different' = if the version number is different, + * the remote version is newer, 'vcompare' = use version compare between the two versions, 'newest' = + * compare the release dates to find the newest. I suggest using 'different' on most cases. + * @var string + */ + protected $_versionStrategy = 'different'; + + /** @var The current version of your extension. Populated automatically from the XML manifest. */ + protected $_currentVersion = ''; + /** @var The current release date of your extension. Populated automatically from the XML manifest. */ + protected $_currentReleaseDate = ''; + + /** @var string The URL to the INI update stream of this extension */ + protected $_updateURL = ''; + /** @var bool Does the download URL require authorization to download the package? */ + protected $_requiresAuthorization = false; + + /** @var string The username to authorize a download on your site */ + protected $_username = ''; + /** @var string The password to authorize a download on your site */ + protected $_password = ''; + /** @var string The Download ID to authorize a download on your site; use it instead of the username/password pair */ + protected $_downloadID = ''; + + /** @var string The path to a local copy of cacert.pem, required if you plan on using HTTPS URLs to fetch live udpate information or download files from */ + protected $_cacerts = null; + + /** @var string The minimum stability level to report as available update. One of alpha, beta, rc and stable. */ + protected $_minStability = 'alpha'; + + /** + * Singleton implementation + * @return LiveUpdateConfig An instance of the Live Update configuration class + */ + public static function &getInstance() + { + static $instance = null; + + if(!is_object($instance)) { + $instance = new LiveUpdateConfig(); + } + + return $instance; + } + + /** + * Public constructor. It populates all extension-specific fields. Override to your liking if necessary. + */ + public function __construct() + { + parent::__construct(); + $this->populateExtensionInfo(); + $this->populateAuthorization(); + } + + /** + * Returns the URL to the update INI stream. By default it returns the value to + * the protected $_updateURL property of the class. Override with your implementation + * if you want to modify its logic. + */ + public function getUpdateURL() + { + return $this->_updateURL; + } + + /** + * Override this ethod to load customized CSS and media files instead of the stock + * CSS and media provided by Live Update. If you override this class it MUST return + * true, otherwise LiveUpdate's CSS will be loaded after yours and will override your + * settings. + * + * @return bool Return true to stop Live Update from loading its own CSS files. + */ + public function addMedia() + { + return false; + } + + /** + * Gets the authorization string to append to the download URL. It returns either the + * download ID or username/password pair. Please override the class constructor, not + * this method, if you want to fetch these values. + */ + public final function getAuthorization() + { + if(!empty($this->_downloadID)) { + return "dlid=".urlencode($this->_downloadID); + } + if(!empty($this->_username) && !empty($this->_password)) { + return "username=".urlencode($this->_username)."&password=".urlencode($this->_password); + } + return ""; + } + + public final function requiresAuthorization() + { + return $this->_requiresAuthorization; + } + + /** + * Returns all the information we have about the extension and its update preferences + * @return array The extension information + */ + public final function getExtensionInformation() + { + return array( + 'name' => $this->_extensionName, + 'title' => $this->_extensionTitle, + 'version' => $this->_currentVersion, + 'date' => $this->_currentReleaseDate, + 'updateurl' => $this->_updateURL, + 'requireauth' => $this->_requiresAuthorization + ); + } + + /** + * Returns the information regarding the storage adapter + * @return array + */ + public final function getStorageAdapterPreferences() + { + $config = $this->_storageConfig; + $config['extensionName'] = $this->_extensionName; + + return array( + 'adapter' => $this->_storageAdapter, + 'config' => $config + ); + } + + public final function getVersionStrategy() + { + return $this->_versionStrategy; + } + + /** + * Get the current version from the XML manifest of the extension and + * populate the class' properties. + */ + private function populateExtensionInfo() + { + require_once dirname(__FILE__).'/xmlslurp.php'; + $xmlslurp = new LiveUpdateXMLSlurp(); + $data = $xmlslurp->getInfo($this->_extensionName, $this->_xmlFilename); + if(empty($this->_currentVersion)) $this->_currentVersion = $data['version']; + if(empty($this->_currentReleaseDate)) $this->_currentReleaseDate = $data['date']; + } + + /** + * Fetch username/password and Download ID from the component's configuration. + */ + protected function populateAuthorization() + { + if(!$this->_requiresAuthorization) return; + + // Do we already have authorizaton information? + if( (!empty($this->_username) && !empty($this->_password)) || !empty($this->_downloadID) ) { + return; + } + + if(substr($this->_extensionName,0,3) != 'com') return; + + // Not using JComponentHelper to avoid conflicts ;) + $db = JFactory::getDbo(); + $sql = $db->getQuery(true) + ->select($db->qn('params')) + ->from($db->qn('#__extensions')) + ->where($db->qn('type').' = '.$db->q('component')) + ->where($db->qn('element').' = '.$db->q($this->_extensionName)); + $db->setQuery($sql); + $rawparams = $db->loadResult(); + $params = new JRegistry(); + $params->loadString($rawparams, 'JSON'); + + $this->_username = $params->get('username',''); + $this->_password = $params->get('password',''); + $this->_downloadID = $params->get('downloadid',''); + } + + public function applyCACert(&$ch) + { + if(!empty($this->_cacerts)) { + if(file_exists($this->_cacerts)) { + @curl_setopt($ch, CURLOPT_CAINFO, $this->_cacerts); + } + } + } + + public function getMinimumStability() + { + return $this->_minStability; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/controller.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/controller.php new file mode 100644 index 00000000..98fe674c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/controller.php @@ -0,0 +1,274 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); + +JLoader::import('joomla.application.component.controller'); + +if(!class_exists('JoomlaCompatController')) { + if(interface_exists('JController')) { + abstract class JoomlaCompatController extends JControllerLegacy {} + } else { + class JoomlaCompatController extends JController {} + } +} + +/** + * The Live Update MVC controller + */ +class LiveUpdateController extends JoomlaCompatController +{ + /** + * Object contructor + * @param array $config + * + * @return LiveUpdateController + */ + public function __construct($config = array()) + { + parent::__construct(); + + $this->registerDefaultTask('overview'); + } + + /** + * Runs the overview page task + */ + public function overview() + { + $this->display(); + } + + /** + * Starts the update procedure. If the FTP credentials are required, it asks for them. + */ + public function startupdate() + { + $updateInfo = LiveUpdate::getUpdateInformation(); + if($updateInfo->stability != 'stable') { + $skipNag = JRequest::getBool('skipnag', false); + if(!$skipNag) { + $this->setRedirect('index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=nagscreen'); + $this->redirect(); + } + } + + $ftp = $this->setCredentialsFromRequest('ftp'); + if($ftp === true) { + // The user needs to supply the FTP credentials + $this->display(); + } else { + // No FTP credentials required; proceed with the download + $this->setRedirect('index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=download'); + $this->redirect(); + } + } + + /** + * Download the update package + */ + public function download() + { + $ftp = $this->setCredentialsFromRequest('ftp'); + $model = $this->getThisModel(); + $result = $model->download(); + if(!$result) { + // Download failed + $msg = JText::_('LIVEUPDATE_DOWNLOAD_FAILED'); + $this->setRedirect('index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=overview', $msg, 'error'); + } else { + // Download successful. Let's extract the package. + $url = 'index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=extract'; + $user = JRequest::getString('username', null, 'GET', JREQUEST_ALLOWRAW); + $pass = JRequest::getString('password', null, 'GET', JREQUEST_ALLOWRAW); + if($user) { + $url .= '&username='.urlencode($user).'&password='.urlencode($pass); + } + $this->setRedirect($url); + } + $this->redirect(); + } + + public function extract() + { + $ftp = $this->setCredentialsFromRequest('ftp'); + $model = $this->getThisModel(); + $result = $model->extract(); + if(!$result) { + // Download failed + $msg = JText::_('LIVEUPDATE_EXTRACT_FAILED'); + $this->setRedirect('index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=overview', $msg, 'error'); + } else { + // Extract successful. Let's install the package. + $url = 'index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=install'; + $user = JRequest::getString('username', null, 'GET', JREQUEST_ALLOWRAW); + $pass = JRequest::getString('password', null, 'GET', JREQUEST_ALLOWRAW); + if($user) { + $url .= '&username='.urlencode($user).'&password='.urlencode($pass); + } + + // Do we have SRP installed yet? + $app = JFactory::getApplication(); + $jResponse = $app->triggerEvent('onSRPEnabled'); + $status = false; + if(!empty($jResponse)) { + $status = false; + foreach($jResponse as $response) + { + $status = $status || $response; + } + } + + // SRP enabled, use it + if($status) { + $return = $url; + $url = $model->getSRPURL($return); + if(!$url) { + $url = $return; + } + } + + $this->setRedirect($url); + } + $this->redirect(); + } + + public function install() + { + $ftp = $this->setCredentialsFromRequest('ftp'); + $model = $this->getThisModel(); + $result = $model->install(); + if(!$result) { + // Installation failed + $model->cleanup(); + $this->setRedirect('index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=overview'); + $this->redirect(); + } else { + // Installation successful. Show the installation message. + $cache = JFactory::getCache('mod_menu'); + $cache->clean(); + + $this->display(); + } + } + + public function cleanup() + { + // Perform the cleanup + $ftp = $this->setCredentialsFromRequest('ftp'); + $model = $this->getThisModel(); + $model->cleanup(); + + // Force reload update information + $dummy = LiveUpdate::getUpdateInformation(true); + + die('OK'); + } + + /** + * Displays the current view + * @param bool $cachable Ignored! + */ + public final function display($cachable = false, $urlparams = false) + { + $viewLayout = JRequest::getCmd( 'layout', 'default' ); + + $view = $this->getThisView(); + + // Get/Create the model + $model = $this->getThisModel(); + $view->setModel($model, true); + + // Assign the FTP credentials from the request, or return TRUE if they are required + JLoader::import('joomla.client.helper'); + $ftp = $this->setCredentialsFromRequest('ftp'); + $view->assignRef('ftp', $ftp); + + // Set the layout + $view->setLayout($viewLayout); + + // Display the view + $view->display(); + } + + public final function getThisView() + { + static $view = null; + + if(is_null($view)) + { + $basePath = $this->basePath; + $tPath = dirname(__FILE__).'/tmpl'; + + require_once('view.php'); + $view = new LiveUpdateView(array('base_path'=>$basePath, 'template_path'=>$tPath)); + } + + return $view; + } + + public final function getThisModel() + { + static $model = null; + + if(is_null($model)) + { + require_once('model.php'); + $model = new LiveUpdateModel(); + $task = $this->task; + + $model->setState( 'task', $task ); + + $app = JFactory::getApplication(); + $menu = $app->getMenu(); + if (is_object( $menu )) + { + $item = $menu->getActive(); + if ($item) + { + $params = $menu->getParams($item->id); + // Set Default State Data + $model->setState( 'parameters.menu', $params ); + } + } + + } + + return $model; + } + + private function setCredentialsFromRequest($client) + { + // Determine wether FTP credentials have been passed along with the current request + JLoader::import('joomla.client.helper'); + $user = JRequest::getString('username', null, 'GET', JREQUEST_ALLOWRAW); + $pass = JRequest::getString('password', null, 'GET', JREQUEST_ALLOWRAW); + if ($user != '' && $pass != '') + { + // Add credentials to the session + if (JClientHelper::setCredentials($client, $user, $pass)) { + $return = false; + } else { + $return = JError::raiseWarning('SOME_ERROR_CODE', 'JClientHelper::setCredentialsFromRequest failed'); + } + } + else + { + // Just determine if the FTP input fields need to be shown + $return = !JClientHelper::hasCredentials('ftp'); + } + + return $return; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/download.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/download.php new file mode 100644 index 00000000..8e571bf4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/download.php @@ -0,0 +1,443 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); + +/** + * Allows downloading packages over the web to your server + */ +class LiveUpdateDownloadHelper +{ + /** + * Downloads from a URL and saves the result as a local file + * + * @param string $url The URL to fetch + * @param string $target Where to save the file + * + * @return boolean True on success + */ + public static function download($url, $target) + { + // Import Joomla! libraries + JLoader::import('joomla.filesystem.file'); + + /** @var bool Did we try to force permissions? */ + $hackPermissions = false; + + // Make sure the target does not exist + if (JFile::exists($target)) + { + if (!@unlink($target)) + { + JFile::delete($target); + } + } + + // Try to open the output file for writing + $fp = @fopen($target, 'wb'); + + if ($fp === false) + { + // The file can not be opened for writing. Let's try a hack. + $empty = ''; + if (JFile::write($target, $empty)) + { + if (self::chmod($target, 511)) + { + $fp = @fopen($target, 'wb'); + $hackPermissions = true; + } + } + } + + $result = false; + + if ($fp !== false) + { + // First try to download directly to file if $fp !== false + $adapters = self::getAdapters(); + $result = false; + + while (!empty($adapters) && ($result === false)) + { + // Run the current download method + $method = 'get' . strtoupper(array_shift($adapters)); + $result = self::$method($url, $fp); + + // Check if we have a download + if ($result === true) + { + // The download is complete, close the file pointer + @fclose($fp); + + // If the filesize is not at least 1 byte, we consider it failed. + clearstatcache(); + $filesize = @filesize($target); + + if ($filesize <= 0) + { + $result = false; + $fp = @fopen($target, 'wb'); + } + } + } + + // If we have no download, close the file pointer + if ($result === false) + { + @fclose($fp); + } + } + + if ($result === false) + { + // Delete the target file if it exists + if (file_exists($target)) + { + if (!@unlink($target)) + { + JFile::delete($target); + } + } + // Download and write using JFile::write(); + $result = JFile::write($target, self::downloadAndReturn($url)); + } + + return $result; + } + + /** + * Downloads from a URL and returns the result as a string + * + * @param string $url The URL to download from + * + * @return mixed Result string on success, false on failure + */ + public static function downloadAndReturn($url) + { + $adapters = self::getAdapters(); + $result = false; + + while (!empty($adapters) && ($result === false)) + { + // Run the current download method + $method = 'get' . strtoupper(array_shift($adapters)); + $result = self::$method($url, null); + } + + return $result; + } + + /** + * Does the server support PHP's cURL extension? + * + * @return boolean True if it is supported + */ + private static function hasCURL() + { + static $result = null; + + if (is_null($result)) + { + $result = function_exists('curl_init'); + } + + return $result; + } + + /** + * Downloads the contents of a URL and writes them to disk (if $fp is not null) + * or returns them as a string (if $fp is null) using cURL + * + * @param string $url The URL to download from + * @param resource $fp The file pointer to download to. Omit to return the contents. + * + * @return boolean|string False on failure, true on success ($fp not null) or the URL contents (if $fp is null) + */ + private static function &getCURL($url, $fp = null, $nofollow = false) + { + $result = false; + + $ch = curl_init($url); + $config = new LiveUpdateConfig(); + $config->applyCACert($ch); + + if (!@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1) && !$nofollow) + { + // Safe Mode is enabled. We have to fetch the headers and + // parse any redirections present in there. + curl_setopt($ch, CURLOPT_AUTOREFERER, true); + curl_setopt($ch, CURLOPT_FAILONERROR, true); + curl_setopt($ch, CURLOPT_HEADER, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + + // Get the headers + $data = curl_exec($ch); + curl_close($ch); + + // Init + $newURL = $url; + + // Parse the headers + $lines = explode("\n", $data); + + foreach ($lines as $line) + { + if (substr($line, 0, 9) == "Location:") + { + $newURL = trim(substr($line, 9)); + } + } + + // Download from the new URL + if ($url != $newURL) + { + return self::getCURL($newURL, $fp); + } + else + { + return self::getCURL($newURL, $fp, true); + } + } + else + { + @curl_setopt($ch, CURLOPT_MAXREDIRS, 20); + } + + curl_setopt($ch, CURLOPT_AUTOREFERER, true); + curl_setopt($ch, CURLOPT_FAILONERROR, true); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + // Pretend we are IE7, so that webservers play nice with us + curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)'); + + if (is_resource($fp)) + { + curl_setopt($ch, CURLOPT_FILE, $fp); + } + + $result = curl_exec($ch); + curl_close($ch); + + return $result; + } + + /** + * Does the server support URL fopen() wrappers? + * + * @return boolean + */ + private static function hasFOPEN() + { + static $result = null; + + if (is_null($result)) + { + // If we are not allowed to use ini_get, we assume that URL fopen is + // disabled. + if (!function_exists('ini_get')) + { + $result = false; + } + else + { + $result = ini_get('allow_url_fopen'); + } + } + + return $result; + } + + /** + * Downloads the contents of a URL and writes them to disk (if $fp is not null) + * or returns them as a string (if $fp is null) using fopen() URL wrappers + * + * @param string $url The URL to download from + * @param resource $fp The file pointer to download to. Omit to return the contents. + * + * @return boolean|string False on failure, true on success ($fp not null) or the URL contents (if $fp is null) + */ + private static function &getFOPEN($url, $fp = null) + { + $result = false; + + // Track errors + if (function_exists('ini_set')) + { + $track_errors = ini_set('track_errors', true); + } + + // Open the URL for reading + if (function_exists('stream_context_create')) + { + // PHP 5+ way (best) + $httpopts = array( + 'user_agent' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)', + 'timeout' => 10.0, + ); + $context = stream_context_create(array('http' => $httpopts)); + $ih = @fopen($url, 'r', false, $context); + } + else + { + // PHP 4 way (actually, it's just a fallback as we can't run this code in PHP4) + if (function_exists('ini_set')) + { + ini_set('user_agent', 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)'); + } + $ih = @fopen($url, 'r'); + } + + // If fopen() fails, abort + if (!is_resource($ih)) + { + return $result; + } + + // Try to download + $bytes = 0; + $result = true; + $return = ''; + while (!feof($ih) && $result) + { + $contents = fread($ih, 4096); + if ($contents === false) + { + @fclose($ih); + $result = false; + return $result; + } + else + { + $bytes += strlen($contents); + if (is_resource($fp)) + { + $result = @fwrite($fp, $contents); + } + else + { + $return .= $contents; + unset($contents); + } + } + } + + @fclose($ih); + + if (is_resource($fp)) + { + return $result; + } + elseif ($result === true) + { + return $return; + } + else + { + return $result; + } + } + + /** + * Detect and return available download methods + * + * @return array + */ + private static function getAdapters() + { + // Detect available adapters + $adapters = array(); + if (self::hasCURL()) + $adapters[] = 'curl'; + if (self::hasFOPEN()) + $adapters[] = 'fopen'; + return $adapters; + } + + /** + * Change the permissions of a file, optionally using FTP + * + * @param string $file Absolute path to file + * @param int $mode Permissions, e.g. 0755 + * + * @return boolean Ture if successful + */ + private static function chmod($path, $mode) + { + if (is_string($mode)) + { + $mode = octdec($mode); + if (($mode < 0600) || ($mode > 0777)) + $mode = 0755; + } + + // Initialize variables + JLoader::import('joomla.client.helper'); + $ftpOptions = JClientHelper::getCredentials('ftp'); + + // Check to make sure the path valid and clean + $path = JPath::clean($path); + + if ($ftpOptions['enabled'] == 1) + { + // Connect the FTP client + JLoader::import('joomla.client.ftp'); + if (version_compare(JVERSION, '3.0', 'ge')) + { + $ftp = JClientFTP::getInstance( + $ftpOptions['host'], $ftpOptions['port'], array(), $ftpOptions['user'], $ftpOptions['pass'] + ); + } + else + { + if (version_compare(JVERSION, '3.0', 'ge')) + { + $ftp = JClientFTP::getInstance( + $ftpOptions['host'], $ftpOptions['port'], array(), $ftpOptions['user'], $ftpOptions['pass'] + ); + } + else + { + $ftp = JFTP::getInstance( + $ftpOptions['host'], $ftpOptions['port'], array(), $ftpOptions['user'], $ftpOptions['pass'] + ); + } + } + } + + if (@chmod($path, $mode)) + { + $ret = true; + } + elseif ($ftpOptions['enabled'] == 1) + { + // Translate path and delete + JLoader::import('joomla.client.ftp'); + $path = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $path), '/'); + // FTP connector throws an error + $ret = $ftp->chmod($path, $mode); + } + else + { + return false; + } + } + +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/inihelper.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/inihelper.php new file mode 100644 index 00000000..54354327 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/inihelper.php @@ -0,0 +1,149 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); + +/** + * A smart INI file parser with reproducible behaviour among different PHP versions + */ +class LiveUpdateINIHelper +{ + /** + * Parse an INI file and return an associative array. Since PHP versions before + * 5.1 are bitches with regards to INI parsing, I use a PHP-only solution to + * overcome this obstacle. + * @param string $file The file to process + * @param bool $process_sections True to also process INI sections + * @return array An associative array of sections, keys and values + */ + public static function parse_ini_file( $file, $process_sections, $rawdata = false ) + { + if($rawdata) + { + return self::parse_ini_file_php($file, $process_sections, $rawdata); + } + else + { + if( version_compare(PHP_VERSION, '5.1.0', '>=') && (!$rawdata) ) + { + if( function_exists('parse_ini_file') ) + { + return parse_ini_file($file, $process_sections); + } + else + { + return self::parse_ini_file_php($file, $process_sections); + } + } else { + return self::parse_ini_file_php($file, $process_sections, $rawdata); + } + } + } + + /** + * A PHP based INI file parser. + * Thanks to asohn ~at~ aircanopy ~dot~ net for posting this handy function on + * the parse_ini_file page on http://gr.php.net/parse_ini_file + * @param string $file Filename to process + * @param bool $process_sections True to also process INI sections + * @param bool $rawdata If true, the $file contains raw INI data, not a filename + * @return array An associative array of sections, keys and values + */ + static function parse_ini_file_php($file, $process_sections = false, $rawdata = false) + { + $process_sections = ($process_sections !== true) ? false : true; + + if(!$rawdata) + { + $ini = file($file); + } + else + { + $file = str_replace("\r","",$file); + $ini = explode("\n", $file); + } + + if (count($ini) == 0) {return array();} + + $sections = array(); + $values = array(); + $result = array(); + $globals = array(); + $i = 0; + foreach ($ini as $line) { + $line = trim($line); + $line = str_replace("\t", " ", $line); + + // Comments + if (!preg_match('/^[a-zA-Z0-9[]/', $line)) {continue;} + + // Sections + if ($line{0} == '[') { + $tmp = explode(']', $line); + $sections[] = trim(substr($tmp[0], 1)); + $i++; + continue; + } + + // Key-value pair + list($key, $value) = explode('=', $line, 2); + $key = trim($key); + $value = trim($value); + if (strstr($value, ";")) { + $tmp = explode(';', $value); + if (count($tmp) == 2) { + if ((($value{0} != '"') && ($value{0} != "'")) || + preg_match('/^".*"\s*;/', $value) || preg_match('/^".*;[^"]*$/', $value) || + preg_match("/^'.*'\\s*;/", $value) || preg_match("/^'.*;[^']*$/", $value) ){ + $value = $tmp[0]; + } + } else { + if ($value{0} == '"') { + $value = preg_replace('/^"(.*)".*/', '$1', $value); + } elseif ($value{0} == "'") { + $value = preg_replace("/^'(.*)'.*/", '$1', $value); + } else { + $value = $tmp[0]; + } + } + } + $value = trim($value); + $value = trim($value, "'\""); + + if ($i == 0) { + if (substr($line, -1, 2) == '[]') { + $globals[$key][] = $value; + } else { + $globals[$key] = $value; + } + } else { + if (substr($line, -1, 2) == '[]') { + $values[$i-1][$key][] = $value; + } else { + $values[$i-1][$key] = $value; + } + } + } + + for($j = 0; $j < $i; $j++) { + if ($process_sections === true) { + if( isset($sections[$j]) && isset($values[$j]) ) $result[$sections[$j]] = $values[$j]; + } else { + if( isset($values[$j]) ) $result[] = $values[$j]; + } + } + + return $result + $globals; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/model.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/model.php new file mode 100644 index 00000000..fc76ef57 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/model.php @@ -0,0 +1,186 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ +/** + * Specific error message update - iCagenda + */ + +defined('_JEXEC') or die(); + +JLoader::import('joomla.application.component.model'); + +if(!class_exists('JoomlaCompatModel')) { + if(interface_exists('JModel')) { + abstract class JoomlaCompatModel extends JModelLegacy {} + } else { + class JoomlaCompatModel extends JModel {} + } +} + +/** + * The Live Update MVC model + */ +class LiveUpdateModel extends JoomlaCompatModel +{ + public function download() + { + // Get the path to Joomla!'s temporary directory + $jreg = JFactory::getConfig(); + $tmpdir = $jreg->get('tmp_path'); + + JLoader::import('joomla.filesystem.folder'); + // Make sure the user doesn't use the system-wide tmp directory. You know, the one that's + // being erased periodically and will cause a real mess while installing extensions (Grrr!) + if(realpath($tmpdir) == '/tmp') { + // Someone inform the user that what he's doing is insecure and stupid, please. In the + // meantime, I will fix what is broken. + $tmpdir = JPATH_SITE.'/tmp'; + } // Make sure that folder exists (users do stupid things too often; you'd be surprised) + elseif(!JFolder::exists($tmpdir)) { + // Darn it, user! WTF where you thinking? OK, let's use a directory I know it's there... + $tmpdir = JPATH_SITE.'/tmp'; + } + + // Oki. Let's get the URL of the package + $updateInfo = LiveUpdate::getUpdateInformation(); + $config = LiveUpdateConfig::getInstance(); + $auth = $config->getAuthorization(); + $url = $updateInfo->downloadURL; + + // Sniff the package type. If sniffing is impossible, I'll assume a ZIP package + $basename = basename($url); + if(strstr($basename,'?')) { + $basename = substr($basename, strstr($basename,'?')+1); + } + if(substr($basename,-4) == '.zip') { + $type = 'zip'; + } elseif(substr($basename,-4) == '.tar') { + $type = 'tar'; + } elseif(substr($basename,-4) == '.tgz') { + $type = 'tar.gz'; + } elseif(substr($basename,-7) == '.tar.gz') { + $type = 'tar.gz'; + } else { + $type = 'zip'; + } + + // Cache the path to the package file and the temp installation directory in the session + $target = $tmpdir.'/'.$updateInfo->extInfo->name.'.update.'.$type; + $tempdir = $tmpdir.'/'.$updateInfo->extInfo->name.'_update'; + + $session = JFactory::getSession(); + $session->set('target', $target, 'liveupdate'); + $session->set('tempdir', $tempdir, 'liveupdate'); + + // Let's download! + require_once dirname(__FILE__).'/download.php'; + return LiveUpdateDownloadHelper::download($url, $target); + } + + public function extract() + { + $session = JFactory::getSession(); + $target = $session->get('target', '', 'liveupdate'); + $tempdir = $session->get('tempdir', '', 'liveupdate'); + + JLoader::import('joomla.filesystem.archive'); + return JArchive::extract( $target, $tempdir); + } + + public function install() + { + $session = JFactory::getSession(); + $tempdir = $session->get('tempdir', '', 'liveupdate'); + + JLoader::import('joomla.installer.installer'); + JLoader::import('joomla.installer.helper'); + $installer = JInstaller::getInstance(); + $packageType = JInstallerHelper::detectType($tempdir); + + if(!$packageType) { + $msg = JText::_('LIVEUPDATE_INVALID_PACKAGE_TYPE'); + $result = false; + } elseif (!$installer->install($tempdir)) { + // There was an error installing the package +// $msg = JText::sprintf('LIVEUPDATE_INSTALLEXT', JText::_($packageType), JText::_('LIVEUPDATE_Error')); + $msg = JText::sprintf('LIVEUPDATE_INSTALL_ERROR', JText::_('LIVEUPDATE_INSTALL_TYPE_'.strtoupper($packageType))); + $result = false; + } else { + // Package installed sucessfully +// $msg = JText::sprintf('LIVEUPDATE_INSTALLEXT', JText::_($packageType), JText::_('LIVEUPDATE_Success')); + $msg = JText::sprintf('LIVEUPDATE_INSTALL_SUCCESS', JText::_('LIVEUPDATE_INSTALL_TYPE_'.strtoupper($packageType))); + $result = true; + } + + $app = JFactory::getApplication(); + $app->enqueueMessage($msg); + $this->setState('result', $result); + $this->setState('packageType', $packageType); + if($packageType) { + $this->setState('name', $installer->get('name')); + $this->setState('message', $installer->message); + $this->setState('extmessage', $installer->get('extension_message')); + } + + return $result; + } + + public function cleanup() + { + $session = JFactory::getSession(); + $target = $session->get('target', '', 'liveupdate'); + $tempdir = $session->get('tempdir', '', 'liveupdate'); + + JLoader::import('joomla.installer.helper'); + JInstallerHelper::cleanupInstall($target, $tempdir); + + $session->clear('target','liveupdate'); + $session->clear('tempdir','liveupdate'); + } + + public function getSRPURL($return = '') + { + $session = JFactory::getSession(); + $tempdir = $session->get('tempdir', '', 'liveupdate'); + + JLoader::import('joomla.installer.installer'); + JLoader::import('joomla.installer.helper'); + JLoader::import('joomla.filesystem.file'); + + $instModelFile = JPATH_ADMINISTRATOR.'/components/com_akeeba/models/installer.php'; + if(!JFile::exists($instModelFile)) { + $instModelFile = JPATH_ADMINISTRATOR.'/components/com_akeeba/plugins/models/installer.php'; + }; + if(!JFile::exists($instModelFile)) return false; + + require_once $instModelFile; + $model = JoomlaCompatModel::getInstance('Installer', 'AkeebaModel'); + $packageType = JInstallerHelper::detectType($tempdir); + $name = $model->getExtensionName($tempdir); + + $url = 'index.php?option=com_akeeba&view=backup&tag=restorepoint&type='.$packageType.'&name='.urlencode($name['name']); + switch($packageType) { + case 'module': + case 'template': + $url .= '&group='.$name['client']; + break; + case 'plugin': + $url .= '&group='.$name['group']; + break; + } + + if(!empty($return)) $url .= '&returnurl='.urlencode($return); + + return $url; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/storage/component.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/storage/component.php new file mode 100644 index 00000000..92fc3dde --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/storage/component.php @@ -0,0 +1,110 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ +defined('_JEXEC') or die(); + +/** + * Live Update Component Storage Class + * Allows to store the update data to a component's parameters. This is the most reliable method. + * Its configuration options are: + * component string The name of the component which will store our data. If not specified the extension name will be used. + * key string The name of the component parameter where the serialized data will be stored. If not specified "liveupdate" will be used. + */ +class LiveUpdateStorageComponent extends LiveUpdateStorage +{ + private $component = null; + + private $key = null; + + public function __construct() + { + $this->keyPrefix = ''; + } + + public function load($config) + { + if (!array_key_exists('component', $config)) + { + $this->component = $config['extensionName']; + } + else + { + $this->component = $config['component']; + } + + if (!array_key_exists('key', $config)) + { + $this->key = 'liveupdate'; + } + else + { + $this->key = $config['key']; + } + + // Not using JComponentHelper to avoid conflicts ;) + $db = JFactory::getDbo(); + $sql = $db->getQuery(true) + ->select($db->qn('params')) + ->from($db->qn('#__extensions')) + ->where($db->qn('type') . ' = ' . $db->q('component')) + ->where($db->qn('element') . ' = ' . $db->q($this->component)); + $db->setQuery($sql); + $rawparams = $db->loadResult(); + $params = new JRegistry(); + $params->loadString($rawparams, 'JSON'); + + $data = $params->get($this->key, ''); + + JLoader::import('joomla.registry.registry'); + $this->registry = new JRegistry('update'); + + $this->registry->loadString($data, 'INI'); + } + + public function save() + { + $data = $this->registry->toString('INI'); + + $db = JFactory::getDBO(); + + // An interesting discovery: if your component is manually updating its + // component parameters before Live Update is called, then calling Live + // Update will reset the modified component parameters because + // JComponentHelper::getComponent() returns the old, cached version of + // them. So, we have to forget the following code and shoot ourselves in + // the feet. Dammit!!! + $sql = $db->getQuery(true) + ->select($db->qn('params')) + ->from($db->qn('#__extensions')) + ->where($db->qn('type') . ' = ' . $db->q('component')) + ->where($db->qn('element') . ' = ' . $db->q($this->component)); + $db->setQuery($sql); + $rawparams = $db->loadResult(); + $params = new JRegistry(); + $params->loadString($rawparams, 'JSON'); + + $params->set($this->key, $data); + + $data = $params->toString('JSON'); + $sql = $db->getQuery(true) + ->update($db->qn('#__extensions')) + ->set($db->qn('params') . ' = ' . $db->q($data)) + ->where($db->qn('type') . ' = ' . $db->q('component')) + ->where($db->qn('element') . ' = ' . $db->q($this->component)); + + $db->setQuery($sql); + $db->execute(); + } + +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/storage/file.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/storage/file.php new file mode 100644 index 00000000..cc2afe12 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/storage/file.php @@ -0,0 +1,87 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ +defined('_JEXEC') or die(); + +/** + * Live Update File Storage Class + * Allows to store the update data to files on disk. Its configuration options are: + * path string The absolute path to the directory where the update data will be stored as INI files + * + */ +class LiveUpdateStorageFile extends LiveUpdateStorage +{ + private $filename = null; + private $extname = null; + + public function __construct() + { + } + + public function load($config) + { + JLoader::import('joomla.registry.registry'); + JLoader::import('joomla.filesystem.file'); + + if (array_key_exists('path', $config)) + { + $path = $config['path']; + } + else + { + $path = JPATH_CACHE; + } + $extname = $config['extensionName']; + $filename = "$path/$extname.updates.php"; + + // Kill old files + $filenameKill = "$path/$extname.updates.ini"; + if (JFile::exists($filenameKill)) + { + JFile::delete($filenameKill); + } + + $this->filename = $filename; + $this->extname = $extname; + + $this->registry = new JRegistry('update'); + + if (JFile::exists($this->filename)) + { + // Workaround for broken JRegistryFormatPHP API... + @include_once $this->filename; + + $className = 'LiveUpdate' . ucwords($extname) . 'Cache'; + + if (class_exists($className)) + { + $object = new $className; + $this->registry->loadObject($object); + } + } + } + + public function save() + { + JLoader::import('joomla.registry.registry'); + JLoader::import('joomla.filesystem.file'); + + $options = array( + 'class' => 'LiveUpdate' . ucwords($this->extname) . 'Cache' + ); + $data = $this->registry->toString('PHP', $options); + JFile::write($this->filename, $data); + } + +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/storage/storage.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/storage/storage.php new file mode 100644 index 00000000..41d2d308 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/storage/storage.php @@ -0,0 +1,139 @@ + + * + * @version 3.1.8 2013-08-30 + * @since 1.2.6 + */ +/** + * Specific PHP 5.3 min control - iCagenda + */ +defined('_JEXEC') or die(); + +/** + * Abstract class for the update parameters storage + * @author nicholas + * + */ +abstract class LiveUpdateStorage +{ + /** + * @var JRegistry The update data registry + */ + protected $registry = null; + + /** + * @var string The key prefix for the registry data + */ + protected $keyPrefix = 'update.'; + + /** + * Singleton implementation + * + * @param string $type Storage tyme (file, component) + * @param array $config Configuration array + * + * @return LiveUpdateStorage + */ + public static function getInstance($type, $config) + { + static $instances = array(); + + $sig = md5($type, serialize($config)); + if (!array_key_exists($sig, $instances)) + { + $className = 'LiveUpdateStorage' . ucfirst($type); + + if (!class_exists($className)) + { + if (version_compare(phpversion(), '5.3.0', '<')) { + require_once dirname(__FILE__).'/'.strtolower($type).'.php'; + } else { + require_once __DIR__ . '/' . strtolower($type) . '.php'; + } + } + + $object = new $className($config); + $object->load($config); + + $instances[$sig] = $object; + } + + return $instances[$sig]; + } + + /** + * Set a value to the storage registry. Automatically encodes updatedata. + * + * @param string $key The key to set + * @param mixed $value The value of the key to set + * + * @return void + */ + public final function set($key, $value) + { + if ($key == 'updatedata') + { + if (function_exists('base64_encode') && function_exists('base64_decode')) + { + $value = base64_encode(serialize($value)); + } + else + { + $value = serialize($value); + } + } + + $this->registry->set($this->keyPrefix . $key, $value); + } + + /** + * Read a value from the storage registry + * + * @param string $key The key to read + * @param mixed $default The default value of the key, if the key is not present + * + * @return mixed The value of the key + */ + public final function get($key, $default) + { + $value = $this->registry->get($this->keyPrefix . $key, $default); + + if ($key == 'updatedata') + { + if (function_exists('base64_encode') && function_exists('base64_decode')) + { + $value = unserialize(base64_decode($value)); + } + else + { + $value = unserialize($value); + } + } + + return $value; + } + + /** + * Save the contents of the registry to the appropriate storage + * + * @return void + */ + abstract public function save(); + + /** + * Load data from the storage + * + * @param array The configuration options + * + * @return void + */ + abstract public function load($config); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/install.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/install.php new file mode 100644 index 00000000..c9c4eeed --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/install.php @@ -0,0 +1,41 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined( '_JEXEC' ) or die(); + +$state = $this->get('State'); +$message1 = $state->get('message'); +$message2 = $state->get('extmessage'); +?> + + + + + + + + + + + + + +
+ +

+ Powered by Akeeba Live Update +

+ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/nagscreen.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/nagscreen.php new file mode 100644 index 00000000..0cba6ca5 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/nagscreen.php @@ -0,0 +1,68 @@ + + * + * @version 3.4.0 2014-12-21 + * @since 1.2.6 + */ +/** + * Specific strings iCagenda + */ + +defined('_JEXEC') or die(); + +$stability = JText::_('LIVEUPDATE_STABILITY_'.$this->updateInfo->stability); +?> + +
+ +
+

+ +

+ updateInfo->version, $stability) ?> +

+ +

+ +

+ +

+ +

+

+ : + +

+

+ : + +

+

+ : + +

+

+ +

+ + +
+

+ +

+ +

+ Powered by Akeeba Live Update +

+ +
diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/overview.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/overview.php new file mode 100644 index 00000000..b2992f12 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/overview.php @@ -0,0 +1,153 @@ + + * + * @version 3.4.0 2014-12-21 + * @since 1.2.6 + */ +/** + * Specific strings iCagenda + */ + +defined('_JEXEC') or die(); + +JHtml::_('behavior.framework'); +JHtml::_('behavior.modal'); +?> + +
+ + updateInfo->releasenotes): ?> +
+
+
+ updateInfo->releasenotes ?> +
+
+
+ + + updateInfo->supported): ?> +
+

+ +

+

+ escape($this->updateInfo->extInfo->updateurl) ?> +

+

escape($this->updateInfo->extInfo->title)); ?>

+

+ +

+
+ + updateInfo->stuck):?> +
+

+ +

+

escape($this->updateInfo->extInfo->title)); ?>

+ +

+ +

+
+ + + updateInfo->hasUpdates ? 'hasupdates' : 'noupdates'; + $auth = $this->config->getAuthorization(); + $auth = empty($auth) ? '' : '?'.$auth; + ?> + needsAuth): ?> +

+ +

+ +
+

!

+
+
+ + updateInfo->extInfo->version ?> +
+
+ + updateInfo->version ?> +
+
+ + updateInfo->date ?> +
+ + updateInfo->releasenotes) || !empty($this->updateInfo->infoURL)): ?> +
+ + + updateInfo->releasenotes): ?> + + addScriptDeclaration($script,'text/javascript'); + ?> + + updateInfo->releasenotes && $this->updateInfo->infoURL): ?> + + + updateInfo->infoURL): ?> + + + + +
+ +
+ +

+ updateInfo->hasUpdates):?> + needsAuth ? 'disabled="disabled"' : ''?> + + + +

+
+ + + +

+ Powered by Akeeba Live Update +

+ +
diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/startupdate.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/startupdate.php new file mode 100644 index 00000000..beaf1e7e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/tmpl/startupdate.php @@ -0,0 +1,57 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); +?> + +
+
+

+
+ + + +
+ + + + + + + + + + + + + +
+ + + +
+ + + +
+ +
+
+
+ +

+ Powered by Akeeba Live Update +

+ +
diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/updatefetch.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/updatefetch.php new file mode 100644 index 00000000..8a879316 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/updatefetch.php @@ -0,0 +1,357 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); + +/** + * Fetches the update information from the server or the cache, depending on + * whether the cache is fresh or not. + */ +class LiveUpdateFetch extends JObject +{ + private $cacheTTL = 24; + + private $storage = null; + + /** + * One-stop-shop function which fetches update information and tells you + * if there are updates available or not, or if updates are not supported. + * + * @return int 0 = no updates, 1 = updates available, -1 = updates not supported, -2 = fetching updates crashes the server + */ + public function hasUpdates($force = false) + { + $updateInfo = $this->getUpdateInformation($force); + + if($updateInfo->stuck) return -2; + + if(!$updateInfo->supported) return -1; + + $config = LiveUpdateConfig::getInstance(); + $extInfo = $config->getExtensionInformation(); + + // Filter by stability level + $minStability = $config->getMinimumStability(); + $stability = strtolower($updateInfo->stability); + + switch($minStability) { + case 'alpha': + default: + // Reports any stability level as an available update + break; + + case 'beta': + // Do not report alphas as available updates + if(in_array($stability, array('alpha'))) return 0; + break; + + case 'rc': + // Do not report alphas and betas as available updates + if(in_array($stability, array('alpha','beta'))) return 0; + break; + + case 'stable': + // Do not report alphas, betas and rcs as available updates + if(in_array($stability, array('alpha','beta','rc'))) return 0; + break; + } + + if(empty($updateInfo->version) && empty($updateInfo->date)) return 0; + + // Use the version strategy to determine the availability of an update + switch($config->getVersionStrategy()) { + case 'newest': + JLoader::import('joomla.utilities.date'); + if(empty($extInfo)) { + $mine = new JDate('2000-01-01 00:00:00'); + } else { + try { + $mine = new JDate($extInfo['date']); + } catch(Exception $e) { + $mine = new JDate('2000-01-01 00:00:00'); + } + } + + $theirs = new JDate($updateInfo->date); + + return ($theirs->toUnix() > $mine->toUnix()) ? 1 : 0; + break; + + case 'vcompare': + $mine = $extInfo['version']; + if(empty($mine)) $mine = '0.0.0'; + $theirs = $updateInfo->version; + if(empty($theirs)) $theirs = '0.0.0'; + + return (version_compare($theirs, $mine, 'gt')) ? 1 : 0; + break; + + case 'different': + $mine = $extInfo['version']; + if(empty($mine)) $mine = '0.0.0'; + $theirs = $updateInfo->version; + if(empty($theirs)) $theirs = '0.0.0'; + + return ($theirs != $mine) ? 1 : 0; + break; + } + } + + /** + * Get the latest version (update) information, either from the cache or + * from the update server. + * + * @param $force bool Set to true to force fetching fresh data from the server + * + * @return stdClass The update information, in object format + */ + public function getUpdateInformation($force = false) + { + // Get the Live Update configuration + $config = LiveUpdateConfig::getInstance(); + + // Get an instance of the storage class + $storageOptions = $config->getStorageAdapterPreferences(); + require_once dirname(__FILE__).'/storage/storage.php'; + $this->storage = LiveUpdateStorage::getInstance($storageOptions['adapter'], $storageOptions['config']); + + // If we are requested to forcibly reload the information, clear old data first + if($force) { + $this->storage->set('lastcheck', null); + $this->storage->set('updatedata', null); + $this->storage->save(); + } + + // Fetch information from the cache + $lastCheck = $this->storage->get('lastcheck', 0); + $cachedData = $this->storage->get('updatedata', null); + + if (!is_object($cachedData)) + { + $cachedData = null; + } + + if(empty($cachedData)) { + $lastCheck = 0; + } + + // Check if the cache is at most $cacheTTL hours old + $now = time(); + $maxDifference = $this->cacheTTL * 3600; + $difference = abs($now - $lastCheck); + + if(!($force) && ($difference <= $maxDifference)) { + // The cache is fresh enough; return cached data + return $cachedData; + } else { + // The cache is stale; fetch new data, cache it and return it to the caller + $data = $this->getUpdateData($force); + $this->storage->set('lastcheck', $now); + $this->storage->set('updatedata', $data); + $this->storage->save(); + return $data; + } + } + + /** + * Retrieves the update data from the server, unless previous runs indicate + * that the download process gets stuck and ends up in a WSOD. + * + * @param bool $force Set to true to force fetching new data no matter if the process is marked as stuck + * @return stdClass + */ + private function getUpdateData($force = false) + { + $ret = array( + 'supported' => false, + 'stuck' => true, + 'version' => '', + 'date' => '', + 'stability' => '', + 'downloadURL' => '', + 'infoURL' => '', + 'releasenotes' => '' + ); + + // If the process is marked as "stuck", we won't bother fetching data again; well, + // unless you really force me to, by setting $force = true. + if( ($this->storage->get('stuck',0) != 0) && !$force) return (object)$ret; + + $ret['stuck'] = false; + + require_once dirname(__FILE__).'/download.php'; + + // First we mark Live Updates as getting stuck. This way, if fetching the update + // fails with a server error, reloading the page will not result to a White Screen + // of Death again. Hey, Joomla! core team, are you listening? Some hosts PRETEND to + // support cURL or URL fopen() wrappers but using them throws an immediate WSOD. + $this->storage->set('stuck', 1); + $this->storage->save(); + + $config = LiveUpdateConfig::getInstance(); + $extInfo = $config->getExtensionInformation(); + $url = $extInfo['updateurl']; + $rawData = LiveUpdateDownloadHelper::downloadAndReturn($url); + + // Now that we have some data returned, let's unmark the process as being stuck ;) + $this->storage->set('stuck', 0); + $this->storage->save(); + + // If we didn't get anything, assume Live Update is not supported (communication error) + if(empty($rawData) || ($rawData == false)) return (object)$ret; + + // TODO Detect the content type of the returned update stream. For now, I will pretend it's an INI file. + + $data = $this->parseINI($rawData); + $ret['supported'] = true; + + return (object)array_merge($ret, $data); + } + + /** + * Fetches update information from the server using cURL + * @return string The raw server data + */ + private function fetchCURL() + { + $config = LiveUpdateConfig::getInstance(); + $extInfo = $config->getExtensionInformation(); + $url = $extInfo['updateurl']; + + $process = curl_init($url); + $config = new LiveUpdateConfig(); + $config->applyCACert($process); + curl_setopt($process, CURLOPT_HEADER, 0); + // Pretend we are Firefox, so that webservers play nice with us + curl_setopt($process, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110105 Firefox/3.6.14'); + curl_setopt($process, CURLOPT_ENCODING, 'gzip'); + curl_setopt($process, CURLOPT_TIMEOUT, 10); + curl_setopt($process, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false); + // The @ sign allows the next line to fail if open_basedir is set or if safe mode is enabled + @curl_setopt($process, CURLOPT_FOLLOWLOCATION, 1); + @curl_setopt($process, CURLOPT_MAXREDIRS, 20); + $inidata = curl_exec($process); + curl_close($process); + return $inidata; + } + + /** + * Fetches update information from the server using file_get_contents, which internally + * uses URL fopen() wrappers. + * @return string The raw server data + */ + private function fetchFOPEN() + { + $config = LiveUpdateConfig::getInstance(); + $extInfo = $config->getExtensionInformation(); + $url = $extInfo['updateurl']; + + return @file_get_contents($url); + } + + /** + * Parses the raw INI data into an array of update information + * @param string $rawData The raw INI data + * @return array The parsed data + */ + private function parseINI($rawData) + { + $ret = array( + 'version' => '', + 'date' => '', + 'stability' => '', + 'downloadURL' => '', + 'infoURL' => '', + 'releasenotes' => '' + ); + + // Get the magic string + $magicPos = strpos($rawData, '; Live Update provision file'); + + if($magicPos === false) { + // That's not an INI file :( + return $ret; + } + + if($magicPos !== 0) { + $rawData = substr($rawData, $magicPos); + } + + require_once dirname(__FILE__).'/inihelper.php'; + $iniData = LiveUpdateINIHelper::parse_ini_file($rawData, false, true); + + // Get the supported platforms + $supportedPlatform = false; + $versionParts = explode('.',JVERSION); + $currentPlatform = $versionParts[0].'.'.$versionParts[1]; + + if(array_key_exists('platforms', $iniData)) { + $rawPlatforms = explode(',', $iniData['platforms']); + foreach($rawPlatforms as $platform) { + $platform = trim($platform); + if(substr($platform,0,7) != 'joomla/') { + continue; + } + $platform = substr($platform, 7); + if($currentPlatform == $platform) { + $supportedPlatform = true; + } + } + } else { + // Lies, damn lies + $supportedPlatform = true; + } + + if(!$supportedPlatform) { + return $ret; + } + + $ret['version'] = array_key_exists('version', $iniData) ? $iniData['version'] : ''; + $ret['date'] = array_key_exists('date', $iniData) ? $iniData['date'] : ''; + $config = LiveUpdateConfig::getInstance(); + $auth = $config->getAuthorization(); + if(!array_key_exists('link', $iniData)) $iniData['link'] = ''; + $glue = strpos($iniData['link'],'?') === false ? '?' : '&'; + $ret['downloadURL'] = $iniData['link'] . (empty($auth) ? '' : $glue.$auth); + if(array_key_exists('stability', $iniData)) { + $stability = $iniData['stability']; + } else { + // Stability not defined; guesswork mode enabled + $version = $ret['version']; + if( preg_match('#^[0-9\.]*a[0-9\.]*#', $version) == 1 ) { + $stability = 'alpha'; + } elseif( preg_match('#^[0-9\.]*b[0-9\.]*#', $version) == 1 ) { + $stability = 'beta'; + } elseif( preg_match('#^[0-9\.]*rc[0-9\.]*#', $version) == 1 ) { + $stability = 'rc'; + } elseif( preg_match('#^[0-9\.]*$#', $version) == 1 ) { + $stability = 'stable'; + } else { + $stability = 'svn'; + } + } + $ret['stability'] = $stability; + + if(array_key_exists('releasenotes', $iniData)) { + $ret['releasenotes'] = $iniData['releasenotes']; + } + + if(array_key_exists('infourl', $iniData)) { + $ret['infoURL'] = $iniData['infourl']; + } + + return $ret; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/view.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/view.php new file mode 100644 index 00000000..49a17f52 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/view.php @@ -0,0 +1,110 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); + +JLoader::import('joomla.application.component.view'); + +if(!class_exists('JoomlaCompatView')) { + if(interface_exists('JView')) { + abstract class JoomlaCompatView extends JViewLegacy {} + } else { + class JoomlaCompatView extends JView {} + } +} + +/** + * The Live Update MVC view + */ +class LiveUpdateView extends JoomlaCompatView +{ + public function display($tpl = null) + { + // Load the CSS + $config = LiveUpdateConfig::getInstance(); + $this->assign('config', $config); + if(!$config->addMedia()) { + // No custom CSS overrides were set; include our own + $document = JFactory::getDocument(); + $url = JURI::base().'/components/'.JRequest::getCmd('option','').'/liveupdate/assets/liveupdate.css'; + $document->addStyleSheet($url, 'text/css'); + } + + $requeryURL = rtrim(JURI::base(),'/').'/index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&force=1'; + $this->assign('requeryURL', $requeryURL); + + $model = $this->getModel(); + + $extInfo = (object)$config->getExtensionInformation(); + JToolBarHelper::title($extInfo->title.' – '.JText::_('LIVEUPDATE_TASK_OVERVIEW'),'liveupdate'); + JToolBarHelper::back('JTOOLBAR_BACK', 'index.php?option='.JRequest::getCmd('option','')); + + if(version_compare(JVERSION, '3.0', 'ge')) { + $j3css = <<addStyleDeclaration($j3css); + } + + switch(JRequest::getCmd('task','default')) + { + case 'startupdate': + $this->setLayout('startupdate'); + $this->assign('url','index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=download'); + break; + + case 'install': + $this->setLayout('install'); + + // Get data from the model + $state = $this->get('State'); + + // Are there messages to display ? + $showMessage = false; + if ( is_object($state) ) + { + $message1 = $state->get('message'); + $message2 = $state->get('extension.message'); + $showMessage = ( $message1 || $message2 ); + } + + $this->assign('showMessage', $showMessage); + $this->assignRef('state', $state); + + break; + + case 'nagscreen': + $this->setLayout('nagscreen'); + $this->assign('updateInfo', LiveUpdate::getUpdateInformation()); + $this->assign('runUpdateURL','index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=startupdate&skipnag=1'); + break; + + case 'overview': + default: + $this->setLayout('overview'); + + $force = JRequest::getInt('force',0); + $this->assign('updateInfo', LiveUpdate::getUpdateInformation($force)); + $this->assign('runUpdateURL','index.php?option='.JRequest::getCmd('option','').'&view='.JRequest::getCmd('view','liveupdate').'&task=startupdate'); + + $needsAuth = !($config->getAuthorization()) && ($config->requiresAuthorization()); + $this->assign('needsAuth', $needsAuth); + break; + } + + parent::display($tpl); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/xmlslurp.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/xmlslurp.php new file mode 100644 index 00000000..f8c00c3f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/classes/xmlslurp.php @@ -0,0 +1,376 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); + +class LiveUpdateXMLSlurp extends JObject +{ + private $_info = array(); + + public function getInfo($extensionName, $xmlName) + { + if(!array_key_exists($extensionName, $this->_info)) { + $this->_info[$extensionName] = $this->fetchInfo($extensionName, $xmlName); + } + + return $this->_info[$extensionName]; + } + + /** + * Gets the version information of an extension by reading its XML file + * @param string $extensionName The name of the extension, e.g. com_foobar, mod_foobar, plg_foobar or tpl_foobar. + * @param string $xmlName The name of the XML manifest filename. If empty uses $extensionName.xml + */ + private function fetchInfo($extensionName, $xmlName) + { + $type = strtolower(substr($extensionName,0,3)); + switch($type) { + case 'com': + return $this->getComponentData($extensionName, $xmlName); + break; + case 'mod': + return $this->getModuleData($extensionName, $xmlName); + break; + case 'plg': + return $this->getPluginData($extensionName, $xmlName); + break; + case 'tpl': + return $this->getTemplateData($extensionName, $xmlName); + break; + case 'pkg': + return $this->getPackageData($extensionName, $xmlName); + break; + case 'lib': + return $this->getPackageData($extensionName, $xmlName); + break; + default: + if(strtolower(substr($extensionName, 0, 4)) == 'file') { + return $this->getPackageData($extensionName, $xmlName); + } else { + return array('version'=>'', 'date'=>''); + } + } + } + + /** + * Gets the version information of a component by reading its XML file + * @param string $extensionName The name of the extension, e.g. com_foobar + * @param string $xmlName The name of the XML manifest filename. If empty uses $extensionName.xml + */ + private function getComponentData($extensionName, $xmlName) + { + $extensionName = strtolower($extensionName); + $path = JPATH_ADMINISTRATOR.'/components/'.$extensionName; + $altExtensionName = substr($extensionName,4); + + JLoader::import('joomla.filesystem.file'); + if(JFile::exists("$path/$xmlName")) { + $filename = "$path/$xmlName"; + } elseif(JFile::exists("$path/$extensionName.xml")) { + $filename = "$path/$extensionName.xml"; + } elseif(JFile::exists("$path/$altExtensionName.xml")) { + $filename = "$path/$altExtensionName.xml"; + } elseif(JFile::exists("$path/manifest.xml")) { + $filename = "$path/manifest.xml"; + } else { + $filename = $this->searchForManifest($path); + if($filename === false) $filename = null; + } + + if(empty($filename)) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + try { + $xml = new SimpleXMLElement($filename, LIBXML_NONET, true); + } catch(Exception $e) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + // Need to check for extension (since 1.6) and install (supported through 2.5) + if ($xml->getName() != 'extension' && $xml->getName() != 'install') { + unset($xml); + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + $data['version'] = $xml->version ? (string) $xml->version : ''; + $data['date'] = $xml->creationDate ? (string) $xml->creationDate : ''; + $data['xmlfile'] = $filename; + + return $data; + } + + /** + * Gets the version information of a module by reading its XML file + * @param string $extensionName The name of the extension, e.g. mod_foobar + * @param string $xmlName The name of the XML manifest filename. If empty uses $extensionName.xml + */ + private function getModuleData($extensionName, $xmlName) + { + $extensionName = strtolower($extensionName); + $altExtensionName = substr($extensionName,4); + + JLoader::import('joomla.filesystem.folder'); + JLoader::import('joomla.filesystem.file'); + $path = JPATH_SITE.'/modules/'.$extensionName; + if(!JFolder::exists($path)) { + $path = JPATH_ADMINISTRATOR.'/modules/'.$extensionName; + } + if(!JFolder::exists($path)) { + // Joomla! 1.5 + // 1. Check front-end + $path = JPATH_ADMINISTRATOR.'/modules'; + $filename = "$path/$xmlName"; + if(!JFile::exists($filename)) { + $filename = "$path/$extensionName.xml"; + } + if(!JFile::exists($filename)) { + $filename = "$path/$altExtensionName.xml"; + } + // 2. Check front-end + if(!JFile::exists($filename)) { + $path = JPATH_SITE.'/modules'; + $filename = "$path/$xmlName"; + if(!JFile::exists($filename)) { + $filename = "$path/$extensionName.xml"; + } + if(!JFile::exists($filename)) { + $filename = "$path/$altExtensionName.xml"; + } + if(!JFile::exists($filename)) { + return array('version' => '', 'date' => ''); + } + } + } else { + // Joomla! 1.6 + $filename = "$path/$xmlName"; + if(!JFile::exists($filename)) { + $filename = "$path/$extensionName.xml"; + } + if(!JFile::exists($filename)) { + $filename = "$path/$altExtensionName.xml"; + } + if(!JFile::exists($filename)) { + return array('version' => '', 'date' => ''); + } + } + + if(empty($filename)) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + try { + $xml = new SimpleXMLElement($filename, LIBXML_NONET, true); + } catch(Exception $e) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + // Need to check for extension (since 1.6) and install (supported through 2.5) + if ($xml->getName() != 'extension' && $xml->getName() != 'install') { + unset($xml); + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + $data['version'] = $xml->version ? (string) $xml->version : ''; + $data['date'] = $xml->creationDate ? (string) $xml->creationDate : ''; + $data['xmlfile'] = $filename; + + return $data; + } + + /** + * Gets the version information of a plugin by reading its XML file + * @param string $extensionName The name of the plugin, e.g. plg_foobar + * @param string $xmlName The name of the XML manifest filename. If empty uses $extensionName.xml + */ + private function getPluginData($extensionName, $xmlName) + { + $extensionName = strtolower($extensionName); + $altExtensionName = substr($extensionName,4); + + JLoader::import('joomla.filesystem.folder'); + JLoader::import('joomla.filesystem.file'); + + $base = JPATH_PLUGINS; + + // Get a list of directories + $stack = JFolder::folders($base,'.',true,true); + foreach($stack as $path) + { + $filename = "$path/$xmlName"; + if(JFile::exists($filename)) break; + $filename = "$path/$extensionName.xml"; + if(JFile::exists($filename)) break; + $filename = "$path/$altExtensionName.xml"; + if(JFile::exists($filename)) break; + } + + if(!JFile::exists($filename)) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + try { + $xml = new SimpleXMLElement($filename, LIBXML_NONET, true); + } catch(Exception $e) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + // Need to check for extension (since 1.6) and install (supported through 2.5) + if ($xml->getName() != 'extension' && $xml->getName() != 'install') { + unset($xml); + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + $data['version'] = $xml->version ? (string) $xml->version : ''; + $data['date'] = $xml->creationDate ? (string) $xml->creationDate : ''; + $data['xmlfile'] = $filename; + + return $data; + } + + /** + * Gets the version information of a template by reading its XML file + * @param string $extensionName The name of the template, e.g. tpl_foobar + * @param string $xmlName The name of the XML manifest filename. If empty uses $extensionName.xml or templateDetails.xml + */ + private function getTemplateData($extensionName, $xmlName) + { + $extensionName = strtolower($extensionName); + $altExtensionName = substr($extensionName,4); + + JLoader::import('joomla.filesystem.folder'); + JLoader::import('joomla.filesystem.file'); + + // First look for administrator templates + $path = JPATH_THEMES.'/'.$altExtensionName; + if(!JFolder::exists($path)) { + // Then look for front-end templates + $path = JPATH_SITE.'/templates/'.$altExtensionName; + if(!JFolder::exists($path)) return array('version' => '', 'date' => ''); + } + + $filename = "$path/$xmlName"; + if(!JFile::exists($filename)) { + $filename = "$path/templateDetails.xml"; + } + if(!JFile::exists($filename)) { + $filename = "$path/$extensionName.xml"; + } + if(!JFile::exists($filename)) { + $filename = "$path/$altExtensionName.xml"; + } + if(!JFile::exists($filename)) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + try { + $xml = new SimpleXMLElement($filename, LIBXML_NONET, true); + } catch(Exception $e) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + // Need to check for extension (since 1.6) and install (supported through 2.5) + if ($xml->getName() != 'extension' && $xml->getName() != 'install') { + unset($xml); + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + $data['version'] = $xml->version ? (string) $xml->version : ''; + $data['date'] = $xml->creationDate ? (string) $xml->creationDate : ''; + $data['xmlfile'] = $filename; + + return $data; + } + + /** + * This method parses the manifest information of package, library and file + * extensions. All of those extensions do not store their manifests in the + * extension's directory, but in administrator/manifests. Kudos to @mbabker + * for sharing this method! + * + * @param string $extensionName + * @param string $xmlName + * @return type + */ + private function getPackageData($extensionName, $xmlName) + { + $extensionName = strtolower($extensionName); + $altExtensionName = substr($extensionName,4); + + JLoader::import('joomla.filesystem.folder'); + JLoader::import('joomla.filesystem.file'); + $path = JPATH_ADMINISTRATOR.'/manifests/packages'; + + $filename = "$path/$xmlName"; + if(!JFile::exists($filename)) { + $filename = "$path/$extensionName.xml"; + } + if(!JFile::exists($filename)) { + $filename = "$path/$altExtensionName.xml"; + } + if(!JFile::exists($filename)) { + return array('version' => '', 'date' => ''); + } + + if(empty($filename)) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + try { + $xml = new SimpleXMLElement($filename, LIBXML_NONET, true); + } catch(Exception $e) { + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + // Need to check for extension (since 1.6) and install (supported through 2.5) + if ($xml->getName() != 'extension') { + unset($xml); + return array('version' => '', 'date' => '', 'xmlfile' => ''); + } + + $data['version'] = $xml->version ? (string) $xml->version : ''; + $data['date'] = $xml->creationDate ? (string) $xml->creationDate : ''; + $data['xmlfile'] = $filename; + + return $data; + } + + /** + * Scans a directory for XML manifest files. The first XML file to be a + * manifest wins. + * + * @var $path string The path to look into + * + * @return string|bool The full path to a manifest file or false if not found + */ + private function searchForManifest($path) + { + JLoader::import('joomla.filesystem.folder'); + $files = JFolder::files($path, '\.xml$', false, true); + if(!empty($files)) foreach($files as $filename) { + try { + $xml = new SimpleXMLElement($filename, LIBXML_NONET, true); + } catch(Exception $e) { + continue; + } + + // Check for extension (since 1.6) and install (supported through 2.5) + if(($xml->getName() != 'extension' && $xml->getName() != 'install')) continue; + unset($xml); + return $filename; + } + + return false; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/config.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/config.php new file mode 100644 index 00000000..3aa9664f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/config.php @@ -0,0 +1,40 @@ + + * + * @version 3.1.7 2013-08-28 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); + +/** + * Configuration class for your extension's updates. + */ +class LiveUpdateConfig extends LiveUpdateAbstractConfig +{ + var $_extensionName = 'com_icagenda'; + var $_extensionTitle = 'iCagenda Release System'; + var $_updateURL = 'https://www.joomlic.com/index.php?option=com_ars&view=update&format=ini&id=2'; + var $_requiresAuthorization = false; + var $_versionStrategy = 'newest'; + var $_storageAdapter = 'file'; + var $_storageConfig = array('path' => JPATH_CACHE); + + public function __construct() { + JLoader::import('joomla.filesystem.file'); + + // Should I use our private CA store? + if(@file_exists(dirname(__FILE__).'/../assets/cacert.pem')) { + $this->_cacerts = dirname(__FILE__).'/../assets/cacert.pem'; + } + + parent::__construct(); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/index.html b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/index.html new file mode 100644 index 00000000..a3ac1d48 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/bg-BG/bg-BG.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/bg-BG/bg-BG.liveupdate.ini new file mode 100644 index 00000000..98511b6a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/bg-BG/bg-BG.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +; LIVEUPDATE_TASK_OVERVIEW="Live Update" + +; LIVEUPDATE_NOTSUPPORTED_HEAD="Live Update is not supported on this server" +; LIVEUPDATE_NOTSUPPORTED_INFO="Your server indicates that Live Update is not supported. Please contact your host and ask them to enable the cURL PHP extension or activate the URL fopen() wrappers. If these are already enabled, please ask them to configure their firewall so that it allows access to the following URL:" +; LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="You can always update %s by visiting our site manually, downloading the latest release and installing it using Joomla!'s extension installer." + +; LIVEUPDATE_STUCK_HEAD="Live Update has marked itself as crashed" +; LIVEUPDATE_STUCK_INFO="Live Update determined that it crashed the last time it tried to contact the update server. This usually indicates a host which actively blocks communications with external sites. If you would like to retry fetching the update information, please click the "_QQ_"Refresh update information"_QQ_" button below. If that results to a blank page, please contact your host and report this issue." + +; LIVEUPDATE_ERROR_NEEDSAUTH="You have to supply your username/password or Download ID to the component's parameters before trying to upgrade to the latest release. The upgrade button will remain disabled until you do that." +; LIVEUPDATE_HASUPDATES_HEAD="A new version is available" +; LIVEUPDATE_NOUPDATES_HEAD="You already have the latest version" +LIVEUPDATE_CURRENTVERSION="инсталирана версия" +LIVEUPDATE_LATESTVERSION="последна налична версия" +; LIVEUPDATE_LATESTRELEASED="Latest release date" +LIVEUPDATE_DOWNLOADURL="директно сваляне от URL адрес" + +LIVEUPDATE_REFRESH_INFO="актуализиране на информация за актуализацията" +LIVEUPDATE_DO_UPDATE="актуализиране към последната налична версия" + +; LIVEUPDATE_FTP_REQUIRED="Live Update determined that it needs to use FTP in order to download and install your update, but you have not saved your FTP login information in your Joomla! Global Configuration.

Please provide the FTP username and password below to proceed with the update." +LIVEUPDATE_FTP="FTP информация" +LIVEUPDATE_FTPUSERNAME="FTP потребителско име" +LIVEUPDATE_FTPPASSWORD="FTP парола" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="изтегли и инсталирай актуализацията" + +; LIVEUPDATE_DOWNLOAD_FAILED="Downloading the update package failed. Make sure that your temp-directory is writable or that you have enabled Joomla!'s FTP options in your site's Global Configuration." +; LIVEUPDATE_EXTRACT_FAILED="Extracting the update package failed. Please try updating the extension manually." + +; LIVEUPDATE_INVALID_PACKAGE_TYPE="Invalid package type. The update can not proceed." +LIVEUPDATE_INSTALLEXT="инсталирайте %s %s" +LIVEUPDATE_ERROR="грешка" +LIVEUPDATE_SUCCESS="успех" + +; LIVEUPDATE_ICON_UNSUPPORTED="Live Update not supported" +; LIVEUPDATE_ICON_CRASHED="Live Update crashed" +LIVEUPDATE_ICON_CURRENT="Вие имате последната версия" +LIVEUPDATE_ICON_UPDATES="НАМЕРЕНА Е АКТУАЛИЗАЦИЯ! ЩРАКНЕТЕ, ЗА ДА АКТУАЛИЗИРАТЕ." + +LIVEUPDATE_RELEASEINFO="информация" +; LIVEUPDATE_RELEASENOTES="Release notes" +LIVEUPDATE_READMOREINFO="прочети още" + +LIVEUPDATE_NAGSCREEN_HEAD="ПРЕДУПРЕЖДЕНИЕ! Вие се опитвате да инсталирате нестабилна версия." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +LIVEUPDATE_NAGSCREEN_BUTTON="разбирам какви са възможните рискове. Продължи с инсталацията." + +LIVEUPDATE_STABILITY_ALPHA="алфа версия" +LIVEUPDATE_STABILITY_BETA="бета версия" +; LIVEUPDATE_STABILITY_RC="RC" +LIVEUPDATE_STABILITY_STABLE="стабилна версия" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/bs-BA/bs-BA.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/bs-BA/bs-BA.liveupdate.ini new file mode 100644 index 00000000..99213a3f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/bs-BA/bs-BA.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Nadogradnja uživo" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Nadogradnaj uživo nije podržana na ovo serveru" +LIVEUPDATE_NOTSUPPORTED_INFO="Vaš server ukazuje da Nadogradnja uživo nije podržana. Molimo kontaktirajte vaš host i pitajte da omoguće cURL PHP ekstenziju ili aktiviraju URL fopen() omotače. Ako su ove već omogućene, molimo da ih pitate da podese vatreni zid kako bi dozvolio pristup sljedećem URL-u:" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Možete uvijek nadograditi %s tako što će te ručno posjetiti našu stanicu, gdje možete preuzeti posljednje izdanje i instalirati upotrebom Joomla! instalera za ekstenzije." + +LIVEUPDATE_STUCK_HEAD="Nadogradnja uživo se označila kao srušena" +LIVEUPDATE_STUCK_INFO="Nadogradnja uživo je odredila da se srušila posljednji put pri pokušaju da kontaktira server za nadogradnu. Ovo pretežno ukazuje na host koji aktivno blokira komunikaciju sa eksternim stranicama. Ako želite pokušati povući informacije o nadogradnji, molimo kliknite na "_QQ_"Osvježi informacije o nadogradnji"_QQ_" dugme ispod. Ako to rezultira sa praznom stranicom, molimo kontaktirajte svoj host i prijavite ovaj problem." + +LIVEUPDATE_ERROR_NEEDSAUTH="Morate obezbijediti vaše korisničko ime/šifru ili ID za preuzimanje na parametre komponente prije pokušavanja nadogradnej na zadnje izdanje. Dugme za nadogradnju će ostati isključeno sve dok to ne učinite." +LIVEUPDATE_HASUPDATES_HEAD="Dostupna je nova verzija" +LIVEUPDATE_NOUPDATES_HEAD="Već posjedujete posljednju verziju" +LIVEUPDATE_CURRENTVERSION="Instalirana verzija" +LIVEUPDATE_LATESTVERSION="Posljednja verzija" +LIVEUPDATE_LATESTRELEASED="Datum posljednjeg izdanja" +LIVEUPDATE_DOWNLOADURL="Direktan URL za preuzimanje" + +LIVEUPDATE_REFRESH_INFO="Osvježi informacije o nadogradnji" +LIVEUPDATE_DO_UPDATE="Nadogradi na posljednju verziju" + +LIVEUPDATE_FTP_REQUIRED="Nadogradnja uživo je odredila da je potrebna upotreba FTP-a kako bi se preuzela i instalirala vaša nadogradnja, ali niste snimili vaše FTP informacije za prijavu u Joomla! globalnoj konfiguraciji.

Molimo da obezbjedite FTP korisničko ime i šifru ispod kako bi nastavili sa nadogradnjom." +LIVEUPDATE_FTP="FTP informacija" +LIVEUPDATE_FTPUSERNAME="FTP korisničko ime" +LIVEUPDATE_FTPPASSWORD="FTP šifra" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Preuzmi i instaliraj nadogradnju" + +LIVEUPDATE_DOWNLOAD_FAILED="Preuzimanje paketa nadogradnje je neuspješno. Provjerite da li je vaš privremeni direktorij zapisiv ili da li imate uključene Joomla! FTP opcije na vašoj globalnoj konfiguraciji za stranicu." +LIVEUPDATE_EXTRACT_FAILED="Otpakivanje paketa nadogradnje neuspješno. Molimo da pokušate ručno nadograditi ekstenziju." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Nevažeći tip paketa. Nadogradnja se ne može nastaviti." +LIVEUPDATE_INSTALLEXT="Instaliraj %s %s" +LIVEUPDATE_ERROR="Greška" +LIVEUPDATE_SUCCESS="Uspjeh" + +LIVEUPDATE_ICON_UNSUPPORTED="Nadogradnja uživo nije podržana" +LIVEUPDATE_ICON_CRASHED="Nadogradnja uživo se srušila" +LIVEUPDATE_ICON_CURRENT="Posjedujete posljednju verziju" +LIVEUPDATE_ICON_UPDATES="NADOGRADNJA PRONAĐENA! KLIKNITE ZA NADOGRADNJU." + +LIVEUPDATE_RELEASEINFO="Informacije" +LIVEUPDATE_RELEASENOTES="Obavijesti o izdanju" +LIVEUPDATE_READMOREINFO="Pročitaj više" + +LIVEUPDATE_NAGSCREEN_HEAD="UPOZORENJE! Upravo će te instalirati nestabilnu verziju." +LIVEUPDATE_NAGSCREEN_BODY="Upravo će te instalirati nestabilnu verziju (%s - %s). Nestabilne verzije su prošle minimalno ili nikakvo testiranje i sadrže greške koje štete stabilnosti i funkcionalnosti vaše web-stranice. Ako niste sigurno šta će te raditi, molimo da zatvorite prozor preglednika. Ako se potpuno sigurni da razumijete rizike uključene za instalacijom nestabilnih izdanja, molimo da kliknete dugme ispod kako bi nastavili instalaciju ovog nestabilnog izdanja." +LIVEUPDATE_NAGSCREEN_BUTTON="Razumijem rizike. Nastavi sa instalacijom." + +LIVEUPDATE_STABILITY_ALPHA="Alfa" +LIVEUPDATE_STABILITY_BETA="Beta" +LIVEUPDATE_STABILITY_RC="RC" +LIVEUPDATE_STABILITY_STABLE="Stabilna" +LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/cs-CZ/cs-CZ.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/cs-CZ/cs-CZ.liveupdate.ini new file mode 100644 index 00000000..e1db2ab6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/cs-CZ/cs-CZ.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Aktualizace" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Tento server nepodporuje kontrolu aktualizací" +LIVEUPDATE_NOTSUPPORTED_INFO="Nastavení Vašeho serveru nedovoluje spustit aktualizaci. Kontaktujte prosím provozovatele serveru a požádejte ho o zprovoznění PHP rozšíření cUrl nebo o povolení možnosti allow_url_fopen. Pokud je jedna z těchto možností již povolena, požádejte o prověření nastavení firewall, zda je povolena komunikace s následující adresou URL:" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Aktualizaci rozšíření %s můžete provést ručně, stažením nejnovější verze z našich stránek a instalací ve správci rozšíření." + +LIVEUPDATE_STUCK_HEAD="Poslední pokus o získání aktualizace se nezdařil" +LIVEUPDATE_STUCK_INFO="Poslední pokus o komunikaci se serverem aktualizací se nezdařil. Obvykle je to způsobeno nastavením serveru, které neumožňuje komunikaci s jinými servery. Pro opětovný pokus získání informací o aktualizacích stiskněte tlačítko "_QQ_"Aktualizovat informace"_QQ_". Pokud se Vám po stisknutí tohoto tlačítka zobrazí prázdná bílá stránka, kontaktujte prosím provozovatele serveru." + +LIVEUPDATE_ERROR_NEEDSAUTH="Tato aktualizace vyžaduje vyplněné Přihlašovací jméno a Heslo, nebo Klientské ID (Download ID) v nastavení komponenty. Po vyplnění potřebných informací bude povoleno tlačítko Aktualizovat." +LIVEUPDATE_HASUPDATES_HEAD="Je k dispozici nová verze" +LIVEUPDATE_NOUPDATES_HEAD="Instalovaná verze je aktuální" +LIVEUPDATE_CURRENTVERSION="Instalovaná verze" +LIVEUPDATE_LATESTVERSION="Nejnovější verze" +LIVEUPDATE_LATESTRELEASED="Datum nejnovější verze" +LIVEUPDATE_DOWNLOADURL="Adresa pro ruční stažení" + +LIVEUPDATE_REFRESH_INFO="Najít aktualizace" +LIVEUPDATE_DO_UPDATE="Aktualizovat" + +LIVEUPDATE_FTP_REQUIRED="Pro dokončení instalace na Vašem serveru je nutné využít vrstvu FTP, v globálním nastavení Joomla! však nejsou vyplněny všechna potřebná nastavení.

Vyplňte prosím informace pro připojení k serveru FTP níže." +LIVEUPDATE_FTP="Nastavení FTP" +LIVEUPDATE_FTPUSERNAME="FTP Přihlašovací jméno" +LIVEUPDATE_FTPPASSWORD="FTP Heslo" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Stáhnout a nainstalovat aktualizaci" + +LIVEUPDATE_DOWNLOAD_FAILED="Nepodařilo se stáhnout aktualizační balíček. Ověřte prosím, zda je Vaše dočasná složka zapisovatelná, nebo zda máte povolenu Vrstvu FTP v globálním nastavení Joomla!." +LIVEUPDATE_EXTRACT_FAILED="Nepodařilo se rozbalit aktualizační balíček. Zkuste prosím rozšíření aktualizovat ručně." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Nebyl rozpoznán formát aktualizačního balíčku. V aktualizaci nelze pokračovat." +LIVEUPDATE_INSTALLEXT="Instalovat %s %s" +LIVEUPDATE_ERROR="Chyba" +LIVEUPDATE_SUCCESS="Dokončeno" + +LIVEUPDATE_ICON_UNSUPPORTED="Aktualizace není podporována" +LIVEUPDATE_ICON_CRASHED="Aktualizace skončila chybou" +LIVEUPDATE_ICON_CURRENT="Vaše verze je aktuální" +LIVEUPDATE_ICON_UPDATES="NALEZENA NOVÁ VERZE! AKTUALIZOVAT" + +LIVEUPDATE_RELEASEINFO="Informace" +LIVEUPDATE_RELEASENOTES="Poznámky k verzi" +LIVEUPDATE_READMOREINFO="Podrobnosti" + +LIVEUPDATE_NAGSCREEN_HEAD="UPOZORNĚNÍ! Chystáte se instalovat nestabilní verzi." +LIVEUPDATE_NAGSCREEN_BODY="Chystáte se instalovat nestabilní verzi (%s - %s). Nestabilní verze jsou minimálně, nebo nejsou vůbec testovány a mohou obsahovat chyby, ovlivňující stabilitu a funkčnost Vašich stránek. Pokud si nejste jisti tím co děláte, uzavřete prosím okno prohlížeče. Pokud jste si naprosto jisti a rozumíte rizikům spojeným s instalací nestabilní verze, klikněte na tlačítko níže pro pokračování v instalaci této nestabilní verze." +LIVEUPDATE_NAGSCREEN_BUTTON="Rozumím rizikům. Pokračovat v instalaci." + +LIVEUPDATE_STABILITY_ALPHA="Alfa" +LIVEUPDATE_STABILITY_BETA="Beta" +LIVEUPDATE_STABILITY_RC="RC" +LIVEUPDATE_STABILITY_STABLE="Stable" +LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/da-DK/da-DK.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/da-DK/da-DK.liveupdate.ini new file mode 100644 index 00000000..91bd725d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/da-DK/da-DK.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Live Opdatering" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Live opdatering understøttes ikke af denne server" +LIVEUPDATE_NOTSUPPORTED_INFO="Din server indikerer at Live opdatering ikke er understøttet. Kontakt venligst din udbyder og spørg dem om at aktivere cURL PHP udvidelsen eller aktivere URL fopen() wrappers. Hvis disse allerede er aktive, så spørg dem venligst om at konfigurere deres firewall, således at den tillader adgang til følgende :" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Du kan altid opdatere %s ved at besøge vores hjemmeside manuelt og hente den seneste udgivelse og derefter installere den ved at bruge Joomla!'s udvidelsesinstalleren." + +LIVEUPDATE_STUCK_HEAD="Live opdatering melder at den gik ned" +LIVEUPDATE_STUCK_INFO="Live opdatering opdagede at den gik ned sidste gang den prøvede at kontakte opdateringsserveren. Dette indikerer nomalt en udbyder der aktivt blokerer kommunikation med eksterne sider. Hvis du vil forsøge at hente opdateringsinformationen igen, klik da venligst på "_QQ_"Opdatér opdateringsinformation"_QQ_" herunder. Hvis det resulterer i en blank side, så kontakt venligst din udbyder og rapportér dette problem." + +LIVEUPDATE_ERROR_NEEDSAUTH="Du skal angive dit brugernavn/adgangskode eller Overførsel's ID i komponenten's indstillinger, før du kan opdatere til den seneste version. Opdateringsknappen vil forblive inaktiv indtil da." +LIVEUPDATE_HASUPDATES_HEAD="En ny version er tilgængelig" +LIVEUPDATE_NOUPDATES_HEAD="Du har allerede den seneste version" +LIVEUPDATE_CURRENTVERSION="Installeret version" +LIVEUPDATE_LATESTVERSION="Seneste version" +LIVEUPDATE_LATESTRELEASED="Seneste udgivelsesdato" +LIVEUPDATE_DOWNLOADURL="Direkte link" + +LIVEUPDATE_REFRESH_INFO="Opdatér opdateringsinformation" +LIVEUPDATE_DO_UPDATE="Opdatér til seneste version" + +LIVEUPDATE_FTP_REQUIRED="Live opdatering har opdaget at den skal bruge FTP for at kunne overføre og installere din opdatering, men du har ikke gemt en FTP log ind information i din Joomla!'s konfiguration.

Angiv venligst FTP brugernavn og adgangskode herunder for at fortsætte med opdateringen." +LIVEUPDATE_FTP="FTP information" +LIVEUPDATE_FTPUSERNAME="FTP Brugernavn" +LIVEUPDATE_FTPPASSWORD="FTP Adgangskode" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Overfør og installér opdatering" + +LIVEUPDATE_DOWNLOAD_FAILED="Overførsel af opdateringspakken fejlede. Vær venligst sikker på der kan skrives til din midlertidige mappe og at du har aktiveret Joomla!'s FTP mulighed i Joomla!'s konfiguration." +LIVEUPDATE_EXTRACT_FAILED="Udpakning af opdateringspakken fejlede. Opdatér venligst udvidelsen manuelt." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Ugyldig pakketype. Opdateringen kan ikke fortsætte." +LIVEUPDATE_INSTALLEXT="Installér %s %s" +LIVEUPDATE_ERROR="Fejl" +LIVEUPDATE_SUCCESS="Korrekt" + +LIVEUPDATE_ICON_UNSUPPORTED="Live opdatering er ikke understøttet" +LIVEUPDATE_ICON_CRASHED="Live opdatering gik ned" +LIVEUPDATE_ICON_CURRENT="Du har den seneste version" +LIVEUPDATE_ICON_UPDATES="OPDATERING FUNDET! OPDATER NU." + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/de-DE/de-DE.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/de-DE/de-DE.liveupdate.ini new file mode 100644 index 00000000..524848f1 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/de-DE/de-DE.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Echtzeitaktualisierung" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Die Echtzeitaktualisierung wird auf diesem Server nicht unterstützt" +LIVEUPDATE_NOTSUPPORTED_INFO="Ihr Server zeigt an, dass die Echtzeitaktualisierung nicht unterstützt wird. Bitte kontaktieren Sie Ihren Anbieter und bitten ihn, die cURL-PHP-Erweiterung zu aktivieren oder die URL fopen() Wrapper. Sollten diese schon aktviert sein, bitten Sie ihn, die Firewall so zu konfigurieren, dass sie den Zugriff auf folgende URL zulässt:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Sie können immer aktualisieren %s indem Sie unsere Internetseite besuchen, die neueste Version herunterladen und ganz normal installieren." + +LIVEUPDATE_STUCK_HEAD="Die Echtzeitaktualisierung hat sich selbst als abgestürzt gemeldet" +LIVEUPDATE_STUCK_INFO="Die Echtzeitaktualisierung hat festgestellt, dass sie beim letzten Versuch den Aktualisierungsserver zu erreichen abgestürzt ist. Dies deutet meist auf einen Anbieter hin, der die Kommunikation mit externen Servern blockiert. Sollten Sie die Aktulalisierungsinformationen nochmals abrufen wollen, klicken Sie bitte auf den Knopf "_QQ_"Aktualisierungsinformationen abrufen"_QQ_". Sollte dieser Versuch auf einer weißen Seite enden, melden Sie diesen Fehler ihrem Anbieter." + +LIVEUPDATE_ERROR_NEEDSAUTH="Bevor Sie eine Echtzeitaktualisierung durchführen können, müssen Sie Ihren Benutzernamen, das Passwort bzw. die Download-ID angeben. Der Aktualisierungsknopf wird solange ohne Funktion bleiben." +LIVEUPDATE_HASUPDATES_HEAD="Es gibt eine neue Version" +LIVEUPDATE_NOUPDATES_HEAD="Sie haben die aktuelle Version" +LIVEUPDATE_CURRENTVERSION="Installierte Version" +LIVEUPDATE_LATESTVERSION="Neueste Version" +LIVEUPDATE_LATESTRELEASED="Neuestes Veröffentlichungsdatum" +LIVEUPDATE_DOWNLOADURL="Direkte Download-URL" + +LIVEUPDATE_REFRESH_INFO="Aktualisierungsinformationen abrufen" +LIVEUPDATE_DO_UPDATE="Auf die neueste Version aktualisieren" + +LIVEUPDATE_FTP_REQUIRED="Die Echtzeitaktualisierung hat festgestellt, dass FTP für die Aktualisierung und Installation verwednet werden muss. Sie haben aber noch keine FTP-Daten in der Joomla!-Konfiguraton angegeben.

BItte geben Sie Ihre FTP-Daten ein, bevor Sie mit der Aktualisierung fortfahren." +LIVEUPDATE_FTP="FTP Informationen" +LIVEUPDATE_FTPUSERNAME="FTP Benutzername" +LIVEUPDATE_FTPPASSWORD="FTP Passwort" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Aktualisierung herunterladen und installieren" + +LIVEUPDATE_DOWNLOAD_FAILED="Das Herunterladen des Aktualisierungspakets ist fehlgeschlagen. Bitte stellen Sie sicher, dass Ihr temp-Verzeichnis Schreibrechte besitzt und Sie Ihre FTP-Nutzerdaten in der Joomla!-Konfiguration angegeben haben." +LIVEUPDATE_EXTRACT_FAILED="Das Auspacken des Aktualisierungspakets ist fehlgeschlagen. Bitte aktualisieren Sie die Erweiterung manuell." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Falscher Aktualisierungspakettyp. Die Aktualisierung kann nicht durchgeführt werden." +LIVEUPDATE_INSTALLEXT="Installiere %s %s" +LIVEUPDATE_ERROR="Fehler" +LIVEUPDATE_SUCCESS="Erfolg" + +LIVEUPDATE_ICON_UNSUPPORTED="Echtzeitaktualisierung nicht unterstützt" +LIVEUPDATE_ICON_CRASHED="Live Update abgestürzt" +LIVEUPDATE_ICON_CURRENT="Sie haben die aktuelle Version" +LIVEUPDATE_ICON_UPDATES="AKTUALISIERUNG GEFUNDEN! JETZT AKTUALISIEREN." + +LIVEUPDATE_RELEASEINFO="Information" +LIVEUPDATE_RELEASENOTES="Infos zur Veröffentlichung" +LIVEUPDATE_READMOREINFO="Weiterlesen" + +LIVEUPDATE_NAGSCREEN_HEAD="ACHTUNG! Sie sind dabei, eine instabile Version zu installieren." +LIVEUPDATE_NAGSCREEN_BODY="Sie sind dabei, eine instabile Version zu installieren (%s - %s). Instabile Versionen sind noch in Entwicklung oder nicht final getestet und können Bugs enthalten, die die Stabilität und Funktionalität Ihrer Webseite beeinträchtigen können. Wenn Sie nicht sicher sind, was Sie tun sollen, dann schließen Sie dieses Browserfenster. Sollten Sie absolut sicher sein, dass Sie das Risiko eingehen und die möglichen Folgen einer unfertigen Version auf eigene Gefahr in Kauf nehmen wollen, klicken Sie auf den unten stehenden Button um die instabile Version zu installieren." +LIVEUPDATE_NAGSCREEN_BUTTON="Ich kenne die Risiken. Mit der Installation fortfahren." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/el-GR/el-GR.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/el-GR/el-GR.liveupdate.ini new file mode 100644 index 00000000..4f70c553 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/el-GR/el-GR.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Απευθείας Ενημέρωση" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Η Απευθείας Ενημέρωση δεν υποστηρίζεται από αυτόν τον διακομιστή" +LIVEUPDATE_NOTSUPPORTED_INFO="Ο διακομιστής σας δείχνει ότι η Απευθείας Ενημέρωση δεν υποστηρίζεται. Παρακαλώ επικοινωνήστε με τον πάροχο φιλοξενίας σας και ζητήστε του να ενεργοποιήσει την επέκταση cURL της PHP ή τους URL fopen() wrappers. Εάν είναι ήδη ενεργοποιημένα, παρακαλώ ζητήστε του να ανοίξει το τείχος ασφαλείας ώστε να επιτρέπει την πρόσβαση στην παρακάτω διεύθυνση URL:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Μπορείτε πάντα να ενημερώστε το λογισμικό %s επισκεπτόμενοι τον ιστότοπό μας, κατεβάζοντας την τελευταία έκδοση και εγκαθιστόντας την με την εγκατάσταση εφαρμογών του Joomla!." + +LIVEUPDATE_STUCK_HEAD="Η Απευθείας Ενημέρωση ανίχνευσε αποτυχία λειτουργίας" +LIVEUPDATE_STUCK_INFO="Η Απευθείας Ενημέρωση εντόπισε ότι η τελευταία απόπειρα επικοινωνίας με τον διακομιστή ενημερώσεων κατέληξε σε κόλλημα. Αυτό συνήθως υποδυκνείει έναν πάροχο φιλοξενίας που μπλοκάρει ενεργά τις προσπάθειες επικοινωνίας με εξωετρικούς ιστοχώρους. Εάν θα θέλατε να δοκιμάσετε να ξαναπροσπαθήσουμε να λάβουμε τις πληροφορίες ενημέρωσεις, παρακαλώ κάντε κλικ στο κουμπί "_QQ_"Ανανέωση πληροφοριών ενημερώσεων"_QQ_" πιο κάτω. Εάν αυτό οδηγήσει σε λευκή σελίδα, παρακαλώ επικοινωνήστε με τον πάροχο φιλοξενίας και αναφέρετε αυτό το πρόβλημα." + +LIVEUPDATE_ERROR_NEEDSAUTH="Πρέπει να εισάγετε το όνομα χρήστη και συνθηματικό ή το Αναγνωριστικό Μεταφόρτωσης στις παραμέτρους της εφαρμογής πριν προσπαθήσετε να αναβαθμίσετε στην τελευταία έκδοση. Το κουμπί ενημέρωσης θα παραμείνει ανενεργό έως ότου το κάνετε." +LIVEUPDATE_HASUPDATES_HEAD="Μια νέα έκδοση είναι διαθέσιμη" +LIVEUPDATE_NOUPDATES_HEAD="Έχετε ήδη την τελευταία έκδοση" +LIVEUPDATE_CURRENTVERSION="Εγκατεστημένη έκδοση" +LIVEUPDATE_LATESTVERSION="Τελευταία έκδοση" +LIVEUPDATE_LATESTRELEASED="Ημερομηνία έκδοσης" +LIVEUPDATE_DOWNLOADURL="Διεύθυνση απευθείας μεταφόρτωσης" + +LIVEUPDATE_REFRESH_INFO="Ανανέωση πληροφοριών ενημερώσεων" +LIVEUPDATE_DO_UPDATE="Ενημέρωση στην τελευταία έκδοση" + +LIVEUPDATE_FTP_REQUIRED="Η Απευθείας Ενημέρωση εντόπισε ότι απαιτείται η χρήση FTP για να μεταφορτώσει και να εγκαταστήσει την ενημέρωσή σας, αλλά δεν έχετε σώσει τις πληροφορίες εισόδου στο FTP στις Γενικές Ρυθμίσεις του Joomla!.

Παρακαλώ εισάγετε το όνομα χρήστη και το συνθηματικό για το FTP προκειμένου να προχωρήσετε με την ενημέρωση." +LIVEUPDATE_FTP="Πληροφορίες FTP" +LIVEUPDATE_FTPUSERNAME="Όνομα Χρήστη FTP" +LIVEUPDATE_FTPPASSWORD="Συνθηματικό FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Μεταφόρτωση και εγκατάσταση ενημέρωσης" + +LIVEUPDATE_DOWNLOAD_FAILED="Η μεταφόρτωση του πακέτου ενημέρωσης απέτυχε. Παρακαλώ βεβαιωθείτε ότι ο κάταλογος προσωρινής αποθήκευσης είναι εγγράψιμος ή ότι έχετε ενεργοποιήσει τις επιλογές FTP στις Γενικές Ρυθμίσεις του ιστοχώρου σας." +LIVEUPDATE_EXTRACT_FAILED="Η αποσυμπίεση του πακέτου αναβάθμισης απέτυχε. Παρακαλώ δοκιμάστε να εγκαταστήσετε την επέκταση χειροκίνητα." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Ο τύπος του πακέτου δεν είναι έγκυρος. Η αναβάθμιση δεν μπορεί να συνεχίσει." +LIVEUPDATE_INSTALLEXT="Εγκατάσταση %s %s" +LIVEUPDATE_ERROR="Σφάλμα" +LIVEUPDATE_SUCCESS="Επιτυχία" + +LIVEUPDATE_ICON_UNSUPPORTED="Η Απευθείας Ενημέρωση δεν υποστηρίζεται" +LIVEUPDATE_ICON_CRASHED="Η Απευθείας Ενημέρωση κόλλησε" +LIVEUPDATE_ICON_CURRENT="Έχετε την τελευταία έκδοση" +LIVEUPDATE_ICON_UPDATES="ΒΡΕΘΗΚΕ ΕΝΗΜΕΡΩΣΗ! ΚΑΝΤΕ ΚΛΙΚ ΓΙΑ ΑΝΑΒΑΘΜΙΣΗ." + +LIVEUPDATE_RELEASEINFO="Πληροφορίες" +LIVEUPDATE_RELEASENOTES="Σημειώσεις έκδοσης" +LIVEUPDATE_READMOREINFO="Διαβάστε περισσότερα" + +LIVEUPDATE_NAGSCREEN_HEAD="ΠΡΟΣΟΧΗ! Πρόκειται να εγκαταστήσετε μια ασταθή έκδοση." +LIVEUPDATE_NAGSCREEN_BODY="Πρόκειται να εγκαταστήσετε μια ασταθή έκδοση (%s - %s). Οι ασταθείς εκδόσεις μπορεί να έχουν υποβληθεί σε ελάχιστο ή περιορισμένο ποιοτικό έλεγχο και να περιέχουν σφάλματα που μπορεί να έχουν σοβαρές παρενέργειες στην σταθερότητα και λειτουργία τουιστοχώρου σας. Εάν δεν είστε βέβαιος για αυτό που πρόκειται να κάνετε, παρακαλώ κλείστε αυτό το παράθυρο του περιηγητή σας. Εάν κατανοείτε πλήρως τους κινδύνους που συνοδεύουν την εγκατάσταση ασταθών εκδόσεων παρακαλώ κάντε κλικ στο παρακάτω κουμπί για να συνεχίσετε την εγκατάσταση αυτής της ασταθούς έκδοσης." +LIVEUPDATE_NAGSCREEN_BUTTON="Καταννοώ τους κινδύνους. Συνέχισε την εγκατάσταση." + +LIVEUPDATE_STABILITY_ALPHA="Άλφα" +LIVEUPDATE_STABILITY_BETA="Βήτα" +LIVEUPDATE_STABILITY_RC="Υποψήφια Έκδοσης" +LIVEUPDATE_STABILITY_STABLE="Σταθερή" +LIVEUPDATE_STABILITY_SVN="Έκδοση Προγραμματιστή" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/en-GB/en-GB.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/en-GB/en-GB.liveupdate.ini new file mode 100644 index 00000000..097f3c4a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/en-GB/en-GB.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Live Update" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Live Update is not supported on this server" +LIVEUPDATE_NOTSUPPORTED_INFO="Your server indicates that Live Update is not supported. Please contact your host and ask them to enable the cURL PHP extension or activate the URL fopen() wrappers. If these are already enabled, please ask them to configure their firewall so that it allows access to the following URL:" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="You can always update %s by visiting our site manually, downloading the latest release and installing it using Joomla!'s extension installer." + +LIVEUPDATE_STUCK_HEAD="Live Update has marked itself as crashed" +LIVEUPDATE_STUCK_INFO="Live Update determined that it crashed the last time it tried to contact the update server. This usually indicates a host which actively blocks communications with external sites. If you would like to retry fetching the update information, please click the "_QQ_"Refresh update information"_QQ_" button below. If that results to a blank page, please contact your host and report this issue." + +LIVEUPDATE_ERROR_NEEDSAUTH="You have to supply your username/password or Download ID to the component's parameters before trying to upgrade to the latest release. The upgrade button will remain disabled until you do that." +LIVEUPDATE_HASUPDATES_HEAD="A new version is available" +LIVEUPDATE_NOUPDATES_HEAD="You already have the latest version" +LIVEUPDATE_CURRENTVERSION="Installed version" +LIVEUPDATE_LATESTVERSION="Latest version" +LIVEUPDATE_LATESTRELEASED="Latest release date" +LIVEUPDATE_DOWNLOADURL="Direct download URL" + +LIVEUPDATE_REFRESH_INFO="Refresh update information" +LIVEUPDATE_DO_UPDATE="Update to the latest version" + +LIVEUPDATE_FTP_REQUIRED="Live Update determined that it needs to use FTP in order to download and install your update, but you have not saved your FTP login information in your Joomla! Global Configuration.

Please provide the FTP username and password below to proceed with the update." +LIVEUPDATE_FTP="FTP Information" +LIVEUPDATE_FTPUSERNAME="FTP Username" +LIVEUPDATE_FTPPASSWORD="FTP Password" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Download and install update" + +LIVEUPDATE_DOWNLOAD_FAILED="Downloading the update package failed. Make sure that your temp-directory is writable or that you have enabled Joomla!'s FTP options in your site's Global Configuration." +LIVEUPDATE_EXTRACT_FAILED="Extracting the update package failed. Please try updating the extension manually." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Invalid package type. The update can not proceed." +LIVEUPDATE_INSTALLEXT="Install %s %s" +LIVEUPDATE_ERROR="Error" +LIVEUPDATE_SUCCESS="Success" + +LIVEUPDATE_ICON_UNSUPPORTED="Live Update not supported" +LIVEUPDATE_ICON_CRASHED="Live Update crashed" +LIVEUPDATE_ICON_CURRENT="You have the latest version" +LIVEUPDATE_ICON_UPDATES="UPDATE FOUND! CLICK TO UPDATE." + +LIVEUPDATE_RELEASEINFO="Information" +LIVEUPDATE_RELEASENOTES="Release notes" +LIVEUPDATE_READMOREINFO="Read more" + +LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an adverse effect to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +LIVEUPDATE_STABILITY_ALPHA="Alpha" +LIVEUPDATE_STABILITY_BETA="Beta" +LIVEUPDATE_STABILITY_RC="RC" +LIVEUPDATE_STABILITY_STABLE="Stable" +LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/es-ES/es-ES.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/es-ES/es-ES.liveupdate.ini new file mode 100644 index 00000000..de2549e8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/es-ES/es-ES.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Actualización automática" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Este servidor no soporta la Actualización automática" +LIVEUPDATE_NOTSUPPORTED_INFO="Su servidor indica que no soporta la Actualización automática. Por favor, contacte con su proveedor de hosting y pídale que active la función cURL de PHP, o bien que active los wrappers de URL fopen(). Si alguna de las opciones anteriores ya está activada, por favor pídale que que configure su cortafuegos de manera que permita el acceso a la siguiente URL:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Siempre puede actualizar %s manualmente visitando nuestro sitio, descargando la última versión e instalándola mediante el instalador del gestor de extensiones de Joomla!"_QQ_"" + +LIVEUPDATE_STUCK_HEAD="La actualización automática informa de un fallo" +LIVEUPDATE_STUCK_INFO="La actualización automática determinó que hubo un fallo la última vez que intentó contactar con el servidor de actualizaciones. Esto habitualmente ocurre cuando un host bloquea activamente las comunicaciones con sitios externos. Si desea trata de obtener de nuevo la información sobre nuevas actualizaciones, por favor haga clic en el botón "_QQ_"Refrescar la información sobre actualizaciones"_QQ_" que hay a continuación. Si tras hacerlo obtiene una página en blanco, por favor contacte con su proveedor de hosting y coméntele el problema." + +LIVEUPDATE_ERROR_NEEDSAUTH="Debe introducir su nombre de usuario/contraseña su ID de Descarga (Download ID) en los parámetros de configuración del componente antes de intentar actualizar a la última versión. El botón de actualización permanecerá deshabilitado hasta que lo haga." +LIVEUPDATE_HASUPDATES_HEAD="Hay disponible una nueva versión" +LIVEUPDATE_NOUPDATES_HEAD="Ya tiene instalada la última vesión" +LIVEUPDATE_CURRENTVERSION="Versión instalada" +LIVEUPDATE_LATESTVERSION="Última versión" +LIVEUPDATE_LATESTRELEASED="Fecha de la última versión" +LIVEUPDATE_DOWNLOADURL="URL de descarga directa" + +LIVEUPDATE_REFRESH_INFO="Refrescar la información de actualización" +LIVEUPDATE_DO_UPDATE="Actualizar a la última versión" + +LIVEUPDATE_FTP_REQUIRED="La actualización automática determinó que es necesario usar FTP para poder descargar e instalar su actualización, pero usted aún no ha guardado la información de inicio de sesión FTP en la configuración global de Joomla!.

Por favor introduzca el nombre de usuario y la contraseña de su cuenta FTP a continuación para proceder con la actualización." +LIVEUPDATE_FTP="Información FTP" +LIVEUPDATE_FTPUSERNAME="Usuario FTP" +LIVEUPDATE_FTPPASSWORD="Contraseña FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Descargar e instalar la actualización" + +LIVEUPDATE_DOWNLOAD_FAILED="La descarga del paquete de actualización no se pudo completar. Asegúrese de que su directorio temporal (temp) tiene permisos de escritura o de que ha habilitado la configuración de FTP en la configuración global de su sitio." +LIVEUPDATE_EXTRACT_FAILED="La extracción de los archivos del paquete de actualización falló. Por favor, trate de actualizar la extensión manualmente." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Tipo de paquete erróneo. No se puede proceder con la actualización." +LIVEUPDATE_INSTALLEXT="Instalando %s %s" +LIVEUPDATE_ERROR="Error" +LIVEUPDATE_SUCCESS="Éxito" + +LIVEUPDATE_ICON_UNSUPPORTED="La actualización automática no está soportada" +LIVEUPDATE_ICON_CRASHED="La actualización automática falló" +LIVEUPDATE_ICON_CURRENT="Ya tiene la última versión" +LIVEUPDATE_ICON_UPDATES="¡ACTUALIZACIÓN DISPONIBLE! CLIC PARA INSTALAR." + +LIVEUPDATE_RELEASEINFO="Información" +LIVEUPDATE_RELEASENOTES="Notas de la versión" +LIVEUPDATE_READMOREINFO="Leer más" + +LIVEUPDATE_NAGSCREEN_HEAD="ATENCIÓN! Usted está a punto de instalar una versión inestable." +LIVEUPDATE_NAGSCREEN_BODY="Usted está a punto de instalar una versión inestable (%s - %s). Las versiones inestables pueden tener mínimos o ningún test y contener errores que pueden causar serios problemas a la estabilidad y funcionalidad de su sitio web. Si usted no está seguro sobre qué hacer, por favor cierre esta ventana del explorador. Si usted está totalmente seguro de entender los riesgos involucrados con la instalación de versiones inestables, por favor pulse el botón de abajo para continuar con la instalación de esta versión inestable." +LIVEUPDATE_NAGSCREEN_BUTTON="Entiendo los riesgos. Continuar con la instalación" + +LIVEUPDATE_STABILITY_ALPHA="Alfa" +LIVEUPDATE_STABILITY_BETA="Beta" +LIVEUPDATE_STABILITY_RC="RC" +LIVEUPDATE_STABILITY_STABLE="Estable" +LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/et-EE/et-EE.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/et-EE/et-EE.liveupdate.ini new file mode 100644 index 00000000..cac25ab6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/et-EE/et-EE.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +; LIVEUPDATE_TASK_OVERVIEW="Live Update" + +; LIVEUPDATE_NOTSUPPORTED_HEAD="Live Update is not supported on this server" +; LIVEUPDATE_NOTSUPPORTED_INFO="Your server indicates that Live Update is not supported. Please contact your host and ask them to enable the cURL PHP extension or activate the URL fopen() wrappers. If these are already enabled, please ask them to configure their firewall so that it allows access to the following URL:" +; LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="You can always update %s by visiting our site manually, downloading the latest release and installing it using Joomla!'s extension installer." + +; LIVEUPDATE_STUCK_HEAD="Live Update has marked itself as crashed" +; LIVEUPDATE_STUCK_INFO="Live Update determined that it crashed the last time it tried to contact the update server. This usually indicates a host which actively blocks communications with external sites. If you would like to retry fetching the update information, please click the "_QQ_"Refresh update information"_QQ_" button below. If that results to a blank page, please contact your host and report this issue." + +; LIVEUPDATE_ERROR_NEEDSAUTH="You have to supply your username/password or Download ID to the component's parameters before trying to upgrade to the latest release. The upgrade button will remain disabled until you do that." +; LIVEUPDATE_HASUPDATES_HEAD="A new version is available" +; LIVEUPDATE_NOUPDATES_HEAD="You already have the latest version" +; LIVEUPDATE_CURRENTVERSION="Installed version" +; LIVEUPDATE_LATESTVERSION="Latest version" +; LIVEUPDATE_LATESTRELEASED="Latest release date" +; LIVEUPDATE_DOWNLOADURL="Direct download URL" + +; LIVEUPDATE_REFRESH_INFO="Refresh update information" +; LIVEUPDATE_DO_UPDATE="Update to the latest version" + +; LIVEUPDATE_FTP_REQUIRED="Live Update determined that it needs to use FTP in order to download and install your update, but you have not saved your FTP login information in your Joomla! Global Configuration.

Please provide the FTP username and password below to proceed with the update." +; LIVEUPDATE_FTP="FTP Information" +; LIVEUPDATE_FTPUSERNAME="FTP Username" +; LIVEUPDATE_FTPPASSWORD="FTP Password" +; LIVEUPDATE_DOWNLOAD_AND_INSTALL="Download and install update" + +; LIVEUPDATE_DOWNLOAD_FAILED="Downloading the update package failed. Make sure that your temp-directory is writable or that you have enabled Joomla!'s FTP options in your site's Global Configuration." +; LIVEUPDATE_EXTRACT_FAILED="Extracting the update package failed. Please try updating the extension manually." + +; LIVEUPDATE_INVALID_PACKAGE_TYPE="Invalid package type. The update can not proceed." +; LIVEUPDATE_INSTALLEXT="Install %s %s" +; LIVEUPDATE_ERROR="Error" +; LIVEUPDATE_SUCCESS="Success" + +; LIVEUPDATE_ICON_UNSUPPORTED="Live Update not supported" +; LIVEUPDATE_ICON_CRASHED="Live Update crashed" +; LIVEUPDATE_ICON_CURRENT="You have the latest version" +; LIVEUPDATE_ICON_UPDATES="UPDATE FOUND! CLICK TO UPDATE." + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/fa-IR/fa-IR.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/fa-IR/fa-IR.liveupdate.ini new file mode 100644 index 00000000..7a897c84 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/fa-IR/fa-IR.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="به روز رسانی آنلاین" + +LIVEUPDATE_NOTSUPPORTED_HEAD="به روز رسانی آنلاین در این سرور پشتیبانی نمی شود" +LIVEUPDATE_NOTSUPPORTED_INFO="سرور شما نشان می دهد که به روز رسانی آنلاین پشتیبانی نمی شود. لطفا با میزبان خود تماس بگیرید و از آن ها بخواهید که افزونه cURL یا URL fopen() wrapper را در PHP فعال نمایند. اگر این در حال حاضر فعال است، لطفا از آن ها بخواهید که پیکربندی فایروال خود را به طوری که اجازه دسترسی به این آدرس را بدهد تنظیم نمایند:" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="شما همچنین می توانید با مراجعه به سایت ما و دانلود آخرین نسخه و نصب آن از طریق نصب کننده جوملا اقدام به به روز رسانی %s نمایید." + +LIVEUPDATE_STUCK_HEAD="به روز رسانی آنلاین با مشکل مواجه شد." +LIVEUPDATE_STUCK_INFO="به روز رسانی آنلاین در آخرین باری که تلاش برای ارتباط با سرور به روز رسانی نموده است، با مشکل مواجه شد. این معمولا در مورد میزبان هایی به وجود می آید که ارتباط با سایت های دیگر را مسدود می نمایند. در صورتی که می خواهید اطلاعات به روز رسانی را مجددا دریافت نمایید، روی دکمه "_QQ_"بازیابی مجدد اطلاعات به روز رسانی"_QQ_" در زیر کلیک نمایید. در صورتی که با صفحه ی خالی مواجه شدید، با میزبان خود تماس حاصل نموده و مشکل را گزارش دهید." + +LIVEUPDATE_ERROR_NEEDSAUTH="شما می بایستی نام کاربری/رمز عبور یا شناسه دانلود خود را قبل از تلاش برای به روز رسانی به نسخه نهایی در تنظیمات کامپوننت وارد نمایید. دکمه به روز رسانی تا وقتی که شما این کار را انجام دهید غیرفعال خواهد ماند." +LIVEUPDATE_HASUPDATES_HEAD="نسخه جدیدی موجود می باشد" +LIVEUPDATE_NOUPDATES_HEAD="نسخه شما به روز می باشد" +LIVEUPDATE_CURRENTVERSION="نسخه نصب شده" +LIVEUPDATE_LATESTVERSION="آخرین نسخه" +LIVEUPDATE_LATESTRELEASED="تاریخ آخرین نسخه" +LIVEUPDATE_DOWNLOADURL="آدرس دانلود مستقیم" + +LIVEUPDATE_REFRESH_INFO="بارگزاری مجدد اطلاعات به روز رسانی" +LIVEUPDATE_DO_UPDATE="به روز رسانی به آخرین نسخه" + +LIVEUPDATE_FTP_REQUIRED="به روز رسانی آنلاین تشخیص داده است که شما برای دانلود و نصب به روز رسانی، می بایستی از FTP استفاده نمایید، ولی شما اطلاعات ورود FTP را در تنظیمات سراسری جوملا وارد نکرده اید.

لطفا نام کاربری و رمز عبور FTP را جهت اجرای عملیات به روز رسانی در قسمت های زیر وارد نمایید." +LIVEUPDATE_FTP="اطلاعات FTP" +LIVEUPDATE_FTPUSERNAME="نام کاربری FTP" +LIVEUPDATE_FTPPASSWORD="رمز عبور FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="دانلود و نصب به روز رسانی" + +LIVEUPDATE_DOWNLOAD_FAILED="دانلود فایل به روز رسانی با شکست مواجه شد. جهت رفع این مشکل بررسی نمایید که پوشه موقت سایتتان (temp) قابل نوشتن بوده و یا تنظیمات FTP جوملا را در تنظیمات سراسری سایت فعال کرده باشید." +LIVEUPDATE_EXTRACT_FAILED="استخراج فایل به روز رسانی از حالت فشرده با شکست مواجه شد. لطفا افزونه را به طور دستی به روز رسانی نمایید." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="نوع فایل نامعتبر می باشد. عملیات به روز رسانی قابل اجرا نمی باشد." +LIVEUPDATE_INSTALLEXT="نصب %s %s" +LIVEUPDATE_ERROR="خطا" +LIVEUPDATE_SUCCESS="انجام شد" + +LIVEUPDATE_ICON_UNSUPPORTED="به روز رسانی آنلاین پشتیبانی نمی شود" +LIVEUPDATE_ICON_CRASHED="به روز رسانی آنلاین به خطا مواجه شد" +LIVEUPDATE_ICON_CURRENT="نسخه شما به روز می باشد" +LIVEUPDATE_ICON_UPDATES="به روز رسانی جدیدی یافت شد! جهت به روز رسانی کلیک نمایید." + +LIVEUPDATE_RELEASEINFO="اطلاعات" +LIVEUPDATE_RELEASENOTES="اطلاعات نسخه" +LIVEUPDATE_READMOREINFO="مطالعه بیشتر" + +LIVEUPDATE_NAGSCREEN_HEAD="اخطار! شما در حال نصب نسخه ای ناپایدار هستید." +LIVEUPDATE_NAGSCREEN_BODY="شما در حال نصب نسخه ای ناپایدار هستید (%s - %s). نسخه های ناپایدار ممکن است تحت آزمایش کم و یا هیچ بوده باشند و عوارض جانبی جدی برای پایداری سایت شما داشته باشند. در صورتی که اطلاعاتی در این مورد ندارید، لطفا این صفحه را ببندید. و در صورتی که از ریسک این موضوع مطلع هستید و می خواهید ادامه دهید، روی دکمه زیر جهت ادامه نصب این نسخه ناپایدار کلیک نمایید." +LIVEUPDATE_NAGSCREEN_BUTTON="از خطرات این عمل آگاه هستم. عملیات نصب را ادامه بده." + +LIVEUPDATE_STABILITY_ALPHA="آلفا" +LIVEUPDATE_STABILITY_BETA="بتا" +LIVEUPDATE_STABILITY_RC="کاندید" +LIVEUPDATE_STABILITY_STABLE="پایدار" +LIVEUPDATE_STABILITY_SVN="svn" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/fi-FI/fi-FI.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/fi-FI/fi-FI.liveupdate.ini new file mode 100644 index 00000000..67f08a1f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/fi-FI/fi-FI.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Live Update" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Live Update ei ole tuettu tällä palvelimella" +LIVEUPDATE_NOTSUPPORTED_INFO="Palvelimesi mukaan Live Update ei ole tuettu. Ota yhteyttä palveluntarjoajaasi ja pyydä heitä ottamaan cURL PHP laajennus tai URL fopen() lisätoiminnot käyttöön. Jos nämä ovat jo käytössä, pyydä heitä muuttamaan palomuurinsa asetuksia niin, että se sallii yhteydet seuraavaan osoitteeseen:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Voit aina päivittää %s lisäosan käymällä sivustollamme, lataamalla viimeisimmän version ja asentamalla sen Joomla! lisäosien asennuksella." + +LIVEUPDATE_STUCK_HEAD="Live Update on havainnut kaatuneensa" +LIVEUPDATE_STUCK_INFO="Live Update on havainnut, että se kaatui edellisellä kerralla päivitystä hakiessaan. Yleensä tämä johtuu palvelimestä, joka pyrkii estämään yhteydet muille palvelimille. Jos haluat yrittää päivitystietojen hakemista uudelleen, napsauta "_QQ_"Päivitä päivitystiedot"_QQ_" painiketta. Jos tästä seuraa tyhjä sivu, ota yhteyttä palveluntarjoajaasi ja ilmoita ongelmasta." + +LIVEUPDATE_ERROR_NEEDSAUTH="Sinun täytyy syöttää pyydetty käyttäjätunniste komponentin asetuksissa ennenkuin voit päivittää viimeisimpään versioon. Päivityspainike pysyy estettynä siihen asti." +LIVEUPDATE_HASUPDATES_HEAD="Uusi versio on saatavilla" +LIVEUPDATE_NOUPDATES_HEAD="Sinulla on jo uusin versio" +LIVEUPDATE_CURRENTVERSION="Asennettu versio" +LIVEUPDATE_LATESTVERSION="Uusin versio" +LIVEUPDATE_LATESTRELEASED="Uusimman julkaisupäivä" +LIVEUPDATE_DOWNLOADURL="Suora latauslinkki" + +LIVEUPDATE_REFRESH_INFO="Päivitä päivitystiedot" +LIVEUPDATE_DO_UPDATE="Päivitä uusimpaan versioon" + +LIVEUPDATE_FTP_REQUIRED="Live Update havaitsi, että se tarvitsee FTP yhteyden ladatakseen päivityksesi, mutta FTP tietoja ei ole asetettu Joomla! asetuksissa.

Syötä FTP tunnus ja salasana päivittääksesi." +LIVEUPDATE_FTP="FTP tiedot" +LIVEUPDATE_FTPUSERNAME="FTP käyttäjänimi" +LIVEUPDATE_FTPPASSWORD="FTP salasana" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Lataa ja asenna päivitys" + +LIVEUPDATE_DOWNLOAD_FAILED="Päivityspaketin lataaminen epäonnistui. Varmista, että temp-kansioom voi kirjoittaa tai Joomla! FTP toiminnot on sallittu sivuston asetuksissa." +LIVEUPDATE_EXTRACT_FAILED="Päivityspaketin purkaminen epäonnistui. Yritä päivittää lisäosa manuaalisesti." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Paketin tyyppi ei kelpaa. Päivitystä ei voida tehdä." +LIVEUPDATE_INSTALLEXT="Asenna %s %s" +LIVEUPDATE_ERROR="Virhe" +LIVEUPDATE_SUCCESS="Onnistui" + +LIVEUPDATE_ICON_UNSUPPORTED="Live Update ei tuettu" +LIVEUPDATE_ICON_CRASHED="Live Update kaatui" +LIVEUPDATE_ICON_CURRENT="Sinulla on uusin versio" +LIVEUPDATE_ICON_UPDATES="Päivitys löydetty! Napsauta päivittääksesi." + +LIVEUPDATE_RELEASEINFO="Tietoja" +LIVEUPDATE_RELEASENOTES="Julkaisutiedot" +LIVEUPDATE_READMOREINFO="Lue lisää" + +LIVEUPDATE_NAGSCREEN_HEAD="Varoitus. Olet asentamassa mahdollisesti epävakaata versiota." +LIVEUPDATE_NAGSCREEN_BODY="Olet asentamassa epävakaata versiota (%s - %s). Epävakaita versiota ei ole testattu riittävästi ja ne voivat sisältää ohjelmointivirheitä jotka voivat vahingoittaa sivustosi vakautta ja toimintaa. Jos et ole varma siitä mitä olet tekemässä, sulje tämä selain ikkuna. Jos olet aivan varma, että ymmärrät epävakaiden versioiden asentamiseen liittyvät riskit, napsauta alla olevaa painiketta jatkaaksesi asennusta." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +LIVEUPDATE_STABILITY_ALPHA="Alpha" +LIVEUPDATE_STABILITY_BETA="Beta" +LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/fr-FR/fr-FR.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/fr-FR/fr-FR.liveupdate.ini new file mode 100644 index 00000000..00333d4d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/fr-FR/fr-FR.liveupdate.ini @@ -0,0 +1,79 @@ +; Akeeba Live Update +; Copyright (c)2010-2012 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later +; +; ADMIN [com_icagenda/liveupdate] : liveupdate.ini +; Translation on Transifex : https://www.transifex.com/projects/p/icagenda/ +; iCagenda Version : Copyright (c) 2013 JoomliC.com + + +LIVEUPDATE_TASK_OVERVIEW="Live Update" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Live Update n'est pas pris en charge sur ce serveur" +LIVEUPDATE_NOTSUPPORTED_INFO="Votre serveur indique que Live Update n'est pas supporté. Veuillez contactez votre hébergeur et lui demander d'activer l'extension PHP cURL ou activer la fonction fopen URL (). Si ceux-ci sont déjà activés, veuillez lui demander d'adapter le pare-feu pour qu'il autorise l'accès à l'URL suivante:"; +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Vous pouvez toujours mettre à jour %s à partir de notre site internet, après avoir télécharger la dernière version et effectuer son installation via la gestion des extensions de Joomla!" + +LIVEUPDATE_STUCK_HEAD="Live Update a échoué !" +LIVEUPDATE_STUCK_INFO="Live Update a échoué la dernière fois qu'il a essayé de se connecter au serveur de mise à jour. Cela signifie généralement que votre hébergeur bloque activement les communications avec des sites externes. Si vous souhaitez réessayer de récupérer les informations de mise à jour, cliquez sur le bouton " Rafraichir les informations de mise à jour ". S'il en résulte une page blanche, veuillez contactez votre hébergeur et lui signaler ce problème." + +LIVEUPDATE_ERROR_NEEDSAUTH="Pour activer le bouton de mise à jour, vous devez indiquer vos identifiant/mot de passe ou votre Download ID dans les paramètres du composant. Le bouton de mise à niveau restera désactivé jusqu'à ce que vous le faites." +LIVEUPDATE_HASUPDATES_HEAD="Une nouvelle version est disponible" +LIVEUPDATE_NOUPDATES_HEAD="Vous avez la dernière version" +LIVEUPDATE_CURRENTVERSION="Version installée" +LIVEUPDATE_LATESTVERSION="Dernière version" +LIVEUPDATE_LATESTRELEASED="Date de la dernière version " +LIVEUPDATE_DOWNLOADURL="URL de téléchargement direct" + +LIVEUPDATE_REFRESH_INFO="Rafraîchir les informations de mise à jour" +LIVEUPDATE_DO_UPDATE="Mettre à jour vers la dernière version" + +LIVEUPDATE_FTP_REQUIRED="Live Update a besoin d'utiliser la couche FTP pour télécharger et installer la mise à jour, mais vous n'avez pas sauvegardé vos informations de connexion FTP dans la 'Configuration' de Joomla!

Veuillez fournir ci-dessous votre nom d'utilisateur et votre mot de passe FTP afin de procéder à la mise à jour." +LIVEUPDATE_FTP="Informations FTP" +LIVEUPDATE_FTPUSERNAME="Nom d'utilisateur FTP" +LIVEUPDATE_FTPPASSWORD="Mot de passe FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Télécharger et installer la mise à jour" + +LIVEUPDATE_DOWNLOAD_FAILED="Le téléchargement du package de mise à jour a échoué. Assurez-vous que votre répertoire temporaire (tmp) est accessible en écriture et que vous avez activé les options FTP dans la configuration globale de Joomla!." +LIVEUPDATE_EXTRACT_FAILED="L'extraction du package de mise à jour a échoué. Veuillez mettre à jour l'extension manuellement." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Le type du package n'est pas valide. La mise à jour ne peut pas être effectuée." +LIVEUPDATE_INSTALLEXT="Installation %s %s" +LIVEUPDATE_ERROR="Erreur" +LIVEUPDATE_SUCCESS="effectuée avec succès" + +; Added iCagenda +LIVEUPDATE_INSTALL_ERROR="Erreur à l'installation %s" +LIVEUPDATE_INSTALL_SUCCESS="Installation %s effectuée avec succès." +LIVEUPDATE_INSTALL_TYPE_COMPONENT="du composant iCagenda" +LIVEUPDATE_INSTALL_TYPE_FILE="du fichier" +LIVEUPDATE_INSTALL_TYPE_LANGUAGE="de la langue" +LIVEUPDATE_INSTALL_TYPE_LIBRARY="de la bibliothèque" +LIVEUPDATE_INSTALL_TYPE_MODULE="du module" +LIVEUPDATE_INSTALL_TYPE_PACKAGE="du paquet" +LIVEUPDATE_INSTALL_TYPE_PLUGIN="du plug-in" +LIVEUPDATE_INSTALL_TYPE_TEMPLATE="du template" + +LIVEUPDATE_ICON_UNSUPPORTED="Live Update n'est pas pris en charge" +LIVEUPDATE_ICON_CRASHED="Live Update a échoué!" +LIVEUPDATE_ICON_CURRENT="Vous avez la dernière version" +LIVEUPDATE_ICON_UPDATES="Mise à jour disponible! Cliquez pour mettre à jour." + +LIVEUPDATE_RELEASEINFO="Informations" +LIVEUPDATE_RELEASENOTES="Notes de version" +LIVEUPDATE_READMOREINFO="Plus d'infos" + +LIVEUPDATE_NAGSCREEN_HEAD="ATTENTION! Vous êtes sur le point d'installer une version instable." +LIVEUPDATE_NAGSCREEN_BODY="Vous êtes sur le point d'installer une version dite instable (%s - %s). Les versions instables sont des versions ayant subi peu de tests, voir aucun, et qui peuvent contenir des bugs avec une conséquence importante sur la stabilité et la fonctionnalité de votre site internet. Si vous n'êtes pas sûr de ce que vous êtes sur le point de faire, merci de fermer cette fenêtre et de revenir en arrière. Si vous comprenez parfaitement les risques liés à l'utilisation d'une version instable, vous pouvez cliquer sur le bouton ci-dessous pour continuer l'installation de cette version." +LIVEUPDATE_NAGSCREEN_BUTTON="Je comprends les risques. Poursuivre l'installation." + +LIVEUPDATE_STABILITY_ALPHA="Alpha" +LIVEUPDATE_STABILITY_BETA="Bêta" +LIVEUPDATE_STABILITY_RC="RC" +LIVEUPDATE_STABILITY_STABLE="Stable" + +; Added iCagenda +LIVEUPDATE_ERROR_NEEDS_PRO_ID="Pour activer le bouton de mise à jour, vous devez indiquer dans les paramètres d'iCagenda votre licence Pro ID de mise à jour." +LIVEUPDATE_NAGSCREEN_HEAD_ICAGENDA = "ATTENTION! Vous êtes sur le point d'installer une version beta-test d'iCagenda." +LIVEUPDATE_NAGSCREEN_VERSION_ICAGENDA = "Version de test et de développement(iCagenda %s - %s)." +LIVEUPDATE_NAGSCREEN_BODY_ICAGENDA = "Le cycle de vie d'une version d'un logiciel est la somme des phases de développement, de tests et de maturité.
Alpha :peut être instable et peut causer des accidents ou des pertes de données.
Beta :a généralement plus de bugs que le logiciel terminée, cette version est destinée aux sites de tests uniquement.
RC (Release Candidate) : version bêta avec le potentiel pour être un produit final, qui est prête à être libérée à moins que des bugs importants émergent.
Si vous n'êtes pas sûr de ce que vous êtes sur le point de faire, merci de fermer cette fenêtre et de revenir en arrière. Si vous êtes absolument certain que vous comprenez les risques liés à l'installation des versions instables, vous pouvez cliquer sur le bouton ci-dessous pour continuer l'installation de cette version.
" +LIVEUPDATE_NAGSCREEN_FOOTER_ICAGENDA = "info:" diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/hu-HU/hu-HU.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/hu-HU/hu-HU.liveupdate.ini new file mode 100644 index 00000000..9cdf7f80 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/hu-HU/hu-HU.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Live Update" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Ez a szerver nem támogatja a Live Update-ot" +LIVEUPDATE_NOTSUPPORTED_INFO="A szerver nem támogatja a Live Update-et. Lépj kapcsolatba a szolgáltatóddal és kérd a cURL PHP bővítmény vagy az URL fopen() aktiválását. Ha ezek már engedélyezve vannak, akkor kérd meg őket, hogy úgy állítsák be a tűzfalukat, hogy hozzáférhető legyen a következő URL:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Bármikor frissítheted a(z) %s úgy, hogy meglátogatod a webhelyünket, letöltöd a legfrissebb verziót és a Joomla! bővítmény telepítőjével felrakod." + +LIVEUPDATE_STUCK_HEAD="A saját jelzése szerint a Live Update összeomlott" +LIVEUPDATE_STUCK_INFO="Az utolsó használat során a Live Update összeomlott amikor kapcsolatot próbált létesíteni a frissítő szerverrel. Ez általában azt jelzi, hogy a szolgáltató aktívan blokkolja a külső webhelyekkel való kommunikációt. Ha meg akarod ismételni a frissítési információk lekérését, akkor kattints alul a "_QQ_"Frissítési információk újra letöltése"_QQ_" gombra. Ha ez üres oldalt eredményez, akkor lépj kapcsolatba a szolgáltatóddal és jelezd nekik ezt a problémát" + +LIVEUPDATE_ERROR_NEEDSAUTH="Mielőtt frissíteni szeretnél, meg kell adnod a felhasználói neved/jelszavad vagy a letöltési AZ-t a komponens paraméterekben. A frissítés gomb addig nem lesz aktív, amíg ezeket nem adod meg." +LIVEUPDATE_HASUPDATES_HEAD="Elérhető az új verzió" +LIVEUPDATE_NOUPDATES_HEAD="Már a legújabb verzióval rendelkezel" +LIVEUPDATE_CURRENTVERSION="Telepített verzió" +LIVEUPDATE_LATESTVERSION="Legújabb verzió" +LIVEUPDATE_LATESTRELEASED="A legújabb verzió kiadási időpontja" +LIVEUPDATE_DOWNLOADURL="Direkt letöltési URL" + +LIVEUPDATE_REFRESH_INFO="Frissítési információk újratöltése" +LIVEUPDATE_DO_UPDATE="Frissítés a legújabb verzióra" + +LIVEUPDATE_FTP_REQUIRED="A Live Update-nek szüksége van az FTP használatára, hogy le tudja tölteni és feltelepíteni a frissítést, de te nem adtál meg FTP elérési adatokat a Joomla! globális beállításaiban.

Kérjük, hogy add meg az FTP felhasználói nevet és jelszót, hogy folytatni lehessen a frissítést." +LIVEUPDATE_FTP="FTP információk" +LIVEUPDATE_FTPUSERNAME="FTP felhasználói név" +LIVEUPDATE_FTPPASSWORD="FTP jelszó" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="A frissítés letöltése és telepítése" + +LIVEUPDATE_DOWNLOAD_FAILED="A frissítési csomag letöltése sikertelen. Ellenőrizd az átmeneti (temp) könyvtár írhatóságát vagy a globális beállításoknál engedélyezd a Joomla! FTP feltöltést." +LIVEUPDATE_EXTRACT_FAILED="A frissítési csomag kitömörítése sikertelen. Kérjük, hogy a frissítést próbáld meg manuális módban." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Hibás csomagtípus. A frissítés nem folytatható." +LIVEUPDATE_INSTALLEXT="Telepítés %s %s" +LIVEUPDATE_ERROR="Hiba" +LIVEUPDATE_SUCCESS="Sikeres" + +LIVEUPDATE_ICON_UNSUPPORTED="A Live Update nem támogatott" +LIVEUPDATE_ICON_CRASHED="A Live Update összeomlott" +LIVEUPDATE_ICON_CURRENT="A legfrissebb verzióval rendelkezel" +LIVEUPDATE_ICON_UPDATES="FRISSÍTÉST TALÁLTAM! KATTINTS IDE." + +LIVEUPDATE_RELEASEINFO="Információk" +LIVEUPDATE_RELEASENOTES="Kiadási megjegyzések" +LIVEUPDATE_READMOREINFO="Bővebben" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/it-IT/it-IT.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/it-IT/it-IT.liveupdate.ini new file mode 100644 index 00000000..a1bea52a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/it-IT/it-IT.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Live Update" + +LIVEUPDATE_NOTSUPPORTED_HEAD="La funzionalità di Live Update non è supportata su questo server" +LIVEUPDATE_NOTSUPPORTED_INFO="Il vostro server indica che la funzionalità di Live Update non è supportata. Contattate il fornitore e chiedete di abilitare l'estensione PHP cURL oppure attivare le funzionalità di URL fopen(). Se queste opzioni sono già attive, fate verificare la configurazione del firewall per permettere l'accesso al seguente URL:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="E' sempre possibile aggiornare %s visitando il nostro sito, scaricando l'ultima versione disponibile ed installandola in Joomla usando i normali comando di installazione delle estensioni." + +LIVEUPDATE_STUCK_HEAD="Live Update ha rilevato un precedente crash" +LIVEUPDATE_STUCK_INFO="Live Update ha determinato che, nell'ultimo tentativo di contattare il server di aggiornamento, l'operazione è fallita con un crash. Generalmente questo indica la presenza di un servizio che blocca la comunicazione con siti esterni. Se volete riprovare a recuperare le informazioni di aggiornamento utilizzate il pulsante "_QQ_"Verifica disponibilità aggiornamenti"_QQ_" più sotto. Se il risultato è una pagina vuota, contattate il vostro fornitore per segnalare il problema." + +LIVEUPDATE_ERROR_NEEDSAUTH="E' necessario inserire Username e Password oppure il proprio Download ID tra i parametri di configurazione del componente prima di tentare l'aggiornamento all'ultima versione. Il pulsante di aggiornamento sarà attivato solamente dopo l'inserimento di tali informazioni." +LIVEUPDATE_HASUPDATES_HEAD="E' disponibile una nuova versione" +LIVEUPDATE_NOUPDATES_HEAD="Non sono disponibili nuovi aggiornamenti" +LIVEUPDATE_CURRENTVERSION="Versione installata" +LIVEUPDATE_LATESTVERSION="Ultima versione" +LIVEUPDATE_LATESTRELEASED="Data rilascio ultima versione" +LIVEUPDATE_DOWNLOADURL="URL di scaricamento diretto" + +LIVEUPDATE_REFRESH_INFO="Verifica disponibilità aggiornamenti" +LIVEUPDATE_DO_UPDATE="Aggiorna all'ultima versione" + +LIVEUPDATE_FTP_REQUIRED="Live Update ha determinato che è necessario l'utilizzo di FTP per scaricamente ed installare l'aggiornamento, tuttavia non sono state impostate correttamente le informazioni di configurazione in Joomla. Inserite qui sotto Username e Password per il servizio FTP per proseguire con l'aggiornamento." +LIVEUPDATE_FTP="Informazioni FTP" +LIVEUPDATE_FTPUSERNAME="Username FTP" +LIVEUPDATE_FTPPASSWORD="Password FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Scarica ed installa aggiornamento" + +LIVEUPDATE_DOWNLOAD_FAILED="Lo scaricamento dell'aggiornamento è fallito. Verificate che la cartella temporanea sia scrivibile e che siano abilitate le opzioni FTP di Joomla all'interno della sezione di Configurazione Globale del sito." +LIVEUPDATE_EXTRACT_FAILED="L'estrazione del pacchetto di aggiornamento è fallita. Sarà necessario effettuare l'aggiornamento tramite procedura manuale." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Formato del pacchetto di aggiornamento non riconosciuto. L'aggiornamento non può essere effettuato." +LIVEUPDATE_INSTALLEXT="Installazione %s %s" +LIVEUPDATE_ERROR="Errore" +LIVEUPDATE_SUCCESS="Completato" + +LIVEUPDATE_ICON_UNSUPPORTED="Live Update non supportato" +LIVEUPDATE_ICON_CRASHED="Live Update non funziona correttamente" +LIVEUPDATE_ICON_CURRENT="Non sono disponibili nuovi aggiornamenti" +LIVEUPDATE_ICON_UPDATES="INSTALLA NUOVO AGGIORNAMENTO!" + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/lt-LT/lt-LT.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/lt-LT/lt-LT.liveupdate.ini new file mode 100644 index 00000000..9d45fa94 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/lt-LT/lt-LT.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Automatinis atnaujinimas" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Šiame serveryje automatinis atnaujinimas negalimas" +LIVEUPDATE_NOTSUPPORTED_INFO="Jūsų serveris rodo, kad automatinis atnaujinimas yra negalimas. Prašome susisiekti su savo tinklapio talpintojais ir paprašyti įgalinti cURL PHP plėtinį arba aktyvuoti URL fopen(). Jei šie plėtiniai jau yra įgalinti, paprašykite jų sukonfigūruoti savo ugniasienę taip, kad ji leistų prieigą prie šios URL:" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Jūs visada galite atnaujinti %s rankiniu būdu, aplankydami mūsų tinklapį, parsisiųsdami naujausią programos laidą ir įdiegdami standartiniu Joomla! Būdu." + +LIVEUPDATE_STUCK_HEAD="Automatinis atnaujinimas nurodė, kad įvyko programinė klaida" +LIVEUPDATE_STUCK_INFO="Automatinis atnaujinimas nurodė, kad bandant susisiekti su atnaujinimų serveriu įvyko programinė klaida. Paprastai tai rodo, kad tinklapio talpintojas aktyviai blokuoja ryšius su išorinėmis svetainėmis. Jei norite pabandyti iš naujo parsisiųsti atnaujinimo informaciją, prašome spragtelėti žemiau esantį mygtuką "_QQ_"Atnaujinti informaciją"_QQ_". Jei parodomas tuščias puslapis, norint išspręsti šią problemą turėsite kreiptis į savo tinklapio talpintoją." + +LIVEUPDATE_ERROR_NEEDSAUTH="Norėdami atsinaujinti į naujausią programos versiją, turite nurodyti savo prisijungimo vardą/slaptažodį arba Parsisiuntimo ID komponento parametruose. Kol to nepadarysite, atnaujinimo mygtukas išliks neaktyvus." +LIVEUPDATE_HASUPDATES_HEAD="Yra nauja versija" +LIVEUPDATE_NOUPDATES_HEAD="Jūs turite naujausią programos versiją." +LIVEUPDATE_CURRENTVERSION="Įdiegta versija" +LIVEUPDATE_LATESTVERSION="Naujausia versija" +LIVEUPDATE_LATESTRELEASED="Naujausios versijos išleidimo data" +LIVEUPDATE_DOWNLOADURL="Tiesioginė parsisiuntimo nuoroda" + +LIVEUPDATE_REFRESH_INFO="Atnaujinti informaciją" +LIVEUPDATE_DO_UPDATE="Atnaujinti į naujausią versiją" + +LIVEUPDATE_FTP_REQUIRED="Automatinis atnaujinimas nustatė, kad norint atsisiųsti ir įdiegti atnaujinimą turi būti naudojamas FTP sluoksnis, tačiau Jūs nenurodėte savo FTP prisijungimo duomenų globaliose savo tinklapio Joomla! nuostatose.

Jei norite įdiegti naujinimą, nurodykite FTP prisijungimo duomenis." +LIVEUPDATE_FTP="FTP informacija" +LIVEUPDATE_FTPUSERNAME="FTP naudotojo vardas" +LIVEUPDATE_FTPPASSWORD="FTP slaptažodis" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Atsisiųsti ir įdiegti naujinimą" + +LIVEUPDATE_DOWNLOAD_FAILED="Nepavyko atsisiųsti atnaujinimo paketo. Įsitikinkite, kad į tinklapio laikinąjį aplanką leidžiama rašyti ir tai, kad Jūsų tinklapio globaliose Joomla! nuostatose įgalintas FTP naudojimas." +LIVEUPDATE_EXTRACT_FAILED="Nepavyko išpakuoti atnaujinimo paketo. Prašome bandyti atsinaujinti rankiniu būdu." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Neteisingas paketo tipas. Atnaujinimas negalimas" +LIVEUPDATE_INSTALLEXT="Įdiegti %s %s" +LIVEUPDATE_ERROR="Klaida" +LIVEUPDATE_SUCCESS="Pavyko" + +LIVEUPDATE_ICON_UNSUPPORTED="Automatinis atnaujinimas nepalaikomas" +LIVEUPDATE_ICON_CRASHED="Įvyko automatinio atnaujinimo programinis lūžis" +LIVEUPDATE_ICON_CURRENT="Jūs turite naujausią programos versiją." +LIVEUPDATE_ICON_UPDATES="GALIMAS ATNAUJINIMAS! NORĖDAMI ATSINAUJINTI SPRAGTELĖKITE ČIA" + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/nb-NO/nb-NO.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/nb-NO/nb-NO.liveupdate.ini new file mode 100644 index 00000000..192b5abe --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/nb-NO/nb-NO.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Direkteoppdatering" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Direkteoppdatering støttes ikke på denne serveren." +LIVEUPDATE_NOTSUPPORTED_INFO="Din server indikerer at direkteoppdatering ikke støttes. Kontakt din leverandør og spør om de kan aktivere cURL PHP eller aktivere URL fopen(). Dersom disse allerede er aktivert kan du spørre om de kan konfigurere sin brannmur slik at den gir tilgang til følgende URL:" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Du kan alltid oppdatere %s manuelt ved å besøke vår side. Laste ned og installer den nyeste versjonen ved hjelp av Joomlas installasjonsfunksjon." + +LIVEUPDATE_STUCK_HEAD="Direkteoppdateringen har merket seg selv som krasjet." +LIVEUPDATE_STUCK_INFO="Direkteoppdatering avdekket at den krasjet forrige gang den forsøkte å kontakte oppdateringsserveren. Dette betyr vanligvis at du benytter en leverandør av netthotell som aktivt blokkerer kommunikasjon med eksterne nettsteder. Hvis du ønsker å forsøke på nytt å hente oppdateringsinformasjonen, klikk på knappen "_QQ_"Oppdater informasjon"_QQ_" nedenfor. Dersom dette resulterer i en blank side bør du kontakte din leverandør av netthotell for å melde fra om dette problemet." + +LIVEUPDATE_ERROR_NEEDSAUTH="Du må oppgi ditt brukernavn/passord eller nedlastnings-id i komponentens innstillinger før du forsøker å oppdatere til siste versjon. Oppdateringsknappen vil forbli deaktivert inntil du gjøre dette." +LIVEUPDATE_HASUPDATES_HEAD="En ny versjon er tilgjengelig" +LIVEUPDATE_NOUPDATES_HEAD="Du har allerede den nyeste versjonen" +LIVEUPDATE_CURRENTVERSION="Installert versjon" +LIVEUPDATE_LATESTVERSION="Nyeste versjon" +LIVEUPDATE_LATESTRELEASED="Siste utgivelsesdato" +LIVEUPDATE_DOWNLOADURL="Nedlastingsadresse" + +LIVEUPDATE_REFRESH_INFO="Oppdater informasjon" +LIVEUPDATE_DO_UPDATE="Oppdater til siste versjon" + +LIVEUPDATE_FTP_REQUIRED="Direkteoppdatering har avdekket at den må bruke FTP, for å laste ned og installere oppdateringen, men du har ikke angitt og lagret FTP-informasjonen under nettstedets globale konfigurasjon .

Du må oppgi FTP-brukernavn og passord nedenfor for å kunne fortsette med oppdateringen." +LIVEUPDATE_FTP="FTP-informasjon" +LIVEUPDATE_FTPUSERNAME="FTP-brukernavn" +LIVEUPDATE_FTPPASSWORD="FTP-passord" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Last ned og installer oppdateringen" + +LIVEUPDATE_DOWNLOAD_FAILED="Nedlasting av oppdateringspakke mislyktes. Påse at temp-mappen er skrivbar, eller at du har aktivert Joomlas FTP-innstillinger under nettstedets globale konfigurasjon." +LIVEUPDATE_EXTRACT_FAILED="Utpakking av oppdateringspakken mislyktes. Forsøk å oppdatere utvidelsen manuelt." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Ugyldig pakketype. Oppdateringen kan ikke fortsette." +LIVEUPDATE_INSTALLEXT="Installer %s %s" +LIVEUPDATE_ERROR="Feil" +LIVEUPDATE_SUCCESS="Vellykket" + +LIVEUPDATE_ICON_UNSUPPORTED="Direkteoppdatering støttes ikke." +LIVEUPDATE_ICON_CRASHED="Direkteoppdatering krasjet." +LIVEUPDATE_ICON_CURRENT="Du har den nyeste versjonen." +LIVEUPDATE_ICON_UPDATES="OPPDATERING FUNNET! KLIKK FOR Å OPPDATERE." + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/nl-NL/nl-NL.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/nl-NL/nl-NL.liveupdate.ini new file mode 100644 index 00000000..881bd206 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/nl-NL/nl-NL.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Live Update" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Live Update wordt op deze server niet ondersteund" +LIVEUPDATE_NOTSUPPORTED_INFO="De server geeft aan dat Live Update niet wordt ondersteund. Neem contact op met de hoster en vraag de cURL PHP extensie of om de URL fopen() wrappers te activeren. Vraag, als ze al geactiveerd zijn, de firewall zo in te stellen dat er toegang tot de volgende URL is:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="U kunt %s altijd updaten door onze site te bezoeken, de laatste versie te downloaden en doormiddel van Joomla!'s extensiebeheer te installeren." + +LIVEUPDATE_STUCK_HEAD="Live Update is gecrasht" +LIVEUPDATE_STUCK_INFO="Live Update stelt vast dat het, de laatste keer dat het de update-server trachtte te bereiken, gecrasht is. Dit betekent meestal dat de host actief de communicatie met externe sites blokkeert. Klik, als u de update informatie opnieuw wilt ophalen, op de "_QQ_"Ververs update informatie"_QQ_" knop hieronder. Als dat leidt tot een blanco pagina, neem dan contact op met uw hoster en meld dit." + +LIVEUPDATE_ERROR_NEEDSAUTH="U moet uw gebruikersnaam / wachtwoord of download ID opgegeven in de parameters van de component om naar de laatste release te upgraden. De upgrade knop zal geblokkeerd blijven tot dit gedaan is." +LIVEUPDATE_HASUPDATES_HEAD="Er is een nieuwe versie beschikbaar" +LIVEUPDATE_NOUPDATES_HEAD="U heeft de laatste versie al" +LIVEUPDATE_CURRENTVERSION="Geïnstalleerde versie" +LIVEUPDATE_LATESTVERSION="Nieuwste versie" +LIVEUPDATE_LATESTRELEASED="Datum laatste release" +LIVEUPDATE_DOWNLOADURL="URL voor directe download" + +LIVEUPDATE_REFRESH_INFO="Ververs update-informatie" +LIVEUPDATE_DO_UPDATE="Update naar de laatste versie" + +LIVEUPDATE_FTP_REQUIRED="Live Update stelt vast dat het FTP moet gebruiken om de updates te downloaden en installeren, maar uw FTP logingegevens zijn bij de Joomla algemene instellingen niet opgeslagen.

Vul a.u.b. hieronder de FTP gebruikersnaam en het wachtwoord in om verder te gaan met updaten." +LIVEUPDATE_FTP="FTP informatie" +LIVEUPDATE_FTPUSERNAME="FTP gebruikersnaam" +LIVEUPDATE_FTPPASSWORD="FTP wachtwoord" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Download en installeer de update" + +LIVEUPDATE_DOWNLOAD_FAILED="Het downloaden van het updatepakket is mislukt. Zorg dat de temp map beschrijfbaar is of dat de FTP opties bij de algemene instellingen goed ingevuld zijn." +LIVEUPDATE_EXTRACT_FAILED="Uitpakken van het pakket mislukt. Probeer de extensie handmatig bij te werken." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Verkeerd pakkettype. Updaten kan niet verder gaan." +LIVEUPDATE_INSTALLEXT="Installeer %s %s" +LIVEUPDATE_ERROR="Fout" +LIVEUPDATE_SUCCESS="Succesvol" + +LIVEUPDATE_ICON_UNSUPPORTED="Live Update niet ondersteund" +LIVEUPDATE_ICON_CRASHED="Live Update gecrasht" +LIVEUPDATE_ICON_CURRENT="U heeft de laatste versie" +LIVEUPDATE_ICON_UPDATES="UPDATE GEVONDEN! KLIK OM TE UPDATEN." + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/pl-PL/pl-PL.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/pl-PL/pl-PL.liveupdate.ini new file mode 100644 index 00000000..63e4044d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/pl-PL/pl-PL.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Aktualizacja" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Aktualizacja nie jest obsługiwana na tym serwerze" +LIVEUPDATE_NOTSUPPORTED_INFO="Twój serwer sygnalizuje, że Aktualizacja nie jest obsługiwana. Proszę skontaktować się administratorem hosta i poprosić o włączenie rozszerzenia cURL PHP albo aktywowanie URL fopen() wrappers. Jeżeli te są już włączone, poproś o skonfigurowanie firewalla tak, by umożliwił dostęp do następującego adresu URL:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Zawsze można zaktualizować %s odwiedzając naszeą witrynę ręcznie, pobranie najnowszej wersji i instalacji za pomocą instalatora rozszerzeń Joomla!." + +LIVEUPDATE_STUCK_HEAD="Aktualizacja oznaczona jako niepowodzenie" +LIVEUPDATE_STUCK_INFO="Aktualizacja zaznacza o niepowodzeniu podczas ostatniej próby kontaktu z serwerem aktualizacji. To zwykle wskazuje na hosta, który aktywnie blokuje komunikacje z zewnętrznymi stronami. Jeśli chcesz ponowić próbę pobierania informacje o aktualizacji, kliknij przycisk "_QQ_"Odśwież informacje o aktualizacji"_QQ_" poniżej. Jeśli wynikiem jest pusta strona, proszę skontaktować się z administracją hosta i zgłosić ten problem." + +LIVEUPDATE_ERROR_NEEDSAUTH="Musisz podać swój login/hasło lub Download ID w parametrach komponentu przed próbą aktualizacji do najnowszej wersji. Przycisk aktualizacji pozostanie wyłączony do czasu aż to zrobisz." +LIVEUPDATE_HASUPDATES_HEAD="Nowa wersja jest dostępna" +LIVEUPDATE_NOUPDATES_HEAD="Masz już najnowszą wersję" +LIVEUPDATE_CURRENTVERSION="Zainstalowana wersja" +LIVEUPDATE_LATESTVERSION="Najnowsza wersja" +LIVEUPDATE_LATESTRELEASED="Data najnowszej wersji" +LIVEUPDATE_DOWNLOADURL="URL bezpośredniego pobierania" + +LIVEUPDATE_REFRESH_INFO="Odśwież informacje o aktualizacji" +LIVEUPDATE_DO_UPDATE="Aktualizacja do najnowszej wersji" + +LIVEUPDATE_FTP_REQUIRED="Aktualizacja zaznacza, że musi korzystać z protokołu FTP w celu pobrania i zainstalowania aktualizacji, ale nie zostały wcześniej zapisane dane logowania FTP w twojej Konfiguracji Globalnej Joomla!.

Prosimy o podanie nazwy użytkownika i hasła FTP poniżej, aby kontynuować aktualizację." +LIVEUPDATE_FTP="Informacje FTP" +LIVEUPDATE_FTPUSERNAME="Login FTP" +LIVEUPDATE_FTPPASSWORD="Hasło FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Pobierz i zainstaluj aktualizację" + +LIVEUPDATE_DOWNLOAD_FAILED="Pobranie pakietu aktualizacji nie powiodło się. Upewnij się, że katalog tymczasowy jest zapisywalny lub, że masz włączoną opcję FTP Joomla! w Konfiguracji Globalnej twojej witryny." +LIVEUPDATE_EXTRACT_FAILED="Rozpakowanie pakietu aktualizacji nie powiodło się. Proszę spróbować aktualizacji rozszerzenia ręcznie." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Nieprawidłowy typ pakietu. Aktualizacja nie może być kontynuowana." +LIVEUPDATE_INSTALLEXT="Instalacja %s %s" +LIVEUPDATE_ERROR="Błąd" +LIVEUPDATE_SUCCESS="Powodzenie" + +LIVEUPDATE_ICON_UNSUPPORTED="Aktualizacja nie jest obsługiwana" +LIVEUPDATE_ICON_CRASHED="Aktualizacja nie powiodła się" +LIVEUPDATE_ICON_CURRENT="Masz najnowszą wersję" +LIVEUPDATE_ICON_UPDATES="ZNALEZIONO AKTUALIZACJĘ! Kliknij!." + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/pt-BR/pt-BR.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/pt-BR/pt-BR.liveupdate.ini new file mode 100644 index 00000000..65c7564a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/pt-BR/pt-BR.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Actualização ao vivo" + +LIVEUPDATE_NOTSUPPORTED_HEAD="A atualização ao vivo não esta suportada neste servidor" +LIVEUPDATE_NOTSUPPORTED_INFO="O servidor indica que Atualização ao Vivo não é compatível. Entre em contato com seu Hosting e solicite que permitam a extensão cURL PHP ou desativem o URL fopen(). Se estão já desabilitadas, por favor, solicite que configurem seu firewall para que permita o acesso do seguinte endereço URL:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Sempre é possível atualizar %s, visite nosso site manualmente, baixe a última versão e instale usando o instalador de extensões Joomla!." + +LIVEUPDATE_STUCK_HEAD="Actualização ao Vivo marcou como se danificou" +LIVEUPDATE_STUCK_INFO="Live Update determinou que foi danificado a última vez que tratou de contatar com o servidor de atualizações. Isto d emodo geral indica uma série de bloqueios ativos de comunicação com sites externos. Se deseja voltar a tentar buscar a informação de atualização, por favor clique em 'Atualizar informação de atualização' no botão abaixo. Em caso de ontér uma página em branco como resultado, por favor contate com seu Hosting e informe sobre este tema." + +LIVEUPDATE_ERROR_NEEDSAUTH="Tem que facilitar seu nome de usuário/senha ou ID de download nos parâmetros do componente antes de tentar atualizar a última versão. O botão de atualização permanecerá desativado até que não realize esta ação." +LIVEUPDATE_HASUPDATES_HEAD="Existe uma versão nova disponível" +LIVEUPDATE_NOUPDATES_HEAD="Você já tem a última versão" +LIVEUPDATE_CURRENTVERSION="Versão instalada" +LIVEUPDATE_LATESTVERSION="Última versão" +LIVEUPDATE_LATESTRELEASED="Data do último lançamento" +LIVEUPDATE_DOWNLOADURL="URL de download direto" + +LIVEUPDATE_REFRESH_INFO="Refrescar a informação de atualização" +LIVEUPDATE_DO_UPDATE="Atualizar a última versão" + +LIVEUPDATE_FTP_REQUIRED="Live Update determina que é necessário o uso de FTP para baixar e instalar a atualização, mas não guardou sua informação de acesso FTP em seu site Joomla!, em Configuração Global.

Indique o nome de usuário FTP e senha para continuar com a atualização." +LIVEUPDATE_FTP="Informação FTP" +LIVEUPDATE_FTPUSERNAME="Usuário FTP" +LIVEUPDATE_FTPPASSWORD="Senha FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Baixar e instalar a atualização" + +LIVEUPDATE_DOWNLOAD_FAILED="O download do pacote de atualização falhou. Assegure-se que seu diretório /tmp pode escrever ou que habilitou as opções de FTP na Configuração Global do seu site Joomla!" +LIVEUPDATE_EXTRACT_FAILED="Falhou a descompressão do pacote de atualização. Por favor, tente atualizar a extensão manualmente." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Tipo de pacote não é válido. A atualização não pode continuar." +LIVEUPDATE_INSTALLEXT="Instale %s %s" +LIVEUPDATE_ERROR="Erro" +LIVEUPDATE_SUCCESS="Êxito" + +LIVEUPDATE_ICON_UNSUPPORTED="Atualização ao Vivo não suportadactualización en Vivo no soportada" +LIVEUPDATE_ICON_CRASHED="Atualização ao Vivo foi danificada" +LIVEUPDATE_ICON_CURRENT="Você tem a última versão" +LIVEUPDATE_ICON_UPDATES="ATUALIZAÇÃO ENCONTRADA! CLIQUE PARA ATUALIZAR." + +LIVEUPDATE_RELEASEINFO="Informações" +LIVEUPDATE_RELEASENOTES="Notas de lançamento" +LIVEUPDATE_READMOREINFO="Leia mais" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/pt-PT/pt-PT.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/pt-PT/pt-PT.liveupdate.ini new file mode 100644 index 00000000..5959d2d5 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/pt-PT/pt-PT.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Atualizações" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Atualizações diretas não são suportadas neste servidor" +LIVEUPDATE_NOTSUPPORTED_INFO="O seu servidor indica que a atualização direta não é suportada. Por favor contate o seu alojamento e peça-lhes para ativar a extensão cURL do PHP ou ativar a função fopen(). Se estas já estiverem ativadas, por favor peça-lhes para configurar o firewall para permitir o acesso à seguinte URL:" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Pode sempre atualizar pelo processo normal %s visita o nosso sítio, descarrega a última versão e instala pelo instalador de extensões do Joomla." + +LIVEUPDATE_STUCK_HEAD="O atualizador direto marcou-se a si mesmo como defeituoso" +LIVEUPDATE_STUCK_INFO="O atualizador direto indica que bloqueou na última vez que tentou entrar em contato com o servidor de atualização. Isso geralmente indica um alojamento que bloqueia ativamente as comunicações com sites externos. Se quiser tentar novamente obter as informações de atualização, por favor clique no botão ATUALIZAR INFORMAÇÕES DE ATUALIZAÇÃO. Se isto resultar numa página em branco, carrtegue no botão voltar e depois contate seu gestor de alojamento e relate este problema." + +LIVEUPDATE_ERROR_NEEDSAUTH="Deve indicar um nome de utilizador/senha ou Download ID para os parâmetros do componente antes de tentar fazer a atualização para a última versão. O botão de atualização continuará desativado até que faça isso." +LIVEUPDATE_HASUPDATES_HEAD="Está disponível uma nova versão" +LIVEUPDATE_NOUPDATES_HEAD="Existe uma nova versão disponível" +LIVEUPDATE_CURRENTVERSION="Versão instalada" +LIVEUPDATE_LATESTVERSION="Última versão" +LIVEUPDATE_LATESTRELEASED="Data da última versão" +LIVEUPDATE_DOWNLOADURL="URL de transferência direta" + +LIVEUPDATE_REFRESH_INFO="Atualizar as informações de atualização" +LIVEUPDATE_DO_UPDATE="Atualizar para versão mais recente" + +LIVEUPDATE_FTP_REQUIRED="O atualizador direto indica necessitar de utilizar o FTP para descarregar e instalar a sua atualização, mas você não indicou as suas informações de autenticação FTP na Configuração Global do Joomla!.

Por favor, indique abaixo o nome de utilizador e senha FTP para prosseguir com a atualização." +LIVEUPDATE_FTP="Informação de FTP" +LIVEUPDATE_FTPUSERNAME="Nome de utilizador FTP" +LIVEUPDATE_FTPPASSWORD="Senha FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Transferir e instalar atualização" + +LIVEUPDATE_DOWNLOAD_FAILED="A transferência do pacote de atualização falhou. Certifique-se de que a pasta TEMP é editável ou que ativou as opções de FTP do Joomla nas configurações globais de seu sítio." +LIVEUPDATE_EXTRACT_FAILED="A extração do pacote de atualização falhou. Por favor tente atualizar a extensão manualmente." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Tipo de pacote inválido. A atualização não pode continuar." +LIVEUPDATE_INSTALLEXT="Instalar %s %s" +LIVEUPDATE_ERROR="Erro" +LIVEUPDATE_SUCCESS="Sucesso" + +LIVEUPDATE_ICON_UNSUPPORTED="Atualização direta não suportada" +LIVEUPDATE_ICON_CRASHED="Atualização direta bloqueou" +LIVEUPDATE_ICON_CURRENT="Tem a versão mais recente" +LIVEUPDATE_ICON_UPDATES="ATUALIZAÇÃO ENCONTRADA! Clique para atualizar." + +LIVEUPDATE_RELEASEINFO="Informação" +LIVEUPDATE_RELEASENOTES="Notas da versão" +LIVEUPDATE_READMOREINFO="Ver mais" + +LIVEUPDATE_NAGSCREEN_HEAD="ATENÇÃO: Está prestes a instalar uma versão não estável!" +LIVEUPDATE_NAGSCREEN_BODY="Está prestes a instalar uma versão instável (%s - %s). Versões instáveis destinam-se a programadores avançados já que podem ​​podem ter sofrido testes mínimos ou mesmo nenhuns e conter falhas desconhecidas que podem ter um efeito adverso grave à estabilidade e funcionalidade do seu sítio. Se não tiver a certeza sobre o que está prestes a fazer, por favor, feche esta janela. Se estiver certo dos riscos envolvidos com a instalação de versões instáveis​​, então clique no botão abaixo para continuar a instalação desta versão instável." +LIVEUPDATE_NAGSCREEN_BUTTON="Compreendo os riscos. Continuar com a instalação." + +LIVEUPDATE_STABILITY_ALPHA="Alfa" +LIVEUPDATE_STABILITY_BETA="Beta" +LIVEUPDATE_STABILITY_RC="RC" +LIVEUPDATE_STABILITY_STABLE="Estável" +LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/ru-RU/ru-RU.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/ru-RU/ru-RU.liveupdate.ini new file mode 100644 index 00000000..8f35a41b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/ru-RU/ru-RU.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Автоматическое обновление" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Автоматическое обновление не поддерживается на этом сервере" +LIVEUPDATE_NOTSUPPORTED_INFO="Ваш сервер сообщает, что автоматическое обновление не поддерживается. Пожалуйста, обратитесь к Вашему хостеру и попросите его разрешить CURL расширение для PHP или включить функцию URL FOPEN(). Если они уже включены, пожалуйста, попросите его настроить их сетевой экран так, чтобы она позволяла получить доступ к следующему адресу:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Вы всегда сможете обновить %s посетив наш сайт, вручную, загрузив последнюю версию и установив ее с помощью Joomla!." + +LIVEUPDATE_STUCK_HEAD="Автоматическое обновление обнаружило ошибку" +LIVEUPDATE_STUCK_INFO="Автоматическое обновление обнаружило, что произошла ошибка при последнем сеансе связи с сервером обновлений. Обычно это означает, что хост блокирует связи с внешними сайтами. Если Вы желаете снова получить информацию об обновлении, пожалуйста, нажмите кнопку "_QQ_"Освежить информацию об обновлении"_QQ_" , расположенную ниже. Если это приводит к появлению пустой страницы, пожалуйста, свяжитесь с Вашим хостером и сообщите об этой проблеме." + +LIVEUPDATE_ERROR_NEEDSAUTH="Перед попыткой обновления до последней версии, Вы должны ввести Ваше имя пользователя/пароль или ID загрузки в параметры компонента. Кнопка обновления будет оставаться неактивной, пока Вы этого не сделаете." +LIVEUPDATE_HASUPDATES_HEAD="Доступна новая версия" +LIVEUPDATE_NOUPDATES_HEAD="У Вас уже установлена последняя версия" +LIVEUPDATE_CURRENTVERSION="Установленная версия" +LIVEUPDATE_LATESTVERSION="Последняя версия" +LIVEUPDATE_LATESTRELEASED="Дата выхода последней версии" +LIVEUPDATE_DOWNLOADURL="Ссылка для прямой загрузки" + +LIVEUPDATE_REFRESH_INFO="Освежить информацию об обновлении" +LIVEUPDATE_DO_UPDATE="Обновить до последней версии" + +LIVEUPDATE_FTP_REQUIRED="Автоматическое обновление определило, что необходимо использовать FTP для загрузки и установки обновления, но Вы не сохранили данные для авторизации на FTP в общих настройках Joomla!.

Просьба ввести свое имя пользователя и пароль FTP для продолжения обновления." +LIVEUPDATE_FTP="Информация FTP" +LIVEUPDATE_FTPUSERNAME="Имя пользователя FTP" +LIVEUPDATE_FTPPASSWORD="Пароль пользователя FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Загрузить и установить обновление" + +LIVEUPDATE_DOWNLOAD_FAILED="Загрузка пакета обновления не удалась. Убедитесь, что временный каталог доступен для записи или что Вы включили и настроили FTP в общих настройках Joomla!." +LIVEUPDATE_EXTRACT_FAILED="Извлечение пакета обновления не удалось. Пожалуйста, попробуйте обновить компонент вручную." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Неверный тип пакета. Обновление не может продолжаться." +LIVEUPDATE_INSTALLEXT="Установлено %s %s" +LIVEUPDATE_ERROR="Ошибка" +LIVEUPDATE_SUCCESS="Успешно" + +LIVEUPDATE_ICON_UNSUPPORTED="Автоматическое обновление не поддерживается" +LIVEUPDATE_ICON_CRASHED="Автоматическое обновление не удалось!" +LIVEUPDATE_ICON_CURRENT="У Вас последняя версия" +LIVEUPDATE_ICON_UPDATES="НАЙДЕНА НОВАЯ ВЕРСИЯ! НАЖМИТЕ ДЛЯ ОБНОВЛЕНИЯ." + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/sk-SK/sk-SK.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/sk-SK/sk-SK.liveupdate.ini new file mode 100644 index 00000000..cac25ab6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/sk-SK/sk-SK.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +; LIVEUPDATE_TASK_OVERVIEW="Live Update" + +; LIVEUPDATE_NOTSUPPORTED_HEAD="Live Update is not supported on this server" +; LIVEUPDATE_NOTSUPPORTED_INFO="Your server indicates that Live Update is not supported. Please contact your host and ask them to enable the cURL PHP extension or activate the URL fopen() wrappers. If these are already enabled, please ask them to configure their firewall so that it allows access to the following URL:" +; LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="You can always update %s by visiting our site manually, downloading the latest release and installing it using Joomla!'s extension installer." + +; LIVEUPDATE_STUCK_HEAD="Live Update has marked itself as crashed" +; LIVEUPDATE_STUCK_INFO="Live Update determined that it crashed the last time it tried to contact the update server. This usually indicates a host which actively blocks communications with external sites. If you would like to retry fetching the update information, please click the "_QQ_"Refresh update information"_QQ_" button below. If that results to a blank page, please contact your host and report this issue." + +; LIVEUPDATE_ERROR_NEEDSAUTH="You have to supply your username/password or Download ID to the component's parameters before trying to upgrade to the latest release. The upgrade button will remain disabled until you do that." +; LIVEUPDATE_HASUPDATES_HEAD="A new version is available" +; LIVEUPDATE_NOUPDATES_HEAD="You already have the latest version" +; LIVEUPDATE_CURRENTVERSION="Installed version" +; LIVEUPDATE_LATESTVERSION="Latest version" +; LIVEUPDATE_LATESTRELEASED="Latest release date" +; LIVEUPDATE_DOWNLOADURL="Direct download URL" + +; LIVEUPDATE_REFRESH_INFO="Refresh update information" +; LIVEUPDATE_DO_UPDATE="Update to the latest version" + +; LIVEUPDATE_FTP_REQUIRED="Live Update determined that it needs to use FTP in order to download and install your update, but you have not saved your FTP login information in your Joomla! Global Configuration.

Please provide the FTP username and password below to proceed with the update." +; LIVEUPDATE_FTP="FTP Information" +; LIVEUPDATE_FTPUSERNAME="FTP Username" +; LIVEUPDATE_FTPPASSWORD="FTP Password" +; LIVEUPDATE_DOWNLOAD_AND_INSTALL="Download and install update" + +; LIVEUPDATE_DOWNLOAD_FAILED="Downloading the update package failed. Make sure that your temp-directory is writable or that you have enabled Joomla!'s FTP options in your site's Global Configuration." +; LIVEUPDATE_EXTRACT_FAILED="Extracting the update package failed. Please try updating the extension manually." + +; LIVEUPDATE_INVALID_PACKAGE_TYPE="Invalid package type. The update can not proceed." +; LIVEUPDATE_INSTALLEXT="Install %s %s" +; LIVEUPDATE_ERROR="Error" +; LIVEUPDATE_SUCCESS="Success" + +; LIVEUPDATE_ICON_UNSUPPORTED="Live Update not supported" +; LIVEUPDATE_ICON_CRASHED="Live Update crashed" +; LIVEUPDATE_ICON_CURRENT="You have the latest version" +; LIVEUPDATE_ICON_UPDATES="UPDATE FOUND! CLICK TO UPDATE." + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/sl-SI/sl-SI.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/sl-SI/sl-SI.liveupdate.ini new file mode 100644 index 00000000..4e2d136e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/sl-SI/sl-SI.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Posodobljanje v živo" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Posodabljanje v živo ni podprto na tem strežniku" +LIVEUPDATE_NOTSUPPORTED_INFO="Vaš server ne podpira Live Posodobitev. Obrnite se na svojega gostitelja in ga prosite, da se omogoči razširitev CURL PHP ali aktivira URL fopen () ovoje. Če so ti že omogočeno, ga prosite, naj svoje požarni zid konfigurirate tako, da omogoča dostop do naslednjih URL:" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Vedno lahko posodobite %s tako, da obiščete našo spletno stran, ročno prenesete najnovejše sprostitve in jih namestite z Joomla! 's namestitev razširitve." + +LIVEUPDATE_STUCK_HEAD="Posodobitev v živo je označena kot spodletelo" +LIVEUPDATE_STUCK_INFO="Posodobitev v živo je določila, da se je zrušila v zadnjem času, ko je poskušala stopiti v stik strežnika za posodabljanje. To ponavadi pomeni, gostitelja, ki aktivno blokira komunikacijo z zunanjimi spletnimi stranmi. Če želite ponoviti ljubek posodabljanje informacij, prosimo, kliknite "_QQ_"Osvežite informacije posodabljanja"_QQ_" spodnji gumb. Če bo rezultat prazna stran, prosimo, obrnite se na gostitelja, in poročajte o tej zadevi." + +LIVEUPDATE_ERROR_NEEDSAUTH="Morate predloži svoje uporabniško ime / geslo ali ID Prenosa s parametri sestavnega dela, preden poskušate nadgraditi na najnovejšo različico. Gumb Nadgradnja bo ostal onemogočen." +LIVEUPDATE_HASUPDATES_HEAD="Nova različica je na voljo" +LIVEUPDATE_NOUPDATES_HEAD="Že imate zadnjo verzijo" +LIVEUPDATE_CURRENTVERSION="Nameščena različica" +LIVEUPDATE_LATESTVERSION="Zadnja različica" +LIVEUPDATE_LATESTRELEASED="Zadnji Datum izdaje" +LIVEUPDATE_DOWNLOADURL="Direktni prenos URL" + +LIVEUPDATE_REFRESH_INFO="Osveži informacij posodobitev" +LIVEUPDATE_DO_UPDATE="Posodobitev na najnovejšo različico" + +LIVEUPDATE_FTP_REQUIRED="Posodobitev v živo določa, da morate uporabiti FTP, da prenesete in namestite posodobitev, vendar niste shranili FTP podatke za prijavo v vaši Joomla! Globalne Konfiguracije.

Prosimo, za FTP uporabniško ime in geslo za nadaljevanje posodobitve." +LIVEUPDATE_FTP="FTP Informacije" +LIVEUPDATE_FTPUSERNAME="FTP Uporabniško ime" +LIVEUPDATE_FTPPASSWORD="FTP Geslo" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Prenesite in namestite posodobitev" + +LIVEUPDATE_DOWNLOAD_FAILED="Nalaganje posodobitvenega paketa ni uspela. Prepričajte se, da je vaš temp-imenik zapisljiv ali da ste omogočili Joomla! 'S FTP možnosti v vaše strani Globalne Konfiguracije." +LIVEUPDATE_EXTRACT_FAILED="Pridobivanja posodobitvenega paketa ni uspela. Poskusite posodabljanje razširitve ročno." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Neveljavna vrsta paketa.Posodobitev ne morem nadaljevati." +LIVEUPDATE_INSTALLEXT="Nameščeno %s %s" +LIVEUPDATE_ERROR="Napaka" +LIVEUPDATE_SUCCESS="Uspešno" + +LIVEUPDATE_ICON_UNSUPPORTED="Posodabljanje v živo ni podprto" +LIVEUPDATE_ICON_CRASHED="Posodabljanje v živo je spodletelo" +LIVEUPDATE_ICON_CURRENT="Imate najnovejšo različico" +LIVEUPDATE_ICON_UPDATES="POSODOBITEV NA VOLJO! KLIKNITE ZA POSODOBITEV." + +LIVEUPDATE_RELEASEINFO="Informacije" +LIVEUPDATE_RELEASENOTES="Opombe ob izdaji" +LIVEUPDATE_READMOREINFO="Preberite več" + +LIVEUPDATE_NAGSCREEN_HEAD="OPOZORILO! Ste pred tem namestiti nestabilno različico." +LIVEUPDATE_NAGSCREEN_BODY="Ste pred tem namestili nestabilno različico (%s - %s). Nestabilne različice so lahko opravili minimalno ali brez testiranja in vsebujejo napake, ki imajo lahko resno škodljivost za stabilnost in funkcionalnost vaše spletne strani. Če niste prepričani o tem, kaj si o tem narediti, zaprite to okno brskalnika. Če ste popolnoma prepričani, da razumete tveganja, povezana z namestitvijo nestabilnih izdaj, kliknite na spodnji gumb, da nadaljujte z namestitvijo te nestabilne izdaje." +LIVEUPDATE_NAGSCREEN_BUTTON="Razumem tveganja. Nadaljujte z namestitvijo." + +LIVEUPDATE_STABILITY_ALPHA="Alfa" +LIVEUPDATE_STABILITY_BETA="Beta" +LIVEUPDATE_STABILITY_RC="RC" +LIVEUPDATE_STABILITY_STABLE="Stabilna" +LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/sv-SE/sv-SE.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/sv-SE/sv-SE.liveupdate.ini new file mode 100644 index 00000000..cd903f80 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/sv-SE/sv-SE.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Live Update" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Live Update stöds inte på denna server" +LIVEUPDATE_NOTSUPPORTED_INFO="Din server indikerar att Live Update inte stöds. Kontakta ditt webbhotell och be dem aktivera PHP-tillägget cURL och att aktivera URL fopen() wrappers. Om detta redan är aktiverat skall du be dem konfiurera brandväggen så att den accepterar anslutningar från följande URL:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Du kan alltid uppdatera %s manuellt genom att vår webbplats och ladda ned senaste utgåvan och installera via Joomla som vanligt." + +LIVEUPDATE_STUCK_HEAD="Live Update har markerat sig själv som krashad" +LIVEUPDATE_STUCK_INFO="Live Update har indikerat att den kraschade förra gången den försökte kontakta uppdateringsservern. Detta händer vanligen om kommunikationen med externa webbplatser aktivt har blockerats. Om du vill fortsätta hämta uppdateringsinformation, klicka på knappen "_QQ_"Hämta uppdateringsinfo på nytt"_QQ_" här nedan. Om detta resluterar i en blank sida skall du kontakta ditt webbhotell och rapportera ärendet." + +LIVEUPDATE_ERROR_NEEDSAUTH="Du måste ange användarnamn/lösenord eller Nedladdnings-ID i komponentens Inställningar innan du försöker uppdatera till senaste version. Uppgraderingsknappen kommer att vara inaktiv till dess detta är gjort." +LIVEUPDATE_HASUPDATES_HEAD="Det finns en ny version tillgänglig" +LIVEUPDATE_NOUPDATES_HEAD="Du har den senatste versionen" +LIVEUPDATE_CURRENTVERSION="Installerad version" +LIVEUPDATE_LATESTVERSION="Senaste version" +LIVEUPDATE_LATESTRELEASED="Senaste utgåvodatum" +LIVEUPDATE_DOWNLOADURL="Direkt nedladdnings-URL" + +LIVEUPDATE_REFRESH_INFO="Hämta uppdateringsinformation" +LIVEUPDATE_DO_UPDATE="Uppdatera till senaste version" + +LIVEUPDATE_FTP_REQUIRED="Live Update har upptäckt att den behöver använda FTP för att kunna ladda ned och installera uppdateringen. Du har inte sparat din FTP-inloggningsinfo i Joomlas globala inställningar.

Ange ditt FTP användarnamn och lösenord nedan för att fortsätta med uppdateringen." +LIVEUPDATE_FTP="FTP-Information" +LIVEUPDATE_FTPUSERNAME="FTP användarnamn" +LIVEUPDATE_FTPPASSWORD="FTP Lösenord" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Ladda ned och installera uppdateringen" + +LIVEUPDATE_DOWNLOAD_FAILED="Nedladdningen av uppdateringen misslyckades. Kontrollera att temp-mappen är skrivbar och att du aktiverat Joomla!s FTP-lager i de globala inställningarna för din webbplats." +LIVEUPDATE_EXTRACT_FAILED="Uppackningen av uppdaterinspaketet misslyckades. Försök att uppdatera tillägget manuellt." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Ogiltig pakettyp. Uppdateringen kan inte fortsätta." +LIVEUPDATE_INSTALLEXT="Installera %s %s" +LIVEUPDATE_ERROR="FEL!" +LIVEUPDATE_SUCCESS="Klart" + +LIVEUPDATE_ICON_UNSUPPORTED="Live Update stöds inte" +LIVEUPDATE_ICON_CRASHED="Live Update krashade" +LIVEUPDATE_ICON_CURRENT="Du har den senaste versionen" +LIVEUPDATE_ICON_UPDATES="UPPDATERING HITTAD! KLICKA FÖR ATT UPPDATERA." + +LIVEUPDATE_RELEASEINFO="Information" +LIVEUPDATE_RELEASENOTES="Release notes" +LIVEUPDATE_READMOREINFO="Läs mer" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/tr-TR/tr-TR.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/tr-TR/tr-TR.liveupdate.ini new file mode 100644 index 00000000..0b97ffcd --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/tr-TR/tr-TR.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Canlı Güncelleme" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Canlı Güncelleme bu sunucu üzerinde desteklenmiyor" +LIVEUPDATE_NOTSUPPORTED_INFO="Sunucunuz Canlı Güncellemeyi desteklemiyor. Lütfen sunucu yöneticinizle görüşerek cURL PHP ekini ya da URL fopen() sarıcılarını etkinleştirmelerini isteyin. Bu ekler zaten etkinleştirilmişse, güvenlik duvarını şu İnternet adresine izin verecek şekilde ayarlamalarını isteyin:" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="%s güncellemelerini istediğiniz zaman el ile kurmak için, sitemizden en son sürümü indirip Joomla! bileşen kurucusu ile yükleyebilirsiniz." + +LIVEUPDATE_STUCK_HEAD="Canlı güncellemede bir sorun çıkmış" +LIVEUPDATE_STUCK_INFO="Canlı Güncelleme, güncelleme sunucusuna son kez bağlanmaya çalıştığında bir sorun çıkmış. Bu duruma genellikle dışarıdaki sunuculara yapılan bağlantıları engelleyen bir ayar yol açar. Güncelleme bilgisini yeniden almak isterseniz lütfen aşağıdaki "_QQ_"Güncelleme bilgisini alın"_QQ_" düğmesine tıklayın. Boş beyaz bir sayfa ile karşılaşırsanız bu durumu sunucu yöneticinize iletin." + +LIVEUPDATE_ERROR_NEEDSAUTH="Son sürüme güncellemeyi denemeden önce, bileşen ayarları bölümüne kullanıcı adınızı/parolanızı ya da indirme kodunuzu yazmalısınız. Bu bilgileri yazana kadar Güncelleyin düğmesi devre dışı kalır." +LIVEUPDATE_HASUPDATES_HEAD="Yeni bir sürüm var" +LIVEUPDATE_NOUPDATES_HEAD="Son sürümü kullanıyorsunuz" +LIVEUPDATE_CURRENTVERSION="Kullandığınız sürüm" +LIVEUPDATE_LATESTVERSION="Son sürüm" +LIVEUPDATE_LATESTRELEASED="Son yayın tarihi" +LIVEUPDATE_DOWNLOADURL="Doğrudan indirme adresi" + +LIVEUPDATE_REFRESH_INFO="Güncelleme bilgisini alın" +LIVEUPDATE_DO_UPDATE="Son sürüme güncelleyin" + +LIVEUPDATE_FTP_REQUIRED="Canlı Güncelleme, güncellemeyi indirip kurmak yerine FTP kullanmaya gerek duyuyor, ancak FTP bilgilerinizi Joomla! Genel Ayarlarına kaydetmemişsiniz.

Bu güncellemeyi yapabilmek için FTP kullanıcı adı ve parolanızı aşağıya yazın." +LIVEUPDATE_FTP="FTP Bilgileri" +LIVEUPDATE_FTPUSERNAME="FTP Kullanıcı Adı" +LIVEUPDATE_FTPPASSWORD="FTP Parolası" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Güncellemeyi indirin ve yükleyin" + +LIVEUPDATE_DOWNLOAD_FAILED="Güncelleme paketi indirilemedi. Geçici klasörünüzün yazılabilir olduğundan ya da Joomla! Genel Ayarlarından FTP seçeneğini etkinleştirdiğinizden emin olun." +LIVEUPDATE_EXTRACT_FAILED="Güncelleme paketi ayıklanamadı. Lütfen bileşeni el ile güncellemeyi deneyin." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Geçersiz paket tipi. Güncelleme yapılamıyor." +LIVEUPDATE_INSTALLEXT="%s %s yükleyin" +LIVEUPDATE_ERROR="Hata" +LIVEUPDATE_SUCCESS="Başarılı" + +LIVEUPDATE_ICON_UNSUPPORTED="Canlı Güncelleme desteklenmiyor" +LIVEUPDATE_ICON_CRASHED="Canlı Güncelleme hata verdi" +LIVEUPDATE_ICON_CURRENT="Son sürümü kullanıyorsunuz" +LIVEUPDATE_ICON_UPDATES="GÜNCELLEME VAR! YÜKLEMEK İÇİN TIKLAYIN." + +LIVEUPDATE_RELEASEINFO="Bilgiler" +LIVEUPDATE_RELEASENOTES="Yayın Notları" +LIVEUPDATE_READMOREINFO="Devamını okuyun" + +LIVEUPDATE_NAGSCREEN_HEAD="DİKKAT! Kararsız bir sürüm yüklemek üzeresiniz." +LIVEUPDATE_NAGSCREEN_BODY="Kararsız bir sürüm yüklemek üzeresiniz (%s - %s). Kararsız sürümler çok az denendiği ya da hiç denenmediği için hatalar içerir ve web sitenizin düzgün çalışmasını engelleyebilir. Ne yaptığınızdan emin değilseniz bu tarayıcı penceresini kapatın. Kararsız sürümleri yüklemekle alacağınız risklerin farkındaysanız, yüklemeye devam etmek için aşağıdaki düğmeye tıklayın." +LIVEUPDATE_NAGSCREEN_BUTTON="Riskleri anladım. Yüklemeye devam edeceğim." + +LIVEUPDATE_STABILITY_ALPHA="Alfa" +LIVEUPDATE_STABILITY_BETA="Beta" +LIVEUPDATE_STABILITY_RC="Yayın adayı" +LIVEUPDATE_STABILITY_STABLE="Kararlı" +LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/uk-UA/uk-UA.liveupdate.ini b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/uk-UA/uk-UA.liveupdate.ini new file mode 100644 index 00000000..ea4c9a04 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/language/uk-UA/uk-UA.liveupdate.ini @@ -0,0 +1,56 @@ +; Akeeba Live Update +; Copyright (c)2010-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com +; Licensed under the GNU LGPLv3 or later + +LIVEUPDATE_TASK_OVERVIEW="Live Update" + +LIVEUPDATE_NOTSUPPORTED_HEAD="Live Update не підтримується на цьому сервері" +LIVEUPDATE_NOTSUPPORTED_INFO="Ваш сервер сигналізує, що Live Update не підтримується. Будь ласка, зв’яжіться з вашим постачальником послуг хостингу і попросіть його ввімкнути розширення PHP cURL або активувати пакувальники URL fopen(). Якщо вони вже ввімкнені, будь ласка, попросіть його сконфігурувати мережеві екрани так, щоб вони дозволяли доступ до цих URL:"_QQ_"" +LIVEUPDATE_NOTSUPPORTED_ALTMETHOD="Ви можете завжди оновити %s відвідавши наш сайт персонально, завантажити останній випуск та встановити його, використовуючи інсталятор розширень Joomla!." + +LIVEUPDATE_STUCK_HEAD="Live Update позначив себе таким, що зазнав краху" +LIVEUPDATE_STUCK_INFO="Live Update визначив, що він зазнав краху останнього разу, коли намагався зв’язатися з сервером оновлень. Це зазвичай означає, що хост активно блокує комунікацію з зовнішніми сайтами. Якщо ви ви захочете спробувати знову отримати інформацію про оновлення, будь ласка, натисніть на кнопку "_QQ_"Оновити інформацію "_QQ_" нижче. Якщо це видасть пусту сторінку, будь ласка, зв’яжіться з постачальником послуг хостингу і опишіть цю проблему." + +LIVEUPDATE_ERROR_NEEDSAUTH="Ви повинні надати ваше ім’я користувача/пароль або ID завантаження в параметрах компоненту перед тим, як намагатися оновитися до останнього випуску. Кнопка оновлення буде залишатися неактивною, доки ви цього не зробите." +LIVEUPDATE_HASUPDATES_HEAD="Доступна нова версія" +LIVEUPDATE_NOUPDATES_HEAD="У вас уже встановлена остання версія" +LIVEUPDATE_CURRENTVERSION="Встановлена версія" +LIVEUPDATE_LATESTVERSION="Остання версія" +LIVEUPDATE_LATESTRELEASED="Дата останнього випуску" +LIVEUPDATE_DOWNLOADURL="URL для безпосереднього завантаження" + +LIVEUPDATE_REFRESH_INFO="Оновити інформацію" +LIVEUPDATE_DO_UPDATE="Оновити до останньої версії" + +LIVEUPDATE_FTP_REQUIRED="Live Update визначив, що йому потрібно використовувати FTP для завантаження та встановлення вашого оновлення, але ви не зберегли інформацію вашого логіну FTP на сторінці Загальної Конфігурації Joomla! .

Будь ласка, надайте ім’я користувача і пароль FTP нижче, щоб продовжити процес оновлення." +LIVEUPDATE_FTP="Інформація FTP" +LIVEUPDATE_FTPUSERNAME="Ім’я користувача FTP" +LIVEUPDATE_FTPPASSWORD="Пароль FTP" +LIVEUPDATE_DOWNLOAD_AND_INSTALL="Завантажити і встановити оновлення" + +LIVEUPDATE_DOWNLOAD_FAILED="Завантаження пакету оновлень не вдалося. Переконайтесь, що ваш тимчасовий каталог доступний для запису або що ви ввімкнули налаштування FTP в Загальній Конфігурації Joomla!." +LIVEUPDATE_EXTRACT_FAILED="Видобування пакету оновлень не вдалося. Будь ласка, спробуйте оновити розширення вручну." + +LIVEUPDATE_INVALID_PACKAGE_TYPE="Неправильний тип пакету. Оновлення не може бути продовжено." +LIVEUPDATE_INSTALLEXT="Встановлення %s %s" +LIVEUPDATE_ERROR="Помилка" +LIVEUPDATE_SUCCESS="Успішно" + +LIVEUPDATE_ICON_UNSUPPORTED="Live Update не підтримується" +LIVEUPDATE_ICON_CRASHED="Live Update зазнало краху" +LIVEUPDATE_ICON_CURRENT="У вас остання версія" +LIVEUPDATE_ICON_UPDATES="ЗНАЙДЕНО ОНОВЛЕННЯ! НАТИСНІТЬ ДЛЯ ЗАПУСКУ ОНОВЛЕННЯ." + +; LIVEUPDATE_RELEASEINFO="Information" +; LIVEUPDATE_RELEASENOTES="Release notes" +; LIVEUPDATE_READMOREINFO="Read more" + +; LIVEUPDATE_NAGSCREEN_HEAD="WARNING! You are about to install an unstable version." +; LIVEUPDATE_NAGSCREEN_BODY="You are about to install an unstable version (%s - %s). Unstable versions may have undergone minimal or no testing and contain bugs which may have an serious adverse to the stability and functionality of your web site. If you are not sure about what you are about to do, please close this browser window. If you are absolutely certain you understand the risks involved with the installation of unstable releases, please click the button below to continue the installation of this unstable release." +; LIVEUPDATE_NAGSCREEN_BUTTON="I understand the risks. Continue with the installation." + +; LIVEUPDATE_STABILITY_ALPHA="Alpha" +; LIVEUPDATE_STABILITY_BETA="Beta" +; LIVEUPDATE_STABILITY_RC="RC" +; LIVEUPDATE_STABILITY_STABLE="Stable" +; LIVEUPDATE_STABILITY_SVN="SVN" \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/liveupdate/liveupdate.php b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/liveupdate.php new file mode 100644 index 00000000..cdb1f3a8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/liveupdate/liveupdate.php @@ -0,0 +1,163 @@ + + * + * One-click updater for Joomla! extensions + * Copyright (C) 2011-2013 Nicholas K. Dionysopoulos / AkeebaBackup.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * @version 3.6.0 2016-03-08 + * @since 1.2.6 + */ + +defined('_JEXEC') or die(); + +require_once dirname(__FILE__).'/classes/abstractconfig.php'; +require_once dirname(__FILE__).'/config.php'; + +class LiveUpdate +{ + /** @var string The current version of Akeeba Live Update */ + public static $version = '1.1'; + + /** + * Loads the translation strings -- this is an internal function, called automatically + */ + private static function loadLanguage() + { + // Load translations + $basePath = dirname(__FILE__); + $jlang = JFactory::getLanguage(); + $jlang->load('liveupdate', $basePath, 'en-GB', true); // Load English (British) + $jlang->load('liveupdate', $basePath, $jlang->getDefault(), true); // Load the site's default language + $jlang->load('liveupdate', $basePath, null, true); // Load the currently selected language + } + + /** + * Handles requests to the "liveupdate" view which is used to display + * update information and perform the live updates + */ + public static function handleRequest() + { + // Load language strings + self::loadLanguage(); + + // Load the controller and let it run the show + require_once dirname(__FILE__).'/classes/controller.php'; + $controller = new LiveUpdateController(); + $controller->execute(JRequest::getCmd('task','overview')); + $controller->redirect(); + } + + /** + * Returns update information about your extension, based on your configuration settings + * @return stdClass + */ + public static function getUpdateInformation($force = false) + { + require_once dirname(__FILE__).'/classes/updatefetch.php'; + $update = new LiveUpdateFetch(); + $info = $update->getUpdateInformation($force); + $hasUpdates = $update->hasUpdates($force); + $info->hasUpdates = $hasUpdates; + + $config = LiveUpdateConfig::getInstance(); + $extInfo = $config->getExtensionInformation(); + + $info->extInfo = (object)$extInfo; + + return $info; + } + + public static function getIcon($config=array()) + { + // Load language strings + self::loadLanguage(); + + // Initialize the array of button options + $button = array(); + + $defaultConfig = array( + 'option' => JRequest::getCmd('option',''), + 'view' => 'liveupdate', + 'mediaurl' => JURI::base().'components/'.JRequest::getCmd('option','').'/liveupdate/assets/' + ); + $c = array_merge($defaultConfig, $config); + + $button['link'] = 'index.php?option='.$c['option'].'&view='.$c['view']; + $button['image'] = $c['mediaurl']; + + $updateInfo = self::getUpdateInformation(); + if(!$updateInfo->supported) { + // Unsupported + $button['icon'] = 'liveupdate-icon-notsupported'; + $button['class'] = version_compare(JVERSION, '3.0', 'lt') ? 'liveupdate-icon-notsupported' : ''; + $button['suffix'] = version_compare(JVERSION, '3.0', 'lt') ? '' : ''; + $button['image'] .= 'nosupport-32.png'; + $button['text'] = JText::_('LIVEUPDATE_ICON_UNSUPPORTED'); + } elseif($updateInfo->stuck) { + // Stuck + $button['icon'] = 'liveupdate-icon-crashed'; + $button['class'] = version_compare(JVERSION, '3.0', 'lt') ? 'liveupdate-icon-crashed' : ''; + $button['suffix'] = version_compare(JVERSION, '3.0', 'lt') ? '' : ''; + $button['image'] .= 'nosupport-32.png'; + $button['text'] = JText::_('LIVEUPDATE_ICON_CRASHED'); + } + + // Has updates + elseif($updateInfo->hasUpdates) + { + $button['icon'] = version_compare(JVERSION, '3.0', 'lt') ? 'liveupdate-icon-updates' : 'icon-upload'; + $button['class'] = version_compare(JVERSION, '3.0', 'lt') ? 'liveupdate-icon-updates' : 'btn btn-danger'; + $button['suffix'] = version_compare(JVERSION, '3.0', 'lt') ? '' : 'danger'; + $button['text'] = '' . JText::_('LIVEUPDATE_ICON_UPDATES') . ''; + } + + // Already in the latest release + else + { + $button['icon'] = 'liveupdate-icon-noupdates'; + $button['class'] = version_compare(JVERSION, '3.0', 'lt') ? 'liveupdate-icon-noupdates' : ''; + $button['suffix'] = version_compare(JVERSION, '3.0', 'lt') ? '' : ''; + $button['image'] .= 'current-32.png'; + $button['text'] = JText::_('LIVEUPDATE_ICON_CURRENT'); + } + + if (version_compare(JVERSION, '3.0', 'lt')) + { + $iCupdate = ''; + } + else + { + $iCupdate = ''; + } + + return $iCupdate; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/categories.php b/deployed/icagenda/administrator/components/com_icagenda/models/categories.php new file mode 100644 index 00000000..3b9c263f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/categories.php @@ -0,0 +1,163 @@ +getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $published = $app->getUserStateFromRequest($this->context . '.filter.state', 'filter_published', '', 'string'); + $this->setState('filter.state', $published); + + // Load the parameters. + $params = JComponentHelper::getParams('com_icagenda'); + $this->setState('params', $params); + + // List state information. + parent::populateState('a.title', 'asc'); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id.= ':' . $this->getState('filter.search'); + $id.= ':' . $this->getState('filter.state'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * @since 1.0 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.*' + ) + ); + $query->from('#__icagenda_category AS a'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor') + ->join('LEFT', '#__users AS uc ON uc.id = a.checked_out'); + + // Filter by published state + $published = $this->getState('filter.state'); + + if (is_numeric($published)) + { + $query->where('a.state = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.state IN (0, 1))'); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if ( ! empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->Quote('%' . $db->escape($search, true) . '%'); + $query->where('( a.title LIKE ' . $search . ' OR a.color LIKE ' . $search . ' OR a.desc LIKE ' . $search . ' )'); + } + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering'); + $orderDirn = $this->state->get('list.direction'); + + if ($orderCol && $orderDirn) + { + $query->order($db->escape($orderCol . ' ' . $orderDirn)); + } + + return $query; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/category.php b/deployed/icagenda/administrator/components/com_icagenda/models/category.php new file mode 100644 index 00000000..a1071750 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/category.php @@ -0,0 +1,179 @@ +loadForm('com_icagenda.category', 'category', + array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_icagenda.edit.category.data', array()); + + if (empty($data)) { + $data = $this->getItem(); + } + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer The id of the primary key. + * + * @return mixed Object on success, false on failure. + * @since 1.6 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) { + + //Do any procesing on fields here if needed + + } + + return $item; + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @since 1.0 + */ + + protected function prepareTable( $table ) + { + if (empty($table->id)) { + + // Set ordering to the last item if not set + if (@$table->ordering === '') { + $db = JFactory::getDbo(); + $db->setQuery('SELECT MAX(ordering) FROM #__icagenda_category'); + $max = $db->loadResult(); + $table->ordering = $max+1; + } + + } + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 3.4.0 + */ + public function save($data) + { + $jinput = JFactory::getApplication()->input; + $date = JFactory::getDate(); + + // Fix version before 3.4.0 to set a created date (will use last modified date if exists, or current date) + if (empty($data['created'])) + { + $data['created'] = ! empty($data['modified']) ? $data['modified'] : $date->toSql(); + } + + // Automatic handling of alias if empty + if (in_array($jinput->get('task'), array('apply', 'save', 'save2new')) && $data['alias'] == null) + { + if (JFactory::getConfig()->get('unicodeslugs') == 1) + { + $data['alias'] = JFilterOutput::stringURLUnicodeSlug($data['title']); + } + else + { + $data['alias'] = JFilterOutput::stringURLSafe($data['title']); + } + } + + // Use created date in case alias is still empty + if ($data['alias'] == null || empty($data['alias'])) + { + $data['alias'] = JFilterOutput::stringURLSafe($data['created']); + } + + // Force to not add unicode characters if unicodeslugs is not enabled + if (JFactory::getConfig()->get('unicodeslugs') != 1) + { + $data['alias'] = JFilterOutput::stringURLSafe($data['alias']); + } + + $return = parent::save($data); + + return $return; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/customfield.php b/deployed/icagenda/administrator/components/com_icagenda/models/customfield.php new file mode 100644 index 00000000..64201094 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/customfield.php @@ -0,0 +1,183 @@ +loadForm('com_icagenda.customfield', 'customfield', + array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * @since 3.4.0 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_icagenda.edit.customfield.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + // Set Options to placeholder, and unset options (if input type with hint) + $hintFields = array('text', 'url', 'tel', 'email', 'core_name', 'core_email', 'core_phone'); + + if (isset($data->options) + && in_array($data->type, $hintFields)) + { + $data->placeholder = $data->options; + unset($data->options); + } + + // Set Options to spacer_class, and unset options (if input type is spacer) + $spacerFields = array('spacer_label', 'spacer_description'); + + if (isset($data->options) + && in_array($data->type, $spacerFields)) + { + $data->spacer_class = $data->options; + unset($data->options); + } + + // If not array, creates array with custom forms data + if ( ! is_array($data->groups)) + { + $data->groups = explode(',', $data->groups); + } + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer The id of the primary key. + * + * @return mixed Object on success, false on failure. + * @since 3.4.0 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) + { + // Get custom forms +// $registry = new JRegistry; +// $registry->loadString($item->groups); +// $item->groups = $registry->toArray(); + } + + return $item; + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @since 3.4.0 + */ + protected function prepareTable($table) + { + $app = JFactory::getApplication(); + + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + if (empty($table->id)) + { + // Set the values + $table->created = $date->toSql(); + + // Set ordering to the last item if not set + if (empty($table->ordering)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('MAX(ordering)') + ->from($db->quoteName('#__icagenda_customfields')); + $db->setQuery($query); + $max = $db->loadResult(); + + $table->ordering = $max + 1; + } + } + else + { + // Set the values + $table->modified = $date->toSql(); + $table->modified_by = $user->get('id'); + } + + // Alter the title for save as copy + if ($app->input->get('task') == 'save2copy') + { + $table->title = iCString::increment($table->title); + $table->alias = iCString::increment($table->alias, 'dash'); + $table->slug = iCString::increment($table->slug, 'underscore'); + $table->state = '0'; + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/customfields.php b/deployed/icagenda/administrator/components/com_icagenda/models/customfields.php new file mode 100644 index 00000000..164fc342 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/customfields.php @@ -0,0 +1,309 @@ +getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $published = $app->getUserStateFromRequest($this->context . '.filter.state', 'filter_published', '', 'string'); + $this->setState('filter.state', $published); + + // Filter (dropdown) parent form + $parent_form = $this->getUserStateFromRequest($this->context . '.filter.parent_form', 'filter_parent_form', '', 'string'); + $this->setState('filter.parent_form', $parent_form); + + // Filter (dropdown) field type + $type = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string'); + $this->setState('filter.type', $type); + + // Filter (dropdown) custom field group + $group = $this->getUserStateFromRequest($this->context . '.filter.group', 'filter_group', '', 'string'); + $this->setState('filter.group', $group); + + // Load the parameters. + $params = JComponentHelper::getParams('com_icagenda'); + $this->setState('params', $params); + + // List state information. + parent::populateState('cf.ordering', 'asc'); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 3.4.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id.= ':' . $this->getState('filter.search'); + $id.= ':' . $this->getState('filter.state'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 3.4.0 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'cf.*' + ) + ); + $query->from('#__icagenda_customfields AS cf'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor'); + $query->join('LEFT', '#__users AS uc ON uc.id = cf.checked_out'); + + // Filter by published state + $published = $this->getState('filter.state'); + + if (is_numeric($published)) + { + $query->where($db->qn('cf.state') . ' = ' . (int) $published); + } + elseif ($published === '') + { + $query->where($db->qn('cf.state') . ' IN (0, 1)'); + } + + // Filter by Parent Form + $parent_form = $db->escape($this->getState('filter.parent_form')); + + if ( ! empty($parent_form)) + { + $query->where($db->qn('cf.parent_form') . ' = ' . (int) $parent_form); + } + + // Filter by Group + $group = $db->escape($this->getState('filter.group')); + + if ( ! empty($group)) + { + $query->where($db->qn('cf.groups') . ' LIKE "%' . $group . '%"'); + } + + // Filter by Field Type + $type = $db->escape($this->getState('filter.type')); + + if ( ! empty($type)) + { + $query->where($db->qn('cf.type') . ' = ' . (string) $db->q($type)); + } + + // Search Filters + $search = $this->getState('filter.search'); + + if ( ! empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->qn('cf.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->Quote('%' . $db->escape($search, true) . '%'); + $query->where('( cf.title LIKE ' . $search . ' OR cf.slug LIKE ' . $search . ' OR cf.type LIKE ' . $search . ' )'); + } + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering'); + $orderDirn = $this->state->get('list.direction'); + + if ($orderCol && $orderDirn) + { + $query->order($db->escape($orderCol . ' ' . $orderDirn)); + } + + return $query; + } + + /** + * Gets a list of Parent Forms. + * + * @since 3.4.0 + */ + function getParentForm() + { + $list['1'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_PARENT_REGISTRATION_FORM'); + $list['2'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_PARENT_EVENT_EDIT'); + + return $list; + } + + /** + * Gets list of Custom Field Groups. + * + * @since 3.6.0 + */ + function getGroups() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + $query->select('f.value, f.option'); + $query->from('#__icagenda_filters AS f'); + $query->where('f.type = "customfield"'); + $query->where('f.filter = "groups"'); + $query->order('f.option ASC'); + $db->setQuery($query); + $groups = $db->loadObjectList(); + + $list = array(); + + foreach ($groups AS $g) + { + $list[$g->value] = $g->option; + } + + return $list; + } + + /** + * Gets a list of Field Types. + * + * @since 3.4.0 + */ + function getFieldTypes() + { + $type['text'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_TEXT'); + $type['list'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_LIST'); + $type['radio'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_RADIO'); + $type['calendar'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_DATE'); + $type['url'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_URL'); + $type['email'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_EMAIL'); + $type['spacer_label'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_SPACER_LABEL'); + $type['spacer_description'] = JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_SPACER_DESCRIPTION'); + $type['core_name'] = JText::_('COM_ICAGENDA_LABEL_OVERRIDE') . ': ' . JText::_('COM_ICAGENDA_REGISTRATION_NAME'); + $type['core_email'] = JText::_('COM_ICAGENDA_LABEL_OVERRIDE') . ': ' . JText::_('COM_ICAGENDA_REGISTRATION_EMAIL'); + $type['core_phone'] = JText::_('COM_ICAGENDA_LABEL_OVERRIDE') . ': ' . JText::_('COM_ICAGENDA_REGISTRATION_PHONE'); + $type['core_date'] = JText::_('COM_ICAGENDA_LABEL_OVERRIDE') . ': ' . JText::_('COM_ICAGENDA_REGISTRATION_DATE'); + $type['core_people'] = JText::_('COM_ICAGENDA_LABEL_OVERRIDE') . ': ' . JText::_('COM_ICAGENDA_REGISTRATION_TICKETS'); + + return $type; + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 3.6.0 + */ + public function getItems() + { + if ($items = parent::getItems()) + { + // Do any procesing on fields here if needed + foreach ($items AS $item) + { + } + } + + return $items; + } + + /** + * Gets list of Custom Field Groups. + * + * @since 3.6.0 + */ + function getCustomFieldGroups() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + $query->select('f.value, f.option'); + $query->from('#__icagenda_filters AS f'); + $query->where('f.type = "customfield"'); + $query->where('f.filter = "groups"'); + $query->order('f.option ASC'); + $db->setQuery($query); + $groups = $db->loadObjectList(); + + return $groups; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/download.php b/deployed/icagenda/administrator/components/com_icagenda/models/download.php new file mode 100644 index 00000000..23298149 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/download.php @@ -0,0 +1,96 @@ +input; + + $basename = $input->cookie->getString(JApplicationHelper::getHash($this->_context . '.basename'), '__SITE__'); + $this->setState('basename', $basename); + + $compressed = $input->cookie->getInt(JApplicationHelper::getHash($this->_context . '.compressed'), 1); + $this->setState('compressed', $compressed); + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return mixed A JForm object on success, false on failure + * + * @since 3.5.0 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_icagenda.download', 'download', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 3.5.0 + */ + protected function loadFormData() + { + $data = array( + 'basename' => $this->getState('basename'), + 'compressed' => $this->getState('compressed') + ); + + // Joomla 3 + if (version_compare(JVERSION, '3.0', 'ge')) + { + $this->preprocessData('com_icagenda.download', $data); + } + + return $data; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/event.php b/deployed/icagenda/administrator/components/com_icagenda/models/event.php new file mode 100644 index 00000000..3849e07f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/event.php @@ -0,0 +1,942 @@ +id)) + { + if ($record->state != -2) + { + return false; + } + + $user = JFactory::getUser(); + + if ($user->authorise('core.delete')) + { + icagendaCustomfields::deleteData($record->id, 2); + icagendaCustomfields::cleanData(2); + + return true; + } + } + + return false; + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @param JTable $table A JTable object. + * + * @return void + * + * @since 1.0 + */ + protected function prepareTable( $table ) + { + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); + + if (empty($table->id)) + { + // Set the values + $table->created = $date->toSql(); + + // Set ordering to the last item if not set + if (empty($table->ordering)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('MAX(ordering)') + ->from($db->quoteName('#__icagenda_events')); + $db->setQuery($query); + $max = $db->loadResult(); + + $table->ordering = $max + 1; + } + } + else + { + // Set the values + $table->modified = $date->toSql(); + $table->modified_by = $user->get('id'); + } + } + + /** + * Returns a Table object, always creating it. + * + * @param string $type The table type to instantiate + * @param string $prefix A prefix for the table class name. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JTable A database object + * + * @since 1.0 + */ + public function getTable($type = 'Event', $prefix = 'iCagendaTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.0 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) + { + // Do any procesing on fields here if needed + } + + return $item; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return mixed A JForm object on success, false on failure + * + * @since 1.0 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_icagenda.event', 'event', + array('control' => 'jform', 'load_data' => $loadData)); + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.0 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $app = JFactory::getApplication(); + $data_array = $app->getUserState('com_icagenda.edit.event.data', array()); + + if (empty($data_array)) + { + $data = $this->getItem(); + } + else + { + $data = new JObject; + $data->setProperties($data_array); + } + +// if (JFactory::getUser($data->created_by)->get('name') == false) +// { +// JLog::add(JText::_('The author of this event is no longer a user on this site'), JLog::WARNING, 'jerror'); +// } + + // Set correctly param 'first_published_and_approved' if not set (for frontend submitted and approved events) + if ($data->state == 1 + && $data->approval == 0) + { + $data->params['first_published_and_approved'] = 1; + } + + // If not array, creates array with week days data + if ( ! is_array($data->weekdays)) + { + $data->weekdays = explode(',', $data->weekdays); + } + + // Retrieves data, to display selected week days + $arrayWeekDays = $data->weekdays; + + foreach ($arrayWeekDays as $allTest) + { + if ($allTest == '') + { + $data->weekdays = '0,1,2,3,4,5,6'; + } + } + + // Set displaytime default value + if ( ! isset($data->displaytime)) + { + $data->displaytime = JComponentHelper::getParams('com_icagenda')->get('displaytime', '1'); + } + + // Set Features + $data->features = $this->getFeatures($data->id); + + // Convert features into an array so that the form control can be set + if ( ! isset($data->features)) + { + $data->features = array(); + } + + if ( ! is_array($data->features)) + { + $data->features = explode(',', $data->features); + } + + return $data; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 3.4.0 + */ + public function save($data) + { + $jinput = JFactory::getApplication()->input; + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + // Fix version before 3.4.0 to set a created date (will use last modified date if exists, or current date) + if (empty($data['created'])) + { + $data['created'] = ( ! empty($data['modified'])) ? $data['modified'] : $date->toSql(); + } + + // Event cancelled date + if (empty($data['params']['event_cancelled_date']) && $data['params']['event_cancelled'] == 1) + { + $data['params']['event_cancelled_date'] = $date->toSql(); + } + elseif ($data['params']['event_cancelled'] == 0) + { + unset($data['params']['event_cancelled_date']); + } + + // Check first published and approved + if ($data['state'] == 1 + && $data['approval'] == 0 + && $data['params']['first_published_and_approved'] == 0) + { + $data['params']['first_published_and_approved'] = 1; + $first_published_and_approved = true; + } + else + { + $first_published_and_approved = false; + } + + // Alter the title for save as copy + if ($jinput->get('task') == 'save2copy') + { + $origTable = clone $this->getTable(); + $origTable->load($jinput->getInt('id')); + + if ($data['title'] == $origTable->title) + { + list($title, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['title']); + $data['title'] = $title; + $data['alias'] = $alias; + } + else + { + if ($data['alias'] == $origTable->alias) + { + $data['alias'] = ''; + } + } + $data['state'] = 0; + } + + // Automatic handling of alias if empty + if (in_array($jinput->get('task'), array('apply', 'save', 'save2new')) && $data['alias'] == null) + { + if (JFactory::getConfig()->get('unicodeslugs') == 1) + { + $data['alias'] = JFilterOutput::stringURLUnicodeSlug($data['title']); + } + else + { + $data['alias'] = JFilterOutput::stringURLSafe($data['title']); + } + } + + // Use created date in case alias is still empty + if ($data['alias'] == null || empty($data['alias'])) + { + $data['alias'] = JFilterOutput::stringURLSafe($data['created']); + } + + // Force to not add unicode characters if unicodeslugs is not enabled + if (JFactory::getConfig()->get('unicodeslugs') != 1) + { + $data['alias'] = JFilterOutput::stringURLSafe($data['alias']); + } + + // Check start and end date format (am/pm to sql date) + $data['startdate'] = iCDate::isDate($data['startdate']) ? date('Y-m-d H:i:s', strtotime($data['startdate'])) : $data['startdate']; + $data['enddate'] = iCDate::isDate($data['enddate']) ? date('Y-m-d H:i:s', strtotime($data['enddate'])) : $data['enddate']; + + // Set File Uploaded + if ( ! isset($data['file'])) + { + $files = $jinput->files->get('jform', null); + $fileUrl = ! empty($files['file']['name']) ? $this->upload($files['file']) : ''; + $data['file'] = $fileUrl; + } + + // Set Creator infos + $userId = $user->get('id'); + $userName = $user->get('name'); + + // Event created in admin, set current logged-in user as creator + if (empty($data['created_by']) && empty($data['username'])) + { + $data['created_by'] = (int) $userId; + $data['username'] = $userName; + } + + // Event edited in admin, created_by not empty, but creator is not the current logged-in user + elseif ( ! empty($data['created_by']) && $data['created_by'] != $userId) + { + $data['username'] = JFactory::getUser($data['created_by'])->get('name', ''); + } + + // Set Params + if (isset($data['params']) && is_array($data['params'])) + { + // Keep params for later control + $params = $data['params']; + + // Convert the params field to a string. + $parameter = new JRegistry; + $parameter->loadArray($data['params']); + + $data['params'] = (string)$parameter; + } + + // Get Event ID from the result back to the Table after saving. + $table = $this->getTable(); + + if ($table->save($data) === true) + { + $data['id'] = $table->id; + } + else + { + $data['id'] = null; + } + + if (parent::save($data)) + { + // Save Features to database + $this->maintainFeatures($data); + + // Save Custom Fields to database + if (isset($data['custom_fields']) && is_array($data['custom_fields'])) + { + icagendaCustomfields::saveToData($data['custom_fields'], $data['id'], 2); + } + + // ==================================== + // START : HACK FOR A FEW PRO USERS !!! + // ==================================== + + $mail_new_event = JComponentHelper::getParams('com_icagenda')->get('mail_new_event', '0'); + + if ($mail_new_event == 1) + { + $new_event = $jinput->get('new_event'); + + // Send notification email if new event + if ($new_event == '1' && $data['id'] && $data['state'] == '1' && $data['approval'] == '0') + { + self::notificationNewEvent($data); + } + } + + // ==================================== + // END : HACK FOR A FEW PRO USERS !!! + // ==================================== + + // Plugin Event handler 'iCagendaOnNewEvent' + if ($first_published_and_approved) + { + // JOOMLA 3.x/2.5 SWITCH + if (version_compare(JVERSION, '3.0', 'ge')) + { + $dispatcher = JEventDispatcher::getInstance(); + } + else + { + $dispatcher = JDispatcher::getInstance(); + } + + JPluginHelper::importPlugin('icagenda'); + + $dispatcher->trigger('iCagendaOnNewEvent', array((object) $data)); + } + + return true; + } + + return false; + } + + /** + * Upload File + * + * @since 3.5.3 + */ + protected function upload($file) + { + // Get Joomla Images PATH setting + $image_path = JComponentHelper::getParams('com_media')->get('image_path', 'images'); + + // Get filename (name + ext) + $filename = $file['name']; + + // Get file extension + $fileExtension = JFile::getExt($filename); + + // Clean up file name to url safe string + $fileTitle = iCFilterOutput::stringToSlug(JFile::stripExt($filename), '-'); + + // If slug generated is empty, new slug based on current date/time + if ( ! $fileTitle) + { + $fileTitle = JFactory::getDate()->format("YmdHis"); + } + + // Return new filename + $filename = $fileTitle . '.' . $fileExtension; + + // Increment file name if filename already exists + while (JFile::exists(JPATH_SITE . '/' . $image_path . '/icagenda/files/' . $filename)) + { + // Get file extension + $fileExtension = JFile::getExt($filename); + + // Get file title + $fileTitle = JFile::stripExt($filename); + + // Increment file title (eg. filename-3.jpg) + $fileTitle = iCString::increment($fileTitle, 'dash'); + + $filename = $fileTitle . '.' . $fileExtension; + } + + // Save file + if ($filename != '') + { + // Set up the temporary source and destination of the file + $src = $file['tmp_name']; + $dest = JPATH_SITE . '/' . $image_path . '/icagenda/files/' . $filename; + + // Create folder 'files' in ROOT/IMAGES_PATH/icagenda/ if does not exist + $folder[0][0] = 'icagenda/files/' ; + $folder[0][1] = JPATH_SITE . '/' . $image_path . '/' . $folder[0][0]; + + $error = array(); + + foreach ($folder as $key => $value) + { + if ( ! JFolder::exists( $value[1])) + { + if (JFolder::create( $value[1], 0755 )) + { + $this->data = "\n\n\n"; + JFile::write($value[1] . "/index.html", $this->data); + $error[] = 0; + } + else + { + $error[] = 1; + } + } + else //Folder exist + { + $error[] = 0; + } + } + + // Return file path on success + if ( JFile::upload($src, $dest, false) ) + { + return $image_path . '/icagenda/files/' . $filename; + } + } + } + + /** + * Maintain features to data + * + * @since 3.4.0 + */ + protected function maintainFeatures($data) + { + // Get the list of feature ids to be linked to the event + $features = isset($data['features']) && is_array($data['features']) ? implode(',', $data['features']) : ''; + + $db = JFactory::getDbo(); + + // Write any new feature records to the icagenda_feature_xref table + if ( ! empty($features)) + { + // Get a list of the valid features already present for this event + $query = $db->getQuery(true); + + $query->select('feature_id') + ->from($db->qn('#__icagenda_feature_xref')); + + $query->where('event_id = ' . (int) $data['id']); + $query->where('feature_id IN (' . $features . ')'); + + $db->setQuery($query); + + $existing_features = $db->loadColumn(0); + + // Identify the insert list + if (empty($existing_features)) + { + $new_features = $data['features']; + } + else + { + $new_features = array(); + + foreach ($data['features'] as $feature) + { + if ( ! in_array($feature, $existing_features)) + { + $new_features[] = $feature; + } + } + } + // Write the needed xref records + if ( ! empty($new_features)) + { + $xref = new JObject; + $xref->set('event_id', $data['id']); + + foreach ($new_features as $feature) + { + $xref->set('feature_id', $feature); + $db->insertObject('#__icagenda_feature_xref', $xref); + $db->setQuery($query); + + if ( ! $db->execute()) + { + return false; + } + } + } + } + + // Delete any unwanted feature records from the icagenda_feature_xref table + $query = $db->getQuery(true); + $query->delete($db->qn('#__icagenda_feature_xref')); + $query->where('event_id = ' . (int) $data['id']); + + if ( ! empty($features)) + { + // Delete only unwanted features + $query->where('feature_id NOT IN (' . $features . ')'); + } + + $db->setQuery($query); + $db->execute($query); + + if ( ! $db->execute()) + { + return false; + } + + return true; + } + + /** + * Extracts the list of Feature IDs linked to the event and returns an array + * + * @param integer $event_id + * + * @return array/integer Set of Feature IDs + * + * @since 3.5.3 + */ + protected function getFeatures($event_id) + { + // Write any new feature records to the icagenda_feature_xref table + if (empty($event_id)) + { + return ''; + } + else + { + $db = JFactory::getDbo(); + + // Get a comma separated list of the ids of features present for this event + // Note: Direct extraction of a comma separated list is avoided because each db type uses proprietary syntax + $query = $db->getQuery(true); + $query->select('fx.feature_id') + ->from($db->qn('#__icagenda_events', 'e')) + ->innerJoin('#__icagenda_feature_xref AS fx ON e.id=fx.event_id') + ->innerJoin('#__icagenda_feature AS f ON fx.feature_id=f.id AND f.state=1'); + $query->where('e.id = ' . (int) $event_id); + $db->setQuery($query); + $features = $db->loadColumn(0); + + // Return a comma separated list + return implode(',', $features); + } + } + + /** + * Approve Function. + * + * @since 3.2.0 + */ + function approve($cid, $approval = 0) + { + if (count($cid)) + { + JArrayHelper::toInteger($cid); + $cids = implode( ',', $cid ); + $query = 'UPDATE #__icagenda_events' + . ' SET approval = ' . (int) $approval + . ' WHERE id IN (' . $cids . ')'; + $this->_db->setQuery( $query ); + + if ( ! $this->_db->query()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + } + + return true; + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 3.6.0 + */ +// protected function canDelete($record) +// { +// if ( ! empty($record->id)) +// { +// if ($record->state != -2) +// { +// return false; +// } + +// $user = JFactory::getUser(); + +// return $user->authorise('core.delete', 'com_icagenda.event.' . (int) $record->id); +// } + +// return false; +// } + + /** + * Method to test whether a record can have its state edited. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. + * + * @since 3.6.0 + */ +// protected function canEditState($record) +// { +// $user = JFactory::getUser(); + + // Check for existing event. +// if (!empty($record->id)) +// { +// return $user->authorise('core.edit.state', 'com_icagenda.event.' . (int) $record->id); +// } + // New event, so check against the category. +// elseif (!empty($record->catid)) +// { +// return $user->authorise('core.edit.state', 'com_icagenda.event.' . (int) $record->catid); +// } + // Default to component settings if neither event nor category known. +// else +// { +// return parent::canEditState('com_icagenda'); +// } +// } + + + + /** + * HACK FOR A FEW PRO USERS !!! + * + * Will be removed when creation of a notification plugin + * + */ + function notificationNewEvent($data) + { + $eventID = $data['id']; + $title = $data['title']; + $description = $data['desc']; + + $venue = ''; + $venue.= $data['place'] ? $data['place'] . ' - ' : ''; + $venue.= $data['city'] ?: ''; + $venue.= ($data['city'] && $data['country']) ? ', ' : ''; + $venue.= $data['country'] ?: ''; + + // Set Date + $date = strtotime($data['startdate']) + ? 'Du ' . $data['startdate'] . ' au ' . $data['startdate'] + : $data['next']; + + // Set Image tag if exists + $baseURL = JURI::base(); + $baseURL = str_replace('/administrator', '', $baseURL); + $baseURL = ltrim($baseURL, '/'); + + $image = $data['image'] ? '' . $data['image'] . '' : ''; + + // Load iCagenda Global Options + $iCparams = JComponentHelper::getParams('com_icagenda'); + + // Load Joomla Config + $config = JFactory::getConfig(); + + // Switch Joomla 3.x / 2.5 + if (version_compare(JVERSION, '3.0', 'ge')) + { + // Get the site name + $sitename = $config->get('sitename'); + + // Get Global Joomla Contact Infos + $mailfrom = $config->get('mailfrom'); + $fromname = $config->get('fromname'); + + // Get default language + $langdefault = $config->get('language'); + } + else + { + // Get the site name + $sitename = $config->getValue('config.sitename'); + + // Get Global Joomla Contact Infos + $mailfrom = $config->getValue('config.mailfrom'); + $fromname = $config->getValue('config.fromname'); + + // Get default language + $langdefault = $config->getValue('config.language'); + } + + $siteURL = JURI::base(); + $siteURL = rtrim($siteURL,'/'); + + $iCmenuitem = false; + + // Itemid Request (automatic detection of the first iCagenda menu-link, by menuID, and depending of current language) + + $langFrontend = $langdefault; + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('id AS idm') + ->from('#__menu') + ->where( "(link = 'index.php?option=com_icagenda&view=list') AND (published > 0) AND (language = '$langFrontend')" ); + $db->setQuery($query); + $idm = $db->loadResult(); + $mItemid = $idm; + + if ($mItemid == NULL) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('id AS noidm') + ->from('#__menu') + ->where( "(link = 'index.php?option=com_icagenda&view=list') AND (published > 0) AND (language = '*')" ); + $db->setQuery($query); + $noidm = $db->loadResult(); + } + + $nolink = ''; + + if ($noidm == NULL && $mItemid == NULL) + { + $nolink = 1; + } + + if (is_numeric($iCmenuitem)) + { + $lien = $iCmenuitem; + } + else + { + if ($mItemid == NULL) + { + $lien = $noidm; + } + else + { + $lien = $mItemid; + } + } + + // Set Notification Email to each User groups allowed to receive a notification email when a new event created + $groupid = $iCparams->get('newevent_Groups', array("8")); + + jimport( 'joomla.access.access' ); + $newevent_Groups_Array = array(); + + foreach ($groupid AS $gp) + { + $GroupUsers = JAccess::getUsersByGroup($gp, False); + $newevent_Groups_Array = array_merge($newevent_Groups_Array, $GroupUsers); + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $matches = implode(',', $newevent_Groups_Array); + $query->select('ui.username AS username, ui.email AS email, ui.password AS passw, ui.block AS block, ui.activation AS activation') + ->from('#__users AS ui') + ->where( "ui.id IN ($matches) "); + $db->setQuery($query); + $users = $db->loadObjectList(); + + foreach ($users AS $user) + { + // Create Notification Mailer + $new_mailer = JFactory::getMailer(); + + // Set Sender of Notification Email + $new_mailer->setSender(array( $mailfrom, $fromname )); + + $username = $user->username; + $passw = $user->passw; + $email = $user->email; + + // Set Recipient of Notification Email + $new_recipient = $email; + $new_mailer->addRecipient($email); + + // Set Subject of New Event Notification Email + $new_subject = 'Nouvel évènement, '.$sitename; + $new_mailer->setSubject($new_subject); + + // Set Url to preview new event + $baseURL = JURI::base(); + $baseURL = str_replace('/administrator', '', $baseURL); + + $urlpreview = str_replace('&','&', JRoute::_($baseURL . 'index.php?option=com_icagenda&view=event&id=' . (int) $eventID . '&Itemid=' . (int) $lien)); + + // Set Body of User Notification Email + $new_body_hello = 'Bonjour,'; + $new_bodycontent = $new_body_hello.'

'; + $new_body_text = $sitename.' vous propose un nouvel évènement :'; + $new_bodycontent.= $new_body_text.'

'; + + // Event Details + $new_bodycontent.= $title ? 'Titre: '.$title.'
' : ''; + $new_bodycontent.= $description ? 'Description: '.$description.'
' : ''; + $new_bodycontent.= $venue ? 'Lieu: '.$venue.'
' : ''; + $new_bodycontent.= $date ? 'Date: '.$date.'

' : ''; + $new_bodycontent.= $image.'

'; + + // Link to event details view + $new_bodycontent.= ''.$urlpreview.'

'; + + // Footer + $new_body_footer = 'Do not answer to this e-mail notification as it is a generated e-mail. You are receiving this email message because you are registered at '.$sitename.'.'; + $new_bodycontent.= '
'.$new_body_footer.''; + + // Removes spaces (leading, ending) from Body + $new_body = rtrim($new_bodycontent); + + // Authorizes HTML + $new_mailer->isHTML(true); + + // JDocs: When sending HTML emails you should normally set the Encoding to base64 + // in order to avoid unwanted characters in the output. + // See https://docs.joomla.org/Sending_email_from_extensions + $new_mailer->Encoding = 'base64'; // JDocs Sending HTML Email + + // Set Body + $new_mailer->setBody($new_body); + + // Send User Notification Email + if (isset($email)) + { + if ($user->block == '0' && empty($user->activation)) + { + $send = $new_mailer->Send(); + } + } + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/events.php b/deployed/icagenda/administrator/components/com_icagenda/models/events.php new file mode 100644 index 00000000..8c7d4b6b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/events.php @@ -0,0 +1,452 @@ +getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + // Load the filter state. + $published = $app->getUserStateFromRequest($this->context . '.filter.state', 'filter_published', '', 'string'); + $this->setState('filter.state', $published); + + // Load the filter approval. + $approval = $app->getUserStateFromRequest($this->context . '.filter.approval', 'filter_approval'); + $this->setState('filter.approval', $approval); + + // Filter (dropdown) category + $category = $this->getUserStateFromRequest($this->context . '.filter.category', 'filter_category'); + $this->setState('filter.category', $category); + + // Filter categoryId + $categoryId = $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id'); + $this->setState('filter.category_id', $categoryId); + + // Filter (dropdown) upcoming + $upcoming = $this->getUserStateFromRequest($this->context . '.filter.upcoming', 'filter_upcoming', '', 'string'); + $this->setState('filter.upcoming', $upcoming); + + // Filter (dropdown) Frontend Menu Itemid + $site_itemid = $this->getUserStateFromRequest($this->context . '.filter.site_itemid', 'filter_site_itemid', '', 'string'); + $this->setState('filter.site_itemid', $site_itemid); + + // Load the parameters. + $params = JComponentHelper::getParams('com_icagenda'); + $this->setState('params', $params); + + // List state information. + parent::populateState('e.id', 'desc'); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 1.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id.= ':' . $this->getState('filter.search'); + $id.= ':' . $this->getState('filter.state'); + $id.= ':' . $this->getState('filter.approval'); + $id.= ':' . $this->getState('filter.category_id'); + $id.= ':' . $this->getState('filter.site_itemid'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 1.0 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'e.*' + ) + ); + $query->from('#__icagenda_events AS e'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor'); + $query->join('LEFT', '#__users AS uc ON uc.id = e.checked_out'); + + // Join over the asset groups. + $query->select('ag.title AS access_level') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = e.access'); + + // Join the category + $query->select('c.title AS category'); + $query->join('LEFT', '#__icagenda_category AS c ON c.id = e.catid'); + + // Join over the users for the author. + $query->select('CASE WHEN e.created_by = "0" THEN e.username ELSE ua.name END AS author_name, ua.username AS author_username') + ->join('LEFT', '#__users AS ua ON ua.id = e.created_by'); + + // Filter by published state + $published = $this->getState('filter.state'); + + if (is_numeric($published)) + { + $query->where('e.state = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(e.state IN (0, 1))'); + } + + // Filter by approval state + $approval = $this->getState('filter.approval'); + + if ($approval == '1') + { + $query->where('e.approval = "1"'); + } + elseif ($approval == '0') + { + $query->where('e.approval = "0"'); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if ( ! empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('e.id = ' . (int) substr($search, 3)); + } + else + { + if (iCDate::isDate($search)) + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + + $query->where('( e.startdate LIKE ' . $search . + ' OR e.enddate LIKE ' . $search . + ' OR e.period LIKE ' . $search . + ' OR e.dates LIKE ' . $search . ')'); + } + else + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + + $query->where('( e.title LIKE ' . $search . + ' OR e.username LIKE ' . $search . + ' OR e.id LIKE ' . $search . + ' OR e.email LIKE ' . $search . + ' OR e.file LIKE ' . $search . + ' OR e.place LIKE ' . $search . + ' OR e.city LIKE ' . $search . + ' OR e.country LIKE ' . $search . + ' OR e.desc LIKE ' . $search . + ' OR e.period LIKE ' . $search . + ' OR e.dates LIKE ' . $search . + ' OR c.title LIKE ' . $search . ')'); + } + } + } + + // Filter category (admin) + $category = $db->escape($this->getState('filter.category')); + + if (!empty($category)) + { + $query->where('(e.catid = ' . $category . ')'); + } + + // Filter Frontend Menu Itemid (admin) + $site_itemid = $db->escape($this->getState('filter.site_itemid')); + + if ($site_itemid == '0') + { + $query->where('(e.site_itemid = "0")'); + } + elseif ($site_itemid) + { + $query->where('(e.site_itemid = ' . (int) $site_itemid . ')'); + } + + // Filter by categories. (NOT USED (multiple-categories filter)) + $categoryId = $this->getState('filter.category_id'); + + if (is_numeric($categoryId) && ! empty($categoryId)) + { + $query->where('e.catid = ' . (int) $categoryId . ''); + } + elseif (is_array($categoryId) && ! empty($categoryId)) + { + JArrayHelper::toInteger($categoryId); + $categoryId = implode(',', $categoryId); + $query->where('e.catid IN (' . $categoryId . ')'); + } + + + // Filter Upcoming Dates + $upcoming = $db->escape($this->getState('filter.upcoming')); + + if ( ! empty($upcoming)) + { + if ($upcoming == '1') + { + $query->where(' e.next >= CURDATE()'); + } + elseif ($upcoming == '2') + { + $query->where(' e.next < CURDATE() '); + } + elseif ($upcoming == '3') + { + $query->where(' e.next >= NOW() '); + } + elseif ($upcoming == '4') + { + $query->where(' e.next >= CURDATE() AND e.next < ( CURDATE() + INTERVAL 1 DAY ) '); + } + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering'); + $orderDirn = $this->state->get('list.direction'); + + if ($orderCol && $orderDirn) + { + $query->order($db->escape($orderCol.' '.$orderDirn)); + } + + return $query; + } + + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 3.6.0 + */ + public function getItems() + { + // Since Joomla 3.6.0, need to check if user ID exists to prevent alert message in list + $usersTable = JUser::getTable(); + + if ($items = parent::getItems()) + { + // Do any procesing on fields here if needed + foreach ($items AS $item) + { + if ($item->created_by && $usersTable->load($item->created_by)) + { + $item->username = JFactory::getUser($item->created_by)->get('name'); + } + + // Check Next Date + $item->next = icagendaEvent::getNextDate($item); + } + } + + return $items; + } + + /** + * Build an SQL query to load the list of all categories. + * + * @return JDatabaseQuery + * @since 3.3.0 + */ + function getCategories() + { + // Create a new query object. + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select('c.id AS catid, c.title AS category'); + $query->from('#__icagenda_category AS c'); + + // Filter by published state + $query->where('(c.state IN (0,1))'); + + // Order Ordering ASC + $query->order('c.ordering ASC'); + + $db->setQuery($query); + $categories = $db->loadObjectList(); + + if (count($categories) > 0) + { + foreach ($categories as $cat) + { + $list[$cat->catid] = $cat->category; + } + + return $list; + } + else + { + return array(); + } + } + + /** + * Build an SQL query to load the list of menu item itemid. + * + * @return JDatabaseQuery + * @since 3.3.0 + */ + function getMenuItemID() + { + // Create a new query object. + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select('m.id AS itemid, m.link AS menu_link, m.title AS menu_title'); + $query->from('#__menu AS m'); + + // Filter by published state + $query->where('(m.link = "index.php?option=com_icagenda&view=submit")'); + $query->where('(m.published IN (0,1))'); + + $db->setQuery($query); + $itemids = $db->loadObjectList(); + + $list['0'] = 'Created in admin'; + + if (count($itemids) > 0) + { + foreach ($itemids as $itemid) + { + $list[$itemid->itemid] = $itemid->itemid . ' - ' . $itemid->menu_title; + } + + return $list; + } + else + { + return array(); + } + } + + /** + * Gets a list of options for Upcoming (Events) Filter. + * + * @since 3.3.0 + */ + function getUpcoming() + { + $list['1'] = JText::_('COM_ICAGENDA_OPTION_TODAY_AND_UPCOMING'); + $list['2'] = JText::_('COM_ICAGENDA_OPTION_PAST_EVENTS'); + $list['3'] = JText::_('COM_ICAGENDA_OPTION_UPCOMING_EVENTS'); + $list['4'] = JText::_('COM_ICAGENDA_OPTION_TODAY'); + + return $list; + } + + /** + * Gets a list of options for Approval Filter. + * + * @since 3.6.12 + */ + function getApprovalOptions() + { + $list['0'] = JText::_('COM_ICAGENDA_APPROVED'); + $list['1'] = JText::_('COM_ICAGENDA_UNAPPROVED'); + + return $list; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/feature.php b/deployed/icagenda/administrator/components/com_icagenda/models/feature.php new file mode 100644 index 00000000..32123607 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/feature.php @@ -0,0 +1,172 @@ +loadForm('com_icagenda.feature', 'feature', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * @since 3.4.0 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_icagenda.edit.feature.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer The id of the primary key. + * + * @return mixed Object on success, false on failure. + * @since 3.4.0 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) + { + //Do any procesing on fields here if needed + } + + return $item; + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @since 3.4.0 + */ + protected function prepareTable($table) + { + jimport('joomla.filter.output'); + + if (empty($table->id)) + { + // Set ordering to the last item if not set + if (@$table->ordering === '') + { + $db = JFactory::getDbo(); + $db->setQuery('SELECT MAX(ordering) FROM #__icagenda_feature'); + $max = $db->loadResult(); + $table->ordering = $max+1; + } + } + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 3.4.0 + */ + public function save($data) + { + $date = JFactory::getDate(); + + if (empty($data['created'])) + { + $data['created'] = !empty($data['created']) ? $data['created'] : $date->toSql(); + } + + // Generates Alias if empty + // Alias is not generated if non-latin characters, so we fix it by using created date, or title if unicode is activated, as alias + if ($data['alias'] == null || empty($data['alias'])) + { + $data['alias'] = JFilterOutput::stringURLSafe($data['title']); + + if ($data['alias'] == null || empty($data['alias'])) + { + if (JFactory::getConfig()->get('unicodeslugs') == 1) + { + $data['alias'] = JFilterOutput::stringURLUnicodeSlug($data['title']); + } + else + { + $data['alias'] = JFilterOutput::stringURLSafe($data['created']); + } + } + } + + $return = parent::save($data); + + return $return; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/features.php b/deployed/icagenda/administrator/components/com_icagenda/models/features.php new file mode 100644 index 00000000..689ea891 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/features.php @@ -0,0 +1,164 @@ +getUserStateFromRequest($this->context.'.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + $published = $app->getUserStateFromRequest($this->context.'.filter.state', 'filter_published', '', 'string'); + $this->setState('filter.state', $published); + + // Load the parameters. + $params = JComponentHelper::getParams('com_icagenda'); + $this->setState('params', $params); + + // List state information. + parent::populateState('a.title', 'asc'); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * @return string A store id. + * @since 3.4.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id.= ':' . $this->getState('filter.search'); + $id.= ':' . $this->getState('filter.state'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * @since 3.4.0 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.*' + ) + ); + $query->from('#__icagenda_feature AS a'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor'); + $query->leftJoin('#__users AS uc ON uc.id=a.checked_out'); + + // Filter by published state + $published = $this->getState('filter.state'); + if (is_numeric($published)) + { + $query->where('a.state=' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.state IN (0, 1))'); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->Quote('%'.$db->escape($search, true).'%'); + $query->where("(a.title LIKE $search OR a.desc LIKE $search)"); + } + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering'); + $orderDirn = $this->state->get('list.direction'); + + if ($orderCol && $orderDirn) + { + $query->order($db->escape("$orderCol $orderDirn")); + } + + return $query; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields.php new file mode 100644 index 00000000..d8e27763 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields.php @@ -0,0 +1,26 @@ +getTag(); + $langName = $lang->getName(); + + if ( ! file_exists(JPATH_LIBRARIES . '/ic_library/globalize/culture/' . $langTag . '.php')) + { + $langTag = 'en-GB'; + $currentText = JTEXT::_('COM_ICAGENDA_DATE_FORMAT_DEFAULT') . ' [' . $langTag . '] :'; + + } + else + { + $currentText = JTEXT::_('COM_ICAGENDA_DATE_FORMAT_CURRENT') . ' [' . $langTag . '] :'; + } + + $globalize = JPATH_LIBRARIES . '/ic_library/globalize/culture/' . $langTag . '.php'; + $iso = JPATH_LIBRARIES . '/ic_library/globalize/culture/iso.php'; + + require_once $globalize; + require_once $iso; + + $class = isset($class) ? ' class="' . $class . '"' : ''; + $selected = ' selected="selected" style="background:#D4D4D4;"'; + + // Start Select List of Date Formats + $html = ''; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/iclist/index.html b/deployed/icagenda/administrator/components/com_icagenda/models/fields/iclist/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/iclist/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/city.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/city.php new file mode 100644 index 00000000..2ded61ed --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/city.php @@ -0,0 +1,48 @@ +get('ic_submit_city', ''); + + $city_value = $ic_submit_city ? $ic_submit_city : $this->value; + + $class = isset($this->class) ? ' class="' . $this->class . '"' : ''; + + $html = '
'; + $html.= ' '; + + // clear the data so we don't process it again + $session->clear('ic_submit_city'); + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/country.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/country.php new file mode 100644 index 00000000..a98e63ca --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/country.php @@ -0,0 +1,48 @@ +get('ic_submit_country', ''); + + $country_value = $ic_submit_country ? $ic_submit_country : $this->value; + + $class = isset($this->class) ? ' class="' . $this->class . '"' : ''; + + $html = '
'; + $html.= ' '; + + // clear the data so we don't process it again + $session->clear('ic_submit_country'); + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/index.html b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/lat.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/lat.php new file mode 100644 index 00000000..670da032 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/lat.php @@ -0,0 +1,83 @@ +input->getInt('id'); + + $class = isset($this->class) ? ' class="' . $this->class . '"' : ''; + + if (isset($id)) + { + $db = JFactory::getDbo(); + $db->setQuery( + 'SELECT a.coordinate' . + ' FROM #__icagenda_events AS a' . + ' WHERE a.id = ' . (int) $id + ); + + $coords = $db->loadResult(); + } + else + { + $coords = NULL; + } + + $ic_submit_lat = $session->get('ic_submit_lat', ''); + + $lat_value = $ic_submit_lat ? $ic_submit_lat : $this->value; + + if ($coords != NULL + && $lat_value == '0.0000000000000000') + { + $ex = explode(', ', $coords); + $lat_value = $ex[0]; + } + elseif ($lat_value != '0.0000000000000000') + { + $lat_value = $lat_value; + } + else + { + $lat_value = NULL; + } + + $html = '
'; + $html.= ' '; + + // clear the data so we don't process it again + $session->clear('ic_submit_lat'); + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/lng.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/lng.php new file mode 100644 index 00000000..0b0b9eaa --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/icmap/lng.php @@ -0,0 +1,83 @@ +input->getInt('id'); + + $class = isset($this->class) ? ' class="' . $this->class . '"' : ''; + + if (isset($id)) + { + $db = JFactory::getDbo(); + $db->setQuery( + 'SELECT a.coordinate' . + ' FROM #__icagenda_events AS a' . + ' WHERE a.id = ' . (int) $id + ); + + $coords = $db->loadResult(); + } + else + { + $coords = NULL; + } + + $ic_submit_lng = $session->get('ic_submit_lng', ''); + + $lng_value = $ic_submit_lng ? $ic_submit_lng : $this->value; + + if ($coords != NULL + && $lng_value == '0.0000000000000000') + { + $ex = explode(', ', $coords); + $lng_value = $ex[1]; + } + elseif ($lng_value != '0.0000000000000000') + { + $lng_value = $lng_value; + } + else + { + $lng_value = NULL; + } + + $html = '
'; + $html.= ' '; + + // clear the data so we don't process it again + $session->clear('ic_submit_lng'); + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/index.html b/deployed/icagenda/administrator/components/com_icagenda/models/fields/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/list.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/list.php new file mode 100644 index 00000000..74205e8c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/list.php @@ -0,0 +1,263 @@ +class) ? ' class="' . $this->class . '"' : ''; + $attr .= !empty($this->size) ? ' size="' . $this->size . '"' : ''; + $attr .= $this->multiple ? ' multiple' : ''; + $attr .= $this->required ? ' required aria-required="true"' : ''; + $attr .= $this->autofocus ? ' autofocus' : ''; + + // To avoid user's confusion, readonly="true" should imply disabled="true". + if ((string) $this->readonly == '1' || (string) $this->readonly == 'true' || (string) $this->disabled == '1'|| (string) $this->disabled == 'true') + { + $attr .= ' disabled="disabled"'; + } + + // Initialize JavaScript field attributes. + $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : ''; + + // Get the field options. + $options = (array) $this->getOptions(); + + // Create a read-only list (no name) with hidden input(s) to store the value(s). + if ((string) $this->readonly == '1' || (string) $this->readonly == 'true') + { + $html[] = JHtml::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $this->value, $this->id); + + // E.g. form field type tag sends $this->value as array + if ($this->multiple && is_array($this->value)) + { + if (!count($this->value)) + { + $this->value[] = ''; + } + + foreach ($this->value as $value) + { + $html[] = ''; + } + } + else + { + $html[] = ''; + } + } + else + // Create a regular list. + { + $html[] = JHtml::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id); + } + + return implode($html); + } + + /** + * Method to get the field options. + * + * @return array The field option objects. + * + * @since 3.7.0 + */ + protected function getOptions() + { + $fieldname = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $this->fieldname); + $options = array(); + + foreach ($this->element->xpath('option') as $option) + { + // Filter requirements + if ($requires = explode(',', (string) $option['requires'])) + { + // Requires multilanguage + if (in_array('multilanguage', $requires) && !JLanguageMultilang::isEnabled()) + { + continue; + } + + // Requires associations + if (in_array('associations', $requires) && !JLanguageAssociations::isEnabled()) + { + continue; + } + } + + $value = (string) $option['value']; + $text = trim((string) $option) != '' ? trim((string) $option) : $value; + + $disabled = (string) $option['disabled']; + $disabled = ($disabled == 'true' || $disabled == 'disabled' || $disabled == '1'); + $disabled = $disabled || ($this->readonly && $value != $this->value); + + $checked = (string) $option['checked']; + $checked = ($checked == 'true' || $checked == 'checked' || $checked == '1'); + + $selected = (string) $option['selected']; + $selected = ($selected == 'true' || $selected == 'selected' || $selected == '1'); + + $tmp = array( + 'value' => $value, + 'text' => JText::alt($text, $fieldname), + 'disable' => $disabled, + 'class' => (string) $option['class'], + 'selected' => ($checked || $selected), + 'checked' => ($checked || $selected), + ); + + // Set some event handler attributes. But really, should be using unobtrusive js. + $tmp['onclick'] = (string) $option['onclick']; + $tmp['onchange'] = (string) $option['onchange']; + + // Add the option object to the result set. + $options[] = (object) $tmp; + } + + if ($this->element['useglobal']) + { + $tmp = new stdClass; + $tmp->value = ''; + $tmp->text = JText::_('JGLOBAL_USE_GLOBAL'); + $component = JFactory::getApplication()->input->getCmd('option'); + + // Get correct component for menu items + if (version_compare(JVERSION, '3.2', 'ge') + && $component == 'com_menus') + { + $link = $this->form->getData()->get('link'); + $uri = new JUri($link); + $component = $uri->getVar('option', 'com_menus'); + } + + $params = JComponentHelper::getParams($component); + $value = $params->get($this->fieldname); + + // Try with global configuration + if (is_null($value)) + { + $value = JFactory::getConfig()->get($this->fieldname); + } + + // Try with menu configuration + if (is_null($value) && JFactory::getApplication()->input->getCmd('option') == 'com_menus') + { + $value = JComponentHelper::getParams('com_menus')->get($this->fieldname); + } + + if (!is_null($value)) + { + $value = (string) $value; + + foreach ($options as $option) + { + if ($option->value === $value) + { + $value = $option->text; + + break; + } + } + + $tmp->text = (version_compare(JVERSION, '3.7', 'lt')) + ? JText::_('JGLOBAL_USE_GLOBAL') . ' (' . $value . ')' + : JText::sprintf('JGLOBAL_USE_GLOBAL_VALUE', $value); + } + + array_unshift($options, $tmp); + } + + reset($options); + + return $options; + } + + /** + * Method to add an option to the list field. + * + * @param string $text Text/Language variable of the option. + * @param array $attributes Array of attributes ('name' => 'value' format) + * + * @return JFormFieldList For chaining. + * + * @since 3.7.0 + */ + public function addOption($text, $attributes = array()) + { + if ($text && $this->element instanceof SimpleXMLElement) + { + $child = $this->element->addChild('option', $text); + + foreach ($attributes as $name => $value) + { + $child->addAttribute($name, $value); + } + } + + return $this; + } + + /** + * 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 3.7.0 + */ + public function __get($name) + { + if ($name == 'options') + { + return $this->getOptions(); + } + + return parent::__get($name); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/cat.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/cat.php new file mode 100644 index 00000000..d22ef28d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/cat.php @@ -0,0 +1,140 @@ +class) ? ' class="' . $this->class . '"' : ''; + + if ($app->isAdmin()) + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + } + else + { + $iCparams = $app->getParams(); + } + + $orderby_catlist = $iCparams->get('orderby_catlist', 'alpha'); + $default_catlist = $iCparams->get('default_catlist', ''); + + $admin_status_catlist = $iCparams->get('admin_status_catlist', '1'); + $site_status_catlist = $iCparams->get('site_status_catlist', '1'); + + $admin_status_array = is_array($admin_status_catlist) ? $admin_status_catlist : array($admin_status_catlist); + $site_status_array = is_array($site_status_catlist) ? $site_status_catlist : array($site_status_catlist); + + $admin_status = implode(',', $admin_status_array); + $site_status = implode(',', $site_status_array); + + $catid = $session->get('ic_submit_catid', ''); + + // Query List of Categories + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('c.ordering, c.title, c.state, c.id'); + $query->from($db->qn('#__icagenda_category') . ' AS c'); + + // Not display Trashed Categories + $query->where($db->qn('c.state') . ' <> -2'); + + if ($app->isAdmin()) + { + $query->where($db->qn('c.state') . ' IN (' . $admin_status . ') '); + } + else + { + $query->where($db->qn('c.state') . ' IN (' . $site_status . ') '); + } + + if ($orderby_catlist == 'alpha') + { + $query->order('c.title ASC'); + } + elseif ($orderby_catlist == 'ralpha') + { + $query->order('c.title DESC'); + } + elseif ($orderby_catlist == 'order') + { + $query->order('c.ordering ASC'); + } + + $db->setQuery($query); + $categories = $db->loadObjectList(); + + $html = ''; + + // clear the data so we don't process it again + $session->clear('ic_submit_catid'); + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/checkdnsrr.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/checkdnsrr.php new file mode 100644 index 00000000..0b5498e0 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/checkdnsrr.php @@ -0,0 +1,48 @@ + ' . JText::_('COM_ICAGENDA_REGISTRATION_EMAIL_CHECKDNSRR_NOT_PRESENT_1') . '
' . JText::_('COM_ICAGENDA_REGISTRATION_EMAIL_CHECKDNSRR_NOT_PRESENT_2') . '
'; + } + else + { + $html = '
' . JText::_('COM_ICAGENDA_REGISTRATION_EMAIL_CHECKDNSRR_NOT_PRESENT_1') . '
' . JText::_('COM_ICAGENDA_REGISTRATION_EMAIL_CHECKDNSRR_NOT_PRESENT_2') . '
'; + } + } + else + { + $html = ''; + } + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/color.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/color.php new file mode 100644 index 00000000..c1df1bb3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/color.php @@ -0,0 +1,40 @@ + +
+ +
+
+
+
+
+ '; + + return $html; + } +} \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/coordinate.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/coordinate.php new file mode 100644 index 00000000..4e9f2f05 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/coordinate.php @@ -0,0 +1,49 @@ +input->get('def'); + + if ($def == '') $def = $this->value; + + $html = ' + +
+ '; + + $html.= ' + '; + + return $html; + } +} \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/date.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/date.php new file mode 100644 index 00000000..255dff96 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/date.php @@ -0,0 +1,176 @@ +getTag() == 'fa-IR') ? '_jalali' : ''; + + if ($lang->getTag() == 'fa-IR') + { + // Including fallback code for HTML5 non supported browsers. + JHtml::_('jquery.framework'); + JHtml::_('script', 'system/html5fallback.js', false, true); + } + + $id = JFactory::getApplication()->input->getInt('id'); + + $class = !empty($this->class) ? ' ' . $this->class : ''; + + $session = JFactory::getSession(); + $datesDB = $session->get('ic_submit_dates', ''); + + if ($id && empty($datesDB)) + { + $db = JFactory::getDBO(); + $db->setQuery( + 'SELECT a.dates' . + ' FROM #__icagenda_events AS a' . + ' WHERE a.id = ' . (int) $id + ); + $datesDB = $db->loadResult(); + } + + $dates = iCString::isSerialized($datesDB) ? unserialize($datesDB) : false; + + if ($dates) + { + foreach ($dates as $key => $date) + { + if ( ! iCDate::isDate($date)) + { + unset($dates[$key]); + } + } + } + +// if ($lang->getTag() == 'fa-IR' +// && $dates +// && $dates != array('0000-00-00 00:00')) +// { +// $dates_to_sql = array(); + +// foreach ($dates AS $date) +// { +// if (iCDate::isDate($date)) +// { +// $year = date('Y', strtotime($date)); +// $month = date('m', strtotime($date)); +// $day = date('d', strtotime($date)); +// $time = date('H:i', strtotime($date)); + +// $dates_to_sql[] = iCGlobalizeConvert::gregorianToJalali($year, $month, $day, true) . ' ' . $time; +// } +// } + +// $dates = $dates_to_sql; +// } + + $html = ''; + + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + + $add_counter = 0; + + if ($dates + && $dates != array('0000-00-00 00:00')) + { + foreach ($dates as $date) + { + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + } + + // clear the data so we don't process it again + $session->clear('ic_submit_dates'); + } + else + { + $html.= ''; + $html.= ''; + $html.= ''; + $html.= ''; + } + + $html.= '
'; + $html.= JText::_('COM_ICAGENDA_TB_DATE'); + $html.= ''; +// $html.= JText::_('COM_ICAGENDA_TB_ACT'); + $html.= '
'; + + if ($lang->getTag() == 'fa-IR') + { + $add_counter = $add_counter+1; +// $this_number = $add_counter ? $add_counter : ''; + $html.= JHtml::_('calendar', $date, 'd', 'date_jalali' . $add_counter, '%Y-%m-%d %H:%M', ' class="ic-date-input' . $id_suffix . '"'); + } + else + { + $html.= ''; + } + + $html.= ''; + $html.= '' . JText::_('COM_ICAGENDA_DELETE_DATE') . ''; + $html.= '
'; + + if ($lang->getTag() == 'fa-IR') + { + $html.= JHtml::_('calendar', '0000-00-00 00:00', 'd', 'date_jalali', '%Y-%m-%d %H:%M', ' class="ic-date-input' . $id_suffix . '"'); + } + else + { + $html.= ''; + } + $html.= ''; + $html.= '' . JText::_('COM_ICAGENDA_DELETE_DATE') . ''; + $html.= '
'; + + $html.= '' . JText::_('COM_ICAGENDA_ADD_DATE') . '
'; + + $html.= 'id . '_id"'; + $html.= ' name="' . $this->name . '"'; + $html.= ' value=\''.$datesDB.'\''; + $html.= '/>'; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/enddate.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/enddate.php new file mode 100644 index 00000000..b331e06d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/enddate.php @@ -0,0 +1,56 @@ +class) ? ' class="' . $this->class . '"' : ''; + + $lang = JFactory::getLanguage(); + + if ($lang->getTag() == 'fa-IR') + { + // Including fallback code for HTML5 non supported browsers. + JHtml::_('jquery.framework'); + JHtml::_('script', 'system/html5fallback.js', false, true); + + $attributes = ''; + + $html = JHtml::_('calendar', $this->value, $this->name, 'enddate_jalali', '%Y-%m-%d %H:%M:%S', $attributes); + } + else + { + $html =''; + } + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/evt.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/evt.php new file mode 100644 index 00000000..95381a7d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/evt.php @@ -0,0 +1,351 @@ +input; + $view = $jinput->get('view'); + $id = $jinput->get('id', null); + $eventid = $jinput->get('eventid', $this->value); + + $class = isset($this->class) ? ' class="' . $this->class . '"' : ''; + + $typeReg = $db_date = $db_period = $db_date_is_valid = ''; + + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('e.title, e.state, e.id, e.weekdays, e.params') + ->from('`#__icagenda_events` AS e'); + + if ($view == 'mail') + { + // Join Total of registrations + $query->select('r.count AS registered'); + $sub_query = $db->getQuery(true); + $sub_query->select('r.state, r.date AS reg_date, r.period AS reg_period, r.eventid, sum(r.people) AS count'); + $sub_query->from('`#__icagenda_registration` AS r'); + $sub_query->where('r.state = 1'); + $sub_query->where('r.email <> ""'); + $sub_query->group('r.eventid'); + $query->leftJoin('(' . (string) $sub_query . ') AS r ON (e.id = r.eventid)'); + $query->where('r.count > 0'); + } + + $query->order('e.title ASC'); + + $db->setQuery($query); + $events = $db->loadObjectList(); + + if ($eventid != 0 && $id && $view == 'registration') + { + $query = $db->getQuery(true); + $query->select('r.date AS reg_date, r.period AS reg_period') + ->from('`#__icagenda_registration` AS r'); + $query->where('r.eventid = ' . (int) $eventid); + $query->where('r.id = ' . (int) $id); + $db->setQuery($query); + $reg = $db->loadObject(); + + if ($reg) + { + $db_date = $reg->reg_date; + $db_date_is_valid = iCDate::isDate($db_date); + $db_period = $reg->reg_period; + } + } + + // User state used in Newsletter + $data = JFactory::getApplication()->getUserState('com_icagenda.mail.data', array()); + $session_eventid = isset($data['eventid']) ? $data['eventid'] : $eventid; + $session_date = isset($data['date']) ? $data['date'] : ''; + + $html = '
'; + $html.= ''; + $html.= '
'; + + $id_display = $id ? '&id=' . (int) $id : ''; + + if ($view == 'registration') + { + // Info message with 'Registration Type' option setting, if the saved date is not in the list of dates for selected event. + if ($typeReg == 1) + { + $reg_type = JText::_('COM_ICAGENDA_REG_BY_INDIVIDUAL_DATE'); + } + elseif ($typeReg == 2) + { + $reg_type = JText::_('COM_ICAGENDA_REG_FOR_ALL_DATES'); + } + else + { + $reg_type = JText::_('COM_ICAGENDA_REG_BY_DATE_OR_PERIOD'); + } + + $registration_type = '' . $reg_type . ''; + + $alert_reg_type = '
'; + $alert_reg_type.= '' . JText::sprintf('COM_ICAGENDA_REGISTRATION_TYPE_FOR_THIS_EVENT', $registration_type) . ''; + $alert_reg_type.= '
'; + $alert_reg_type = addslashes($alert_reg_type); + + // Alert message for a date saved with a version before 3.3.3 (date not formatted as expected in sql format) + $date_no_longer_exists = '"' . $db_date . '"'; + $alert_date_format = '
' . JText::_('NOTICE') . '
' . JText::sprintf('COM_ICAGENDA_REGISTRATION_ERROR_DATE_CONTROL', $date_no_longer_exists) . '
'; + $alert_date_format = addslashes($alert_date_format); + + // Alert message if a date does not exist anymore for the selected event + $alert_date_no_longer_exists = '
' . JText::_('COM_ICAGENDA_FORM_WARNING') . '
' . JText::sprintf('COM_ICAGENDA_REGISTRATION_DATE_NO_LONGER_EXISTS', $date_no_longer_exists) . '
'; + $alert_date_no_longer_exists = addslashes($alert_date_no_longer_exists); + + // Alert message if a date does not exist anymore for the selected event + $alert_full_period_no_longer_exists = '
' . JText::_('COM_ICAGENDA_FORM_WARNING') . '
' . JText::sprintf('COM_ICAGENDA_REGISTRATION_PERIOD_NO_LONGER_EXISTS', $date_no_longer_exists) . '
'; + $alert_full_period_no_longer_exists = addslashes($alert_full_period_no_longer_exists); + + // Alert message if a date or period is set for the registration, but event registration type is now 'for all dates of the event' + $for_all_dates = '' . JText::_('COM_ICAGENDA_ADMIN_REGISTRATION_FOR_ALL_DATES') . ''; + $alert_by_date_no_longer_possible = '
' . JText::_('COM_ICAGENDA_FORM_WARNING') . '
' . JText::sprintf('COM_ICAGENDA_REGISTRATION_BY_DATE_NO_LONGER_POSSIBLE', $for_all_dates, $for_all_dates) . '
'; + $alert_by_date_no_longer_possible = addslashes($alert_by_date_no_longer_possible); + + // Alert message if registration for all dates of the event, but event registration type is now 'select list of dates' + $by_date = '' . JText::_('COM_ICAGENDA_ADMIN_REGISTRATION_BY_INDIVIDUAL_DATE') . ''; + $alert_for_all_dates_no_longer_possible = '
' . JText::_('COM_ICAGENDA_FORM_WARNING') . '
' . JText::sprintf('COM_ICAGENDA_REGISTRATION_FOR_ALL_DATES_NO_LONGER_POSSIBLE', $by_date) . '
'; + $alert_for_all_dates_no_longer_possible = addslashes($alert_for_all_dates_no_longer_possible); + + $html.= '
'; + $html.= '
'; + + if ($typeReg == '1') + { + ?> + + + + + + input; + $view = $jinput->get('view'); + + $id = ($view == 'mail') ? $jinput->getInt('eventid', '0') : $jinput->getInt('id', '0'); + + if ($id != 0) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('r.id as reg_id, r.date AS reg_date, r.period AS reg_period, r.eventid AS reg_eventid, sum(r.people) AS reg_count') + ->from('#__icagenda_registration AS r'); + + if ($view == 'mail') + { + $query->where('r.state = 1'); + $query->group('r.date'); + } + + $query->where('r.eventid = ' . (int) $id); + + $db->setQuery($query); + + if ($view == 'mail') + { + $result = $db->loadObjectList(); + } + else + { + $result = $db->loadObject(); + $event_id = $result->reg_eventid; + $saveddate = $result->reg_date; + } + } + elseif ($view == 'registration') + { + $event_id = ''; + $saveddate = ''; + } + + if ($view == 'registration') + { + // Test if date saved in in datetime data format + $date_is_datetime_sql = false; + $array_ex_date = array('-', ' ', ':'); + $d_ex = str_replace($array_ex_date, '-', $saveddate); + $d_ex = explode('-', $d_ex); + + if (count($d_ex) > 4) + { + if ( strlen($d_ex[0]) == 4 + && strlen($d_ex[1]) == 2 + && strlen($d_ex[2]) == 2 + && strlen($d_ex[3]) == 2 + && strlen($d_ex[4]) == 2 ) + { + $date_is_datetime_sql = true; + } + } + + // Test if registered date before 3.3.3 could be converted + // Control if new date format (Y-m-d H:i:s) + $input = trim($saveddate); + $is_valid = date('Y-m-d H:i:s', strtotime($input)) == $input; + + if ($is_valid + && strtotime($saveddate)) + { + $date_get = explode (' ', $saveddate); + $saved_date = $date_get['0']; + $saved_time = date('H:i:s', strtotime($date_get['1'])); + } + else + { + // Explode to test if stored in old format in database + $ex_saveddate = explode (' - ', $saveddate); + $saved_date = isset($ex_saveddate['0']) ? trim($ex_saveddate['0']) : ''; + $saved_time = isset($ex_saveddate['1']) ? trim(date('H:i:s', strtotime($ex_saveddate['1']))) : ''; + } + + $data_eventid = $event_id; + + $eventid_url = $jinput->getInt('eventid', ''); + + if ( ! $date_is_datetime_sql && $saveddate ) + { + $saveddate_text = '"' . $saveddate . '"'; + echo '
' . JText::_('NOTICE') . '
' + . JText::sprintf('COM_ICAGENDA_REGISTRATION_ERROR_DATE_CONTROL', $saveddate_text) . '
'; + } + + $event_id = isset($event_id) ? $eventid_url : ''; + + $html = ''; + } + else + { + $html = ''; + } + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ic_editor.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ic_editor.php new file mode 100644 index 00000000..ff9940a7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ic_editor.php @@ -0,0 +1,56 @@ +value; + + if (strpos($icBody,'\n') !== false) + { + $array_newline = array('\\n', '\n'); + $icBody = str_replace($array_newline, '
', $icBody); + } + + $editor = JFactory::getEditor(); + + $html = array(); + + $html[] = '
'; + $html[] = $editor->display($this->name, $icBody, "100%", "300", "300", "20", 1, null, null, null, array('mode' => 'advanced')); + $html[] = '
'; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ic_password.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ic_password.php new file mode 100644 index 00000000..45e29d07 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ic_password.php @@ -0,0 +1,46 @@ +value); + $pass_ex = explode('.', $_pass); + + if (isset($pass_ex[1])) + { + $value = base64_decode($pass_ex[1]); // Decode password data stored + } + else + { + $value = $this->value; + } + + $html = ''; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icalert_msg.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icalert_msg.php new file mode 100644 index 00000000..482dc414 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icalert_msg.php @@ -0,0 +1,192 @@ +name); + $get_error = explode('_', $name_input); + $error = $get_error['1']; + $name = $get_error['0']; + + $url=JPATH_SITE.'/components/com_icagenda/themes/packs'; + + // Set Function to condition to be checked + $events_php=$this->getList($url); + $cal_date=$this->getCalDate($url); + + if ($name == 'eventsfile') + { + $list = $events_php; + $doc_url = 'http://www.icagenda.com/theme-pack-upgrade/3-2-8-new-option-all-dates'; + $parent_field = 'datesDisplay'; + $action_value = '1'; + } + elseif ($name == 'caldate') + { + $list = $cal_date; + $doc_url = 'http://www.icagenda.com/theme-pack-upgrade/3-3-3-change-cal-date-to-data-cal-date'; + $parent_field = 'setTodayTimezone'; + $action_value = ''; + } + + $span_style = 'input-xlarge'; + + if (version_compare(JVERSION, '3.0', 'lt')) { + $listP = implode('
- ', $list); + $setlist = ' - '.$listP.' '; + } else { + $listP = implode('
  • ', $list); + $setlist = '
    • '.$listP.'
    '; +// $span_style = 'span8'; + } + + $html = array(); + + if (count($list) >= 1) + { + $html[] = '
    '; + $html[] = ''.JText::_( $this->title ).''; + $html[] = '

    '; + $html[] = JText::_( $this->description ) . ' ' .JText::_( 'IC_MORE_INFORMATION' ). ''; + $html[] = '

    '; + + if ($this->id == 'jform_params_'.$name.'_error') + { + $html[] = '

    '; + $html[] = ''.JText::_( 'COM_ICAGENDA_EVENTS_PHPFILE_MISSING_PACKS_LIST' ).'
    '; + $html[] = $setlist; + $html[] = '

    '; + } + $html[] = '
    '; + + $html[] = ''; + } + + return implode("\n", $html); + } + + /** + * Function to check if the file 'THEME_events.php' exists in each Theme Pack + */ + function getList($dirname) + { + $arrayfiles = Array(); + + if(file_exists($dirname)) + { + $handle = opendir($dirname); + + while (false !== ($file = readdir($handle))) + { + if ( !is_file($dirname.$file) + && $file!= '.' + && $file!='..' + && $file!='index.php' + && $file!='index.html' + && $file!='.DS_Store' + && $file!='.thumbs' ) + { + if (!file_exists($dirname.'/'.$file.'/'.$file.'_events.php')) + { + array_push($arrayfiles,$file); + } + } + } + $handle = closedir($handle); + } + sort($arrayfiles); + + return $arrayfiles; + } + + /** + * Function to check if 'data-cal-date' is defined inside the file 'THEME_day.php' for each Theme Pack. + * Returns an alert if deprecated 'cal_date' found. + */ + function getCalDate($dirname) + { + $arrayfiles = Array(); + + if (ini_get('allow_url_fopen')) + { + if (file_exists($dirname)) + { + $handle = opendir($dirname); + + while (false !== ($file = readdir($handle))) + { + if ( !is_file($dirname.$file) + && $file!= '.' + && $file!='..' + && $file!='index.php' + && $file!='index.html' + && $file!='.DS_Store' + && $file!='.thumbs' ) + { + $t_day = $dirname.'/'.$file.'/'.$file.'_day.php'; + $file_t_day = file_get_contents($t_day); + + if (!strpos($file_t_day, "cal_date") + && !strpos($file_t_day, "data-cal-date")) + { + array_push($arrayfiles,$file); + } + elseif (strpos($file_t_day, "cal_date")) + { + array_push($arrayfiles,$file); + } + } + } + } + $handle = closedir($handle); + } + sort($arrayfiles); + + return $arrayfiles; + } + +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icfile.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icfile.php new file mode 100644 index 00000000..90166360 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icfile.php @@ -0,0 +1,145 @@ +element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id'; + $authorField = $this->element['created_by_field'] ? (string) $this->element['created_by_field'] : 'created_by'; + $asset = $this->form->getValue($assetField) ? $this->form->getValue($assetField) : (string) $this->element['asset_id']; + + if ($asset == '') + { + $asset = JFactory::getApplication()->input->get('option'); + } + + $link = (string) $this->element['link']; + + if ( ! self::$initialised) + { + // Load the modal behavior script. + JHtml::_('behavior.modal'); + + // Build the script. + $script = array(); + $script[] = ' function jInsertFieldValue(value, id) {'; + $script[] = ' var old_id = document.id(id).value;'; + $script[] = ' if (old_id != id) {'; + $script[] = ' var elem = document.id(id)'; + $script[] = ' elem.value = value;'; + $script[] = ' elem.fireEvent("change");'; + $script[] = ' }'; + $script[] = ' }'; + + // Add the script to the document head. + JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); + + self::$initialised = true; + } + + // Initialize variables. + $html = array(); + $attr = ''; + + // Initialize some field attributes. + $attr .= $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + $attr .= $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : ''; + $attr .= $this->element['accept'] ? ' accept="' . (string) $this->element['accept'] . '"' : ''; + $attr .= ((string) $this->element['disabled'] == 'true') ? ' disabled="disabled"' : ''; + + // Initialize JavaScript field attributes. + $attr .= $this->element['onchange'] ? ' onchange="' . (string) $this->element['onchange'] . '"' : ''; + + // The text field. + if ($this->value == NULL) + { + $html[] = ''; + $html[] = ' '; + $html[] = ''; + } + else + { + $html[] = ''; + $html[] = ' '; + $html[] = ''; + } + +// $folder = 'icagenda_doc'; + + // The button. +// $html[] = '
    '; +// $html[] = '
    '; +// $html[] = ' '; +// $html[] = JText::_('JLIB_FORM_BUTTON_SELECT') . ''; +// $html[] = '
    '; +// $html[] = '
    '; + + if ($this->value == NULL) + { + $html[] = '
    '; + $html[] = ' '; + $html[] = '
    '; + } + else + { + $html[] = '
    '; + $html[] = ' '; + $html[] = '
    '; + } + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/iclink_article.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/iclink_article.php new file mode 100644 index 00000000..d1b37b7e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/iclink_article.php @@ -0,0 +1,195 @@ +name); + $TypeName = $Explode[0] . ']'; + + $replace = array("jform", "params", "[", "]"); + $name = str_replace($replace, "", $TypeName); + + $allowEdit = ((string) $this->element['edit'] == 'true') ? true : false; + $allowClear = ((string) $this->element['clear'] != 'false') ? true : false; + + // Load language + JFactory::getLanguage()->load('com_content', JPATH_ADMINISTRATOR); + + // Load the modal behavior script. + JHtml::_('behavior.modal', 'a.modal'); + + // Build the script. + $script = array(); + + // Select button script + $script[] = ' function jSelectArticle_' . $this->id . '(id, title, catid, object) {'; + $script[] = ' document.getElementById("' . $this->id . '_id").value = id;'; + $script[] = ' document.getElementById("' . $this->id . '_name").value = title;'; + + if ($allowEdit) + { + $script[] = ' jQuery("#' . $this->id . '_edit").removeClass("hidden");'; + } + + if ($allowClear) + { + $script[] = ' jQuery("#' . $this->id . '_clear").removeClass("hidden");'; + } + + $script[] = ' SqueezeBox.close();'; + $script[] = ' }'; + + // Clear button script + static $scriptClear; + + if ($allowClear && !$scriptClear) + { + $scriptClear = true; + + $script[] = ' function jClearArticle(id) {'; + $script[] = ' document.getElementById(id + "_id").value = "";'; + $script[] = ' document.getElementById(id + "_name").value = "' . htmlspecialchars(JText::_('COM_CONTENT_SELECT_AN_ARTICLE', true), ENT_COMPAT, 'UTF-8') . '";'; + $script[] = ' jQuery("#"+id + "_clear").addClass("hidden");'; + $script[] = ' if (document.getElementById(id + "_edit")) {'; + $script[] = ' jQuery("#"+id + "_edit").addClass("hidden");'; + $script[] = ' }'; + $script[] = ' return false;'; + $script[] = ' }'; + } + + // Add the script to the document head. + JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); + + // Setup variables for display. + $html = array(); + $link = 'index.php?option=com_content&view=articles&layout=modal&tmpl=component&function=jSelectArticle_' . $this->id; + + if (isset($this->element['language'])) + { + $link .= '&forcedLanguage=' . $this->element['language']; + } + + $db = JFactory::getDbo(); + $db->setQuery( + 'SELECT title' . + ' FROM #__content' . + ' WHERE id = ' . (int) $this->value + ); + + try + { + $title = $db->loadResult(); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500, $e); + } + + if (empty($title)) + { + $title = JText::_('COM_CONTENT_SELECT_AN_ARTICLE'); + } + $title = htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); + + // The active article id field. + if (0 == (int) $this->value) + { + $value = ''; + } + else + { + $value = (int) $this->value; + } + + // The current article display field. + $html[] = '
     
    '; + $html[] = ''; + + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = '' . JText::_('JSELECT') . ''; + } + else + { + $html[] = ' ' . JText::_('JSELECT') . ''; + } + + // Edit article button + if ($allowEdit) + { + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = '' . JText::_('JACTION_EDIT') . ''; + } + else + { + $html[] = ' ' . JText::_('JACTION_EDIT') . ''; + } + } + + // Clear article button + if ($allowClear) + { + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = '' . JText::_('JCLEAR') . ''; + } + else + { + $html[] = ''; + } + } + + $html[] = ''; + + // class='required' for client side validation + $class = ''; + + if ($this->required) + { + $class = ' class="required modal-value"'; + } + + + $html[] = '
    '; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/iclink_type.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/iclink_type.php new file mode 100644 index 00000000..65294aa3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/iclink_type.php @@ -0,0 +1,129 @@ +input; + + $location = $jinput->get('option', 'com_config'); + + if ($location != 'com_config') + { + $default_text = JText::_('JGLOBAL_USE_GLOBAL'); + } + else + { + $default_text = JText::_('IC_DEFAULT'); + } + + // Get Type value + $Type = isset($this->value) ? $this->value : ''; + + // Clean jform name + $replace = array("jform", "params", "[", "]"); + $name = str_replace($replace, "", $this->name); + + $Type_default = $name . '_default'; + $Type_article = $name . '_article'; + $Type_url = $name . '_url'; + + // Set Var type, to get selected option + $jinput->set('type', $Type); + + // Article + if ($Type == '1') + { + $class_default = ''; + $class_article = 'btn-success'; + $class_url = ''; + $checked_default = ''; + $checked_article = ' checked="checked"'; + $checked_url = ''; + } + + // URL + elseif ($Type == '2') + { + $class_default = ''; + $class_article = ''; + $class_url = 'btn-success'; + $checked_default = ''; + $checked_article = ''; + $checked_url = ' checked="checked"'; + } + + // iCagenda default + else + { + $class_default = 'btn-primary'; + $class_article = ''; + $class_url = ''; + $checked_default = ' checked="checked"'; + $checked_article = ''; + $checked_url = ''; + } + + $html = array(); + $html[] = '
    '; + $html[] = ''; + $html[] = ''; + $html[] = ''; + $html[] = '
    '; + + // Script + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/iclink_url.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/iclink_url.php new file mode 100644 index 00000000..c40c49b6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/iclink_url.php @@ -0,0 +1,92 @@ +name); + $TypeName = $Explode[0] . ']'; + + $replace = array("jform", "params", "[", "]"); + $name = str_replace($replace, "", $TypeName); + + $Type = JFactory::getApplication()->input->get('type'); + + $Type_default = $name . '_default'; + $Type_article = $name . '_article'; + $Type_url = $name . '_url'; + + $editor = JFactory::getEditor(); + + $html = array(); + + $html[] = '
    '; + $html[] = ''; + $html[] = '
    '; + + // Article + if ($Type == '1') + { + $html[] = ''; + } + + // URL + elseif ($Type == '2') + { + $html[] = ''; + } + + // iCagenda default + else + { + $html[] = ''; + } + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icmulti_checkbox.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icmulti_checkbox.php new file mode 100644 index 00000000..1c4b230d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icmulti_checkbox.php @@ -0,0 +1,83 @@ +name); + $TypeName = $Explode[0].']'; + + $replace = array("jform", "[params]", "[", "]"); + $name = str_replace($replace, "", $TypeName); + + $selected = $this->value; + if (!is_array($selected)) $selected = array(); + + $check_1 = ' checked="checked"'; + $check_2 = ' checked="checked"'; + + if (in_array('1', $selected)) { + $check_1 = ' checked="checked"'; + } else { + $check_1 = ''; + } + if (in_array('2', $selected)) { + $check_2 = ' checked="checked"'; + } else { + $check_2 = ''; + } + + $Type_none = $name.'_none'; + $Type_checkbox = $name.'_checkbox'; + + $html = array(); + + $html[] = '
    '; +// $html[] = ''; + $html[] = '
     '.JText::_( 'ICTITLE' ).'
    '; + $html[] = '
     '.JText::_( 'ICDESC' ).'
    '; + $html[] = '
    '; + + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icmulti_opt.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icmulti_opt.php new file mode 100644 index 00000000..93221fe8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icmulti_opt.php @@ -0,0 +1,114 @@ +name); + $get_location = explode('_', $name_input); + $location = $get_location['1']; + $name = $get_location['0']; + + $Type = $this->value; + + $Type_none = $name . '_none'; + $Type_checkbox = $name . '_checkbox'; + + $class_global = 'btn-primary'; + $class_none = 'btn-danger'; + $class_checkbox = 'btn-success'; + $checked_none = ' checked="checked"'; + $checked_checkbox = ''; + + if ($Type == '0') + { + $class_global = ''; + $class_none = 'btn-danger'; + $class_checkbox = ''; + $checked_global = ''; + $checked_none = ' checked="checked"'; + $checked_checkbox = ''; + } + elseif ($Type == '1') + { + $class_global = ''; + $class_none = ''; + $class_checkbox = 'btn-success'; + $checked_global = ''; + $checked_none = ''; + $checked_checkbox = ' checked="checked"'; + } + else + { + $class_global = 'btn-primary'; + $class_none = ''; + $class_checkbox = ''; + $checked_global = ' checked="checked"'; + $checked_none = ''; + $checked_checkbox = ''; + } + + $html = array(); + + + $html[] = '
    '; + + if ($location == 'menu') + { + $html[] = ''; + } + + $html[] = ''; + $html[] = ''; + $html[] = '
    '; + + + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictext_content.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictext_content.php new file mode 100644 index 00000000..44e52b7e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictext_content.php @@ -0,0 +1,68 @@ +name); + $TypeName = $Explode[0].']'; + + $replace = array("jform", "[", "]"); + $name = str_replace($replace, "", $TypeName); + $icContent = $icagendaParams->get($name.'_Content', ''); + + $Type = $icagendaParams->get($name, ''); + + $Type_default = $name.'_default'; + $Type_content = $name.'_custom'; + + + $editor = JFactory::getEditor(); + + $html = array(); + + $html[] = '
    '; + $html[] = $editor->display($this->name, $icContent, "100%", "300", "300", "20", 1, null, null, null, array('mode' => 'advanced')); + $html[] = '
    '; + + if ($Type == '2') { + $html[] = ''; + } else { + $html[] = ''; + } + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictext_placeholder.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictext_placeholder.php new file mode 100644 index 00000000..029658b8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictext_placeholder.php @@ -0,0 +1,50 @@ +input->get('class'); + + $icagendaParams = JComponentHelper::getParams('com_icagenda'); + + $replace = array("jform", "[", "]", "_Placeholder"); + $name = str_replace($replace, "", $this->name); + $Type = $name . '_Placeholder'; + + $tos_Type = $icagendaParams->get($Type); + + $placeholder = ( ! isset($tos_Type)) ? JText::_( 'COM_ICAGENDA_' . strtoupper($name) . '_PLACEHOLDER') : ''; + + $html =''; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictext_type.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictext_type.php new file mode 100644 index 00000000..8b2c65bc --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictext_type.php @@ -0,0 +1,85 @@ +name); + $Type = $icagendaParams->get($name, ''); + + $Type_default = $name.'_default'; + $Type_content = $name.'_custom'; + + $class_default = ''; + $class_custom = ''; + $checked_default = ''; + $checked_custom = ''; + if ($Type == '') { + $class_default = 'btn-success'; + $checked_default = ' checked="checked"'; + $checked_custom = ''; + } + elseif ($Type == '2') { + $class_custom = 'btn-success'; + $checked_default = ''; + $checked_custom = ' checked="checked"'; + } else { + $class_default = 'btn-success'; + $checked_default = ' checked="checked"'; + $checked_custom = ''; + } + + $html = array(); + $html[] = '
    '; + $html[] = ''; + $html[] = ''; + $html[] = '
    '; + + + + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictextarea_counter.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictextarea_counter.php new file mode 100644 index 00000000..ae2fe2cc --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictextarea_counter.php @@ -0,0 +1,154 @@ +name); + $nb_chars = strlen(trim(utf8_decode($this->value))); + $class = !empty($this->class) ? ' class="' . $this->class . '"' : ''; + + if ($app->isAdmin()) + { + $params = JComponentHelper::getParams('com_icagenda'); + $iCparams = JComponentHelper::getParams('com_icagenda'); + } + else + { + $params = $app->getParams(); + $iCparams = JComponentHelper::getParams('com_icagenda'); + } + + $session = JFactory::getSession(); + $ic_submit_shortdesc = $session->get('ic_submit_shortdesc', ''); + $ic_submit_metadesc = $session->get('ic_submit_metadesc', ''); + + $event_shortdesc = $ic_submit_shortdesc ? $ic_submit_shortdesc : $this->value; + $event_metadesc = $ic_submit_metadesc ? $ic_submit_metadesc : $this->value; + + if ($name == 'shortdesc') + { + $ic_max_component = $iCparams->get('char_limit_short_description', '100'); + $ic_max = $params->get('char_limit_short_description', '100'); + $ic_max = ($ic_max_component >= $ic_max) ? $ic_max : $ic_max_component; + } + elseif ($name == 'metadesc') + { + $ic_max_component = $iCparams->get('char_limit_meta_description', '320'); + $ic_max = $params->get('char_limit_meta_description', '320'); + $ic_max = ($ic_max_component >= $ic_max) ? $ic_max : $ic_max_component; + } + else + { + $ic_max = $params->get('ShortDescLimit', '100'); + } + + // Alert if text stored in the database exceeds the character limit currently set. + $display_alert = ($nb_chars > $ic_max) ? true : false; + + $count_value = $nb_chars ? ($ic_max-$nb_chars) : $ic_max; + $ic_size = (strlen($ic_max))-1; + $ic_size = $ic_size ? $ic_size : '1'; + + $counter_input = 'name . ', this, ' . $ic_max . ');"'; + $counter_input.= ' class="valid"'; +// $counter_input.= ' onfocus="this.blur();"'; +// $counter_input.= ' tabindex="999" maxlength="' . $ic_size . '" size="' . $ic_size . '"'; + $counter_input.= ' size="' . $ic_size . '"'; + $counter_input.= ' value="' . $count_value . '"'; + $counter_input.= ' name="counter_' . $name . '">'; + + $html = '
    '; + + if ($display_alert) + { + $html.= '

    Warning

    ' + . JText::sprintf('COM_ICAGENDA_ALERT_S_TEXT_S_EXCEEDS_CHARACTER_LIMIT', $this->title) . '
    ' + . JText::_('COM_ICAGENDA_ALERT_EDIT_TEXT_TO_FIT_CHAR_LIMIT') . '

    ' + . JText::sprintf('COM_ICAGENDA_ALERT_S_TEXT_S_CURRENTLY_STORED_IN_DATABASE', $this->title) . ' :
    ' + . $this->value . '
    '; + } + $html.= ''; + + if ($name == 'shortdesc') + { + $html.= $event_shortdesc; + + // clear the data so we don't process it again + $session->clear('ic_submit_shortdesc'); + } + elseif ($name == 'metadesc') + { + $html.= $event_metadesc; + + // clear the data so we don't process it again + $session->clear('ic_submit_metadesc'); + } + else + { + $html.= $this->value; + } + + $html.= ''; + + $html.= '
    '; + $html.= '
    '; + $html.= '
    '; + $html.= JText::sprintf('COM_ICAGENDA_MAXIMUM_N_CHARACTERS', $ic_max); + $html.= '
    '; + $html.= '
    '; + $html.= JText::sprintf('COM_ICAGENDA_N_REMAINING', $counter_input); + $html.= '
    '; + $html.= '
    '; + $html.= '
     
    '; + +// $html.= ''; +// $html.= ''; +// $html.= '

    0 characters entered | 140 characters remaining

    '; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_article.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_article.php new file mode 100644 index 00000000..28c4c433 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_article.php @@ -0,0 +1,201 @@ +name); + + $tos_Type = $icagendaParams->get($name . '_Type', ''); + + $allowEdit = ((string) $this->element['edit'] == 'true') ? true : false; + $allowClear = ((string) $this->element['clear'] != 'false') ? true : false; + + // Load language + JFactory::getLanguage()->load('com_content', JPATH_ADMINISTRATOR); + + // Load the modal behavior script. + JHtml::_('behavior.modal', 'a.modal'); + + // Build the script. + $script = array(); + + // Select button script + $script[] = ' function jSelectArticle_' . $this->id . '(id, title, catid, object) {'; + $script[] = ' document.getElementById("' . $this->id . '_id").value = id;'; + $script[] = ' document.getElementById("' . $this->id . '_name").value = title;'; + + if ($allowEdit) + { + $script[] = ' jQuery("#' . $this->id . '_edit").removeClass("hidden");'; + } + + if ($allowClear) + { + $script[] = ' jQuery("#' . $this->id . '_clear").removeClass("hidden");'; + } + + $script[] = ' SqueezeBox.close();'; + $script[] = ' }'; + + // Clear button script + static $scriptClear; + + if ($allowClear && !$scriptClear) + { + $scriptClear = true; + + $script[] = ' function jClearArticle(id) {'; + $script[] = ' document.getElementById(id + "_id").value = "";'; + $script[] = ' document.getElementById(id + "_name").value = "' . htmlspecialchars(JText::_('COM_CONTENT_SELECT_AN_ARTICLE', true), ENT_COMPAT, 'UTF-8') . '";'; + $script[] = ' jQuery("#"+id + "_clear").addClass("hidden");'; + $script[] = ' if (document.getElementById(id + "_edit")) {'; + $script[] = ' jQuery("#"+id + "_edit").addClass("hidden");'; + $script[] = ' }'; + $script[] = ' return false;'; + $script[] = ' }'; + } + + // Add the script to the document head. + JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); + + // Setup variables for display. + $html = array(); + $link = 'index.php?option=com_content&view=articles&layout=modal&tmpl=component&function=jSelectArticle_' . $this->id; + + if (isset($this->element['language'])) + { + $link .= '&forcedLanguage=' . $this->element['language']; + } + + $db = JFactory::getDbo(); + $db->setQuery( + 'SELECT title' . + ' FROM #__content' . + ' WHERE id = ' . (int) $this->value + ); + + try + { + $title = $db->loadResult(); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500, $e); + } + + if (empty($title)) + { + $title = JText::_('COM_CONTENT_SELECT_AN_ARTICLE'); + } + $title = htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); + + // The active article id field. + if (0 == (int) $this->value) + { + $value = ''; + } + else + { + $value = (int) $this->value; + } + + // The current article display field. + $html[] = '
     
    '; + $html[] = ''; + + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = '' . JText::_('JSELECT') . ''; + } + else + { + $html[] = ' ' . JText::_('JSELECT') . ''; + } + + // Edit article button + if ($allowEdit) + { + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = '' . JText::_('JACTION_EDIT') . ''; + } + else + { + $html[] = ' ' . JText::_('JACTION_EDIT') . ''; + } + } + + // Clear article button + if ($allowClear) + { + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = '' . JText::_('JCLEAR') . ''; + } + else + { + $html[] = ''; + } + } + + $html[] = ''; + + // class='required' for client side validation + $class = ''; + + if ($this->required) + { + $class = ' class="required modal-value"'; + } + + $html[] = '
    '; + + if ($tos_Type == '1') + { + $html[] = ''; + } + else + { + $html[] = ''; + } + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_content.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_content.php new file mode 100644 index 00000000..94aa8a41 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_content.php @@ -0,0 +1,65 @@ +name); + + $tosContent = $icagendaParams->get($name.'Content', ''); + $tos_Type = $icagendaParams->get($name.'_Type', ''); + + $editor = JFactory::getEditor(); + + $html = array(); + + $html[] = '
    '; + $html[] = $editor->display($this->name, $tosContent, "100%", "300", "300", "20", 1, null, null, null, array('mode' => 'advanced')); + $html[] = '
    '; + + if ($tos_Type == '2') { + $html[] = ''; + } else { + $html[] = ''; + } + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_default.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_default.php new file mode 100644 index 00000000..d1afa3a9 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_default.php @@ -0,0 +1,79 @@ +name); + + $tos_Type = $icagendaParams->get($name.'_Type', ''); + + $Type_default = $name.'_default'; + $Type_article = $name.'_article'; + $Type_content = $name.'_custom'; + + $html = array(); + + $html[] = '
    '; + $html[] = '
    '; + if(version_compare(JVERSION, '3.0', 'ge')) { + $html[] = ''; + } + $html[] = ' '.JText::sprintf( 'COM_ICAGENDA_TERMS_IMPORTANT_INFOS', $this->description ).'
    '.JText::_( 'COM_ICAGENDA_SUBMIT_TOS_TYPE_DEFAULT_LBL' ).'
    '.$this->description.'
    '.JText::_( $this->description ).'
    '; + $html[] = ''; + $html[] = '
    '; + + if ($tos_Type == '') { + $html[] = ''; + } else { + $html[] = ''; + } + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_type.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_type.php new file mode 100644 index 00000000..550999a1 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ictxt_type.php @@ -0,0 +1,110 @@ +name); + + $Type = $name.'_Type'; + $tos_Type = $icagendaParams->get($Type, ''); + + $class_default = ''; + $class_article = ''; + $class_custom = ''; + $checked_default = ''; + $checked_article = ''; + $checked_custom = ''; + if ($tos_Type == '') { + $class_default = 'btn-success'; + $checked_default = ' checked="checked"'; + $checked_article = ''; + $checked_custom = ''; + } + elseif ($tos_Type == '1') { + $class_article = 'btn-success'; + $checked_default = ''; + $checked_article = ' checked="checked"'; + $checked_custom = ''; + } + elseif ($tos_Type == '2') { + $class_custom = 'btn-success'; + $checked_default = ''; + $checked_article = ''; + $checked_custom = ' checked="checked"'; + } else { + $class_default = 'btn-success'; + $checked_default = ' checked="checked"'; + $checked_article = ''; + $checked_custom = ''; + } + + $html = array(); + $html[] = '
    '; + $html[] = ''; + $html[] = ''; + $html[] = ''; + $html[] = '
    '; + + + + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icvalue_field.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icvalue_field.php new file mode 100644 index 00000000..8e4c9461 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icvalue_field.php @@ -0,0 +1,57 @@ +name); + $TypeName = $Explode[0].']'; + + $replace = array("jform", "[params]", "[", "]"); + $name = str_replace($replace, "", $TypeName); + + $Type_default = $name.'_default'; + $Type_content = $name.'_custom'; + + $html = array(); + + $html[] = '
    '; + $html[] = ''; + $html[] = '
    '; + + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icvalue_opt.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icvalue_opt.php new file mode 100644 index 00000000..25c84f9d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/icvalue_opt.php @@ -0,0 +1,89 @@ +name); + + $Type = $this->value; + + if ($name == 'calendarclosebtn') { + $default_text = JText::_( 'JTOOLBAR_DEFAULT' ); + } else { + $default_text = JText::_( 'JGLOBAL_USE_GLOBAL' ); + } + + $Type_default = $name.'_default'; + $Type_content = $name.'_custom'; + + $class_default = ''; + $class_custom = ''; + $checked_default = ' checked="checked"'; + $checked_custom = ''; + if ($Type == '0') { + $class_default = 'btn-primary'; + $checked_default = ' checked="checked"'; + $checked_custom = ''; + } + elseif ($Type == '1') { + $class_custom = 'btn-success'; + $checked_default = ''; + $checked_custom = ' checked="checked"'; + } else { + $class_default = 'btn-primary'; + $checked_default = ' checked="checked"'; + $checked_custom = ''; + } + + $html = array(); + + + $html[] = '
    '; + $html[] = ''; + $html[] = ''; + $html[] = '
    '; + + + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/index.html b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/media.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/media.php new file mode 100644 index 00000000..0f147b4a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/media.php @@ -0,0 +1,146 @@ +element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id'; + $authorField = $this->element['created_by_field'] ? (string) $this->element['created_by_field'] : 'created_by'; + $asset = $this->form->getValue($assetField) ? $this->form->getValue($assetField) : (string) $this->element['asset_id']; + + if ($asset == '') + { + $asset = JFactory::getApplication()->input->get('option'); + } + + $link = (string) $this->element['link']; + + if ( ! self::$initialised) + { + // Load the modal behavior script. + JHtml::_('behavior.modal'); + + // Build the script. + $script = array(); + $script[] = ' function jInsertFieldValue(value, id) {'; + $script[] = ' var old_id = document.id(id).value;'; + $script[] = ' if (old_id != id) {'; + $script[] = ' var elem = document.id(id)'; + $script[] = ' elem.value = value;'; + $script[] = ' elem.fireEvent("change");'; + $script[] = ' }'; + $script[] = ' }'; + + // Add the script to the document head. + JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); + + self::$initialised = true; + } + + // Initialize variables. + $html = array(); + $attr = ''; + + // Initialize some field attributes. + $attr .= $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + $attr .= $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : ''; + + // Initialize JavaScript field attributes. + $attr .= $this->element['onchange'] ? ' onchange="' . (string) $this->element['onchange'] . '"' : ''; + + // The text field. + $html[] = ''; + $html[] = ' '; + $html[] = ''; + + $directory = (string) $this->element['directory']; + + if ($this->value && file_exists(JPATH_ROOT . '/' . $this->value)) + { + $folder = explode('/', $this->value); + array_shift($folder); + array_pop($folder); + $folder = implode('/', $folder); + } + elseif (file_exists(JPATH_ROOT . '/' . JComponentHelper::getParams('com_media')->get('image_path', 'images') . '/' . $directory)) + { + $folder = $directory; + } + else + { + $folder = ''; + } + + // The button. + $html[] = ''; + $html[] = ' '; + $html[] = ' '; + $html[] = JText::_('JLIB_FORM_BUTTON_SELECT') . ''; + $html[] = ' '; + $html[] = ''; + + $html[] = ''; + $html[] = ' '; + $html[] = ' '; + $html[] = JText::_('JLIB_FORM_BUTTON_CLEAR') . ''; + $html[] = ' '; + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/menulink.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/menulink.php new file mode 100644 index 00000000..5ac0d3bb --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/menulink.php @@ -0,0 +1,61 @@ +getQuery(true); + + $query->select('a.title, a.published, a.id, a.path') + ->from('#__menu AS a') + ->where( "(link = 'index.php?option=com_icagenda&view=list') AND (published > 0)" ); + + $db->setQuery($query); + + $links = $db->loadObjectList(); + + $class = isset($this->class) ? ' class="' . $this->class . '"' : ''; + + $html = ''; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/multicat.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/multicat.php new file mode 100644 index 00000000..595a55fb --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/multicat.php @@ -0,0 +1,85 @@ +class) ? ' class="' . $this->class . '"' : ''; + + // Query List of Categories + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('a.title, a.state, a.id') + ->from('#__icagenda_category AS a'); + + $db->setQuery($query); + + $cat = $db->loadObjectList(); + + if ( ! is_array($this->value)) + { + $this->value = array($this->value); + } + + $html = ' '; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/param_place.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/param_place.php new file mode 100644 index 00000000..01fc3a00 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/param_place.php @@ -0,0 +1,53 @@ +getQuery(true); + $query->select('a.place, a.id, a.coordinate') + ->from('#__icagenda_events AS a'); + $db->setQuery($query); + $loc = $db->loadObjectList(); + + $html= ' + '.$span; + + return $html; + } +} \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/period.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/period.php new file mode 100644 index 00000000..698e19f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/period.php @@ -0,0 +1,50 @@ + + $(function(){ + $(\'#jform_period\').datetimepicker({ + dateFormat: \'yy-mm-dd\', + hourGrid: 4, + minuteGrid: 10 + }); + }) + + + '; + $html =''; + + return $html; + } +} \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ph_regbt.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ph_regbt.php new file mode 100644 index 00000000..3fa63f83 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/ph_regbt.php @@ -0,0 +1,43 @@ +input->get('class'); + + $icagendaParams = JComponentHelper::getParams('com_icagenda'); + $extRegButtonText = $icagendaParams->get('RegButtonText'); + + if ( ! isset($extRegButtonText)) $extRegButtonText = JText::_('COM_ICAGENDA_REGISTRATION_REGISTER'); + + $html =''; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/startdate.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/startdate.php new file mode 100644 index 00000000..b8deb1f8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/startdate.php @@ -0,0 +1,56 @@ +class) ? ' class="' . $this->class . '"' : ''; + + $lang = JFactory::getLanguage(); + + if ($lang->getTag() == 'fa-IR') + { + // Including fallback code for HTML5 non supported browsers. + JHtml::_('jquery.framework'); + JHtml::_('script', 'system/html5fallback.js', false, true); + + $attributes = ''; + + $html = JHtml::_('calendar', $this->value, $this->name, 'startdate_jalali', '%Y-%m-%d %H:%M:%S', $attributes); + } + else + { + $html =''; + } + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/template.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/template.php new file mode 100644 index 00000000..53383c75 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/template.php @@ -0,0 +1,84 @@ +getList($url); + $class = !empty($this->class) ? ' class="' . $this->class . '"' : ''; + $html = ''; + + return $html; + } + + function getList($dirname) + { + $arrayfiles = Array(); + + if (file_exists($dirname)) + { + $handle = opendir($dirname); + + while (false !== ($file = readdir($handle))) + { + if (!is_file($dirname.$file) + && $file != '.' + && $file != '..' + && $file != '.DS_Store' + && $file != '.htaccess' + && $file != '.thumbs' + && $file != 'index.php' + && $file != 'index.html' + && $file != 'php.ini' + ) + { + array_push($arrayfiles, $file); + } + } + + $handle = closedir($handle); + } + + sort($arrayfiles); + + return $arrayfiles; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/thumbs.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/thumbs.php new file mode 100644 index 00000000..86d8cae8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/thumbs.php @@ -0,0 +1,138 @@ +name); + + jimport('joomla.application.component.helper'); + $iCparams = JComponentHelper::getParams('com_icagenda'); + + if ($name_input == 'thumb_large') + { + $thumbOptions = $iCparams->get('thumb_large'); + $width = is_numeric($thumbOptions[0]) ? $thumbOptions[0] : '900'; + $height = is_numeric($thumbOptions[1]) ? $thumbOptions[1] : '600'; + $quality = is_numeric($thumbOptions[2]) ? $thumbOptions[2] : '100'; + $crop = isset($thumbOptions[3]) ? $thumbOptions[3] : false; + $default_width = '900'; + $default_height = '600'; + $default_quality = '100'; + $default_crop = '0'; + } + elseif ($name_input == 'thumb_medium') + { + $thumbOptions = $iCparams->get('thumb_medium'); + $width = is_numeric($thumbOptions[0]) ? $thumbOptions[0] : '300'; + $height = is_numeric($thumbOptions[1]) ? $thumbOptions[1] : '300'; + $quality = is_numeric($thumbOptions[2]) ? $thumbOptions[2] : '100'; + $crop = isset($thumbOptions[3]) ? $thumbOptions[3] : false; + $default_width = '300'; + $default_height = '300'; + $default_quality = '100'; + $default_crop = '0'; + } + elseif ($name_input == 'thumb_small') + { + $thumbOptions = $iCparams->get('thumb_small'); + $width = is_numeric($thumbOptions[0]) ? $thumbOptions[0] : '100'; + $height = is_numeric($thumbOptions[1]) ? $thumbOptions[1] : '100'; + $quality = is_numeric($thumbOptions[2]) ? $thumbOptions[2] : '100'; + $crop = isset($thumbOptions[3]) ? $thumbOptions[3] : false; + $default_width = '100'; + $default_height = '100'; + $default_quality = '100'; + $default_crop = '0'; + } + elseif ($name_input == 'thumb_xsmall') + { + $thumbOptions = $iCparams->get('thumb_xsmall'); + $width = is_numeric($thumbOptions[0]) ? $thumbOptions[0] : '48'; + $height = is_numeric($thumbOptions[1]) ? $thumbOptions[1] : '48'; + $quality = is_numeric($thumbOptions[2]) ? $thumbOptions[2] : '80'; + $crop = isset($thumbOptions[3]) ? $thumbOptions[3] : true; + $default_width = '48'; + $default_height = '48'; + $default_quality = '80'; + $default_crop = '1'; + } + + $crop_false = $crop_true = ''; + + if ($crop) + { + $crop_true = ' selected="selected"'; + } + else + { + $crop_false = ' selected="selected"'; + } + + $quality_80 = ''; + + if ($quality == '80') + { + $quality_80 = ' selected="selected"'; + } + + $quality_values = array('100', '95', '90', '85', '80', '75', '70', '60', '50'); + + $html = array(); + + $html[] = '
    ' . JText::_('IC_WIDTH') . '
    '; + $html[] = '
    '; + + $html[] = '
    ' . JText::_('IC_HEIGHT') . '
    '; + $html[] = '
    '; + + $html[] = '
    ' . JText::_('IC_QUALITY') . '
    '; + $html[] = '
    '; + + $html[] = '
    ' . JText::_('IC_CROPPED') . '
    '; + $html[] = '
    '; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_article.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_article.php new file mode 100644 index 00000000..c57299a8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_article.php @@ -0,0 +1,199 @@ +get('tos_Type', '1'); + + $allowEdit = ((string) $this->element['edit'] == 'true') ? true : false; + $allowClear = ((string) $this->element['clear'] != 'false') ? true : false; + + // Load language + JFactory::getLanguage()->load('com_content', JPATH_ADMINISTRATOR); + + // Load the modal behavior script. + JHtml::_('behavior.modal', 'a.modal'); + + // Build the script. + $script = array(); + + // Select button script + $script[] = ' function jSelectArticle_' . $this->id . '(id, title, catid, object) {'; + $script[] = ' document.getElementById("' . $this->id . '_id").value = id;'; + $script[] = ' document.getElementById("' . $this->id . '_name").value = title;'; + + if ($allowEdit) + { + $script[] = ' jQuery("#' . $this->id . '_edit").removeClass("hidden");'; + } + + if ($allowClear) + { + $script[] = ' jQuery("#' . $this->id . '_clear").removeClass("hidden");'; + } + + $script[] = ' SqueezeBox.close();'; + $script[] = ' }'; + + // Clear button script + static $scriptClear; + + if ($allowClear && ! $scriptClear) + { + $scriptClear = true; + + $script[] = ' function jClearArticle(id) {'; + $script[] = ' document.getElementById(id + "_id").value = "";'; + $script[] = ' document.getElementById(id + "_name").value = "' . htmlspecialchars(JText::_('COM_CONTENT_SELECT_AN_ARTICLE', true), ENT_COMPAT, 'UTF-8') . '";'; + $script[] = ' jQuery("#"+id + "_clear").addClass("hidden");'; + $script[] = ' if (document.getElementById(id + "_edit")) {'; + $script[] = ' jQuery("#"+id + "_edit").addClass("hidden");'; + $script[] = ' }'; + $script[] = ' return false;'; + $script[] = ' }'; + } + + // Add the script to the document head. + JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); + + // Setup variables for display. + $html = array(); + $link = 'index.php?option=com_content&view=articles&layout=modal&tmpl=component&function=jSelectArticle_' . $this->id; + + if (isset($this->element['language'])) + { + $link .= '&forcedLanguage=' . $this->element['language']; + } + + $db = JFactory::getDbo(); + $db->setQuery( + 'SELECT title' . + ' FROM #__content' . + ' WHERE id = ' . (int) $this->value + ); + + try + { + $title = $db->loadResult(); + } + catch (RuntimeException $e) + { + throw new Exception($e->getMessage(), 500, $e); + } + + if (empty($title)) + { + $title = JText::_('COM_CONTENT_SELECT_AN_ARTICLE'); + } + $title = htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); + + // The active article id field. + if (0 == (int) $this->value) + { + $value = ''; + } + else + { + $value = (int) $this->value; + } + + // The current article display field. + $html[] = '
     
    '; + $html[] = ''; + + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = '' . JText::_('JSELECT') . ''; + } + else + { + $html[] = ' ' . JText::_('JSELECT') . ''; + } + + // Edit article button + if ($allowEdit) + { + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = '' . JText::_('JACTION_EDIT') . ''; + } + else + { + $html[] = ' ' . JText::_('JACTION_EDIT') . ''; + } + } + + // Clear article button + if ($allowClear) + { + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = '' . JText::_('JCLEAR') . ''; + } + else + { + $html[] = ''; + } + } + + $html[] = ''; + + // class='required' for client side validation + $class = ''; + + if ($this->required) + { + $class = ' class="required modal-value"'; + } + + $html[] = '
    '; + + if ($tos_Type == '1') + { + $html[] = ''; + } + else + { + $html[] = ''; + } + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_content.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_content.php new file mode 100644 index 00000000..c632c72e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_content.php @@ -0,0 +1,65 @@ +get('tosContent', ''); + $tos_Type = $icagendaParams->get('tos_Type', ''); + + + $editor = JFactory::getEditor(); +// $editor = JEditor::getEditor(); + + $html = array(); + + $html[] = '
    '; + $html[] = $editor->display($this->name, $tosContent, "100%", "300", "300", "20", 1, null, null, null, array('mode' => 'advanced')); + $html[] = '
    '; + + if ($tos_Type == '2') { + $html[] = ''; + } else { + $html[] = ''; + } + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_default.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_default.php new file mode 100644 index 00000000..9a5bfbc6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_default.php @@ -0,0 +1,60 @@ +get('tosContent'); + $tos_Type = $icagendaParams->get('tos_Type', ''); + + $html = array(); + + $html[] = '
    '; + $html[] = ''.JText::_( 'COM_ICAGENDA_SUBMIT_TOS_TYPE_DEFAULT_LBL' ).'
    '.JText::_( 'COM_ICAGENDA_TOS' ).'
    '; + $html[] = '
    '; + + if ($tos_Type == '') { + $html[] = ''; + } else { + $html[] = ''; + } + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_type.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_type.php new file mode 100644 index 00000000..c035030e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/modal/tos_type.php @@ -0,0 +1,117 @@ +get('tos_Type', ''); + $class_default = ''; + $class_article = ''; + $class_custom = ''; + $checked_default = ''; + $checked_article = ''; + $checked_custom = ''; + if ($tos_Type == '') { + $class_default = 'btn-success'; + $checked_default = ' checked="checked"'; + $checked_article = ''; + $checked_custom = ''; + } + elseif ($tos_Type == '1') { + $class_article = 'btn-success'; + $checked_default = ''; + $checked_article = ' checked="checked"'; + $checked_custom = ''; + } + elseif ($tos_Type == '2') { + $class_custom = 'btn-success'; + $checked_default = ''; + $checked_article = ''; + $checked_custom = ' checked="checked"'; + } else { + $class_default = 'btn-success'; + $checked_default = ' checked="checked"'; + $checked_article = ''; + $checked_custom = ''; + } + + $html = array(); + $html[] = '
    '; + $html[] = ''; + $html[] = ''; + $html[] = ''; + $html[] = '
    '; + + + + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/spacer/description.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/spacer/description.php new file mode 100644 index 00000000..6a22bfa7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/spacer/description.php @@ -0,0 +1,55 @@ +element['label'])) + { + return ''; + } + + $desc = $this->element['label'] + ? (string) $this->element['label'] + : ($this->element['title'] ? (string) $this->element['title'] : ''); + + $class = $this->class ? (string) trim($this->class) : ''; + $class = ! empty($class) ? ' class="' . $class . '"' : ' style="clear: both;"'; + + $html = array(); + + $html[] = ''; + $html[] = ! empty($desc) ? $desc : ''; + $html[] = '
  • '; + + return '
    ' . implode('', $html); + } + + public function getInput() + { + return ''; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/fields/spacer/label.php b/deployed/icagenda/administrator/components/com_icagenda/models/fields/spacer/label.php new file mode 100644 index 00000000..3a5625fc --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/fields/spacer/label.php @@ -0,0 +1,68 @@ +element['label'])) + { + return ''; + } + + $title = $this->element['label'] + ? (string) $this->element['label'] + : ($this->element['title'] ? (string) $this->element['title'] : ''); + + $spacer_class = $this->class ? (string) $this->class : ''; + $class_ex = explode(' ', $spacer_class); + + $heading = 'h4'; + + foreach ($class_ex AS $c) + { + if (in_array(strtolower($c), array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) + { + $heading = strtolower($c); + } + } + + $class = trim(str_replace($heading, '', $spacer_class)); + $class = ! empty($class) ? ' class="' . $class . '"' : ''; + + $html = array(); + + $html[] = ''; + $html[] = ! empty($title) ? '<' . $heading . '>' . JText::_($title) . '' : ''; + $html[] = '
    '; + + return '
    ' . implode('', $html); + } + + public function getInput() + { + return ''; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/forms/category.xml b/deployed/icagenda/administrator/components/com_icagenda/models/forms/category.xml new file mode 100644 index 00000000..989b4cc4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/forms/category.xml @@ -0,0 +1,69 @@ + +
    + +
    + + + + + + + + + + + + + + + + + + +
    +
    diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/forms/customfield.xml b/deployed/icagenda/administrator/components/com_icagenda/models/forms/customfield.xml new file mode 100644 index 00000000..61f2c392 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/forms/customfield.xml @@ -0,0 +1,242 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/forms/download.xml b/deployed/icagenda/administrator/components/com_icagenda/models/forms/download.xml new file mode 100644 index 00000000..f21fac65 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/forms/download.xml @@ -0,0 +1,196 @@ + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/forms/event.xml b/deployed/icagenda/administrator/components/com_icagenda/models/forms/event.xml new file mode 100644 index 00000000..990104f6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/forms/event.xml @@ -0,0 +1,664 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    + +
    +
    + + +
    + + + + + + + +
    + + +
    + +
    +
    +
    diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/forms/feature.xml b/deployed/icagenda/administrator/components/com_icagenda/models/forms/feature.xml new file mode 100644 index 00000000..965f1def --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/forms/feature.xml @@ -0,0 +1,100 @@ + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/forms/index.html b/deployed/icagenda/administrator/components/com_icagenda/models/forms/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/forms/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/forms/mail.xml b/deployed/icagenda/administrator/components/com_icagenda/models/forms/mail.xml new file mode 100644 index 00000000..207fb650 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/forms/mail.xml @@ -0,0 +1,42 @@ + +
    +
    + + + + +
    +
    diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/forms/registration.xml b/deployed/icagenda/administrator/components/com_icagenda/models/forms/registration.xml new file mode 100644 index 00000000..2f7aee88 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/forms/registration.xml @@ -0,0 +1,171 @@ + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/icagenda.php b/deployed/icagenda/administrator/components/com_icagenda/models/icagenda.php new file mode 100644 index 00000000..02eaef28 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/icagenda.php @@ -0,0 +1,97 @@ +getDbo(); + $query = $db->getQuery(true); + $query->select('e.catid AS catid, sum(e.hits) AS hits') + ->from('#__icagenda_events AS e'); + + // Join over the category + $query->select('c.id AS cat_id, c.title AS cat_title, c.title AS stats_label, c.color AS cat_color'); + $query->join('LEFT', '#__icagenda_category AS c ON c.id = e.catid'); + + $query->group('c.id'); + $query->order('hits DESC'); + + $db->setQuery($query, 0, 10); + $list = $db->loadObjectList(); + + return $list; + } + + /** + * Build an SQL query to return total of event hits. + * + * @return JDatabaseQuery + */ + public function getEventHitsTotal() + { + // Get database object + $db = $this->getDbo(); + $query = $db->getQuery(true); + $query->select('sum(e.hits) AS hits') + ->from('#__icagenda_events AS e'); + $db->setQuery($query); + $list = $db->loadResult(); + + return $list; + } + + /** + * Build an SQL query to load EVENT STATS. + * + * @return JDatabaseQuery + */ + public function getEventStats() + { + // Get database object + $db = $this->getDbo(); + $query = $db->getQuery(true); + $query->select('e.title AS stats_label, e.hits AS hits') + ->from('#__icagenda_events AS e'); + + // Join over the category + $query->select('c.id AS cat_id, c.title AS cat_title, c.color AS cat_color'); + $query->join('LEFT', '#__icagenda_category AS c ON c.id = e.catid'); + + $query->order('hits DESC'); + + $db->setQuery($query, 0, 10); + $list = $db->loadObjectList(); + + return $list; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/index.html b/deployed/icagenda/administrator/components/com_icagenda/models/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/info.php b/deployed/icagenda/administrator/components/com_icagenda/models/info.php new file mode 100644 index 00000000..96c3f67c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/info.php @@ -0,0 +1,26 @@ +loadForm('com_icagenda.mail', 'mail', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 2.0 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + if (version_compare(JVERSION, '3.0', 'lt')) + { + $data = JFactory::getApplication()->getUserState('com_icagenda.display.mail.data', array()); + + if (empty($data)) + { + $data = JFactory::getApplication()->getUserState('com_icagenda.mail.data', array()); + } + } + else + { + $data = JFactory::getApplication()->getUserState('com_icagenda.display.mail.data', array()); + + if (empty($data)) + { + $data = JFactory::getApplication()->getUserState('com_icagenda.mail.data', array()); + } + + $this->preprocessData('com_icagenda.mail', $data); + } + + return $data; + } + + /** + * Method to preprocess the form + * + * @param JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 2.0 + * @throws Exception if there is an error loading the form. + */ + protected function preprocessForm(JForm $form, $data, $group = 'user') + { + parent::preprocessForm($form, $data, $group); + } + + /** + * Send the email + * + * @return boolean + * + * @since 2.0 + */ + public function send() + { + $app = JFactory::getApplication(); + $user = JFactory::getUser(); + + $send = ''; + $data = $app->input->post->get('jform', array(), 'array'); + $access = new JAccess; + + // Set Form Data to Session + $session = JFactory::getSession(); + $session->set('ic_newsletter', $data); + + $mailfrom = $app->get('mailfrom'); + $fromname = $app->get('fromname'); + $sitename = $app->get('sitename'); + + $eventid = array_key_exists('eventid', $data) ? $data['eventid'] : ''; + $date = array_key_exists('date', $data) ? $data['date'] : ''; + + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query->select('r.email, r.eventid, r.state, r.date, r.people') + ->from('#__icagenda_registration AS r'); + $query->where('r.state = 1'); + $query->where('r.email <> ""'); + $query->where('r.eventid = ' . (int) $eventid); + + if ($date != 'all') + { + if (iCDate::isDate($date)) + { + $query->where('r.date = ' . $db->q($date)); + } + elseif ($date == 1) + { + $query->where('r.period = 1'); + } + elseif ($date) + { + // Fix for old date saving data + $query->where('r.date = ' . $db->q($date)); + } + else + { + $query->where('r.period = 0'); + } + } + + $db->setQuery($query); + + $result = $db->loadObjectList(); + + $list = ''; + $people = 0; + + foreach ($result as $v) + { + $list.= $v->email . ', '; + $people = ($people + $v->people); + } + + $subject = array_key_exists('subject', $data) ? $data['subject'] : ''; + $message = array_key_exists('message', $data) ? $data['message'] : ''; + + $list_emails = explode(', ', $list); + + // Remove dupplicated email addresses + $recipient = array_unique($list_emails); + $recipient = array_filter($recipient); + + $content = stripcslashes($message); + $body = str_replace('src="images/', 'src="' . JURI::root() . '/images/', $content); + + // Set Mail + $mail = JFactory::getMailer(); + $mail->addRecipient($app->getCfg('mailfrom')); + $mail->addBCC($recipient); + + // FIX Joomla 3.5.1 issue on some servers, by addition of "Optional" ReplyTo, not previously set. + // JOOMLA 3.x/2.5 SWITCH + if (version_compare(JVERSION, '3.0', 'ge')) + { + $mail->addReplyTo($mailfrom, $fromname); + } + else + { + $mail->addReplyTo(array($mailfrom, $fromname)); + } + + $mail->setSender(array($mailfrom, $fromname)); + $mail->setSubject($subject); + + $mail->isHTML(true); + + // JDocs: When sending HTML emails you should normally set the Encoding to base64 + // in order to avoid unwanted characters in the output. + // See https://docs.joomla.org/Sending_email_from_extensions + $mail->Encoding = 'base64'; // JDocs Sending HTML Email + + $mail->setBody($body); + + // Send Mail + if ($subject && $body && $eventid && ($date || $date == '0')) + { + $send = $mail->Send(); + } + + if ($send !== true) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_NEWSLETTER_ERROR_ALERT'), 'error'); + + if ( ! $subject) + { + $app->enqueueMessage('- ' . JText::_('COM_ICAGENDA_NEWSLETTER_NO_OBJ_ALERT'), 'error'); + } + + if ( ! $body) + { + $app->enqueueMessage('- ' . JText::_('COM_ICAGENDA_NEWSLETTER_NO_BODY_ALERT'), 'error'); + } + + if ( ! $eventid && ( ! $date && $date != '0')) + { + $app->enqueueMessage('- ' . JText::_('COM_ICAGENDA_NEWSLETTER_NO_EVENT_SELECTED'), 'error'); + } + elseif ( $eventid && ( ! $date && $date != '0')) + { + $app->enqueueMessage('- ' . JText::_('COM_ICAGENDA_NEWSLETTER_NO_DATE_SELECTED'), 'error'); + } + + return false; + } + else + { + $app->enqueueMessage('

    ' . JText::_('COM_ICAGENDA_NEWSLETTER_SUCCESS') . '

    ', 'message'); + + $app->enqueueMessage($this->listSend($recipient, 0, $people), 'message'); + + $dupplicated_emails = count($list_emails) - count($recipient); + + if ($dupplicated_emails) + { + $app->enqueueMessage('' . JText::sprintf('COM_ICAGENDA_NEWSLETTER_NB_EMAIL_NOT_SEND', $dupplicated_emails) . '', 'message'); + } + + return $send; + } + } + + /** + * Html list of emails send + * + * @return HTML + * + * @since 2.0 + */ + public function listSend($recipient, $level = 0, $people = null) + { + $number = 0; + $list_send = ''; + + foreach($recipient AS $key => $value) + { + if (is_array($value) | is_object($value)) + { + parent::listArray($value, $level+=1); + } + else + { + $number = ($number + 1); + + $list_send.= str_repeat(" ", $level*3); + $list_send.= $number . " : " . $value . "
    "; + } + } + + $list_send.= '

    ' . JText::_('COM_ICAGENDA_NEWSLETTER_NB_EMAIL_SEND') . ' = ' . $number . ''; + $list_send.= ' (' . JText::_('COM_ICAGENDA_REGISTRATION_TICKETS') . ': ' . $people . ')

    '; + + return $list_send; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/registration.php b/deployed/icagenda/administrator/components/com_icagenda/models/registration.php new file mode 100644 index 00000000..ea4e4912 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/registration.php @@ -0,0 +1,301 @@ +id)) + { + if ($record->state != -2) + { + return false; + } + + $user = JFactory::getUser(); + + // Delete linked data from other tables + if ($user->authorise('core.delete')) + { + // Delete Custom Fields data + icagendaCustomfields::deleteData($record->id, 1); + icagendaCustomfields::cleanData(1); + + return true; + } + } + + return false; + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @param type The table type to instantiate + * @param string A prefix for the table class name. Optional. + * @param array Configuration array for model. Optional. + * @return JTable A database object + * @since 3.3.3 + */ + public function getTable($type = 'Registration', $prefix = 'iCagendaTable', $config = array()) + { + return JTable::getInstance($type, $prefix, $config); + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * @return JForm A JForm object on success, false on failure + * @since 3.3.3 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_icagenda.registration', 'registration', + array('control' => 'jform', 'load_data' => $loadData)); + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * @since 3.3.3 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data_array = JFactory::getApplication()->getUserState('com_icagenda.edit.registration.data', array()); + + if (empty($data_array)) + { + $data = $this->getItem(); + } + else + { + $data = new JObject; + $data->setProperties($data_array); + } + + return $data; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 3.5.6 + */ + public function save($data) + { + $app = JFactory::getApplication(); + $input = $app->input; + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + // Set registration creator + if (empty($data['created_by'])) + { + $data['created_by'] = (int) $data['userid']; + } + + // Set Params + if (isset($data['params']) && is_array($data['params'])) + { + // Convert the params field to a string. + $parameter = new JRegistry; + $parameter->loadArray($data['params']); + $data['params'] = (string)$parameter; + } + + if ($input->get('task') == 'delete') + { + icagendaCustomfields::deleteData($data['custom_fields'], $data['id'], 1); + // To Be Tested $app->enqueueMessage('Test'); + } + + // Control number of tickets available + $iCParams = JComponentHelper::getParams('com_icagenda'); + $evtParams = icagendaEvent::getParams($data['eventid']); + $typeReg = $evtParams->get('typeReg', 1); + $maxReg = $evtParams->get('maxReg', '1000000'); + $tickets = ($evtParams->get('maxRlistGlobal', '') == 2) + ? $evtParams->get('maxRlist', $iCParams->get('maxRlist', '5')) + : $iCParams->get('maxRlist', '5'); + + $ticketsAvailable = icagendaRegistration::getTicketsBookable($data['eventid'], $data['date'], $typeReg, $maxReg, $tickets); + $extraTickets = ($data['people'] - $data['data_people']); + $ticketsBookable = ($data['data_people'] + $ticketsAvailable); + + if ($data['people'] > $ticketsBookable) + { + $msg = '' . JText::_('COM_ICAGENDA_REGISTRATION_ERROR_NOT_ENOUGH_TICKETS_AVAILABLE') . '
    '; + + if ($data['data_people']) + { + $msg.= JText::sprintf('COM_ICAGENDA_REGISTRATION_ERROR_NOT_ENOUGH_TICKETS_ALREADY_BOOKED', $data['data_people']); + $msg.= JText::sprintf('COM_ICAGENDA_REGISTRATION_ERROR_NOT_ENOUGH_TICKETS_EXTRA_PEOPLE', $extraTickets, $ticketsAvailable) + . '
    '; + } + + $msg.= '' . JText::sprintf('COM_ICAGENDA_REGISTRATION_ERROR_MAXIMUM_TICKETS_BOOKABLE', $ticketsBookable) + . '' + . '
    '; + $msg.= JText::_('COM_ICAGENDA_REGISTRATION_ERROR_NOT_ENOUGH_TICKETS_CHANGE_NUMBER_OF_PEOPLE'); + + +// $msg.= '

    $maxReg: ' . $maxReg; +// $msg.= '
    $tickets: ' . $tickets; +// $msg.= '
    $ticketsAvailable: ' . $ticketsAvailable; + + $this->setError($msg); + + return false; + } + + if ($typeReg == 1 && $data['date'] == '') + { + $msg = '' . JText::_('COM_ICAGENDA_REGISTRATION_NO_DATE_SELECTED') . ''; + + $this->setError($msg); + + return false; + } + + if ($data['date'] == 'from_to') + { + $data['date'] = ''; + } + + // Get Registration ID from the result back to the Table after saving. + $table = $this->getTable(); + + if ($table->save($data) === true) + { + $data['id'] = $table->id; + } + else + { + $data['id'] = null; + } + + if (parent::save($data)) + { + // Save Custom Fields to database + if (isset($data['custom_fields']) && is_array($data['custom_fields'])) + { + icagendaCustomfields::saveToData($data['custom_fields'], $data['id'], 1); + } + + return true; + } + + return false; + } + + /** + * Method to get a single record. + * + * @param integer The id of the primary key. + * + * @return mixed Object on success, false on failure. + * @since 3.3.3 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) + { + // Do any procesing on fields here if needed + } + + return $item; + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @since 3.3.3 + */ + + protected function prepareTable($table) + { + $date = JFactory::getDate(); + $user = JFactory::getUser(); + + $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); + + if (empty($table->id)) + { + // Set the values + $table->created = $date->toSql(); + $table->created_by = $user->get('id'); + + // Set ordering to the last item if not set + if (empty($table->ordering)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('MAX(ordering)') + ->from($db->quoteName('#__icagenda_registration')); + $db->setQuery($query); + $max = $db->loadResult(); + + $table->ordering = $max + 1; + } + } + else + { + // Set the values + $table->modified = $date->toSql(); + $table->modified_by = $user->get('id'); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/registrations.php b/deployed/icagenda/administrator/components/com_icagenda/models/registrations.php new file mode 100644 index 00000000..f247d04e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/registrations.php @@ -0,0 +1,993 @@ +getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); + $this->setState('filter.search', $search); + + // Filter (dropdown) state. + $published = $app->getUserStateFromRequest($this->context . '.filter.state', 'filter_published', '1', 'string'); + $this->setState('filter.state', $published); + + // Filter (dropdown) categories + $categories = $this->getUserStateFromRequest($this->context . '.filter.categories', 'filter_categories', '', 'string'); + $this->setState('filter.categories', $categories); + + // Filter (dropdown) events + $events = $this->getUserStateFromRequest($this->context . '.filter.events', 'filter_events', '', 'string'); + $this->setState('filter.events', $events); + + // Filter (dropdown) dates + $dates = $this->getUserStateFromRequest($this->context . '.filter.dates', 'filter_dates', '', 'string'); + $this->setState('filter.dates', $dates); + + // Load the parameters. + $params = JComponentHelper::getParams('com_icagenda'); + $this->setState('params', $params); + + // List state information. + parent::populateState('a.id', 'desc'); + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 2.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id.= ':' . $this->getState('filter.search'); + $id.= ':' . $this->getState('filter.state'); + $id.= ':' . $this->getState('filter.categories'); + $id.= ':' . $this->getState('filter.events'); + $id.= ':' . $this->getState('filter.dates'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 2.0 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.*' + ) + ); + $query->from('#__icagenda_registration AS a'); + + // Join over the events. + $query->select('e.title AS event, e.created_by AS evt_created_by, e.state AS evt_state, + e.startdate AS startdate, e.enddate AS enddate, e.displaytime AS displaytime, + e.params AS eventParams'); + $query->join('LEFT', '#__icagenda_events AS e ON e.id=a.eventid'); + + // Join over the categories. + $query->select('c.id AS cat_id, c.title AS cat_title'); + $query->join('LEFT', '#__icagenda_category AS c ON c.id=e.catid'); + + // Join over the users for the checked out user. + $query->select('u.username AS username, u.name AS fullname'); + $query->join('LEFT', '#__users AS u ON u.id=a.userid'); + + // Join over the users for the author. + $query->select('ua.name AS author_name, ua.username AS author_username') + ->join('LEFT', '#__users AS ua ON ua.id = a.created_by'); + + // Join over the users actions (consents). + $query->select('GROUP_CONCAT(uc.user_action) AS user_action') + ->join('LEFT', '#__icagenda_user_actions as uc ON uc.parent_id = a.id') + ->group('a.id, uc.parent_id'); + + // Filter by published state + $published = $this->getState('filter.state'); + + if (is_numeric($published)) + { + $query->where('a.state = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.state IN (0, 1))'); + } + + // Filter by edit access + if ( ! JFactory::getUser()->authorise('core.edit', 'com_icagenda') + && JFactory::getUser()->authorise('core.edit.own', 'com_icagenda')) + { + $userID = JFactory::getUser()->get('id'); + $query->where('a.userid = ' . (int) $userID); + } + + // Filter by search in content + $search = $this->getState('filter.search'); + + if ( ! empty($search)) + { + // Search for registration id with Prefix "ID:" + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + // Search for user id with Prefix "USERID:" + elseif (stripos($search, 'userid:') === 0) + { + $query->where('a.userid = ' . (int) substr($search, 7)); + } + // Search for user email with Prefix "EMAIL:" + elseif (stripos($search, 'email:') === 0) + { + $query->where('a.email = ' . $db->quote(trim(substr($search, 6)))); + } + // Search for event id with Prefix "EVENTID:" + elseif (stripos($search, 'eventid:') === 0) + { + $query->where('a.eventid = ' . $db->quote(trim(substr($search, 8)))); + } + else + { + $search = $db->Quote('%' . $db->escape($search, true) . '%'); + + $query->where('(u.username LIKE ' . $search . + ' OR a.name LIKE ' . $search . + ' OR a.userid LIKE ' . $search . + ' OR a.email LIKE ' . $search . + ' OR a.phone LIKE ' . $search . + ' OR a.date LIKE ' . $search . + ' OR a.period LIKE ' . $search . + ' OR a.people LIKE ' . $search . + ' OR a.notes LIKE ' . $search . + ' OR e.title LIKE ' . $search . ' )'); + } + } + + // Filter categories + $category = $db->escape($this->getState('filter.categories')); + + if ( ! empty($category)) + { + $query->where('(c.id=' . $db->q($category) . ')'); + } + + // Filter events + $event = $db->escape($this->getState('filter.events')); + + if ( ! empty($event)) + { + $query->where($db->qn('a.eventid') . ' = ' . $db->q($event)); + } + + // Filter dates + $date = $db->escape($this->getState('filter.dates')); + + if (empty($event) && ! empty($date) && iCDate::isDate($date) && ! in_array($date, array('1', 'all'))) + { + if (empty($event)) + { + $query->where('(DATE(a.date) = ' . $db->q($date) . ' OR (DATE(e.startdate) = ' . $db->q($date) . ' AND ' . $db->qn('a.date') . ' = ""))'); + } + elseif ( ! empty($event)) + { + $query->where('(' . $db->qn('a.date') . ' = ' . $db->q($date) . ' OR (' . $db->qn('e.startdate') . ' = ' . $db->q($date) . ' AND ' . $db->qn('a.date') . ' = ""))'); + } + } + elseif ($date == 1) + { + $query->where($db->qn('a.date') . ' = ""'); + $query->where($db->qn('a.period') . ' = "0"'); + } + elseif ($date == 'all') + { + $query->where($db->qn('a.date') . ' = ""'); + $query->where($db->qn('a.period') . ' = "1"'); + } + elseif ( ! empty($date)) + { + $query->where($db->qn('a.date') . ' = ' . $db->q($date)); + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering'); + $orderDirn = $this->state->get('list.direction'); + + if ($orderCol && $orderDirn) + { + if ($orderCol == 'a.date') + { + $query->order($db->escape($db->qn('a.period') . ' ' . $orderDirn)); + } + + $query->order($db->escape($orderCol . ' ' . $orderDirn)); + } + + return $query; + } + + /** + * Gets a list of categories. + */ + function getCategories() + { + // Create a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select('c.id AS cat_id, c.title AS cat_title'); + $query->from('#__icagenda_category AS c'); + + // Join over the events. + $query->select('e.id AS id'); + $query->join('LEFT', '#__icagenda_events AS e ON e.catid=c.id'); + + // Join over the registrations. + $query->select('r.eventid AS event_id'); + $query->join('LEFT', '#__icagenda_registration AS r ON r.eventid=e.id'); + $query->where('(e.id = r.eventid)'); + $query->order('c.ordering ASC'); + + $db->setQuery($query); + $categories = $db->loadObjectList(); + + $list = array(); + + foreach ($categories as $c) + { + $list[$c->cat_id] = $c->cat_title . ' [' . $c->cat_id . ']'; + } + + return $list; + } + + /** + * Gets a list of all events. + */ + function getEvents() + { + // Create a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select('e.id AS event, e.title AS title'); + $query->from('#__icagenda_events AS e'); + + // Join over the categories. + $query->select('c.id AS cat_id, c.title AS cat_title'); + $query->join('LEFT', '#__icagenda_category AS c ON c.id=e.catid'); + + // Join over the registrations. + $query->select('r.eventid AS eventid'); + $query->join('LEFT', '#__icagenda_registration AS r ON r.eventid=e.id'); + $query->where('(e.id = r.eventid)'); + $query->order('e.title ASC'); + + // Filter by published state +// $query->where('(e.state IN (0, 1))'); + + $db->setQuery($query); + $events = $db->loadObjectList(); + + $list = array(); + + $catId = $db->escape($this->getState('filter.categories')); + + foreach ($events as $e) + { + if ( ! empty($catId) && $catId == $e->cat_id) + { + $list[$e->event] = $e->title . ' [' . $e->event . ']'; + } + elseif (empty($catId)) + { + $list[$e->event] = $e->title . ' [' . $e->event . ']'; + } +// $list[$e->event] = $e->title . ' [' . $e->event . ']'; + } + + return $list; + } + + /** + * Gets a list of dates. + */ + function getDates() + { + $params = $this->getState('params'); + $dateFormat = $params->get('date_format_global', 'Y - m - d'); + $dateSeparator = $params->get('date_separator', ' '); + $timeFormat = ($params->get('timeformat', '1') == 1) ? 'H:i' : 'h:i A'; + + // Create a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select('r.date AS date, r.period AS period, r.eventid AS eventid'); + $query->from('#__icagenda_registration AS r'); + + // Join over the events (period). + $query->select('e.startdate AS startdate, e.enddate AS enddate, e.displaytime AS displaytime'); + $query->join('LEFT', '#__icagenda_events AS e ON e.id=r.eventid'); + + $db->setQuery($query); + $dates = $db->loadObjectList(); + + $list = array(); + + $eventId = $db->escape($this->getState('filter.events')); + + $p = $e = 0; + + // Add to select dropdown the filters 'For all dates of the event' and/or 'For all the period', + // depending of registrations in data, and selected event + foreach ($dates as $d) + { + $period = (empty($d->date) && ($d->period == 1 || $d->period == '')) + ? '[ ' . ucfirst(JText::_('COM_ICAGENDA_ADMIN_REGISTRATION_FOR_ALL_DATES')) . ' ]' + : ''; + + if (empty($d->date) + && $d->period == 1 + && $e == 0 + ) + { + if ( ! empty($eventId) && $eventId == $d->eventid) + { + $e = $e+1; + $list['all'] = $period; + } + elseif (empty($eventId)) + { + $e = $e+1; + $list['all'] = $period; + } + } + } + + // Add to select dropdown the list of dates, + // depending of registrations in data, and selected event + foreach ($dates as $d) + { + $date = ''; + + if (empty($d->date) && $d->period == 0) + { + if ( ! empty($eventId) && $eventId == $d->eventid) + { + if (iCDate::isDate($d->startdate)) + { + $date = iCGlobalize::dateFormat($d->startdate, $dateFormat, $dateSeparator); + + if ($d->displaytime) + { + $date.= ' - ' . date($timeFormat, strtotime($d->startdate)); + } + } + if (iCDate::isDate($d->enddate)) + { + $date.= "\n" . '> ' . iCGlobalize::dateFormat($d->enddate, $dateFormat, $dateSeparator); + + if ($d->displaytime) + { + $date.= ' - ' . date($timeFormat, strtotime($d->enddate)); + } + } + } + elseif (empty($eventId)) + { + if (iCDate::isDate($d->startdate)) + { + $date = iCGlobalize::dateFormat($d->startdate, $dateFormat, $dateSeparator); + } + } + else + { + $date = '[ ' . ucfirst(JText::_('COM_ICAGENDA_ADMIN_REGISTRATION_FOR_ALL_PERIOD')) . ' ]'; + } + } + else + { + $deprecatedDate = iCDate::isDate($d->date) + ? $d->date + : JText::_('JUNDEFINED') . "\n" . '↳ ' . JText::_('COM_ICAGENDA_LEGEND_EDIT_REGISTRATION'); + + if ( ! empty($eventId)) + { + $date = iCDate::isDate($d->date) + ? iCGlobalize::dateFormat($d->date, $dateFormat, $dateSeparator) . ' - ' . date('H:i', strtotime($d->date)) + : '⚠ ' . $deprecatedDate; + } + else + { + $date = iCDate::isDate($d->date) + ? iCGlobalize::dateFormat($d->date, $dateFormat, $dateSeparator) + : '⚠ ' . $deprecatedDate; + } + } + + $display_date = ($date != '0000-00-00 00:00:00' && $d->date) ? true : false; + $display_period = ($date != '0000-00-00 00:00:00' && $d->startdate) ? true : false; + + if ($display_date + && ! empty($eventId) + && $eventId == $d->eventid + ) + { + $list[$d->date] = $date; + } + elseif ($display_date + && empty($eventId) + ) + { + if (iCDate::isDate($d->date)) + { + $list[date('Y-m-d', strtotime($d->date))] = $date; + } + else + { + $list[$d->date] = $date; + } + } + elseif ($display_period + && empty($eventId) + ) + { + $list[date('Y-m-d', strtotime($d->startdate))] = $date; + } + + if (empty($d->date) + && $d->period == 0 + && $p == 0 + ) + { + if ( ! empty($eventId) && $eventId == $d->eventid) + { + $p = $p+1; + $list[1] = $date; + } + elseif (empty($eventId)) + { + $p = $p+1; + $list[1] = $date; + } + } + } + + // Joomla 3 (update chosen) + if (version_compare(JVERSION, '3.0', 'ge')) + { + $js = ' + (function($){ + $(window).load(function(){ + $("#filter_dates.chzn-done option").each( + function(){ + var arr = $(this).html().split(/\n/); + var html = arr[1] ? arr[0]+"
     "+arr[1]+"" : arr[0]; + $(this).html(html); + } + ); + $("#filter_dates").trigger("liszt:updated"); + }); + })(jQuery); + '; + + JFactory::getDocument()->addScriptDeclaration($js); + } + +// if (empty($eventId)) +// { +// $list = array_unique($list); +// } + + krsort($list); + + return $list; + } + /** + * Get file name + * + * @return string The file name + * + * @since 2.0 + */ + public function getBaseName() + { + if (!isset($this->basename)) + { + $app = JFactory::getApplication(); + $basename = $this->getState('basename'); + $basename = str_replace('__SITE__', $app->getCfg('sitename'), $basename); + + $eventId = $this->getState('filter.events'); + + if (is_numeric($eventId)) + { + $basename = str_replace('__EVENTID__', $eventId, $basename); + $basename = str_replace('__EVENT__', $this->getEventTitle($eventId), $basename); + } + else + { + $basename = str_replace('__EVENTID__', '', $basename); + $basename = str_replace('__EVENT__', '', $basename); + } + + $date = $this->getState('filter.dates'); + + if (!empty($date)) + { + if (iCDate::isDate($date)) + { + $basename = str_replace('__DATE__', JHtml::date($date, JText::_('DATE_FORMAT_LC3'), null) + . ' - ' . date('H:i', strtotime($date)), + $basename); + } + else + { + $basename = str_replace('__DATE__', $date, $basename); + } + } + else + { + $basename = str_replace('__DATE__', '', $basename); + } + + $this->basename = $basename; + } + + return $this->basename; + } + + /** + * Get the event title. + * + * @return string The event title + * + * @since 3.5.0 + */ + protected function getEventTitle() + { + $eventId = $this->getState('filter.events'); + + if ($eventId) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('title') + ->from($db->quoteName('#__icagenda_events')) + ->where($db->quoteName('id') . '=' . $db->quote($eventId)); + $db->setQuery($query); + + try + { + $title = $db->loadResult(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + else + { + $title = JText::_('COM_ICAGENDA_NO_EVENT_TITLE'); + } + + return $title; + } + + /** + * Get the status name. + * + * @return string The status name + * + * @since 3.5.0 + */ + protected function getStatusName($status) + { + $status_array = JHtml::_('jgrid.publishedOptions'); + + foreach ($status_array AS $key => $name) + { + if ($status == $name->value) + { + $status_name = $name->text; + } + } + + return JText::_($status_name); + } + + /** + * Get the file type. + * + * @return string The file type + * + * @since 3.5.0 + */ + public function getFileType() + { + return $this->getState('compressed') ? 'zip' : 'csv'; + } + + /** + * Get the mime type. + * + * @return string The mime type. + * + * @since 3.5.0 + */ + public function getMimeType() + { + return $this->getState('compressed') ? 'application/zip' : 'text/csv'; + } + + /** + * Get the separator for values. + * + * @return string The separator. + * + * @since 3.5.9 + */ + public function getSeparator() + { + return ($this->getState('separator') == 1) ? "," : ";"; + } + + /** + * Get the content + * + * @return string The content. + * + * @since 3.5.0 + */ + public function getContent() + { + if (!isset($this->content)) + { + $separator = $this->getSeparator(); + + foreach ($this->getItems() as $item) + { + // Adds filled custom fields + $customfields = icagendaCustomfields::getList($item->id, 1); + + $header_cfs = array(); + + if ($customfields) + { + foreach ($customfields AS $customfield) + { + $header_cfs[]= $customfield->cf_title; + } + } + } + + // Start csv content + $this->content = ''; + + $this->content .= '"'; + + if ($this->getState('event_title')) + { + $this->content .= str_replace('"', '""', JText::_('COM_ICAGENDA_REGISTRATION_EVENTID')) . '"'; + } + else + { + $this->content .= '#' . '"'; + } + + if ($this->getState('date')) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_('COM_ICAGENDA_REGISTRATION_DATE')) . '"'; + } + + if ($this->getState('tickets')) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_('COM_ICAGENDA_REGISTRATION_TICKETS')) . '"'; + } + + if ($this->getState('name')) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_('IC_NAME')) . '"'; + } + + if ($this->getState('email')) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_('COM_ICAGENDA_REGISTRATION_EMAIL')) . '"'; + } + + if ($this->getState('phone')) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_('COM_ICAGENDA_REGISTRATION_PHONE')) . '"'; + } + + if ($this->getState('customfields')) + { + foreach ($header_cfs AS $header) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_($header)) . '"'; + } + } + + if ($this->getState('notes')) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_('COM_ICAGENDA_REGISTRATION_NOTES_DISPLAY_LABEL')) . '"'; + } + + if ($this->getState('status')) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_('JSTATUS')) . '"'; + } + + if ($this->getState('created')) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_('JGLOBAL_FIELD_CREATED_LABEL')) . '"'; + } + + if ($this->getState('reg_id')) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_('JGLOBAL_FIELD_ID_LABEL')) . '"'; + } + + $this->content .= "\n"; + + // Data Rows + $n = 0; + + foreach ($this->getItems() as $item) + { + // Adds filled custom fields + $customfields = icagendaCustomfields::getList($item->id, 1); + + $values_cfs = array(); + + if ($customfields) + { + foreach ($customfields AS $customfield) + { + $cf_value = isset($customfield->cf_value) ? $customfield->cf_value : JText::_('IC_NOT_SPECIFIED'); + + $values_cfs[]= $cf_value; + } + } + + $this->content .= '"'; + + if ($this->getState('event_title')) + { + $this->content .= str_replace('"', '""', $item->event) . '"'; + } + else + { + $n = $n + 1; + $this->content .= $n . '"'; + } + + if ($this->getState('date')) + { + $isPeriod = ($item->period != 1 && ! $item->date) ? true : false; + $regDate = $isPeriod ? $item->startdate . ' > ' . $item->enddate : $item->date; + + $this->content .= $separator . '"' . + str_replace('"', '""', ($item->period == 1 ? JText::_('COM_ICAGENDA_REGISTRATION_ALL_DATES') : $regDate)) . '"'; + } + + if ($this->getState('tickets')) + { + $this->content .= $separator . '"' . str_replace('"', '""', $item->people) . '"'; + } + + if ($this->getState('name')) + { + $this->content .= $separator . '"' . str_replace('"', '""', $item->name) . '"'; + } + + if ($this->getState('email')) + { + $this->content .= $separator . '"' . str_replace('"', '""', $item->email) . '"'; + } + + if ($this->getState('phone')) + { + $this->content .= $separator . '"' . str_replace('"', '""', $item->phone) . '"'; + } + + if ($this->getState('customfields')) + { + foreach ($values_cfs AS $value) + { + $this->content .= $separator . '"' . str_replace('"', '""', JText::_($value)) . '"'; + } + } + + if ($this->getState('notes')) + { + $this->content .= $separator . '"' . str_replace('"', '""', strip_tags($item->notes)) . '"'; + } + + if ($this->getState('status')) + { + $this->content .= $separator . '"' . str_replace('"', '""', $this->getStatusName($item->state)) . '"'; + } + + if ($this->getState('created')) + { + $this->content .= $separator . '"' . str_replace('"', '""', $item->created) . '"'; + } + + if ($this->getState('reg_id')) + { + $this->content .= $separator . '"' . str_replace('"', '""', $item->id) . '"'; + } + + $this->content .= "\n"; + } + + // Exporting Format: character encoding + if (function_exists('mb_convert_encoding')) + { + $this->content = mb_convert_encoding($this->content, $this->getState('character_encoding', 'UTF-8')); + } + + if ($this->getState('compressed')) + { + $app = JFactory::getApplication('administrator'); + + // Remove carriage returns (line breaks) + $this->content = str_replace(CHR(13).CHR(10), " ", $this->content); + + $files = array( + 'registrations' => array( + 'name' => $this->getBasename() . '.csv', + 'data' => $this->content, + 'time' => time() + ) + ); + $ziproot = $app->get('tmp_path') . '/' . uniqid('icagenda_registrations_') . '.zip'; + + // Run the packager + jimport('joomla.filesystem.folder'); + jimport('joomla.filesystem.file'); + $delete = JFolder::files($app->get('tmp_path') . '/', uniqid('icagenda_registrations_'), false, true); + + if ( ! empty($delete)) + { + if (!JFile::delete($delete)) + { + // JFile::delete throws an error + $this->setError(JText::_('COM_ICAGENDA_EXPORT_ERR_ZIP_DELETE_FAILURE')); + + return false; + } + } + + if (version_compare(JVERSION, '3.8', 'ge')) + { + $archive = new Archive; + + if ( ! $packager = $archive->getAdapter('zip')) + { + $this->setError(JText::_('COM_ICAGENDA_EXPORT_ERR_ZIP_ADAPTER_FAILURE')); + + return false; + } + elseif ( ! $packager->create($ziproot, $files)) + { + $this->setError(JText::_('COM_ICAGENDA_EXPORT_ERR_ZIP_CREATE_FAILURE')); + + return false; + } + } + else + { + // JArchive deprecated J4.0 + if ( ! $packager = JArchive::getAdapter('zip')) + { + $this->setError(JText::_('COM_ICAGENDA_EXPORT_ERR_ZIP_ADAPTER_FAILURE')); + + return false; + } + elseif ( ! $packager->create($ziproot, $files)) + { + $this->setError(JText::_('COM_ICAGENDA_EXPORT_ERR_ZIP_CREATE_FAILURE')); + + return false; + } + + } + + $this->content = file_get_contents($ziproot); + } + } + + return $this->content; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/models/themes.php b/deployed/icagenda/administrator/components/com_icagenda/models/themes.php new file mode 100644 index 00000000..84844080 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/models/themes.php @@ -0,0 +1,669 @@ +loadForm('com_icagenda.template', 'themes', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + function install($theme) + { + $app = JFactory::getApplication(); + $db = JFactory::getDbo(); + $package = $this->_getPackageFromUpload(); + + if ( ! $package) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_FIND_INSTALL_PACKAGE'), 'warning'); + $this->deleteTempFiles(); + + return false; + } + + if ($package['dir'] && JFolder::exists($package['dir'])) + { + $this->setPath('source', $package['dir']); + } + else + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_INSTALL_PATH_NOT_EXISTS'), 'warning'); + $this->deleteTempFiles(); + + return false; + } + + // We need to find the installation manifest file + if ( ! $this->_findManifest()) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_FIND_INFO_INSTALL_PACKAGE'), 'warning'); + $this->deleteTempFiles(); + + return false; + } + + // Files - copy files in manifest + foreach ($this->_manifest->children() as $child) + { + if (is_a($child, 'JXMLElement') && $child->name() == 'files') + { + if ($this->parseFiles($child) === false) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_FIND_INFO_INSTALL_PACKAGE'), 'warning'); + $this->deleteTempFiles(); + + return false; + } + } + } + + // File - copy the xml file + $copyFile = array(); + $path['src'] = $this->getPath( 'manifest' ); // XML file will be copied too + $path['dest'] = JPATH_SITE . '/components/com_icagenda/themes/' . basename($this->getPath('manifest')); + $copyFile[] = $path; + + $this->copyFiles($copyFile, array()); + $this->deleteTempFiles(); + + // ------------------- + // Themes + // ------------------- + // Params - Get new themes params + $paramsThemes = $this->getParamsThemes(); + + + // ------------------- + // Component + // ------------------- + if (isset($theme['component']) && $theme['component'] == 1 ) + { + $component = 'com_icagenda'; + $paramsC = JComponentHelper::getParams($component) ; + + foreach ($paramsThemes as $keyT => $valueT) + { + if (version_compare(JVERSION, '3.0', 'lt')) + { + $paramsC->setValue($valueT['name'], $valueT['value']); + } + else + { + $paramsC->set($valueT['name'], $valueT['value']); + } + } + + $data['params'] = $paramsC->toArray(); + $table = JTable::getInstance('extension'); + + $idCom = $table->find( array('element' => $component )); + + $table->load($idCom); + + if ( ! $table->bind($data)) + { + $app->enqueueMessage(JText::_('Not a valid component'), 'warning'); + + return false; + } + + // pre-save checks + if ( ! $table->check()) + { + $app->enqueueMessage(JText::_('Check Problem'), 'warning'); + + return false; + } + + // save the changes + if ( ! $table->store()) + { + $app->enqueueMessage(JText::_('Store Problem'), 'warning'); + + return false; + } + } + + return true; + } + + function _getPackageFromUpload() + { + $app = JFactory::getApplication(); + + // Get the uploaded file information + // Do not change the filter type 'raw'. We need this to let files containing PHP code to upload. See JInputFiles::get. + $userfile = $app->input->files->get('Filedata', null, 'raw'); + + // Make sure that file uploads are enabled in php + if ( ! (bool) ini_get('file_uploads')) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_INSTALL_FILE_UPLOAD'), 'warning'); + + return false; + } + + // Make sure that zlib is loaded so that the package can be unzipped + if ( ! extension_loaded('zlib')) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_INSTALL_ZLIB'), 'warning'); + + return false; + } + + // If there is no uploaded file, we have a problem... + if ( ! is_array($userfile)) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_NO_FILE_SELECTED'), 'warning'); + + return false; + } + + // Check if there was a problem uploading the file. + if ($userfile['error'] || $userfile['size'] < 1) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_UPLOAD_FILE'), 'warning'); + + return false; + } + + // Build the appropriate paths + if (version_compare(JVERSION, '3.0', 'lt')) + { + $config = JFactory::getConfig(); + $tmp_dest = $config->getValue('config.tmp_path') . '/' . $userfile['name']; + } + else + { + $config = JFactory::getConfig(); + $tmp_dest = $config->get('tmp_path') . '/' . $userfile['name']; + } + + $tmp_src = $userfile['tmp_name']; + + // Move uploaded file + jimport('joomla.filesystem.file'); + $uploaded = JFile::upload($tmp_src, $tmp_dest, false, true); + + // Unpack the downloaded package file + if (version_compare(JVERSION, '3.0', 'lt')) + { + $package = JInstallerHelper::unpack($tmp_dest); + } + else + { + $package = self::unpack($tmp_dest); + } + + $this->_manifest =& $manifest; + + $this->setPath('packagefile', $package['packagefile']); + $this->setPath('extractdir', $package['extractdir']); + + return $package; + } + + function getPath($name, $Default = null) + { + return ( ! empty($this->_paths[$name])) ? $this->_paths[$name] : $Default; + } + + function setPath($name, $value) + { + $this->_paths[$name] = $value; + } + + function _findManifest() + { + $app = JFactory::getApplication(); + + // Get an array of all the xml files from teh installation directory + $xmlfiles = JFolder::files($this->getPath('source'), '.xml$', 1, true); + + // If at least one xml file exists + if (count($xmlfiles) > 0) + { + foreach ($xmlfiles as $file) + { + // Is it a valid joomla installation manifest file? + $manifest = $this->_isManifest($file); + + if ( ! is_null($manifest)) + { + $attr = $manifest->attributes(); + + if ((string)$attr['method'] != 'icthemes') + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_NO_THEME_FILE'), 'warning'); + + return false; + } + + // Set the manifest object and path + $this->_manifest =& $manifest; + $this->setPath('manifest', $file); + + // Set the installation source path to that of the manifest file + $this->setPath('source', dirname($file)); + + return true; + } + } + + // None of the xml files found were valid install files + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_XML_INSTALL_ICAGENDA'), 'warning'); + + return false; + } + else + { + // No xml files were found in the install folder + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_XML_INSTALL'), 'warning'); + + return false; + } + } + + function _isManifest($file) + { + $xml = JFactory::getXML($file, true); + + if ( ! $xml) + { + unset ($xml); + + return null; + } + + if ( ! is_object($xml) || ($xml->name() != 'install' && $xml->name() != 'installtheme')) + { + unset ($xml); + + return null; + } + + return $xml; + } + + + function parseFiles($element, $cid = 0) + { + $copyfiles = array(); + $copyfolders = array(); + + if ( ! is_a($element, 'JXMLElement') || ! count($element->children())) + { + return 0; // Either the tag does not exist or has no children therefore we return zero files processed. + } + + $files = $element->children();// Get the array of file nodes to process + + if (count($files) == 0) + { + return 0; // No files to process + } + + $source = $this->getPath('source'); + $destination = JPATH_SITE . '/components/com_icagenda/themes'; + $destination2 = JPATH_SITE . '/components/com_icagenda/themes/packs'; + + if (version_compare(JVERSION, '3.0', 'lt')) + { + foreach ($files as $file) + { + if ($file->name() == 'folder') + { + $path['src'] = $source . '/' . $file->data(); + $path['dest'] = $destination2 . '/' . $file->data(); + $copyfolders[] = $path; + } + else + { + $path['src'] = $source . '/' . $file->data(); + $path['dest'] = $destination . '/' . $file->data(); + $copyfiles[] = $path; + } + } + } + else + { + if ( ! empty($files->folder)) + { + foreach ($files->folder as $fk => $fv) + { + $path['src'] = $source . '/' . $fv; + $path['dest'] = $destination2 . '/' . $fv; + $copyfolders[] = $path; + } + } + + if ( ! empty($files->filename)) + { + foreach ($files->filename as $fik => $fiv) + { + $path['src'] = $source . '/' . $fiv; + $path['dest'] = $destination . '/' . $fiv; + $copyfiles[] = $path; + } + } + } + + return $this->copyFiles($copyfiles, $copyfolders); + } + + function copyFiles($files, $folders) + { + $app = JFactory::getApplication(); + + $i = 0; + $fileIncluded = $folderIncluded = 0; + + if (is_array($folders) && count($folders) > 0) + { + foreach ($folders as $folder) + { + // Get the source and destination paths + $foldersource = JPath::clean($folder['src']); + $folderdest = JPath::clean($folder['dest']); + + if ( ! JFolder::exists($foldersource)) + { + $app->enqueueMessage(JText::sprintf('COM_ICAGENDA_FOLDER_NOT_EXISTS', $foldersource), 'warning'); + + return false; + } + else + { + if ( ! (JFolder::copy($foldersource, $folderdest, '', true))) + { + $app->enqueueMessage(JText::sprintf('COM_ICAGENDA_ERROR_COPY_FOLDER_TO', $foldersource, $folderdest), 'warning'); + + return false; + } + else + { + $i++; + } + } + } + + $folderIncluded = 1; + } + + if (is_array($files) && count($files) > 0) + { + foreach ($files as $file) + { + // Get the source and destination paths + $filesource = JPath::clean($file['src']); + $filedest = JPath::clean($file['dest']); + + if ( ! file_exists($filesource)) + { + $app->enqueueMessage(JText::sprintf('COM_ICAGENDA_FILE_NOT_EXISTS', $filesource), 'warning'); + + return false; + } + else + { + if ( ! (JFile::copy($filesource, $filedest))) + { + $app->enqueueMessage(JText::sprintf('COM_ICAGENDA_ERROR_COPY_FILE_TO', $filesource, $filedest), 'warning'); + + return false; + } + else + { + $i++; + } + } + } + + $fileIncluded = 1; + } + + if ($fileIncluded == 0 && $folderIncluded ==0) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_ERROR_INSTALL_FILE'), 'warning'); + + return false; + } + + return $i; // Possible TO DO, now it returns count folders and files togeter, //return count($files); + } + + protected function getParamsThemes() + { + $element = $this->_manifest->children()->params; + + if ( ! is_a($element, 'JXMLElement') || ! count($element->children())) + { + return null; // Either the tag does not exist or has no children therefore we return zero files processed. + } + + $params = $element->children(); + + if (count($params) == 0) + { + return null; // No params to process + } + + // Process each parameter in the $params array. + $paramsArray = array(); + $i = 0; + + foreach ($params as $param) + { + if ( ! $name = $param['name']) + { + continue; + } + if ( ! $value = $param['default']) + { + continue; + } + + $paramsArray[$i]['name'] = (string)$name; + $paramsArray[$i]['value'] = (string)$value; + $i++; + } + + return $paramsArray; + } + + function deleteTempFiles() + { + $path = $this->getPath('source'); + + if (is_dir($path)) + { + $val = JFolder::delete($path); + } + elseif (is_file($path)) + { + $val = JFile::delete($path); + } + + $packageFile = $this->getPath('packagefile'); + + if (is_file($packageFile)) + { + $val = JFile::delete($packageFile); + } + + $extractDir = $this->getPath('extractdir'); + + if (is_dir($extractDir)) + { + $val = JFolder::delete($extractDir); + } + } + + + /* + * Added @since 3.0. + */ + public static function unpack($p_filename) + { + // Path to the archive + $archivename = $p_filename; + + // Temporary folder to extract the archive into + $tmpdir = uniqid('install_'); + + // Clean the paths to use for archive extraction + $extractdir = JPath::clean(dirname($p_filename) . '/' . $tmpdir); + $archivename = JPath::clean($archivename); + + // Do the unpacking of the archive + try + { + JArchive::extract($archivename, $extractdir); + } + catch (Exception $e) + { + return false; + } + + /* + * Let's set the extraction directory and package file in the result array so we can + * cleanup everything properly later on. + */ + $retval['extractdir'] = $extractdir; + $retval['packagefile'] = $archivename; + + /* + * Try to find the correct install directory. In case the package is inside a + * subdirectory detect this and set the install directory to the correct path. + * + * List all the items in the installation directory. If there is only one, and + * it is a folder, then we will set that folder to be the installation folder. + */ + $dirList = array_merge(JFolder::files($extractdir, ''), JFolder::folders($extractdir, '')); + + if (count($dirList) == 1) + { + if (JFolder::exists($extractdir . '/' . $dirList[0])) + { + $extractdir = JPath::clean($extractdir . '/' . $dirList[0]); + } + } + + /* + * We have found the install directory so lets set it and then move on + * to detecting the extension type. + */ + $retval['dir'] = $extractdir; + + /* + * Get the extension type and return the directory/type array on success or + * false on fail. + */ + $retval['type'] = self::detectType($extractdir); + + if ($retval['type']) + { + return $retval; + } + else + { + return false; + } + } + + /* + * Added @since 3.0. + */ + public static function detectType($p_dir) + { + // Search the install dir for an XML file + $files = JFolder::files($p_dir, '\.xml$', 1, true); + + if ( ! count($files)) + { + JLog::add(JText::_('JLIB_INSTALLER_ERROR_NOTFINDXMLSETUPFILE'), JLog::WARNING, 'jerror'); + + return false; + } + + foreach ($files as $file) + { + $xml = simplexml_load_file($file); + + if ( ! $xml) + { + continue; + } + + if ($xml->getName() != 'install' && $xml->getName() != 'installtheme') + { + unset($xml); + + continue; + } + + $type = (string) $xml->attributes()->type; + + // Free up memory + unset($xml); + + return $type; + } + + JLog::add(JText::_('JLIB_INSTALLER_ERROR_NOTFINDJOOMLAXMLSETUPFILE'), JLog::WARNING, 'jerror'); + + // Free up memory. + unset($xml); + + return false; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/script.icagenda.php b/deployed/icagenda/administrator/components/com_icagenda/script.icagenda.php new file mode 100644 index 00000000..83062e1f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/script.icagenda.php @@ -0,0 +1,1414 @@ + { (folder) => { (module) => { (position), (published) } }* }* + 'modules' => array( + 'admin' => array( + ), + 'site' => array( + 'mod_iccalendar' => array('', 0), + ) + ), + // plugins => { (folder) => { (element) => { (name), (published) } }* }* + 'plugins' => array( + 'actionlog' => array( + 'icagenda' => array('Action Log - iCagenda', 1), + ), + 'installer' => array( + 'icagenda' => array('Installer - iCagenda', 1), + ), + 'privacy' => array( + 'icagenda' => array('Privacy - iCagenda', 1), + ), + 'quickicon' => array( + 'icagendaupdate' => array('Quick Icon - iCagenda :: Update Notification', 1), + ), + 'system' => array( + 'ic_autologin' => array('System - iCagenda :: Autologin', 1), + 'ic_library' => array('System - iC Library', 1), + ), + 'search' => array( + 'icagenda' => array('Search - iCagenda', 1), + ) + ) + ); + + /** @var array Obsolete files and folders to remove from the iCagenda oldest releases*/ + private $icagendaRemoveFiles = array( + 'files' => array( + 'components/com_icagenda/views/list/tmpl/search.php', + 'components/com_icagenda/views/list/tmpl/search.xml', + 'modules/mod_iccalendar/js/bottomcenter_function.js', + 'modules/mod_iccalendar/js/center_function.js', + 'modules/mod_iccalendar/js/left_function.js', + 'modules/mod_iccalendar/js/right_function.js', + 'modules/mod_iccalendar/js/topcenter_function.js', + 'components/com_icagenda/helpers/icmodcalendar.php', + 'administrator/components/com_icagenda/models/fields/eventtitle.php', + 'components/com_icagenda/themes/packs/ic_rounded/ic_rounded_alldates.php', + 'media/com_icagenda/icicons/lte-ie7.js', + 'media/com_icagenda/icicons/fonts/iCicons.dev.svg', + 'media/com_icagenda/icicons/selection.json', + 'modules/mod_iccalendar/js/function.js', + 'modules/mod_iccalendar/js/function_312.js', + 'modules/mod_iccalendar/js/function_316.js', + 'modules/mod_iccalendar/js/ictip.js', + 'components/com_icagenda/themes/packs/default/default_list.php', + 'components/com_icagenda/themes/packs/ic_rounded/ic_rounded_list.php', + 'media/com_icagenda/images/iconicagenda48 - copie.png', + 'administrator/components/com_icagenda/views/event/tmpl/ajaxfile.php', + 'administrator/components/com_icagenda/views/registration/tmpl/default.php', + 'administrator/components/com_icagenda/models/fields/modal/time.php', + 'administrator/components/com_icagenda/UPDATELOGS.php', + 'administrator/components/com_icagenda/sql/install.mysql.utf8.sql', + 'administrator/components/com_icagenda/sql/uninstall.mysql.utf8.sql', + 'administrator/components/com_icagenda/models/fields/custom_field.php', + 'administrator/components/com_icagenda/tables/mail.php', + 'administrator/components/com_icagenda/models/fields/modal/mailinglist.php', + 'components/com_icagenda/add/elements/icsetvar.php', + 'components/com_icagenda/helpers/iCalcreator.class.php', + 'components/com_icagenda/helpers/ichelper.php', + 'components/com_icagenda/helpers/icmodel.php', + 'components/com_icagenda/helpers/media_css.class.php', + 'components/com_icagenda/views/list/tmpl/actions.php', + 'components/com_icagenda/views/list/tmpl/default_vcal.php', + 'components/com_icagenda/views/list/tmpl/event.php', + 'components/com_icagenda/views/list/tmpl/registration.php', + 'media/com_icagenda/images/video_poster_icagenda.jpg', + 'media/com_icagenda/images/youtube_iCagenda.png', + 'media/com_icagenda/js/jsevt.js', + ), + 'folders' => array( + 'modules/mod_iccalendar/tmpl', + 'components/com_icagenda/css', + 'modules/mod_ic_event_list/language', + 'modules/mod_iccalendar/language', + 'administrator/components/com_icagenda/add/js', + 'components/com_icagenda/add/js', + 'media/com_icagenda/scripts', + 'components/com_icagenda/js', + 'administrator/components/com_icagenda/add/css', + 'components/com_icagenda/add/css', + 'administrator/components/com_icagenda/add/image', + 'components/com_icagenda/add/image', + 'administrator/components/com_icagenda/globalization', + 'administrator/components/com_icagenda/add', + 'components/com_icagenda/views/events', + 'libraries/ic_library/form/rules', + ) + ); + + + private function _removeObsoleteFilesAndFolders($icagendaRemoveFiles) + { + // Remove files + jimport('joomla.filesystem.file'); + + if ( ! empty($icagendaRemoveFiles['files'])) + { + foreach ($icagendaRemoveFiles['files'] as $file) + { + $f = JPATH_ROOT . '/' . $file; + + if ( ! JFile::exists($f)) continue; + + JFile::delete($f); + } + } + + // Remove folders + jimport('joomla.filesystem.file'); + + if ( ! empty($icagendaRemoveFiles['folders'])) + { + foreach ($icagendaRemoveFiles['folders'] as $folder) + { + $f = JPATH_ROOT . '/' . $folder; + + if ( ! JFolder::exists($f)) continue; + + JFolder::delete($f); + } + } + } + + + function preflight ($type, $parent) + { + $app = JFactory::getApplication(); + + $jversion = new JVersion(); + + // Installing component manifest file version + $this->release = $parent->get("manifest")->version; + + // Manifest file minimum Joomla version + $this->minimum_joomla_release = $parent->get("manifest")->attributes()->version; + + // Load translations + $language = JFactory::getLanguage(); + $language->load('com_icagenda.sys', JPATH_ADMINISTRATOR, 'en-GB', true); + $language->load('com_icagenda.sys', JPATH_ADMINISTRATOR, null, true); + +// if (version_compare(phpversion(), '5.3.0', '<')) +// { +// $app->enqueueMessage(' '.JText::sprintf('COM_ICAGENDA_YOUR_PHP_VERSION_IS', phpversion()).'
    '.JText::_('COM_ICAGENDA_PHP_VERSION_JOOMLA_RECOMMENDED').' ( '.JText::_('IC_READMORE').': http://www.joomla.org/technical-requirements.html )
    '.JText::_('COM_ICAGENDA_PHP_VERSION_ICAGENDA_RECOMMENDATION').'', 'warning'); +// } + + echo '
    '; + + echo '

    '; + echo ''; + + if ($this->ictype != 'core') echo ' ' . strtoupper($this->ictype) . ''; + + echo '
    '; + echo '' . JText::_('COM_ICAGENDA_XML_DESCRIPTION') . ''; + echo '

    '; + + echo '
    '; + + echo '

    '; + echo '

    '; + echo ''; + echo '
    '; + + echo '' + . JText::_('COM_ICAGENDA_WELCOME') + . '' + . '
    '; + + if ($type == 'install') + { + echo '' + . JText::sprintf('COM_ICAGENDA_WELCOME_1', 'iCagenda') . ' ' . $this->release + . ' ' . JText::_('COM_ICAGENDA_WELCOME_2') . '' + . '

    '; + } + + // Abort if the current Joomla release is older + if (version_compare($jversion->getShortVersion(), $this->minimum_joomla_release, 'lt')) + { + $app->enqueueMessage(' ' . JText::_('COM_ICAGENDA_INSTALL_ERROR_JOOMLA_VERSION') . ' ' . $this->minimum_joomla_release, 'warning'); + + return false; + } + + // Abort if Joomla 3 release is prior to 3.2.3 + if (version_compare(JVERSION, '3.0.0', 'ge') + && version_compare(JVERSION, '3.2.3', 'lt')) + { + $app->enqueueMessage(JText::_('COM_ICAGENDA_INSTALL_ERROR_JOOMLA_VERSION') . ' ' . '3.2.3', 'error'); + + return false; + } + + // Extension Update + if ($type == 'update') + { + echo '' + . JText::_('COM_ICAGENDA') . ' : ' + . JText::_('COM_ICAGENDA_UPDATE') . ' ' . $this->release . ' !' + . '' + . '

    '; + } + + echo '
    '; + echo JText::_('COM_ICAGENDA_FEATURES_BACKEND') . '
    '; + echo JText::_('COM_ICAGENDA_FEATURES_FRONTEND'); + echo '
    '; + + echo '

    '; + + echo '
    '; + + echo '
    '; + + $translationPacks = array( + 'af' => 'Afrikaans (South Africa)', + 'ar' => 'Arabic (Unitag)', + 'eu_es' => 'Basque (Spain)', + 'bg' => 'Bulgarian (Bulgaria)', + 'ca' => 'Catalan (Spain)', + 'zh' => 'Chinese (China)', + 'tw' => 'Chinese (Taiwan)', + 'hr' => 'Croatian (Croatia)', + 'cz' => 'Czech (Czech Republic)', + 'dk' => 'Danish (Denmark)', + 'nl' => 'Dutch (Netherlands)', + 'en' => 'English (United Kingdom)', + 'us' => 'English (United States)', + 'eo' => 'Esperanto', + 'et' => 'Estonian (Estonia)', + 'fi' => 'Finnish (Finland)', + 'fr' => 'French (France)', + 'gl' => 'Galician (Spain)', + 'de' => 'German (Germany)', + 'el' => 'Greek (Greece)', + 'hu' => 'Hungarian (Hungary)', + 'it' => 'Italian (Italy)', + 'ja' => 'Japanese (Japan)', + 'lv' => 'Latvian (Latvia)', + 'lt' => 'Lithuanian (Lithuania)', + 'none' => 'Luxembourgish (Luxembourg)', + 'mk' => 'Macedonian (Macedonia)', + 'no' => 'Norwegian Bokmål (Norway)', + 'fa_ir' => 'Persian (Iran)', + 'pl' => 'Polish (Poland)', + 'pt_br' => 'Portuguese (Brazil)', + 'pt' => 'Portuguese (Portugal)', + 'ro' => 'Romanian (Romania)', + 'ru' => 'Russian (Russia)', + 'sr' => 'Serbian (latin)', + 'sk' => 'Slovak (Slovakia)', + 'sl' => 'Slovenian (Slovenia)', + 'es' => 'Spanish (Spain)', + 'sv' => 'Swedish (Sweden)', + 'th' => 'Thai (Thailand)', + 'tr' => 'Turkish (Turkey)', + 'uk' => 'Ukrainian (Ukraine)', + ); + + echo '
    ' + . JText::sprintf('COM_ICAGENDA_FEATURES_TRANSLATION_PACKS', count($translationPacks)) + . '
    '; + + echo '

    '; + + foreach ($translationPacks as $code => $lang) + { + $flagIcon = ($code == 'none') ? 'icon-16-language.png' : $code . '.gif'; + + echo '' + . 'Tooltip' + . ''; + } + + echo '

    '; + echo '' + . JText::_('COM_ICAGENDA_TRANSLATION_PACKS_DONWLOAD') + . ''; + + echo '

    '; + + echo '
    '; + + echo '
    ' + . JText::_('COM_ICAGENDA_INSTALL_LABEL') + . '
    '; + } + + /* + * $parent is the class calling this method. + * install runs after the database scripts are executed. + * If the extension is new, the install method is run. + * If install returns false, Joomla will abort the install and undo everything already done. + */ + function install( $parent ) + { + // Load language + JFactory::getLanguage()->load('com_installer', JPATH_ADMINISTRATOR); + + $module_type = JText::_( 'COM_INSTALLER_TYPE_TYPE_MODULE' ); + $plugin_type = JText::_( 'COM_INSTALLER_TYPE_TYPE_PLUGIN' ); + $library_type = JText::_( 'COM_INSTALLER_TYPE_TYPE_LIBRARY' ); + + // Addons install (library, modules, plugins) + $db = JFactory::getDbo(); + $manifest = $parent->get("manifest"); + $parent = $parent->getParent(); + $source = $parent->getPath("source"); + $installer = new JInstaller(); + +// $installLibraries = array(); +// $installModules = array(); +// $installPlugins = array(); + + echo '
    ' . JText::_('JTOOLBAR_INSTALL') . '
    '; + + // Proceed Libraries Install + if (is_object($manifest->libraries) && isset($manifest->libraries->library)) + { + foreach ($manifest->libraries->library as $library) + { + $attributes = $library->attributes(); + + // Install Library + $lib = $source . '/' . $attributes['folder'] . '/' . $attributes['library']; + $installer->install($lib); + +// $installLibraries[] = $attributes['library']; + $installed_lib = '' . $attributes['name'] . ''; + + $libraryLabel = version_compare(JVERSION, '3.0.0', 'ge') + ? '' . $library_type . '' + : '[' . $library_type . ']'; + + echo '
    ' . $libraryLabel . ' ' . JText::sprintf( 'COM_INSTALLER_INSTALL_SUCCESS', $installed_lib ) + . ' ⇨ ' . JText::_( 'JPUBLISHED' ) . '
    '; + } + } + + // Proceed Modules Install + if (is_object($manifest->modules) && isset($manifest->modules->module)) + { + foreach ($manifest->modules->module AS $module) + { + $attributes = $module->attributes(); + + // Install Module + $mod = $source . '/' . $attributes['folder'] . '/' . $attributes['module']; + $installer->install($mod); + +// $installModules[] = $attributes['module']; + $installed_mod = '' . $attributes['name'] . ''; + + $moduleLabel = version_compare(JVERSION, '3.0.0', 'ge') + ? '' . $module_type . '' + : '[' . $module_type . ']'; + + echo '
    ' . $moduleLabel . ' ' . JText::sprintf('COM_INSTALLER_INSTALL_SUCCESS', $installed_mod) + . ' ⇨ ' . JText::_( 'JUNPUBLISHED' ) . '
    '; + } + } + + // Proceed Plugins Install + $this->_installAddons($parent, $source); + + echo '

    '; + +// echo '' . JText::_('COM_ICAGENDA_INSTALL') . $this->release . ' | '; + // You can have the backend jump directly to the newly installed component configuration page + // $parent->getParent()->setRedirectURL('index.php?option=com_democompupdate'); + + + // Get Joomla Images PATH setting + $params = JComponentHelper::getParams('com_media'); + $image_path = $params->get('image_path'); + + // Create Folder iCagenda in ROOT/IMAGES_PATH/icagenda + $folder[0][0] = 'icagenda/' ; + $folder[0][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[0][0]; + $folder[1][0] = 'icagenda/files/'; + $folder[1][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[1][0]; + $folder[2][0] = 'icagenda/thumbs/'; + $folder[2][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[2][0]; + $folder[3][0] = 'icagenda/thumbs/system/'; + $folder[3][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[3][0]; + $folder[4][0] = 'icagenda/thumbs/themes/'; + $folder[4][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[4][0]; + $folder[5][0] = 'icagenda/thumbs/copy/'; + $folder[5][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[5][0]; + $folder[6][0] = 'icagenda/feature_icons/'; + $folder[6][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[6][0]; + $folder[7][0] = 'icagenda/feature_icons/16_bit'; + $folder[7][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[7][0]; + $folder[8][0] = 'icagenda/feature_icons/24_bit'; + $folder[8][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[8][0]; + $folder[9][0] = 'icagenda/feature_icons/32_bit'; + $folder[9][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[9][0]; + $folder[10][0] = 'icagenda/feature_icons/48_bit'; + $folder[10][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[10][0]; + $folder[11][0] = 'icagenda/feature_icons/64_bit'; + $folder[11][1] = JPATH_ROOT.'/'.$image_path.'/'.$folder[11][0]; + + + $message = '
    '.JText::_('COM_ICAGENDA_FOLDER_CREATION').'
    '; + $error = array(); + + foreach ($folder as $key => $value) + { + if ( ! JFolder::exists( $value[1])) + { + if (JFolder::create( $value[1], 0755 )) + { + + $data = "\n\n\n"; + JFile::write($value[1]."/index.html", $data); + $message .= '
    '.JText::_('COM_ICAGENDA_FOLDER').' ' . $image_path.'/'.$value[0] + .' '.JText::_('COM_ICAGENDA_CREATED').'
    '; + $error[] = 0; + } + else + { + $message .= '
    '.JText::_('COM_ICAGENDA_FOLDER').' ' . $image_path.'/'.$value[0] + .' '.JText::_('COM_ICAGENDA_CREATION_FAILED').' '.JText::_('COM_ICAGENDA_PLEASE_CREATE_MANUALLY').'
    '; + $error[] = 1; + } + } + else //Folder exist + { + $message .= '
    '.JText::_('COM_ICAGENDA_FOLDER').' ' . $image_path.'/'.$value[0] + .' '.JText::_('COM_ICAGENDA_EXISTS').'
    '; + $error[] = 0; + } + } + + $message.= '

    '; + + echo $message; + } + + /* + * $parent is the class calling this method. + * update runs after the database scripts are executed. + * If the extension exists, then the update method is run. + * If this returns false, Joomla will abort the update and undo everything already done. + */ + function update( $parent ) + { + // Load language + JFactory::getLanguage()->load('com_installer', JPATH_ADMINISTRATOR); + $module_type = JText::_( 'COM_INSTALLER_TYPE_TYPE_MODULE' ); + $plugin_type = JText::_( 'COM_INSTALLER_TYPE_TYPE_PLUGIN' ); + $library_type = JText::_( 'COM_INSTALLER_TYPE_TYPE_LIBRARY' ); + + // Addons update (library, modules, plugins) + $db = JFactory::getDbo(); + $manifest = $parent->get("manifest"); + $parent = $parent->getParent(); + $source = $parent->getPath("source"); + + $installer = new JInstaller(); + + $installLibraries = array(); + $installModules = array(); + $installPlugins = array(); + + echo '
    '.JText::_('COM_INSTALLER_TOOLBAR_UPDATE').'
    '; + + // Pre-test iC Library + $query = $db->getQuery(true); + $query->select('p.enabled') + ->from('`#__extensions` AS p') + ->where($db->qn('type').' = '.$db->q('library')) + ->where($db->qn('element').' = '.$db->q('lib_ic_library')); + $db->setQuery($query); + + $ic_library_ok = $db->loadResult(); + + // Proceed Libraries Update + if (is_object($manifest->libraries) && isset($manifest->libraries->library)) + { + foreach ($manifest->libraries->library as $library) + { + $attributes = $library->attributes(); + + // Install Library + $lib = $source . '/' . $attributes['folder'] . '/' . $attributes['library']; + $installer->install($lib); + + $element = $attributes['element']; + $installLibraries[] = $attributes['library']; + $installed_lib = '' . $attributes['name'] . ''; + + $libraryLabel = version_compare(JVERSION, '3.0.0', 'ge') + ? '' . $library_type . '' + : '[' . $library_type . ']'; + + if (($ic_library_ok == '1') && ($element == 'lib_ic_library')) + { + echo '
    ' . $libraryLabel . ' ' . JText::sprintf( 'COM_INSTALLER_MSG_UPDATE_SUCCESS', $installed_lib ) . '
    '; + } + else + { + echo '
    ' . $libraryLabel . ' ' . JText::sprintf( 'COM_INSTALLER_INSTALL_SUCCESS', $installed_lib ) + . ' ⇨ ' . JText::_( 'JPUBLISHED' ) . '
    '; + } + } + } + + // Proceed Modules Update + if (is_object($manifest->modules) && isset($manifest->modules->module)) + { + foreach ($manifest->modules->module AS $module) + { + $attributes = $module->attributes(); + + // Install Module + $mod = $source . '/' . $attributes['folder'] . '/' . $attributes['module']; + $installer->install($mod); + + $installModules[] = $attributes['module']; + $installed_mod = '' . $attributes['name'] . ''; + + $moduleLabel = version_compare(JVERSION, '3.0.0', 'ge') + ? '' . $module_type . '' + : '[' . $module_type . ']'; + + echo '
    ' . $moduleLabel . ' ' . JText::sprintf('COM_INSTALLER_MSG_UPDATE_SUCCESS', $installed_mod) . '
    '; + } + } + + // Proceed Plugins Update + $this->_installAddons($parent, $source); + + echo '

    '; + +// echo '' . JText::_('COM_ICAGENDA_UPDATE') . $this->release . ' | '; + // You can have the backend jump directly to the newly updated component configuration page + // $parent->getParent()->setRedirectURL('index.php?option=com_democompupdate'); + + + // Get Joomla Images PATH setting + $params = JComponentHelper::getParams('com_media'); + $image_path = $params->get('image_path'); + + // Create Folder iCagenda in ROOT/IMAGES_PATH/icagenda + $folderimg[0][0] = 'icagenda/' ; + $folderimg[0][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[0][0]; + $folderimg[1][0] = 'icagenda/files/'; + $folderimg[1][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[1][0]; + $folderimg[2][0] = 'icagenda/thumbs/'; + $folderimg[2][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[2][0]; + $folderimg[3][0] = 'icagenda/thumbs/system/'; + $folderimg[3][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[3][0]; + $folderimg[4][0] = 'icagenda/thumbs/themes/'; + $folderimg[4][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[4][0]; + $folderimg[5][0] = 'icagenda/thumbs/copy/'; + $folderimg[5][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[5][0]; + $folderimg[6][0] = 'icagenda/feature_icons/'; + $folderimg[6][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[6][0]; + $folderimg[7][0] = 'icagenda/feature_icons/16_bit'; + $folderimg[7][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[7][0]; + $folderimg[8][0] = 'icagenda/feature_icons/24_bit'; + $folderimg[8][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[8][0]; + $folderimg[9][0] = 'icagenda/feature_icons/32_bit'; + $folderimg[9][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[9][0]; + $folderimg[10][0] = 'icagenda/feature_icons/48_bit'; + $folderimg[10][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[10][0]; + $folderimg[11][0] = 'icagenda/feature_icons/64_bit'; + $folderimg[11][1] = JPATH_ROOT.'/'.$image_path.'/'.$folderimg[11][0]; + + + $message = '
    '.JText::_('COM_ICAGENDA_FOLDER_CREATION').'
    '; + $error = array(); + foreach ($folderimg as $key => $value) + { + if (!JFolder::exists( $value[1])) + { + if (JFolder::create( $value[1], 0755 )) + { + + $data = "\n\n\n"; + JFile::write($value[1]."/index.html", $data); + $message .= '
    '.JText::_('COM_ICAGENDA_FOLDER').' ' . $image_path.'/'.$value[0] + .' '.JText::_('COM_ICAGENDA_CREATED').'
    '; + $error[] = 0; + } + else + { + $message .= '
    '.JText::_('COM_ICAGENDA_FOLDER').' ' . $image_path.'/'.$value[0] + .' '.JText::_('COM_ICAGENDA_CREATION_FAILED').' '.JText::_('COM_ICAGENDA_PLEASE_CREATE_MANUALLY').'
    '; + $error[] = 1; + } + } + else//Folder exist + { + $message .= '
    '.JText::_('COM_ICAGENDA_FOLDER').' ' . $image_path.'/'.$value[0] + .' '.JText::_('COM_ICAGENDA_EXISTS').'
    '; + $error[] = 0; + } + } + + $message.= '

    '; + + echo $message; + } + + + /** + * Installs subextensions (modules, plugins) bundled with the main extension + * NOTE: Currently installing only plugins (3.4.0). Modules install to be added later. + * + * @param JInstaller $parent + * + * @return JObject The subextension installation status + */ + private function _installAddons($parent, $source) + { + // Load language + JFactory::getLanguage()->load('com_installer', JPATH_ADMINISTRATOR); + + $module_type = JText::_( 'COM_INSTALLER_TYPE_TYPE_MODULE' ); + $plugin_type = JText::_( 'COM_INSTALLER_TYPE_TYPE_PLUGIN' ); + $library_type = JText::_( 'COM_INSTALLER_TYPE_TYPE_LIBRARY' ); + + $db = JFactory::getDbo(); + + $status = new JObject(); + + /* + * PLUGINS UPDATE/INSTALL + */ + $status->plugins = array(); + + // Plugins installation process + if (count($this->installation_queue['plugins'])) + { + foreach ($this->installation_queue['plugins'] AS $folder => $plugins) + { + if (count($plugins)) + { + foreach ($plugins AS $plugin => $pluginPreferences) + { + $path = "$source/plugins/$folder/$plugin"; + + if ( ! is_dir($path)) + { + $path = "$source/plugins/$folder/plg_$plugin"; + } + + if ( ! is_dir($path)) + { + $path = "$source/plugins/$plugin"; + } + + if ( ! is_dir($path)) + { + $path = "$source/plugins/plg_$plugin"; + } + + if ( ! is_dir($path)) + { + continue; + } + + // Was the plugin already installed? + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->qn('#__extensions')) + ->where($db->qn('element') . ' = ' . $db->q($plugin)) + ->where($db->qn('folder') . ' = ' . $db->q($folder)); + $db->setQuery($query); + + try + { + $count = $db->loadResult(); + } + catch (Exception $exc) + { + $count = 0; + } + + $installer = new JInstaller; + $result = $installer->install($path); + + $status->plugins[] = array('name' => 'plg_' . $plugin, 'group' => $folder, 'result' => $result); + + list($pluginName, $pluginPublished) = $pluginPreferences; + + // We publish the plugin if not already installed, and default is published + if ($pluginPublished && ! $count) + { + $query = $db->getQuery(true) + ->update($db->qn('#__extensions')) + ->set($db->qn('enabled') . ' = ' . $db->q('1')) + ->where($db->qn('element') . ' = ' . $db->q($plugin)) + ->where($db->qn('folder') . ' = ' . $db->q($folder)); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (Exception $exc) + { + // Nothing + } + } + + // Display plugin status + $pluginStatus = ''; + + $pluginName = '' . $pluginName . ''; + + $pluginLabel = version_compare(JVERSION, '3.0.0', 'ge') + ? '' . $plugin_type . '' + : '[' . $plugin_type . ']'; + + $pluginStatus.= '
    ' . $pluginLabel . ' '; + + // Plugin update + if ($count) + { + $pluginStatus.= JText::sprintf('COM_INSTALLER_MSG_UPDATE_SUCCESS', $pluginName); + } + + // Plugin first install + else + { + $pluginStatus.= JText::sprintf('COM_INSTALLER_INSTALL_SUCCESS', $pluginName); + $pluginStatus.= ' ⇨ ' . JText::_('JPUBLISHED') . ''; + } + + $pluginStatus.= '
    '; + + echo $pluginStatus; + } + } + } + } + + return $status; + } + + + /* + * $parent is the class calling this method. + * $type is the type of change (install, update or discover_install, not uninstall). + * postflight is run after the extension is registered in the database. + */ + function postflight($type, $parent) + { + // Updating Params to ensure a correct value + jimport('joomla.application.component.helper'); // Import component helper library + + $this->release = $parent->get("manifest")->version; + $icagendaParams = JComponentHelper::getParams('com_icagenda'); + $oldRelease = $icagendaParams->get('release'); // Since 3.6.0 + $oldSys = $icagendaParams->get('icsys'); + + // Fix old versions created date missing (runs if version previously installed is before 3.3.7) + // update database to set a valid created date for events created with versions of iCagenda < 3.1.5, + // and set in this order : modified date if valid or next/last date if valid or, at the end, will use current date. + // (this fix is to prevent wrong 'Created on 30 November -0001' in search results) + if (version_compare($oldRelease, '3.3.7', 'le')) + { + $db = JFactory::getDbo(); + $date = JFactory::getDate(); + + $null_created = '0000-00-00 00:00:00'; + + $query = $db->getQuery(true); + + $query->select('e.id, e.created, e.modified, e.next') + ->from('`#__icagenda_events` AS e') + ->where($db->qn('e.created').' = '.$db->q($null_created)); + $db->setQuery($query); + + $list_created_null = $db->loadObjectList(); + + foreach ($list_created_null AS $cn) + { + if ($cn->modified != $null_created) + { + $new_created = $cn->modified; + } + elseif ($cn->next != $null_created) + { + $new_created = $cn->next; + } + else + { + $new_created = $date->toSql(); + } + $query = $db->getQuery(true) + ->update($db->qn('#__icagenda_events')) + ->set($db->qn('created').' = '.$db->q($new_created)) + ->where($db->qn('id').' = '.intval($cn->id)); + $db->setQuery($query); + $db->execute(); + } + } + + // Fix for 'period' value in db when registration mode was set on "for all dates" (versions 3.6.0 to 3.6.2) + // Due to possible older issue, good to run this check/update for all version before 3.6 + if (version_compare($oldRelease, '3.6.6', 'lt')) + { + $db = JFactory::getDbo(); + $db->setQuery('SELECT id, params FROM #__icagenda_events'); + $listEvtParams = $db->loadObjectList(); + + foreach ($listEvtParams as $event) + { + $evtID = $event->id; + $evtParams = json_decode($event->params, true); + + if ($evtParams['typeReg'] == 2) + { + $query = $db->getQuery(true) + ->update($db->qn('#__icagenda_registration')) + ->set($db->qn('period') . ' = 1') + ->where($db->qn('eventid') . ' = ' . intval($evtID)) + ->where($db->qn('date') . ' = ""'); + $db->setQuery($query); + $db->execute(); + } + } + } + + // Remove obsolete files and folders + $icagendaRemoveFiles = $this->icagendaRemoveFiles; + + $this->_removeObsoleteFilesAndFolders($icagendaRemoveFiles); + + // Always create or modify these parameters + $ictype_label = ($this->ictype == 'core') ? '' : ' ' . strtoupper($this->ictype) . ''; + + $params['version'] = $ictype_label . ' [' . $this->release . ']'; + $params['release'] = $this->release; + $params['author'] = 'JoomliC'; + $params['icsys'] = $this->ictype; + + if ($this->ictype == 'core') $params['copy'] = '1'; + + if ($oldSys !== $params['icsys']) + { + // Get com_icagenda extension_id + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('extension_id') + ->from('#__extensions') + ->where('element = "com_icagenda"'); + $db->setQuery($query); + + $eid = $db->loadResult(); + + if ($eid) + { + $this->removeObsoleteUpdateSites($eid); + } + + } + + if (($type == 'install' || $oldSys !== $params['icsys']) && $this->ictype != 'core') + { + $params['copy'] = NULL; + } + + // Define the following parameters only if it is an original install // To be checked! + if ($type == 'install') + { + $params['atlist'] = '1'; + $params['atevent'] = '1'; + $params['atfloat'] = '2'; + $params['aticon'] = '2'; + $params['arrowtext'] = '1'; + $params['statutReg'] = '1'; + $params['maxRlist'] = '5'; + $params['navposition'] = '0'; + $params['targetLink'] = '1'; + $params['participantList'] = '0'; + $params['participantSlide'] = '1'; + $params['participantDisplay'] = '1'; + $params['fullListColumns'] = 'tiers'; + $params['regEmailUser'] = '1'; + $params['timeformat'] = '1'; + $params['ShortDescLimit'] = '100'; + $params['limitRegEmail'] = '1'; + $params['limitRegDate'] = '1'; + $params['phoneRequired'] = '2'; + $params['headerList'] = '1'; + } + + $extparticipantList = $icagendaParams->get('participantList'); + $extparticipantSlide = $icagendaParams->get('participantSlide'); + $extstatutReg = $icagendaParams->get('statutReg'); + $extlimitRegEmail = $icagendaParams->get('limitRegEmail'); + $extlimitRegDate = $icagendaParams->get('limitRegDate'); + $extphoneRequired = $icagendaParams->get('phoneRequired'); + $extregEmailUser = $icagendaParams->get('regEmailUser'); + $largewidththreshold = $icagendaParams->get('largewidththreshold', '1201'); + $mediumwidththreshold = $icagendaParams->get('mediumwidththreshold', '769'); + $smallwidththreshold = $icagendaParams->get('smallwidththreshold', '481'); + + $params['largewidththreshold'] = $largewidththreshold; + $params['mediumwidththreshold'] = $mediumwidththreshold; + $params['smallwidththreshold'] = $smallwidththreshold; + + if ($extparticipantList == '2') + { + $params['participantList'] = '0'; + } + + if ($extparticipantSlide == '2') + { + $params['participantSlide'] = '0'; + } + + if ($extstatutReg == '2') + { + $params['statutReg'] = '0'; + } + + if ($extlimitRegEmail == '2') + { + $params['limitRegEmail'] = '0'; + } + + if ($extlimitRegDate == '2') + { + $params['limitRegDate'] = '0'; + } + + if ($extphoneRequired == '2') + { + $params['phoneRequired'] = '0'; + } + + if ($extregEmailUser == '2') + { + $params['regEmailUser'] = '0'; + } + + // Update 3.1.1 + $emailRequired = $icagendaParams->get('emailRequired'); + + if ($emailRequired == '') + { + $params['emailRequired'] = '1'; + } + + // Update 3.4.1 + $datesDisplay_global = $icagendaParams->get('datesDisplay_global'); + $reg_captcha = $icagendaParams->get('reg_captcha', ''); + $submit_captcha = $icagendaParams->get('submit_captcha', ''); + $captcha = $icagendaParams->get('captcha', ''); + + if ($datesDisplay_global) + { + $params['datesDisplay'] = $datesDisplay_global; + } + + if (in_array($reg_captcha, array('', '0')) + && in_array($submit_captcha, array('', '0')) + ) + { + $params['captcha'] = $captcha; + } + elseif ( ! in_array($reg_captcha, array('', '0', '1'))) + { + $params['captcha'] = $reg_captcha; + } + elseif ( ! in_array($submit_captcha, array('', '0', '1'))) + { + $params['captcha'] = $submit_captcha; + } + else + { + $params['captcha'] = $captcha; + } + + $params['reg_captcha'] = (in_array($reg_captcha, array('', '0'))) ? '0' : '1'; + $params['submit_captcha'] = (in_array($submit_captcha, array('', '0'))) ? '0' : '1'; + + // Update 3.6.9 + $filters_mode = $icagendaParams->get('filters_mode'); + + if (version_compare($oldRelease, '3.6.9', 'lt') + && ! $filters_mode) + { + $params['filters_mode'] = '2'; + } + + // Patch for 3.6.9 + if (version_compare($oldRelease, '3.6.8', 'gt') + && version_compare($oldRelease, '3.6.10', 'lt')) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->update($db->qn('#__icagenda_events')) + ->set($db->qn('startdate') . ' = "0000-00-00 00:00:00"') + ->where($db->qn('startdate') . ' = "1970-01-01 01:00:00"') + ->update($db->qn('#__icagenda_events')) + ->set($db->qn('enddate') . ' = "0000-00-00 00:00:00"') + ->where($db->qn('enddate') . ' = "1970-01-01 01:00:00"') + ->update($db->qn('#__icagenda_events')) + ->set($db->qn('next') . ' = "0000-00-00 00:00:00"') + ->where($db->qn('next') . ' = "1970-01-01 01:00:00"'); + $db->setQuery($query); + $db->execute(); + } + + // Update 3.7.0 + $terms_Type = $icagendaParams->get('terms_Type'); + + if ($terms_Type == '') + { + $terms_Type = 3; + } + + $params['terms_type'] = $terms_Type; + + if (version_compare($oldRelease, '3.7.0', 'lt')) + { + $accessParticipantList = $icagendaParams->get('accessParticipantList'); + + $params['participant_name_visibility'] = ($accessParticipantList < 3 ) ? $accessParticipantList : ''; + $params['participant_gravatar_consent'] = '0'; + } + + // Update 3.7.2 + if (version_compare($oldRelease, '3.7.2', 'lt')) + { + $params['maps_service'] = '3'; + } + + // UPDATE PARAMS + $this->setParams($params); + + // Set default Access Permissions for iCagenda component + $rules['core.manage'] = array('6' => 1); + $rules['icagenda.access.categories'] = array('7' => 1); + $rules['icagenda.access.events'] = array('6' => 1); + $rules['icagenda.access.registrations'] = array('7' => 1); + $rules['icagenda.access.newsletter'] = array('7' => 1); + $rules['icagenda.access.themes'] = array('7' => 1); + $rules['icagenda.access.customfields'] = array('7' => 1); + $rules['icagenda.access.features'] = array('7' => 1); + + // UPDATE RULES + $this->setRules( $rules ); + + $this->clean(); + + $usageStats = $icagendaParams->get('usage_stats', '1'); + + $sendSystemInfo = $this->getSystemInfo($type, $parent); + + if ($sendSystemInfo && $usageStats) + { + echo $sendSystemInfo; + } + + echo 'Jooml!C • iCagenda • www.joomlic.com'; + + echo '
    '; + } + + // Delete unused update site + /* + * Delete unused update site + * + * $eid int extension_id + */ + private function removeObsoleteUpdateSites($eid) + { + if ($eid) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->delete('#__update_sites_extensions') + ->where('extension_id = ' . $eid); + $db->setQuery($query); + $db->execute(); + + // Delete any unused update sites + $query->clear() + ->select('update_site_id') + ->from('#__update_sites_extensions'); + $db->setQuery($query); + $results = $db->loadColumn(); + + if (is_array($results)) + { + // So we need to delete the update sites and their associated updates + $updatesite_delete = $db->getQuery(true); + $updatesite_delete->delete('#__update_sites'); + $updatesite_query = $db->getQuery(true); + $updatesite_query->select('update_site_id') + ->from('#__update_sites'); + + // If we get results back then we can exclude them + if (count($results)) + { + $updatesite_query->where('update_site_id NOT IN (' . implode(',', $results) . ')'); + $updatesite_delete->where('update_site_id NOT IN (' . implode(',', $results) . ')'); + } + + // So let's find what update sites we're about to nuke and remove their associated extensions + $db->setQuery($updatesite_query); + $update_sites_pending_delete = $db->loadColumn(); + + if (is_array($update_sites_pending_delete) && count($update_sites_pending_delete)) + { + // Nuke any pending updates with this site before we delete it + // TODO: investigate alternative of using a query after the delete below with a query and not in like above + $query->clear() + ->delete('#__updates') + ->where('update_site_id IN (' . implode(',', $update_sites_pending_delete) . ')'); + $db->setQuery($query); + $db->execute(); + } + + // Note: this might wipe out the entire table if there are no extensions linked + $db->setQuery($updatesite_delete); + $db->execute(); + } + + // Last but not least we wipe out any pending updates for the extension + $query->clear() + ->delete('#__updates') + ->where('extension_id = ' . $eid); + $db->setQuery($query); + $db->execute(); + } + } + + /* + * $parent is the class calling this method + * uninstall runs before any other action is taken (file removal or database processing). + */ + function uninstall( $parent ) + { + echo '

    ' . JText::_('COM_ICAGENDA_UNINSTALL') . '

    '; + } + + + /* + * get a variable from the manifest file (actually, from the manifest cache). + */ + function getParam( $name ) + { + $db = JFactory::getDbo(); + $db->setQuery('SELECT manifest_cache FROM #__extensions WHERE element = "com_icagenda"'); + $manifest = json_decode( $db->loadResult(), true ); + return $manifest[ $name ]; + } + + + /* + * sets parameter values in the component's row of the extension table + */ + function setParams( $param_array ) + { + if ( count($param_array) > 0 ) + { + // read the existing component value(s) + $db = JFactory::getDbo(); + $db->setQuery('SELECT params FROM #__extensions WHERE element = "com_icagenda"'); + $params = json_decode( $db->loadResult(), true ); + // add the new variable(s) to the existing one(s) + foreach ( $param_array as $name => $value ) + { + $params[ (string) $name ] = (string) $value; + } + // store the combined new and existing values back as a JSON string + $paramsString = json_encode( $params ); + $db->setQuery('UPDATE #__extensions SET params = ' . + $db->quote( $paramsString ) . + ' WHERE element = "com_icagenda"' ); + $db->query(); + } + } + + + /* + * sets access permissions values (rules) in the component's row of the assets table + */ + function setRules( $rule_array ) + { + if ( count($rule_array) > 0 ) + { + // read the existing rules values + $db = JFactory::getDbo(); + $db->setQuery('SELECT rules FROM #__assets WHERE name = "com_icagenda"'); + $rules = json_decode( $db->loadResult(), true ); + // add the new variable(s) to the existing one(s) + foreach ( $rule_array as $name => $value ) + { + if (!array_key_exists($name, $rules)) + { + $rules[ (string) $name ] = (array) $value; + } + } + // store the combined new and existing values back as a JSON string + $rulesString = json_encode( $rules ); + $db->setQuery('UPDATE #__assets SET rules = ' . + $db->quote( stripslashes($rulesString) ) . + ' WHERE name = "com_icagenda"' ); + $db->query(); + } + } + + /** + * Purge the cache. + * + * @return void + */ + public function purgeCache() + { + $app = JFactory::getApplication(); + + $ret = $this->clean(); + + $msg = JText::_('COM_ICAGENDA_CACHE_EXPIRED_ITEMS_HAVE_BEEN_PURGED'); + $msgType = 'message'; + + if ($ret === false) + { + $msg = JText::_('COM_ICAGENDA_CACHE_EXPIRED_ITEMS_PURGING_ERROR'); + $msgType = 'error'; + } + + $app->redirect('index.php?option=com_icagenda&view=icagenda', $msg, $msgType); + } + + /** + * Clean out a cache group as named by param. + * If no param is passed clean all cache groups. + * + * @param string $group Cache group name. + * + * @return void + */ + public function clean($group = '') + { + $cache = JFactory::getCache(''); + $cache->clean($group); + } + + /** + * Send site system information + * Adapted from Nicholas K. Dionysopoulos's code (Akeeba - www.akeebabackup.com). + */ + public function getSystemInfo($type, $parent) + { + $this->release = $parent->get( "manifest" )->version; + + // Do not system info on localhost + if ((strpos(JUri::root(), 'localhost') !== false) + || (strpos(JUri::root(), '127.0.0.1') !== false)) + { + return false; + } + + // Set site ID + $siteId = md5(JUri::base()); + + // If info file is missing, stop it! + if ( ! file_exists(JPATH_ROOT . '/administrator/components/com_icagenda/assets/jcms/info.php')) + { + return false; + } + + if ( ! class_exists('iCagendaSystemInfo', false)) + { + require_once JPATH_ROOT . '/administrator/components/com_icagenda/assets/jcms/info.php'; + } + + if ( ! class_exists('iCagendaSystemInfo', false)) + { + return false; + } + + $params = JComponentHelper::getParams('com_icagenda'); + + // Stop if system info is turned off + if ( ! $params->get('system_info', 1)) + { + return false; + } + + $db = JFactory::getDbo(); + $stats = new iCagendaSystemInfo(); + + $stats->setSiteId($siteId); + + // Get iCagenda release + $ic_parts = explode('.', $this->release); + $ic_major = $ic_parts[0]; + $ic_minor = isset($ic_parts[1]) ? $ic_parts[1] : ''; + $ic_revision = isset($ic_parts[2]) ? $ic_parts[2] : ''; + + // Get PHP version + list($php_major, $php_minor, $php_revision) = explode('.', phpversion()); + $php_qualifier = strpos($php_revision, '~') !== false ? substr($php_revision, strpos($php_revision, '~')) : ''; + + // Get Joomla version + list($cms_major, $cms_minor, $cms_revision) = explode('.', JVERSION); + + // Get Database version + list($db_major, $db_minor, $db_revision) = explode('.', $db->getVersion()); + $db_qualifier = strpos($db_revision, '~') !== false ? substr($db_revision, strpos($db_revision, '~')) : ''; + + // Get Database type + $db_driver = get_class($db); + + if (stripos($db_driver, 'mysql') !== false) + { + $db_type = '1'; + } + elseif (stripos($db_driver, 'sqlsrv') !== false || stripos($db_driver, 'sqlazure')) + { + $db_type = '2'; + } + elseif (stripos($db_driver, 'postgresql') !== false) + { + $db_type = '3'; + } + else + { + $db_type = '0'; + } + + $installtype = ($type == 'install') ? '1' : '2'; + $ictype = $this->ictype; + + $stats->setValue('ins', $installtype); // software_install + + // Version : major(x).minor(y).revision/patch(z) + + $stats->setValue('swn', 'iCagenda'); // software_name + $stats->setValue('swt', $ictype); // software_type + $stats->setValue('swx', $ic_major); // software_major + $stats->setValue('swy', $ic_minor); // software_minor + $stats->setValue('swz', $ic_revision); // software_revision + + $stats->setValue('cmst', 1); // cms_type + $stats->setValue('cmsx', $cms_major); // cms_major + $stats->setValue('cmsy', $cms_minor); // cms_minor + $stats->setValue('cmsz', $cms_revision); // cms_revision + + $stats->setValue('phpx', $php_major); // php_major + $stats->setValue('phpy', $php_minor); // php_minor + $stats->setValue('phpz', $php_revision); // php_revision + $stats->setValue('phpq', $php_qualifier); // php_qualifiers + + $stats->setValue('dbt', $db_type); // db_type + $stats->setValue('dbx', $db_major); // db_major + $stats->setValue('dby', $db_minor); // db_minor + $stats->setValue('dbz', $db_revision); // db_revision + $stats->setValue('dbq', $db_qualifier); // db_qualifiers + + $return = $stats->sendInfo(true); + + return $return; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/index.html b/deployed/icagenda/administrator/components/com_icagenda/sql/index.html new file mode 100644 index 00000000..94906bce --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/install/mysql/icagenda.install.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/install/mysql/icagenda.install.sql new file mode 100644 index 00000000..83554fb6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/install/mysql/icagenda.install.sql @@ -0,0 +1,281 @@ +-- +-- iCagenda: Install Database `icagenda` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `version` varchar(255) DEFAULT NULL, + `releasedate` varchar(255) DEFAULT NULL, + `params` text NOT NULL, + PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `#__icagenda` +-- + +INSERT IGNORE INTO `#__icagenda` (`id`, `version`, `releasedate`, `params`) VALUES +(3,'3.7.15','2020-08-29',''); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_category` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_category` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `ordering` int(11) NOT NULL, + `state` tinyint(1) NOT NULL DEFAULT '1', + `checked_out` int(11) NOT NULL, + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `title` varchar(255) NOT NULL, + `alias` varchar(255) NOT NULL, + `color` varchar(255) NOT NULL, + `desc` text(65535) NOT NULL, + `image` varchar(255) NOT NULL, + `groups` varchar(255) NOT NULL DEFAULT '', + `language` varchar(10) NOT NULL DEFAULT '*', + PRIMARY KEY (`id`), + KEY `idx_state` (`state`), + KEY `idx_language` (`language`) +) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_events` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_events` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `ordering` int(11) NOT NULL, + `state` tinyint(1) NOT NULL DEFAULT '1', + `approval` int(11) NOT NULL DEFAULT '0', + `site_itemid` int(10) NOT NULL DEFAULT '0', + `checked_out` int(11) NOT NULL, + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `title` varchar(255) NOT NULL, + `alias` varchar(255) NOT NULL, + `access` int(10) unsigned NOT NULL DEFAULT '0', + `language` varchar(10) NOT NULL DEFAULT '*', + `hits` int(10) unsigned NOT NULL DEFAULT '0', + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` int(10) unsigned NOT NULL DEFAULT '0', + `created_by_alias` varchar(255) NOT NULL, + `created_by_email` varchar(100) NOT NULL, + `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified_by` int(10) unsigned NOT NULL DEFAULT '0', + `username` varchar(255) NOT NULL, + `catid` int(11) NOT NULL, + `image` varchar(255) NOT NULL, + `file` varchar(255) NOT NULL, + `displaytime` int(10) NOT NULL DEFAULT '1', + `weekdays` varchar(255) NOT NULL, + `daystime` varchar(255) NOT NULL, + `startdate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `enddate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `period` text(65535) NOT NULL, + `dates` text(65535) NOT NULL, + `next` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `time` varchar(255) NOT NULL, + `place` varchar(255) NOT NULL, + `website` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `phone` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `city` varchar(255) NOT NULL, + `country` varchar(255) NOT NULL, + `address` varchar(255) NOT NULL, + `coordinate` varchar(255) NOT NULL, + `lat` float( 20, 16 ) NOT NULL, + `lng` FLOAT( 20, 16 ) NOT NULL, + `shortdesc` text NOT NULL, + `desc` text(65535) NOT NULL , + `metadesc` text NOT NULL, + `params` text NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_state` (`state`), + KEY `idx_approval` (`approval`), + KEY `idx_language` (`language`), + KEY `idx_catid` (`catid`) +) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_registration` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_registration` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `ordering` int(11) NOT NULL, + `state` tinyint(1) NOT NULL DEFAULT '1', + `checked_out` int(11) NOT NULL, + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `userid` int(11) NOT NULL, + `itemid` int(11) NOT NULL, + `eventid` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `phone` varchar(255) NOT NULL, + `date` text(65535) NOT NULL, + `period` tinyint(1) NOT NULL DEFAULT '0', + `people` int(2) NOT NULL, + `notes` text(65535) NOT NULL , + `status` tinyint(1) NOT NULL DEFAULT '1', + `params` text NOT NULL , + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` int(10) unsigned NOT NULL DEFAULT '0', + `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified_by` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `idx_state` (`state`), + KEY `idx_userid` (`userid`), + KEY `idx_eventid` (`eventid`), + KEY `idx_status` (`status`), + KEY `idx_created_by` (`created_by`) +) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_customfields` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_customfields` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `ordering` int(11) NOT NULL, + `state` tinyint(1) NOT NULL DEFAULT '1', + `checked_out` int(11) NOT NULL, + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `title` varchar(255) NOT NULL, + `alias` varchar(255) NOT NULL, + `slug` varchar(255) NOT NULL, + `description` mediumtext NOT NULL, + `parent_form` int(11) NOT NULL DEFAULT '0', + `groups` varchar(255) NOT NULL DEFAULT '', + `type` varchar(255) NOT NULL, + `options` mediumtext, + `default` varchar(255) NOT NULL, + `required` tinyint(3) NOT NULL DEFAULT '0', + `language` varchar(10) NOT NULL DEFAULT '*', + `params` mediumtext, + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` int(10) unsigned NOT NULL DEFAULT '0', + `created_by_alias` varchar(255) NOT NULL DEFAULT '', + `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified_by` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `idx_state` (`state`), + KEY `idx_parent_form` (`parent_form`), + KEY `idx_language` (`language`) +) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_customfields_data` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_customfields_data` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `state` tinyint(1) NOT NULL DEFAULT '1', + `slug` varchar(255) NOT NULL, + `parent_form` int(11) NOT NULL DEFAULT '0', + `parent_id` int(11) NOT NULL DEFAULT '0', + `value` varchar(255) NOT NULL, + `language` varchar(10) NOT NULL DEFAULT '*', + PRIMARY KEY (`id`), + KEY `idx_state` (`state`), + KEY `idx_parent_form` (`parent_form`), + KEY `idx_parent_id` (`parent_id`), + KEY `idx_language` (`language`) +) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_feature` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_feature` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `ordering` int(11) NOT NULL, + `state` tinyint(1) NOT NULL DEFAULT '1', + `checked_out` int(11) NOT NULL, + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `title` varchar(255) NOT NULL, + `alias` varchar(255) NOT NULL, + `desc` mediumtext NOT NULL, + `icon` varchar(255) NOT NULL, + `icon_alt` varchar(255) NOT NULL, + `show_filter` tinyint(1) NOT NULL DEFAULT '1', + PRIMARY KEY (`id`), + KEY `idx_state` (`state`) +) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_feature_xref` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_feature_xref` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `event_id` int(11) NOT NULL, + `feature_id` int(11) NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_event_id` (`event_id`), + KEY `idx_feature_id` (`feature_id`) +) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_filters` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_filters` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `ordering` int(11) NOT NULL DEFAULT 0, + `state` tinyint(3) NOT NULL DEFAULT 0, + `type` varchar(255) NOT NULL DEFAULT '', + `filter` varchar(255) NOT NULL DEFAULT '', + `value` varchar(255) NOT NULL DEFAULT '', + `option` varchar(255) NOT NULL DEFAULT '', + `selected` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `idx_state` (`state`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_user_actions` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_user_actions` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `user_id` int(10) unsigned NOT NULL DEFAULT 0, + `user_action` varchar(255) NOT NULL, + `parent_form` int(11) NOT NULL DEFAULT '0', + `parent_id` int(11) NOT NULL DEFAULT '0', + `action_subject` varchar(100) NOT NULL DEFAULT '', + `action_body` text NOT NULL, + `user_ip` varchar(100) NOT NULL DEFAULT '', + `user_agent` text NOT NULL, + `state` tinyint(3) NOT NULL DEFAULT 0, + `created_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + KEY `idx_user_id` (`user_id`), + KEY `idx_parent_form` (`parent_form`), + KEY `idx_parent_id` (`parent_id`), + KEY `idx_state` (`state`) +) DEFAULT CHARSET=utf8; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/uninstall/mysql/icagenda.uninstall.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/uninstall/mysql/icagenda.uninstall.sql new file mode 100644 index 00000000..43019bdc --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/uninstall/mysql/icagenda.uninstall.sql @@ -0,0 +1,17 @@ +-- +-- iCagenda: Uninstall Database `icagenda` +-- + +-- -------------------------------------------------------- + +DROP TABLE IF EXISTS `#__icagenda`; +DROP TABLE IF EXISTS `#__icagenda_category`; +DROP TABLE IF EXISTS `#__icagenda_events`; +DROP TABLE IF EXISTS `#__icagenda_registration`; +DROP TABLE IF EXISTS `#__icagenda_customfields`; +DROP TABLE IF EXISTS `#__icagenda_customfields_data`; +DROP TABLE IF EXISTS `#__icagenda_feature`; +DROP TABLE IF EXISTS `#__icagenda_feature_xref`; +DROP TABLE IF EXISTS `#__icagenda_filters`; +DROP TABLE IF EXISTS `#__icagenda_user_actions`; +DROP TABLE IF EXISTS `#__icagenda_location`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.0.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.0.sql new file mode 100644 index 00000000..e69de29b diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.1.sql new file mode 100644 index 00000000..d19683d7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.1.1' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.2.sql new file mode 100644 index 00000000..4d7867e6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.1.2' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.3.sql new file mode 100644 index 00000000..5ade9fd7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.1.3' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.4.sql new file mode 100644 index 00000000..27b42ccb --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.1.4' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.sql new file mode 100644 index 00000000..bb773288 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.1' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.1.sql new file mode 100644 index 00000000..99576ad4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.1.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.1' WHERE id=1; +DROP TABLE IF EXISTS `#__icagenda_registration`; +DROP TABLE IF EXISTS `#__icagenda_location`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.2.sql new file mode 100644 index 00000000..124f8c96 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.2.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.2' WHERE id=1; +DROP TABLE IF EXISTS `#__icagenda_registration`; +DROP TABLE IF EXISTS `#__icagenda_location`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.3.sql new file mode 100644 index 00000000..7fd5c5af --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.2.3' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.4.sql new file mode 100644 index 00000000..850512c7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.2.4' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.5.sql new file mode 100644 index 00000000..de652910 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.5.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.5' WHERE id=1; + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.1.sql new file mode 100644 index 00000000..d696a22b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.1.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.6 beta1', releasedate='2012-10-09' WHERE id=1; + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.2.sql new file mode 100644 index 00000000..77c90f93 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.2.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.6 beta2', releasedate='2012-10-11' WHERE id=1; + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.3.sql new file mode 100644 index 00000000..1486ebdf --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.3.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.6 beta3', releasedate='2012-10-13' WHERE id=1; + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.4.sql new file mode 100644 index 00000000..7ca99cb6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.4.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.6', releasedate='2012-10-15' WHERE id=1; + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.sql new file mode 100644 index 00000000..965b302d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.6.sql @@ -0,0 +1,20 @@ +ALTER TABLE `#__icagenda` ADD COLUMN `releasedate` TEXT(65535) NOT NULL AFTER `version`; +UPDATE `#__icagenda` SET version='1.2.6', releasedate='2012-10-06' WHERE id=1; + +DROP TABLE IF EXISTS `#__icagenda_registration`; + +CREATE TABLE `#__icagenda_registration` ( +`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, +`ordering` INT(11) NOT NULL , +`checked_out` INT(11) NOT NULL , +`checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', +`userid` INT(11) NOT NULL , +`eventid` INT(11) NOT NULL , +`name` VARCHAR(255) NOT NULL , +`email` VARCHAR(255) NOT NULL , +`phone` VARCHAR(255) NOT NULL , +`date` DATE NOT NULL , +`people` INT(2) NOT NULL , +PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci; + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.7.sql new file mode 100644 index 00000000..4af60e3d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.7.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.7', releasedate='2012-10-18' WHERE id=1; + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.8.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.8.sql new file mode 100644 index 00000000..a23115dc --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.8.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.8', releasedate='2012-10-22' WHERE id=1; + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.9.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.9.sql new file mode 100644 index 00000000..946eb1e2 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.9.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.2.9', releasedate='2012-10-28' WHERE id=1; + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.sql new file mode 100644 index 00000000..15638f16 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.2' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.1.sql new file mode 100644 index 00000000..9fe34237 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.1.sql @@ -0,0 +1,4 @@ +UPDATE `#__icagenda` SET version='1.3 beta1', releasedate='2012-10-28' WHERE id=1; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `registration` TINYINT(1) NOT NULL DEFAULT '1'; + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.2.sql new file mode 100644 index 00000000..cd428ae4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.2.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.3 beta1', releasedate='2012-12-03' WHERE id=1; + +ALTER TABLE `#__icagenda_registration` MODIFY COLUMN `date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.3.sql new file mode 100644 index 00000000..2af2628b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.3.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.3 beta1', releasedate='2012-12-10' WHERE id=1; + +ALTER TABLE `#__icagenda_events` MODIFY COLUMN `params` TEXT NOT NULL DEFAULT ''; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.4.sql new file mode 100644 index 00000000..2a088ed4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.4.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.3 beta1', releasedate='2012-12-11' WHERE id=1; + +ALTER TABLE `#__icagenda_events` DROP COLUMN `registration`; \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.5.sql new file mode 100644 index 00000000..99445aa6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.5.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.3 beta1', releasedate='2012-12-11' WHERE id=1; + +ALTER TABLE `#__icagenda_registration` ADD COLUMN `period` TINYINT(1) NOT NULL DEFAULT '0' AFTER `date`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.6.sql new file mode 100644 index 00000000..1806ab71 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.6.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.3 beta2', releasedate='2012-12-15' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.7.sql new file mode 100644 index 00000000..bc5d1b3e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.7.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.3 beta3', releasedate='2012-12-16' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.8.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.8.sql new file mode 100644 index 00000000..3d4b764c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.8.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.3 beta4', releasedate='2012-12-24' WHERE id=1; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `country` VARCHAR(255) NOT NULL AFTER `city`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.9.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.9.sql new file mode 100644 index 00000000..d5096b8a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.9.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='1.3 beta4', releasedate='2012-12-28' WHERE id=1; + +ALTER TABLE `#__icagenda_registration` MODIFY COLUMN `date` TEXT(65535) NOT NULL; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.sql new file mode 100644 index 00000000..b14ae36f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.0.1.sql @@ -0,0 +1,26 @@ +UPDATE `#__icagenda` SET version='1.3 beta1', releasedate='2012-10-28' WHERE id=1; + +ALTER TABLE `#__icagenda_events` ADD `period` TEXT(65535) NOT NULL AFTER `file`; +ALTER TABLE `#__icagenda_events` ADD `enddate` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `file`; +ALTER TABLE `#__icagenda_events` ADD `startdate` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `file`; +ALTER TABLE `#__icagenda_events` MODIFY `next` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'; +ALTER TABLE `#__icagenda_events` ADD `website` VARCHAR(255) NOT NULL AFTER `place`; + +DROP TABLE IF EXISTS `#__icagenda_registration`; + +CREATE TABLE `#__icagenda_registration` ( +`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, +`ordering` INT(11) NOT NULL , +`state` TINYINT(11) NOT NULL DEFAULT '1', +`checked_out` INT(11) NOT NULL , +`checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', +`userid` INT(11) NOT NULL , +`eventid` INT(11) NOT NULL , +`name` VARCHAR(255) NOT NULL , +`email` VARCHAR(255) NOT NULL , +`phone` VARCHAR(255) NOT NULL , +`date` DATE NOT NULL , +`people` INT(2) NOT NULL , +PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci; + diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.sql new file mode 100644 index 00000000..a5546fbd --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/1.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='1.3', releasedate='2012-10-19' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.1.sql new file mode 100644 index 00000000..7e91c45e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.0.1 RC', releasedate='2013-01-01' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.2.sql new file mode 100644 index 00000000..c90bd172 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.0.2 RC', releasedate='2013-01-04' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.3.sql new file mode 100644 index 00000000..2adc0920 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.0.3', releasedate='2013-01-10' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.4.sql new file mode 100644 index 00000000..4b1a1049 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.0.4', releasedate='2013-01-23' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.5.sql new file mode 100644 index 00000000..caee65d7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.5.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.0.5', releasedate='2013-02-01' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.6.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.6.1.sql new file mode 100644 index 00000000..83062933 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.6.1.sql @@ -0,0 +1,11 @@ +UPDATE `#__icagenda` SET version='2.1 beta', releasedate='2013-02-21' WHERE id=1; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `asset_id` INT(10) NOT NULL DEFAULT '0' AFTER `id`; + + +ALTER TABLE `#__icagenda_events` ADD COLUMN `modified_by` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `alias`; +ALTER TABLE `#__icagenda_events` ADD COLUMN `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `alias`; +ALTER TABLE `#__icagenda_events` ADD COLUMN `created_by_alias` VARCHAR(255) NOT NULL AFTER `alias`; +ALTER TABLE `#__icagenda_events` ADD COLUMN `created_by` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `alias`; +ALTER TABLE `#__icagenda_events` ADD COLUMN `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `alias`; +ALTER TABLE `#__icagenda_events` ADD COLUMN `access` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `alias`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.6.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.6.2.sql new file mode 100644 index 00000000..bfe37122 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.6.2.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='2.1 beta', releasedate='2013-02-22' WHERE id=1; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `displaytime` INT(10) NOT NULL DEFAULT '1' AFTER `file`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.6.sql new file mode 100644 index 00000000..6e8b18cb --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.6.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.0.6', releasedate='2013-02-07' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.sql new file mode 100644 index 00000000..d964bef3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.0.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.0.0 RC', releasedate='2012-12-31' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.1.sql new file mode 100644 index 00000000..86a1ad02 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.1', releasedate='2013-03-14' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.10.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.10.sql new file mode 100644 index 00000000..9ffad140 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.10.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.10', releasedate='2013-05-07' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.11.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.11.sql new file mode 100644 index 00000000..843545cf --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.11.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.11', releasedate='2013-05-13' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.12.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.12.sql new file mode 100644 index 00000000..2b365cc2 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.12.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.12', releasedate='2013-05-21' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.13.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.13.sql new file mode 100644 index 00000000..974e56ee --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.13.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.13', releasedate='2013-05-23' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.14.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.14.sql new file mode 100644 index 00000000..0aa5973e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.14.sql @@ -0,0 +1,4 @@ +UPDATE `#__icagenda` SET version='2.1.14', releasedate='2013-05-29' WHERE id=1; +UPDATE `#__icagenda_events` SET language='*' WHERE language=''; + +ALTER TABLE `#__icagenda_registration` ADD COLUMN `itemid` INT(11) NOT NULL AFTER `userid`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.2.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.2.2.sql new file mode 100644 index 00000000..6fe26dfe --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.2.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.2.2', releasedate='2013-03-27' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.2.sql new file mode 100644 index 00000000..7cfb3c8e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.2', releasedate='2013-03-21' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.3.sql new file mode 100644 index 00000000..fa2d0a93 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.3', releasedate='2013-04-01' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.4.sql new file mode 100644 index 00000000..ada6d156 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.4', releasedate='2013-04-05' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.5.sql new file mode 100644 index 00000000..0227f1c2 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.5.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.5', releasedate='2013-04-10' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.6.sql new file mode 100644 index 00000000..3ff4523e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.6.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.6', releasedate='2013-04-12' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.7.sql new file mode 100644 index 00000000..eb6af5e3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.7.sql @@ -0,0 +1,6 @@ +UPDATE `#__icagenda` SET version='2.1.7', releasedate='2013-04-29' WHERE id=1; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `language` CHAR(7) NOT NULL AFTER `access`; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `lng` FLOAT( 20, 16 ) NOT NULL AFTER `coordinate`; +ALTER TABLE `#__icagenda_events` ADD COLUMN `lat` FLOAT( 20, 16 ) NOT NULL AFTER `coordinate`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.8.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.8.sql new file mode 100644 index 00000000..7e4f6205 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.8.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.8', releasedate='2013-04-30' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.9.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.9.sql new file mode 100644 index 00000000..7346200e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.9.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1.9', releasedate='2013-05-03' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.sql new file mode 100644 index 00000000..5dd30ad8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/2.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='2.1', releasedate='2013-03-11' WHERE id=1; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.0.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.0.1.sql new file mode 100644 index 00000000..53c7a77c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.0.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.0.1', releasedate='2013-07-04' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.0.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.0.sql new file mode 100644 index 00000000..490ab214 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.0.sql @@ -0,0 +1 @@ +INSERT INTO `#__icagenda` (id,version,releasedate) VALUES (2,'3.0','2013-06-04'); diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.0.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.0.sql new file mode 100644 index 00000000..53b5fb3b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.0.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.0', releasedate='2013-07-26' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.1.sql new file mode 100644 index 00000000..0a34ac96 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.1', releasedate='2013-07-29' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.10.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.10.sql new file mode 100644 index 00000000..b160019d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.10.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='3.1.10', releasedate='2013-09-12' WHERE id=2; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `approval` INT(11) NOT NULL DEFAULT '0' AFTER `state`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.11.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.11.sql new file mode 100644 index 00000000..1e74a983 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.11.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.11', releasedate='2013-09-13' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.12.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.12.sql new file mode 100644 index 00000000..bf1181ad --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.12.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.12', releasedate='2013-09-17' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.13.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.13.sql new file mode 100644 index 00000000..2ef67823 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.13.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.13', releasedate='2013-09-20' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.2.sql new file mode 100644 index 00000000..4c25cd30 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.2', releasedate='2013-08-05' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.3.sql new file mode 100644 index 00000000..c071a7f6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.3', releasedate='2013-08-09' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.4.sql new file mode 100644 index 00000000..468df799 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.4', releasedate='2013-08-13' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.5.sql new file mode 100644 index 00000000..d67303ed --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.5.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.5', releasedate='2013-08-19' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.6.sql new file mode 100644 index 00000000..f8f30f8f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.6.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.6', releasedate='2013-08-20' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.7.sql new file mode 100644 index 00000000..09feee9e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.7.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.7', releasedate='2013-08-29' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.8.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.8.sql new file mode 100644 index 00000000..0733c143 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.8.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.1.8', releasedate='2013-08-30' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.9.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.9.sql new file mode 100644 index 00000000..4d3ca2f4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.1.9.sql @@ -0,0 +1,5 @@ +UPDATE `#__icagenda` SET version='3.1.9', releasedate='2013-09-06' WHERE id=2; + +ALTER TABLE `#__icagenda_registration` ADD COLUMN `notes` TEXT(65535) NOT NULL DEFAULT '' AFTER `people`; +ALTER TABLE `#__icagenda_events` ADD COLUMN `created_by_email` VARCHAR(100) NOT NULL DEFAULT '' AFTER `created_by_alias`; +ALTER TABLE `#__icagenda_events` ADD COLUMN `weekdays` VARCHAR(255) NOT NULL DEFAULT '' AFTER `displaytime`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.1.sql new file mode 100644 index 00000000..48b1ab10 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.0 RC2', releasedate='2013-09-22' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.2.sql new file mode 100644 index 00000000..48b1ab10 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.0 RC2', releasedate='2013-09-22' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.3.sql new file mode 100644 index 00000000..c935e8a6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.0 RC3', releasedate='2013-09-26' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.4.sql new file mode 100644 index 00000000..dc3148dc --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.0 RC4', releasedate='2013-10-04' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.sql new file mode 100644 index 00000000..9098f144 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.0.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='3.2.0', releasedate='2013-09-20' WHERE id=2; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `daystime` VARCHAR(255) NOT NULL DEFAULT '' AFTER `weekdays`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.1.sql new file mode 100644 index 00000000..27e11627 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.1', releasedate='2013-10-07' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.10.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.10.sql new file mode 100644 index 00000000..acd77c03 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.10.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.10', releasedate='2014-01-03' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.11.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.11.sql new file mode 100644 index 00000000..3391c368 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.11.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.11', releasedate='2014-01-04' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.12.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.12.sql new file mode 100644 index 00000000..d343682d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.12.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.12', releasedate='2014-01-08' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.13.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.13.sql new file mode 100644 index 00000000..2a3e1d0e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.13.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.13', releasedate='2014-02-01' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.14.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.14.sql new file mode 100644 index 00000000..e3718f67 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.14.sql @@ -0,0 +1,33 @@ +ALTER TABLE `#__icagenda` ADD COLUMN `params` TEXT NOT NULL DEFAULT '' AFTER `releasedate`; +INSERT INTO `#__icagenda` (id,version,releasedate,params) VALUES (3,'3.2.14','2014-03-01',''); + +ALTER TABLE `#__icagenda_events` ADD COLUMN `metadesc` TEXT NOT NULL DEFAULT '' AFTER `desc`; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_customfields` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_customfields` ( + `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `ordering` INT(11) NOT NULL, + `state` TINYINT(1) NOT NULL DEFAULT '1', + `checked_out` INT(11) NOT NULL, + `checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `title` VARCHAR(255) NOT NULL, + `alias` VARCHAR(255) NOT NULL, + `parent_form` INT(11) NOT NULL DEFAULT '0', + `type` VARCHAR(255) NOT NULL, + `options` mediumtext, + `default` VARCHAR(255) NOT NULL, + `required` tinyint(3) NOT NULL DEFAULT '0', + `language` varchar(10) NOT NULL DEFAULT '*', + `params` mediumtext, + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` int(10) unsigned NOT NULL DEFAULT '0', + `created_by_alias` varchar(255) NOT NULL DEFAULT '', + `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified_by` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.2.sql new file mode 100644 index 00000000..5a56ff99 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.2', releasedate='2013-10-10' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.3.sql new file mode 100644 index 00000000..06c198d6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.3', releasedate='2013-10-20' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.4.sql new file mode 100644 index 00000000..38011c6d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.4', releasedate='2013-10-29' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.5.sql new file mode 100644 index 00000000..8471a537 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.5.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.5', releasedate='2013-11-11' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.6.sql new file mode 100644 index 00000000..ee254722 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.6.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.6', releasedate='2013-11-21' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.7.sql new file mode 100644 index 00000000..673d3dec --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.7.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.7', releasedate='2013-11-23' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.8.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.8.sql new file mode 100644 index 00000000..b8736659 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.8.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.8', releasedate='2013-12-15' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.9.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.9.sql new file mode 100644 index 00000000..9f42732f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.9.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2.9', releasedate='2013-12-28' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.sql new file mode 100644 index 00000000..36f69d74 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.2', releasedate='2013-09-20' WHERE id=2; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.1.sql new file mode 100644 index 00000000..91c61a6c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.3.1', releasedate='2014-03-14' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.2.sql new file mode 100644 index 00000000..0a530b21 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.3.2', releasedate='2014-03-17' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.3.sql new file mode 100644 index 00000000..b6eb43b1 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.3.3', releasedate='2014-04-20' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.4.sql new file mode 100644 index 00000000..cb04aeaf --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.3.4', releasedate='2014-04-25' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.5-1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.5-1.sql new file mode 100644 index 00000000..f1fde395 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.5-1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.3.5-1', releasedate='2014-04-29' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.5.sql new file mode 100644 index 00000000..3f16b878 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.5.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.3.5', releasedate='2014-04-27' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.6.sql new file mode 100644 index 00000000..80d45890 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.6.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='3.3.6', releasedate='2014-05-16' WHERE id=3; + +ALTER TABLE `#__icagenda_customfields` ADD COLUMN `slug` VARCHAR(255) NOT NULL DEFAULT '' AFTER `alias`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.7.sql new file mode 100644 index 00000000..5a7a73a3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.7.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.3.7', releasedate='2014-05-29' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.8.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.8.sql new file mode 100644 index 00000000..ed4b67c5 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.8.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.3.8', releasedate='2014-07-04' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.sql new file mode 100644 index 00000000..213f1dd7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.3.0', releasedate='2014-03-06' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-alpha1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-alpha1.sql new file mode 100644 index 00000000..525bb93d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-alpha1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.4.0-alpha1', releasedate='2014-07-11' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-alpha2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-alpha2.sql new file mode 100644 index 00000000..99be0702 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-alpha2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.4.0-alpha2', releasedate='2014-07-16' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-beta1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-beta1.sql new file mode 100644 index 00000000..306d9df4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-beta1.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='3.4.0-beta1', releasedate='2014-07-23' WHERE id=3; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `shortdesc` TEXT NOT NULL DEFAULT '' AFTER `lng`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-beta2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-beta2.sql new file mode 100644 index 00000000..0dc9f6e6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-beta2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.4.0-beta2', releasedate='2014-11-09' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-rc.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-rc.sql new file mode 100644 index 00000000..529b81a0 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0-rc.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.4.0-rc', releasedate='2014-12-14' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0.sql new file mode 100644 index 00000000..e4c84331 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.0.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.4.0', releasedate='2014-12-22' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.1-alpha1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.1-alpha1.sql new file mode 100644 index 00000000..09faacbb --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.1-alpha1.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='3.4.1-alpha1', releasedate='2015-01-24' WHERE id=3; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `site_itemid` INT(10) NOT NULL DEFAULT '0' AFTER `approval`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.1.sql new file mode 100644 index 00000000..0341735a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.4.1', releasedate='2015-01-30' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.sql new file mode 100644 index 00000000..c45e4761 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.4.sql @@ -0,0 +1,54 @@ +UPDATE `#__icagenda` SET version='3.4', releasedate='2014-07-03' WHERE id=3; + +ALTER TABLE `#__icagenda_customfields` ADD COLUMN `description` VARCHAR(255) NOT NULL DEFAULT '' AFTER `slug`; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_customfields_data` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_customfields_data` ( + `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `state` TINYINT(1) NOT NULL DEFAULT '1', + `slug` VARCHAR(255) NOT NULL, + `parent_form` INT(11) NOT NULL DEFAULT '0', + `parent_id` INT(11) NOT NULL DEFAULT '0', + `value` VARCHAR(255) NOT NULL, + `language` varchar(10) NOT NULL DEFAULT '*', + PRIMARY KEY (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_feature` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_feature` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `ordering` int(11) NOT NULL, + `state` tinyint(1) NOT NULL DEFAULT '1', + `checked_out` int(11) NOT NULL, + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `title` varchar(255) NOT NULL, + `alias` varchar(255) NOT NULL, + `desc` mediumtext NOT NULL, + `icon` varchar(255) NOT NULL, + `icon_alt` varchar(255) NOT NULL, + `show_filter` tinyint(1) NOT NULL DEFAULT '1', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `#__icagenda_feature_xref` +-- + +CREATE TABLE IF NOT EXISTS `#__icagenda_feature_xref` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `event_id` int(11) NOT NULL, + `feature_id` int(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT COLLATE=utf8_general_ci; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.0.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.0.sql new file mode 100644 index 00000000..af0a6881 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.0.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.0', releasedate='2015-02-25' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.1.sql new file mode 100644 index 00000000..67e8b31f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.1', releasedate='2015-03-01' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.10.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.10.sql new file mode 100644 index 00000000..01357697 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.10.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.10', releasedate='2015-09-01' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.11.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.11.sql new file mode 100644 index 00000000..68837931 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.11.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.11', releasedate='2015-09-05' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.12.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.12.sql new file mode 100644 index 00000000..51651363 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.12.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.12', releasedate='2015-10-12' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.13.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.13.sql new file mode 100644 index 00000000..62d139d9 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.13.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.13', releasedate='2015-12-05' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.14.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.14.sql new file mode 100644 index 00000000..2f4574f0 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.14.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.14', releasedate='2016-01-23' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.15.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.15.sql new file mode 100644 index 00000000..936608fa --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.15.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.15', releasedate='2016-02-19' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.16.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.16.sql new file mode 100644 index 00000000..4754526f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.16.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.16', releasedate='2016-03-19' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.17.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.17.sql new file mode 100644 index 00000000..123be1ac --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.17.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.17', releasedate='2016-04-12' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.18.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.18.sql new file mode 100644 index 00000000..4ab59c70 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.18.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.18', releasedate='2016-06-19' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.19.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.19.sql new file mode 100644 index 00000000..98d34fdc --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.19.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.19', releasedate='2016-06-30' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.2.sql new file mode 100644 index 00000000..e1aac6ba --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.2', releasedate='2015-03-13' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.20.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.20.sql new file mode 100644 index 00000000..8f1dbfd4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.20.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.20', releasedate='2016-07-28' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.21.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.21.sql new file mode 100644 index 00000000..02d951b6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.21.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.21', releasedate='2016-08-04' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.3.sql new file mode 100644 index 00000000..e77e5300 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.3', releasedate='2015-03-25' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.4.sql new file mode 100644 index 00000000..c7eed6ef --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.4', releasedate='2015-04-24' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.5.sql new file mode 100644 index 00000000..be5e0977 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.5.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.5', releasedate='2015-04-27' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.6.sql new file mode 100644 index 00000000..88ffe166 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.6.sql @@ -0,0 +1,3 @@ +UPDATE `#__icagenda` SET version='3.5.6', releasedate='2015-06-29' WHERE id=3; + +ALTER TABLE `#__icagenda_registration` ADD COLUMN `params` text NOT NULL AFTER `notes`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.7.sql new file mode 100644 index 00000000..ec18ecb6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.7.sql @@ -0,0 +1,7 @@ +UPDATE `#__icagenda` SET version='3.5.7', releasedate='2015-07-16' WHERE id=3; + +ALTER TABLE `#__icagenda_registration` ADD COLUMN `asset_id` int(10) NOT NULL DEFAULT '0' AFTER `id`; +ALTER TABLE `#__icagenda_registration` ADD COLUMN `modified_by` int(10) unsigned NOT NULL DEFAULT '0' AFTER `params`; +ALTER TABLE `#__icagenda_registration` ADD COLUMN `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `params`; +ALTER TABLE `#__icagenda_registration` ADD COLUMN `created_by` int(10) unsigned NOT NULL DEFAULT '0' AFTER `params`; +ALTER TABLE `#__icagenda_registration` ADD COLUMN `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `params`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.8.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.8.sql new file mode 100644 index 00000000..66ad0eb5 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.8.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.8', releasedate='2015-07-17' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.9.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.9.sql new file mode 100644 index 00000000..09915392 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.5.9.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.5.9', releasedate='2015-08-01' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-alpha1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-alpha1.sql new file mode 100644 index 00000000..cb22a409 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-alpha1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.0-alpha1', releasedate='2015-12-28' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-alpha2.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-alpha2.1.sql new file mode 100644 index 00000000..9ff31411 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-alpha2.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.0-alpha2.1', releasedate='2016-06-02' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-alpha2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-alpha2.sql new file mode 100644 index 00000000..1cd853cb --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-alpha2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.0-alpha2', releasedate='2016-05-31' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-beta1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-beta1.sql new file mode 100644 index 00000000..5b41d23f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-beta1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.0-beta1', releasedate='2016-07-13' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-rc1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-rc1.sql new file mode 100644 index 00000000..a8eb01be --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0-rc1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.0-rc1', releasedate='2016-07-30' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0.sql new file mode 100644 index 00000000..5e857f4a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.0.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.0', releasedate='2016-08-19' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.1.sql new file mode 100644 index 00000000..1d617b98 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.1', releasedate='2016-08-29' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.10.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.10.sql new file mode 100644 index 00000000..4e561793 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.10.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.10', releasedate='2017-07-06' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.11.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.11.sql new file mode 100644 index 00000000..f6a17c91 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.11.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.11', releasedate='2017-07-20' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.12.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.12.sql new file mode 100644 index 00000000..045f2ed1 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.12.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.12', releasedate='2017-07-27' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.13.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.13.sql new file mode 100644 index 00000000..8a46c6ff --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.13.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.13', releasedate='2018-04-17' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.14.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.14.sql new file mode 100644 index 00000000..84d4db6e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.14.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.14', releasedate='2018-05-04' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.2.sql new file mode 100644 index 00000000..358e7c10 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.2', releasedate='2016-09-01' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.3.sql new file mode 100644 index 00000000..ecc4631b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.3', releasedate='2016-09-26' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.4.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.4.1.sql new file mode 100644 index 00000000..898a7af2 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.4.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.4.1', releasedate='2016-10-18' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.4.sql new file mode 100644 index 00000000..76d8d5cd --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.4', releasedate='2016-10-15' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.5.sql new file mode 100644 index 00000000..3dfd676e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.5.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.5', releasedate='2016-11-23' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.6.sql new file mode 100644 index 00000000..1efdf851 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.6.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.6', releasedate='2016-12-20' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.7.sql new file mode 100644 index 00000000..970a2925 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.7.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.7', releasedate='2017-04-27' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.8.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.8.sql new file mode 100644 index 00000000..77439034 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.8.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.8', releasedate='2017-05-03' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.9.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.9.sql new file mode 100644 index 00000000..1d27308c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.9.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.6.9', releasedate='2017-07-05' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.sql new file mode 100644 index 00000000..1752f86b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.6.sql @@ -0,0 +1,22 @@ +UPDATE `#__icagenda` SET version='3.6', releasedate='2015-12-28' WHERE id=3; + +ALTER TABLE `#__icagenda_events` ADD COLUMN `hits` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `language`; +ALTER TABLE `#__icagenda_customfields` ADD COLUMN `groups` VARCHAR(255) NOT NULL DEFAULT '' AFTER `parent_form`; +ALTER TABLE `#__icagenda_registration` ADD COLUMN `status` tinyint(1) NOT NULL DEFAULT '0' AFTER `notes`; +ALTER TABLE `#__icagenda_category` ADD COLUMN `language` varchar(10) NOT NULL DEFAULT '*' AFTER `desc`; +ALTER TABLE `#__icagenda_category` ADD COLUMN `groups` varchar(255) NOT NULL DEFAULT '' AFTER `desc`; +ALTER TABLE `#__icagenda_category` ADD COLUMN `image` varchar(255) NOT NULL AFTER `desc`; +ALTER TABLE `#__icagenda_events` MODIFY `language` varchar(10) NOT NULL DEFAULT '*'; +UPDATE `#__icagenda_events` SET language='*' WHERE language=''; + +CREATE TABLE IF NOT EXISTS `#__icagenda_filters` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `ordering` int(11) NOT NULL DEFAULT 0, + `state` tinyint(3) NOT NULL DEFAULT 0, + `type` varchar(255) NOT NULL DEFAULT '', + `filter` varchar(255) NOT NULL DEFAULT '', + `value` varchar(255) NOT NULL DEFAULT '', + `option` varchar(255) NOT NULL DEFAULT '', + `selected` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.0.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.0.sql new file mode 100644 index 00000000..5ce39518 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.0.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.0', releasedate='2018-05-25' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.1.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.1.sql new file mode 100644 index 00000000..be0c5111 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.1.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.1', releasedate='2018-05-28' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.10.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.10.sql new file mode 100644 index 00000000..79102a1a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.10.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.10', releasedate='2019-08-31' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.11.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.11.sql new file mode 100644 index 00000000..32dd562c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.11.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.11', releasedate='2019-12-19' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.12.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.12.sql new file mode 100644 index 00000000..889a92d3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.12.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.12', releasedate='2020-03-28' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.13.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.13.sql new file mode 100644 index 00000000..c8fcab5e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.13.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.13', releasedate='2020-04-02' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.14.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.14.sql new file mode 100644 index 00000000..e52b8335 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.14.sql @@ -0,0 +1,4 @@ +UPDATE `#__icagenda` SET version='3.7.14', releasedate='2020-04-27' WHERE id=3; + +ALTER TABLE `#__icagenda_events` DROP COLUMN `asset_id`; +ALTER TABLE `#__icagenda_registration` DROP COLUMN `asset_id`; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.15.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.15.sql new file mode 100644 index 00000000..f542a8d1 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.15.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.15', releasedate='2020-08-29' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.2.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.2.sql new file mode 100644 index 00000000..f792cfff --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.2.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.2', releasedate='2018-06-11' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.3.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.3.sql new file mode 100644 index 00000000..ce01c4aa --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.3.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.3', releasedate='2018-08-23' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.4.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.4.sql new file mode 100644 index 00000000..ade9ed77 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.4.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.4', releasedate='2018-09-26' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.5.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.5.sql new file mode 100644 index 00000000..9cea8933 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.5.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.5', releasedate='2018-10-30' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.6.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.6.sql new file mode 100644 index 00000000..71b15427 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.6.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.6', releasedate='2018-11-28' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.7.sql new file mode 100644 index 00000000..aa4efd25 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.7.sql @@ -0,0 +1,72 @@ +UPDATE `#__icagenda` SET version='3.7.7', releasedate='2019-01-09' WHERE id=3; + +-- +-- Indexes for table `#__icagenda_category` +-- +ALTER TABLE `#__icagenda_category` + ADD KEY `idx_state` (`state`), + ADD KEY `idx_language` (`language`); + +-- +-- Indexes for table `#__icagenda_customfields` +-- +ALTER TABLE `#__icagenda_customfields` + ADD KEY `idx_state` (`state`), + ADD KEY `idx_parent_form` (`parent_form`), + ADD KEY `idx_language` (`language`); + +-- +-- Indexes for table `#__icagenda_customfields_data` +-- +ALTER TABLE `#__icagenda_customfields_data` + ADD KEY `idx_state` (`state`), + ADD KEY `idx_parent_form` (`parent_form`), + ADD KEY `idx_parent_id` (`parent_id`), + ADD KEY `idx_language` (`language`); + +-- +-- Indexes for table `#__icagenda_events` +-- +ALTER TABLE `#__icagenda_events` + ADD KEY `idx_state` (`state`), + ADD KEY `idx_approval` (`approval`), + ADD KEY `idx_language` (`language`), + ADD KEY `idx_catid` (`catid`); + +-- +-- Indexes for table `#__icagenda_feature` +-- +ALTER TABLE `#__icagenda_feature` + ADD KEY `idx_state` (`state`); + +-- +-- Indexes for table `#__icagenda_feature_xref` +-- +ALTER TABLE `#__icagenda_feature_xref` + ADD KEY `idx_event_id` (`event_id`), + ADD KEY `idx_feature_id` (`feature_id`); + +-- +-- Indexes for table `#__icagenda_filters` +-- +ALTER TABLE `#__icagenda_filters` + ADD KEY `idx_state` (`state`); + +-- +-- Indexes for table `#__icagenda_registration` +-- +ALTER TABLE `#__icagenda_registration` + ADD KEY `idx_state` (`state`), + ADD KEY `idx_userid` (`userid`), + ADD KEY `idx_eventid` (`eventid`), + ADD KEY `idx_status` (`status`), + ADD KEY `idx_created_by` (`created_by`); + +-- +-- Indexes for table `#__icagenda_user_actions` +-- +ALTER TABLE `#__icagenda_user_actions` + ADD KEY `idx_user_id` (`user_id`), + ADD KEY `idx_parent_form` (`parent_form`), + ADD KEY `idx_parent_id` (`parent_id`), + ADD KEY `idx_state` (`state`); diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.8.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.8.sql new file mode 100644 index 00000000..ed7615b7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.8.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.8', releasedate='2019-01-10' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.9.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.9.sql new file mode 100644 index 00000000..cdf4cd7d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.9.sql @@ -0,0 +1 @@ +UPDATE `#__icagenda` SET version='3.7.9', releasedate='2019-06-13' WHERE id=3; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.sql b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.sql new file mode 100644 index 00000000..ac28e230 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/3.7.sql @@ -0,0 +1,16 @@ +UPDATE `#__icagenda` SET version='3.7', releasedate='2018-05-25' WHERE id=3; + +CREATE TABLE IF NOT EXISTS `#__icagenda_user_actions` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `user_id` int(10) unsigned NOT NULL DEFAULT 0, + `user_action` varchar(255) NOT NULL, + `parent_form` int(11) NOT NULL DEFAULT '0', + `parent_id` int(11) NOT NULL DEFAULT '0', + `action_subject` varchar(100) NOT NULL DEFAULT '', + `action_body` text NOT NULL, + `user_ip` varchar(100) NOT NULL DEFAULT '', + `user_agent` text NOT NULL, + `state` tinyint(3) NOT NULL DEFAULT 0, + `created_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8; diff --git a/deployed/icagenda/administrator/components/com_icagenda/sql/updates/index.html b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/index.html new file mode 100644 index 00000000..94906bce --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/sql/updates/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/tables/category.php b/deployed/icagenda/administrator/components/com_icagenda/tables/category.php new file mode 100644 index 00000000..698abbf4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/tables/category.php @@ -0,0 +1,165 @@ +setColumnAlias('published', 'state'); + } + } + + /** + * Overloaded bind function to pre-process the params. + * + * @param array Named array + * @return null|string null is operation was satisfactory, otherwise returns an error + * @see JTable:bind + * @since 1.5 + */ + public function bind($array, $ignore = '') + { + if (isset($array['params']) && is_array($array['params'])) + { + $registry = new JRegistry(); + $registry->loadArray($array['params']); + $array['params'] = (string)$registry; + } + + if (isset($array['metadata']) && is_array($array['metadata'])) + { + $registry = new JRegistry(); + $registry->loadArray($array['metadata']); + $array['metadata'] = (string)$registry; + } + + return parent::bind($array, $ignore); + } + + /** + * Overloaded check function + */ + public function check() + { + // If there is an ordering column and this is a new row then get the next ordering value + if (property_exists($this, 'ordering') && $this->id == 0) + { + $this->ordering = self::getNextOrder(); + } + + return parent::check(); + } + + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed An optional array of primary key values to update. If not + * set the instance property value is used. + * @param integer The publishing state. eg. [0 = unpublished, 1 = published] + * @param integer The user id of the user performing the operation. + * @return boolean True on success. + * @since 1.0.4 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + // Initialise variables. + $k = $this->_tbl_key; + + // Sanitize input. + JArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else { + $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k.'='.implode(' OR '.$k.'=', $pks); + + // Determine if there is checkin support for the table. + if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) { + $checkin = ''; + } + else { + $checkin = ' AND (checked_out = 0 OR checked_out = '.(int) $userId.')'; + } + + // Update the publishing state for rows with the given primary keys. + $this->_db->setQuery( + 'UPDATE '.$this->_tbl.'' . + ' SET state = '.(int) $state . + ' WHERE ('.$where.')' . + $checkin + ); + $this->_db->query(); + + // Check for a database error. + if ($this->_db->getErrorNum()) { + $this->setError($this->_db->getErrorMsg()); + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && (count($pks) == $this->_db->getAffectedRows())) + { + // Checkin the rows. + foreach($pks as $pk) + { + $this->checkin($pk); + } + } + + // If the JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) { + $this->state = $state; + } + + $this->setError(''); + return true; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/tables/customfield.php b/deployed/icagenda/administrator/components/com_icagenda/tables/customfield.php new file mode 100644 index 00000000..4f6c63b7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/tables/customfield.php @@ -0,0 +1,287 @@ +setColumnAlias('published', 'state'); + } + } + + /** + * Overloaded bind function. + * + * @param array Named array + * @return null|string null is operation was satisfactory, otherwise returns an error + * @see JTable:bind + * @since 3.4.0 + */ + public function bind($array, $ignore = '') + { + // Set Creator infos + $user = JFactory::getUser(); + $userId = $user->get('id'); + + if ($array['created_by'] == '0') + { + $array['created_by'] = (int)$userId; + } + + // Set Params + if (isset($array['params']) && is_array($array['params'])) + { + $registry = new JRegistry(); + $registry->loadArray($array['params']); + $array['params'] = (string) $registry; + } + + // Force system slugs for core fields and protect from usage in other field types + $coreFields = array('core_name', 'core_email', 'core_phone', 'core_date', 'core_people'); + + if (in_array($array['type'], $coreFields)) + { + $array['slug'] = $array['type']; + } + elseif (in_array($array['slug'], $coreFields) + && ! in_array($array['type'], $coreFields)) + { + $array['slug'] = $array['slug'] . '_copy'; + } + + // Set Placeholder to Options, and unset placeholder (if input type with hint) + $hintFields = array('text', 'url', 'tel', 'email', 'core_name', 'core_email', 'core_phone'); + + if (isset($array['placeholder']) + && in_array($array['type'], $hintFields)) + { + $array['options'] = $array['placeholder']; + unset($array['placeholder']); + } + + // Set Class to Options, and unset spacer_class (if input type is spacer) + $spacerFields = array('spacer_label', 'spacer_description'); + + if (isset($array['spacer_class']) + && in_array($array['type'], $spacerFields)) + { + $array['options'] = $array['spacer_class']; + unset($array['spacer_class']); + } + + // Set Groups + if ( ! isset($array['groups'])) + { + $array['groups'] = ''; + } + elseif (is_array($array['groups'])) + { + $array['groups'] = implode(',', $array['groups']); + } + + return parent::bind($array, $ignore); + } + + /** + * Overloaded check function + * @since 3.4.0 + */ + public function check() + { + // Import Joomla 2.5 + jimport( 'joomla.filter.output' ); + + // If there is an ordering column and this is a new row then get the next ordering value + if (property_exists($this, 'ordering') + && $this->id == 0) + { + $this->ordering = self::getNextOrder(); + } + + // URL alias + if (empty($this->alias)) + { + $this->alias = $this->title; + } + + $this->alias = JFilterOutput::stringURLSafe($this->alias); + + // Alias is not generated if non-latin characters, so we fix it by using created date, or title if unicode is activated, as alias + if ($this->alias == null || empty($this->alias)) + { + if (JFactory::getConfig()->get('unicodeslugs') == 1) + { + $this->alias = JFilterOutput::stringURLUnicodeSlug($this->title); + } + else + { + $this->alias = JFilterOutput::stringURLSafe($this->created); + } + } + + // Slug auto-create + $slug_empty = empty($this->slug) ? true : false; + + if ($slug_empty) + { + $this->slug = $this->title; + } + + $this->slug = iCFilterOutput::stringToSlug($this->slug); + + // Slug is not generated if non-latin characters, so we fix it by using created date as a slug + if ($this->slug == null) + { + $this->slug = iCFilterOutput::stringToSlug($this->created); + } + + // Check if Slug already exists + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('slug') + ->from($db->qn('#__icagenda_customfields')) + ->where($db->qn('slug') . ' = ' . $db->q($this->slug)); + + if (!empty($this->id)) + { + $query->where('id <> ' . (int) $this->id); + } + + $db->setQuery($query); + $slug_exists = $db->loadResult(); + + if ($slug_exists) + { + $error_slug = $slug_empty + ? JText::sprintf('COM_ICAGENDA_CUSTOMFIELD_DATABASE_ERROR_AUTO_SLUG', + '' . $this->title . '', '' . $this->slug . '') + : '' . JText::_('COM_ICAGENDA_CUSTOMFIELD_DATABASE_ERROR_UNIQUE_SLUG') . ''; + + $this->setError($error_slug . '

    ' + . JTEXT::_('COM_ICAGENDA_CUSTOMFIELD_SLUG_DESC').''); + + return false; + } + + return parent::check(); + } + + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed An optional array of primary key values to update. If not + * set the instance property value is used. + * @param integer The publishing state. eg. [0 = unpublished, 1 = published] + * @param integer The user id of the user performing the operation. + * @return boolean True on success. + * @since 3.4.0 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + // Initialise variables. + $k = $this->_tbl_key; + + // Sanitize input. + JArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k.'='.implode(' OR '.$k.'=', $pks); + + // Determine if there is checkin support for the table. + if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) + { + $checkin = ''; + } + else + { + $checkin = ' AND (checked_out = 0 OR checked_out = '.(int) $userId.')'; + } + + // Update the publishing state for rows with the given primary keys. + $this->_db->setQuery( + 'UPDATE '.$this->_tbl.'' . + ' SET state = '.(int) $state . + ' WHERE ('.$where.')' . + $checkin + ); + $this->_db->query(); + + // Check for a database error. + if ($this->_db->getErrorNum()) + { + $this->setError($this->_db->getErrorMsg()); + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && (count($pks) == $this->_db->getAffectedRows())) + { + // Checkin the rows. + foreach($pks as $pk) + { + $this->checkin($pk); + } + } + + // If the JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + return true; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/tables/event.php b/deployed/icagenda/administrator/components/com_icagenda/tables/event.php new file mode 100644 index 00000000..8d7728aa --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/tables/event.php @@ -0,0 +1,528 @@ +setColumnAlias('published', 'state'); + } + } + + /** + * Overloaded bind function to pre-process the params. + * + * @param array Named array + * @return null|string null is operation was satisfactory, otherwise returns an error + * @see JTable:bind + * @since 1.3 + */ + public function bind($array, $ignore = '') + { + $lang = JFactory::getLanguage(); + + // Serialize Single Dates + $dev_option = '0'; + + // Set Vars + $eventTimeZone = null; + $nodate = '0000-00-00 00:00:00'; + $date_today = JHtml::date('now', 'Y-m-d'); // Joomla Time Zone + + if (iCString::isSerialized($array['dates'])) + { + $dates = unserialize($array['dates']); + + foreach ($dates as $key => $date) + { + if ($date == '-0001-11-30 00:00') + { + unset($dates[$key]); + } + } + } + elseif ($dev_option == '1') // DEV. + { + $dates = $this->setDatesOptions($array['dates']); + } + else + { + $dates = $this->getDates($array['dates']); + + if ($lang->getTag() == 'fa-IR' + && $dates != array('0000-00-00 00:00') + && $dates != array('') + ) + { + $dates_to_sql = array(); + + foreach ($dates AS $date) + { + if (iCDate::isDate($date)) + { + $year = date('Y', strtotime($date)); + $month = date('m', strtotime($date)); + $day = date('d', strtotime($date)); + $time = date('H:i', strtotime($date)); + + $converted_date = iCGlobalizeConvert::jalaliToGregorian($year, $month, $day, true) . ' ' . $time; + $dates_to_sql[] = date('Y-m-d H:i', strtotime($converted_date)); + } + } + + $dates = $dates_to_sql; + } + } + + $dates = ($dates == array('')) ? array('0000-00-00 00:00') : $dates; + + rsort($dates); + + if ($dev_option == '1') // DEV. + { + $array['dates'] = $array['dates']; + } + else + { + $array['dates'] = serialize($dates); + } + + + /** + * Set Week Days + */ + if (!isset($array['weekdays'])) + { + $array['weekdays'] = ''; + } + elseif (is_array($array['weekdays'])) + { + $array['weekdays'] = implode(',', $array['weekdays']); + } + + // Return the dates of the period. + $startdate = iCDate::isDate($array['startdate']) ? date('Y-m-d H:i:s', strtotime($array['startdate'])) : $nodate; + $enddate = iCDate::isDate($array['enddate']) ? date('Y-m-d H:i:s', strtotime($array['enddate'])) : $nodate; + $period = array(); + + if (($startdate == $nodate) && ($enddate != $nodate)) + { + $enddate = $nodate; + } + + if (strtotime($startdate) > strtotime($enddate)) + { + $errorperiod = '1'; + } + else + { + $errorperiod = ''; + + $period_all_dates_array = iCDatePeriod::listDates($startdate, $enddate, $eventTimeZone); + $WeeksDays = iCDatePeriod::weekdaysToArray($array['weekdays']); + + $period_array = array(); + + foreach ($period_all_dates_array AS $date_in_weekdays) + { + $datetime_period_date = JHtml::date($date_in_weekdays, 'Y-m-d H:i', $eventTimeZone); + + if (in_array(date('w', strtotime($datetime_period_date)), $WeeksDays)) + { + array_push($period_array, $datetime_period_date); + } + } + } + + // Serialize Period Dates + if (($startdate != $nodate) && ($enddate != $nodate)) + { + if ($errorperiod != '1') + { + $array['period'] = serialize($period_array); + + $period = (iCString::isSerialized($array['period'])) ? unserialize($array['period']) : array(); + + if ($lang->getTag() == 'fa-IR') + { + $period_to_sql = array(); + + foreach ($period AS $date) + { + if (iCDate::isDate($date)) + { + $year = date('Y', strtotime($date)); + $month = date('m', strtotime($date)); + $day = date('d', strtotime($date)); + $time = date('H:i', strtotime($date)); + + $converted_date = iCGlobalizeConvert::jalaliToGregorian($year, $month, $day, true) . ' ' . $time; + $period_to_sql[] = date('Y-m-d H:i', strtotime($converted_date)); + } + } + + $period = $period_to_sql; + } + + rsort($period); + + $array['period'] = serialize($period); + } + else + { + $array['period'] = ''; + } + } + else + { + $array['period'] = ''; + } + + // Set Next Date + $NextDates = $this->getNextDates($dates); + $NextPeriod = ! empty($period) + ? $this->getNextPeriod($period, $array['weekdays']) + : $this->getNextDates($dates); + + $date_NextDates = JHtml::date($NextDates, 'Y-m-d', $eventTimeZone); + $date_NextPeriod = JHtml::date($NextPeriod, 'Y-m-d', $eventTimeZone); + $time_NextDates = JHtml::date($NextDates, 'H:i', $eventTimeZone); + $time_NextPeriod = JHtml::date($NextPeriod, 'H:i', $eventTimeZone); + + + // Control the next date + if ((strtotime($date_NextDates) >= strtotime($date_today)) && (strtotime($date_NextPeriod) >= strtotime($date_today))) + { + if (strtotime($date_NextDates) < strtotime($date_NextPeriod)) + { + $array['next'] = $this->getNextDates($dates); + } + if (strtotime($date_NextDates) > strtotime($date_NextPeriod)) + { + $array['next'] = ! empty($period) ? $this->getNextPeriod($period, $array['weekdays']) : $this->getNextDates($dates);; + } + if (strtotime($date_NextDates) == strtotime($date_NextPeriod)) + { + if (strtotime($time_NextDates) >= strtotime($time_NextPeriod)) + { + $array['next'] = ! empty($period) ? $this->getNextPeriod($period, $array['weekdays']) : $this->getNextDates($dates); + } + else + { + $array['next'] = $this->getNextDates($dates); + } + } + } + elseif ((strtotime($date_NextDates) < strtotime($date_today)) && (strtotime($date_NextPeriod) >= strtotime($date_today))) + { + $array['next'] = ! empty($period) ? $this->getNextPeriod($period, $array['weekdays']) : $this->getNextDates($dates); + } + elseif ((strtotime($date_NextDates) >= strtotime($date_today)) && (strtotime($date_NextPeriod) < strtotime($date_today))) + { + $array['next'] = $this->getNextDates($dates); + } + elseif ((strtotime($date_NextDates) < strtotime($date_today)) && (strtotime($date_NextPeriod) < strtotime($date_today))) + { + if (strtotime($date_NextDates) < strtotime($date_NextPeriod)) + { + $array['next'] = ! empty($period) ? $this->getNextPeriod($period, $array['weekdays']) : $this->getNextDates($dates); + } + else + { + $array['next'] = $this->getNextDates($dates); + } + } + + // Control of dates if valid (EDIT SINCE VERSION 3.0 - update 3.1.4) + if (((strtotime($NextDates) >= '943916400') + && (strtotime($NextDates) <= '944002800')) + && ($errorperiod == '1')) + { + $array['next'] = '-3600'; + } + if (((strtotime($NextDates)=='943916400') || (strtotime($NextDates)=='943920000')) + && ((strtotime($NextPeriod)=='943916400') || (strtotime($NextPeriod)=='943920000'))) + { + $array['next'] = '-3600'; + } + + if ($array['next'] == '-3600') + { + $state = 0; + + $this->_db->setQuery( + 'UPDATE #__icagenda_events' . + ' SET state = '.(int) $state . + ' WHERE id = '. (int) $array['id'] + ); + + if (version_compare(JVERSION, '3.0', 'lt')) + { + $this->_db->query(); + } + else + { + $this->_db->execute(); + } + } + + $return = parent::bind($array, $ignore); + + return $return; + } + + /** + * DEV. + */ + function setDatesOptions($dates) // DEV. + { + $dates = str_replace('day=', '', $dates); + $dates = str_replace('start=', '', $dates); + $dates = str_replace('end=', '', $dates); +// $dates = str_replace('+', ' ', $dates); + $dates = str_replace('%3A', ':', $dates); + $dates = str_replace('&', ',', $dates); + + $ex_dates = explode(',stop=stop', $dates); + + $singles_dates = array(); + + foreach ($ex_dates AS $sd) + { + if ($sd != '') + { + array_push($singles_dates, $sd); + } + } + + return $singles_dates; + } + + /** + * Get Dates for Single Dates Script Input + */ + function getDates($dates) + { + $dates = str_replace('d=', '', $dates); + $dates = str_replace('+', ' ', $dates); + $dates = str_replace('%3A', ':', $dates); + $ex_dates = explode('&', $dates); + + $setDates = array(); + + foreach ($ex_dates as $date) + { + $setDates[] = iCDate::isDate($date) + ? date('Y-m-d H:i', strtotime($date)) + : '0000-00-00 00:00'; + } + + return $setDates; + } + + /** + * Get Next Date from Single Dates + */ + function getNextDates($dates) + { + // Set Vars + $eventTimeZone = null; + $date_today = JHtml::date('now', 'Y-m-d'); // Joomla Time Zone + + // Get Next + $next = JFactory::getApplication()->input->get('next'); + + if (count($dates)) + { + while (strtotime($next) <= strtotime($date_today)) + { + $nextDate = $dates[0]; + + foreach ($dates as $d) + { + if (strtotime($d) >= strtotime($date_today)) + { + $nextDate = $d; + } + } + +// return JHtml::date($nextDate, 'Y-m-d H:i', $eventTimeZone); + return date('Y-m-d H:i', strtotime($nextDate)); + } + } + } + + /** + * Get Next Date from Period + */ + function getNextPeriod($period, $i_weekdays) + { + // Set Vars + $eventTimeZone = null; + $date_today = JHtml::date('now', 'Y-m-d'); // Joomla Time Zone + + $WeeksDays = iCDatePeriod::weekdaysToArray($i_weekdays); + + // Set Next Date for Period, if dates exist in Period + if (count($period)) + { + $nextPeriod = $period[0]; + + foreach ($period as $e) + { + if (in_array(date('w', strtotime($e)), $WeeksDays)) + { + if (strtotime($e) >= strtotime($date_today)) // if datetime in period >= date today + { + $nextPeriod = $e; + } + } + } + +// return JHtml::date($nextPeriod, 'Y-m-d H:i', $eventTimeZone); + return date('Y-m-d H:i', strtotime($nextPeriod)); + } + } + + /** + * Overloaded check function + */ + public function check() + { + // If there is an ordering column and this is a new row then get the next ordering value + if (property_exists($this, 'ordering') && $this->id == 0) + { + $this->ordering = self::getNextOrder(); + } + + return parent::check(); + } + + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed An optional array of primary key values to update. If not + * set the instance property value is used. + * @param integer The publishing state. eg. [0 = unpublished, 1 = published] + * @param integer The user id of the user performing the operation. + * @return boolean True on success. + * @since 1.0.4 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + // Initialise variables. + $k = $this->_tbl_key; + + // Sanitize input. + JArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k . '=' . implode(' OR ' . $k . '=', $pks); + + // Determine if there is checkin support for the table. + if ( ! property_exists($this, 'checked_out') || ! property_exists($this, 'checked_out_time')) + { + $checkin = ''; + } + else + { + $checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')'; + } + + // Update the publishing state for rows with the given primary keys. + $this->_db->setQuery( + 'UPDATE '.$this->_tbl.'' . + ' SET state = ' . (int) $state . + ' WHERE (' . $where . ')' . + $checkin + ); + $this->_db->query(); + + // Check for a database error. + if ($this->_db->getErrorNum()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && (count($pks) == $this->_db->getAffectedRows())) + { + // Checkin the rows. + foreach($pks as $pk) + { + $this->checkin($pk); + } + } + + // If the JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/tables/feature.php b/deployed/icagenda/administrator/components/com_icagenda/tables/feature.php new file mode 100644 index 00000000..0971dbef --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/tables/feature.php @@ -0,0 +1,221 @@ +setColumnAlias('published', 'state'); + } + } + + /** + * Overloaded bind function to pre-process the params. + * + * @param array Named array + * @return null|string null is operation was satisfactory, otherwise returns an error + * @see JTable:bind + * @since 3.4.0 + */ + public function bind($array, $ignore = '') + { + if (isset($array['new_icon'])) + { + // Get media path + $params_media = JComponentHelper::getParams('com_media'); + $image_path = $params_media->get('image_path', 'images'); + + // Paths to feature icons folder + $thumbsPath = $image_path . '/icagenda/feature_icons'; + + // Get Image File Infos + $link_image = $array['new_icon']; + $decomposition = explode( '/' , $link_image ); + + // in each parent + $i = 0; + + while ( isset($decomposition[$i]) ) + $i++; + $i--; + + $imgname = $decomposition[$i]; + $fichier = explode( '.', $decomposition[$i] ); + $imgtitle = $fichier[0]; + $imgextension = strtolower($fichier[1]); + + // Check file type if authorized to be generated as feature icon + $authorized_types = array('jpg', 'jpeg', 'png', 'gif'); + + if (!in_array($imgextension, $authorized_types) && $imgextension) + { + $this->setError('' . JText::_('COM_ICAGENDA_NOT_AUTHORIZED_IMAGE_TYPE') . '
    ' + . JText::_('COM_ICAGENDA_FORM_FEATURE_MIMETYPE_ERROR')); + + return false; + } + elseif ($imgextension) + { + // Clean icon name + jimport( 'joomla.filter.output' ); + $icon_name = JFilterOutput::stringURLSafe($imgtitle) . '.' . $imgextension; + + // Generate 16_bit if not exist + iCThumbGet::thumbnail($array['new_icon'], $thumbsPath, '16_bit', '16', '16', '100', false, '', '', '', $icon_name); + + // Generate 24_bit if not exist + iCThumbGet::thumbnail($array['new_icon'], $thumbsPath, '24_bit', '24', '24', '100', false, '', '', '', $icon_name); + + // Generate 32_bit if not exist + iCThumbGet::thumbnail($array['new_icon'], $thumbsPath, '32_bit', '32', '32', '100', false, '', '', '', $icon_name); + + // Generate 48_bit if not exist + iCThumbGet::thumbnail($array['new_icon'], $thumbsPath, '48_bit', '48', '48', '100', false, '', '', '', $icon_name); + + // Generate 64_bit if not exist + iCThumbGet::thumbnail($array['new_icon'], $thumbsPath, '64_bit', '64', '64', '100', false, '', '', '', $icon_name); + + $array['icon'] = $icon_name; + } + } + + return parent::bind($array, $ignore); + } + + /** + * Overloaded check function + * @since 3.4.0 + */ + public function check() + { + // If there is an ordering column and this is a new row then get the next ordering value + if (property_exists($this, 'ordering') && $this->id == 0) + { + $this->ordering = self::getNextOrder(); + } + + return parent::check(); + } + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed An optional array of primary key values to update. If not + * set the instance property value is used. + * @param integer The publishing state. eg. [0 = unpublished, 1 = published] + * @param integer The user id of the user performing the operation. + * @return boolean True on success. + * @since 3.4.0 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + // Initialise variables. + $k = $this->_tbl_key; + + // Sanitize input. + JArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k.'='.implode(' OR '.$k.'=', $pks); + + // Determine if there is checkin support for the table. + if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) + { + $checkin = ''; + } + else + { + $checkin = ' AND (checked_out = 0 OR checked_out = '.(int) $userId.')'; + } + + // Update the publishing state for rows with the given primary keys. + $this->_db->setQuery( + 'UPDATE '.$this->_tbl.'' . + ' SET state = '.(int) $state . + ' WHERE ('.$where.')' . + $checkin + ); + $this->_db->query(); + + // Check for a database error. + if ($this->_db->getErrorNum()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && (count($pks) == $this->_db->getAffectedRows())) + { + // Checkin the rows. + foreach($pks as $pk) + { + $this->checkin($pk); + } + } + + // If the JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/tables/icagenda.php b/deployed/icagenda/administrator/components/com_icagenda/tables/icagenda.php new file mode 100644 index 00000000..4ca3e5e4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/tables/icagenda.php @@ -0,0 +1,85 @@ +loadArray($array['params']); + $array['params'] = (string)$parameter; + } + return parent::bind($array, $ignore); + } + + /** + * Overloaded load function + * + * @param int $pk primary key + * @param boolean $reset reset data + * @return boolean + * @see JTable:load + */ + public function load($pk = null, $reset = true) + { + if (parent::load($pk, $reset)) + { + // Convert the params field to a registry. + $params = new JRegistry; + // loadJSON is @deprecated 12.1 Use loadString passing JSON as the format instead. + // $params->loadString($this->item->params, 'JSON'); + // "item" should not be present. + $params->loadJSON($this->params); + + $this->params = $params; + return true; + } + else + { + return false; + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/tables/index.html b/deployed/icagenda/administrator/components/com_icagenda/tables/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/tables/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/tables/registration.php b/deployed/icagenda/administrator/components/com_icagenda/tables/registration.php new file mode 100644 index 00000000..aa54cc4f --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/tables/registration.php @@ -0,0 +1,165 @@ +setColumnAlias('published', 'state'); + } + } + + /** + * Overloaded bind function. + * + * @param array Named array + * @return null|string null is operation was satisfactory, otherwise returns an error + * @see JTable:bind + * @since 3.3.3 + */ + public function bind($array, $ignore = '') + { + if ($array['date'] == 'period') + { + $array['date'] = ''; + } + + return parent::bind($array, $ignore); + } + + /** + * Overloaded check function + */ + public function check() + { + // If there is an ordering column and this is a new row then get the next ordering value + if (property_exists($this, 'ordering') && $this->id == 0) + { + $this->ordering = self::getNextOrder(); + } + + return parent::check(); + } + + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed An optional array of primary key values to update. If not + * set the instance property value is used. + * @param integer The publishing state. eg. [0 = unpublished, 1 = published] + * @param integer The user id of the user performing the operation. + * @return boolean True on success. + * @since 3.3.3 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + // Initialise variables. + $k = $this->_tbl_key; + + // Sanitize input. + JArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k.'='.implode(' OR '.$k.'=', $pks); + + // Determine if there is checkin support for the table. + if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) + { + $checkin = ''; + } + else + { + $checkin = ' AND (checked_out = 0 OR checked_out = '.(int) $userId.')'; + } + + // Update the publishing state for rows with the given primary keys. + $this->_db->setQuery( + 'UPDATE '.$this->_tbl.'' . + ' SET state = '.(int) $state . + ' WHERE ('.$where.')' . + $checkin + ); + $this->_db->query(); + + // Check for a database error. + if ($this->_db->getErrorNum()) + { + $this->setError($this->_db->getErrorMsg()); + + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && (count($pks) == $this->_db->getAffectedRows())) + { + // Checkin the rows. + foreach($pks as $pk) + { + $this->checkin($pk); + } + } + + // If the JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/addthis/addthis.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/addthis/addthis.php new file mode 100644 index 00000000..b81269f4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/addthis/addthis.php @@ -0,0 +1,116 @@ +params->get('atevent', 1); + + if ($addthisEvent == 1) + { + return self::share(); + } + + return false; + } + + // function AddThis social networks sharing + static public function share() + { + $url = parse_url(Juri::base()); + $addthis_scheme = ($url['scheme'] == 'https') ? 'https://' : 'http://'; + + $params = JFactory::getApplication()->getParams(); + + $addthis = $params->get('addthis', ''); + $float = $params->get('atfloat', ''); + $icon = $params->get('aticon', ''); + + if ($float == 1) + { + $floataddthis = 'floating'; + $float_position = 'position: fixed;'; + $float_side = 'left'; + } + elseif ($float == 2) + { + $floataddthis = 'floating'; + $float_position = 'position: fixed;'; + $float_side = 'right'; + } + else + { + $floataddthis = 'default'; + $float_position = ''; + $float_side = 'right'; + } + + if ($icon == 2) + { + $iconaddthis = '32x32'; + } + else + { + $iconaddthis = '16x16'; + } + + $at_div = ''; + + return $at_div; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/addthis/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/addthis/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/addthis/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/addtocal/addtocal.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/addtocal/addtocal.php new file mode 100644 index 00000000..bd8fde5d --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/addtocal/addtocal.php @@ -0,0 +1,296 @@ +input; + + $text = $i->title . ' (' . $i->cat_title . ')'; + $details = $i->desc; + $venue = $i->place; + $s_dates = $i->dates; + $single_dates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); // returns array + $website = icagendaEvent::eventURL($i); + $location = $venue ? $venue . ' - ' . $i->address : $i->address; + + $get_date = ''; + $href = '#'; + + if ($jinput->get('date')) + { + // if 'All Dates' set + $get_date = $jinput->get('date'); + } + else + { + // if 'Only Next/Last Date' set + $get_date = date('Y-m-d-H-i', strtotime($i->next)); + } + + $ex = explode('-', $get_date); + $this_date = $ex['0'] . '-' . $ex['1'] . '-' . $ex['2'] . ' ' . $ex['3'] . ':' . $ex['4']; + + $startdate = date('Y-m-d-H-i', strtotime($i->startdate)); + $enddate = date('Y-m-d-H-i', strtotime($i->enddate)); + + if (icagendaEvent::eventHasPeriod($i->period, $i->startdate, $i->enddate) + && ($get_date >= $startdate) + && ($get_date <= $enddate) + && (!in_array($this_date, $single_dates)) + ) + { + $weekdays = ($i->weekdays || $i->weekdays == '0') ? true : false; + + if ($weekdays) + { + $startdate = date('Y-m-d-H-i', strtotime($this_date)); + $enddate = date('Y-m-d', strtotime($this_date)) . '-' . date('H-i', strtotime($i->enddate)); + } + + $ex_S = explode('-', $startdate); + $ex_E = explode('-', $enddate); + + $dateday = $ex_S['0'] . $ex_S['1'] . $ex_S['2'] . 'T' . $ex_S['3'] . $ex_S['4']; + $dateday.= '00/' . $ex_E['0'] . $ex_E['1'] . $ex_E['2'] . 'T' . $ex_E['3'] . $ex_E['4'] . '00'; + } + else + { + $dateday = $ex['0'] . $ex['1'] . $ex['2'] . 'T' . $ex['3'] . $ex['4']; + $dateday.= '00/' . $ex['0'] . $ex['1'] . $ex['2'] . 'T' . $ex['3'] . $ex['4'] . '00'; + } + + // Get the site name + $sitename = $app->getCfg('sitename'); + + $href = 'https://www.google.com/calendar/event?action=TEMPLATE'; + + $mbString = extension_loaded('mbstring'); + $text = $mbString ? mb_substr($text, 0, 100, 'UTF-8') : substr($text, 0, 100); + $len = strrpos($text, ' '); // interruption on a space + $text = substr($text, 0, $len); + + $href.= '&text=' . urlencode($text) . '...'; + $href.= '&dates=' . $dateday; + $href.= '&location=' . urlencode($location); + $href.= '&trp=true'; + + $limit_reduc = '37'; // 37 chars (&trp=true&details=&sf=true&output=xml) + $limit_notlogged = '785'; + $lenpart = strlen($href); + $lenlast = 2068 - $lenpart - $limit_reduc - $limit_notlogged; // max link length minus (title+location) + $details = urlencode(strip_tags($details)); + $details = substr($details, 0 , $lenlast); + $len = strrpos($details, '+'); + $details = substr($details, 0 , $len); + + $href.= '&details=' . substr($details, 0, $lenlast) . '...'; + + return $href; + } + + /** + * Function to return Url to add to Windows Live (Hotmail) Calendar + * + * @since 3.6.0 + */ + static public function windowsliveCalendar($i) + { + $jinput = JFactory::getApplication()->input; + + $text = $i->title.' ('.$i->cat_title.')'; + $details = $i->desc; + $venue = $i->place; + $s_dates = $i->dates; +// $single_dates = unserialize($s_dates); + $single_dates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); // returns array + $website = icagendaEvent::eventURL($i); + $location = $venue ? $venue . ' - ' . $i->address : $i->address; + + $get_date = ''; + $href = '#'; + $endday = ''; + + if ($jinput->get('date')) + { + // if 'All Dates' set + $get_date = $jinput->get('date'); + } + else + { + // if 'Only Next/Last Date' set + $get_date = date('Y-m-d-H-i', strtotime($i->next)); + } + + $ex = explode('-', $get_date); + $this_date = $ex['0'] . '-' . $ex['1'] . '-' . $ex['2'] . ' ' . $ex['3'] . ':' . $ex['4']; + + $startdate = date('Y-m-d-H-i', strtotime($i->startdate)); + $enddate = date('Y-m-d-H-i', strtotime($i->enddate)); + + if ( icagendaEvent::eventHasPeriod($i->period, $i->startdate, $i->enddate) + && $get_date >= $startdate + && $get_date <= $enddate + && !in_array($this_date, $single_dates) + ) + { + $weekdays = ($i->weekdays || $i->weekdays == '0') ? true : false; + + if ($weekdays) + { + $startdate = date('Y-m-d-H-i', strtotime($this_date)); + $enddate = date('Y-m-d', strtotime($this_date)) . '-' . date('H-i', strtotime($i->enddate)); + } + + $ex_S = explode('-', $startdate); + $ex_E = explode('-', $enddate); + + $dateday = $ex_S['0'] . $ex_S['1'] . $ex_S['2'] . 'T' . $ex_S['3'] . $ex_S['4'] . '00'; + $endday = $ex_E['0'] . $ex_E['1'] . $ex_E['2'] . 'T' . $ex_E['3'] . $ex_E['4'] . '00'; + + } + else + { + $dateday = $ex['0'] . $ex['1'] . $ex['2'] . 'T' . $ex['3'] . $ex['4'] . '00'; + } + + $href = "https://calendar.live.com/calendar/calendar.aspx?rru=addevent"; + $href.= "&dtstart=" . $dateday; + $href.= isset($endday) ? "&dtend=" . $endday : ''; + $href.= "&summary=" . urlencode($text); + $href.= "&location=" . urlencode($location); + + // Shortens the description, if more than 1000 characters + $lengthMax = '1000'; + $details = urlencode(strip_tags($details)); + $details = substr($details, 0, $lengthMax); + $shortenedDetails = strrpos($details, '+'); + $details = substr($details, 0, $shortenedDetails); + + $href.= "&description=" . substr($details, 0, $lengthMax) . '...'; + + return $href; + } + + /** + * Function to return Url to add to Yahoo Calendar + * + * @since 3.6.0 + */ + static public function yahooCalendar($i) + { + $jinput = JFactory::getApplication()->input; + + $text = $i->title . ' (' . $i->cat_title . ')'; + $details = $i->desc; + $venue = $i->place; + $s_dates = $i->dates; +// $single_dates = unserialize($s_dates); + $single_dates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); // returns array + $website = icagendaEvent::eventURL($i); + $location = $venue ? $venue . ' - ' . $i->address : $i->address; + + $get_date = ''; + $href = '#'; + $endday = ''; + + if ($jinput->get('date')) + { + // if 'All Dates' set + $get_date = $jinput->get('date'); + } + else + { + // if 'Only Next/Last Date' set + $get_date = date('Y-m-d-H-i', strtotime($i->next)); + } + + $ex = explode('-', $get_date); + $this_date = $ex['0'] . '-' . $ex['1'] . '-' . $ex['2'] . ' ' . $ex['3'] . ':' . $ex['4']; + + $startdate = date('Y-m-d-H-i', strtotime($i->startdate)); + $enddate = date('Y-m-d-H-i', strtotime($i->enddate)); + + if ( icagendaEvent::eventHasPeriod($i->period, $i->startdate, $i->enddate) + && $get_date >= $startdate + && $get_date <= $enddate + && ! in_array($this_date, $single_dates) + ) + { + $weekdays = ($i->weekdays || $i->weekdays == '0') ? true : false; + + if ($weekdays) + { + $startdate = date('Y-m-d-H-i', strtotime($this_date)); + $enddate = date('Y-m-d', strtotime($this_date)) . '-' . date('H-i', strtotime($i->enddate)); + } + + $ex_S = explode('-', $startdate); + $ex_E = explode('-', $enddate); + + $dateday = $ex_S['0'] . $ex_S['1'] . $ex_S['2'] . 'T' . $ex_S['3'] . $ex_S['4'] . '00'; + +// $diff = strtotime($i->enddate) - strtotime($i->startdate); +// $M = (floor($diff /60)) % 60; +// $M = sprintf("%02d", $M); +// $H = (floor($diff / 3600)); + +// $duration = ($H <= 24) ? $H . $M : ''; + $endday = $ex_E['0'] . $ex_E['1'] . $ex_E['2'] . 'T' . $ex_E['3'] . $ex_E['4'] . '00'; + } + else + { + $dateday = $ex['0'] . $ex['1'] . $ex['2'] . 'T' . $ex['3'] . $ex['4'] . '00'; +// $duration = ''; + } + + // Shortens the description, if more than 1000 characters + $lengthMax = '1000'; + $details = urlencode(strip_tags($details)); + $details = substr($details, 0, $lengthMax); + $shortenedDetails = strrpos($details, '+'); + $details = substr($details, 0, $shortenedDetails); + + $href = "https://calendar.yahoo.com/?v=60"; + $href.= "&VIEW=d"; + $href.= "&in_loc=" . urlencode($location); +// $href.= "&type=20"; + $href.= "&TITLE=" . urlencode($text); + $href.= "&ST=" . $dateday; + $href.= "&ET=" . $endday; +// $href.= "&DUR="; +// $href.= $duration ? "&DUR=" . $duration : ''; + $href.= "&DESC=" . substr($details, 0, $lengthMax) . '...'; + $href.= "&URL=" . urlencode($website); + + return $href; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/addtocal/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/addtocal/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/addtocal/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/ajax/ajax.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/ajax/ajax.php new file mode 100644 index 00000000..3a97707c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/ajax/ajax.php @@ -0,0 +1,356 @@ +input; + $regid = $jinput->get('regid', '0'); + $eventid = $jinput->get('eventid', '0'); + + $data = JFactory::getApplication()->getUserState('com_icagenda.' . $view . '.data', array()); + $date = isset($data['date']) ? $data['date'] : ''; + + $date_format_global = JComponentHelper::getParams('com_icagenda')->get('date_format_global', 'Y - m - d'); + $separator = JComponentHelper::getParams('com_icagenda')->get('date_separator', ' '); + + if ($eventid != 0 && $view == 'mail') + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('r.id as reg_id, r.date AS reg_date, r.period AS reg_period, r.eventid AS reg_eventid, sum(r.people) AS reg_count') + ->from('#__icagenda_registration AS r'); + $query->select('e.startdate AS startdate, e.enddate AS enddate, e.weekdays AS weekdays') + ->join('LEFT', $db->quoteName('#__icagenda_events') . ' AS e ON e.id = r.eventid'); + $query->where('r.state = 1'); + $query->where('r.email <> ""'); + $query->group('r.date'); + $query->where('r.eventid = ' . (int) $eventid); + $db->setQuery($query); + + $result = $db->loadObjectList(); + } + elseif ($view == 'registration') + { + $db = JFactory::getDbo(); + + $query = $db->getQuery(true); + $query->select('next AS next, dates AS dates, + startdate AS startdate, enddate AS enddate, weekdays AS weekdays, + id AS id, state AS state, access AS access, params AS params'); + $query->from('#__icagenda_events AS e'); + $query->where(' e.id = ' . $eventid); + + $db->setQuery($query); + + $i = $db->loadObject(); + + if ($regid != 0) + { + $reg_query = $db->getQuery(true); + $reg_query->select('r.id as reg_id, r.date AS reg_date, r.period AS reg_period, r.eventid AS reg_eventid') + ->from('#__icagenda_registration AS r'); + $reg_query->where('r.id = ' . (int) $regid); + $db->setQuery($reg_query); + + $obj = $db->loadObject(); + + $reg_date = $obj->reg_date; + $reg_period = $obj->reg_period; + } + else + { + $reg_date = ''; + $reg_period = ''; + } + } + + $options = ''; + + if ($view == 'mail') + { + $options.= ''; + $options.= ''; + } + } + + echo $options; + + Jexit(); + } + + public static function getOptionsAllDates($i, $view = null, $reg_date = null, $reg_period = null) + { + $options = ''; + + if ($i) + { + // Set Event Params + $evtParams = new JRegistry($i->params); + $typeReg = $evtParams->get('typeReg'); + + // Registration type for event is set to "All dates of the event" + if ($typeReg == '2') + { + if ( $reg_period != 1 ) + { + $options.= ''; + $options.= ''; + } + else + { + foreach ($perioddates as $Dat) + { + if (in_array(date('w', strtotime($Dat)), $WeeksDays)) + { + // May not work in php < 5.2.3 (should return false if date null since 5.2.4) + $isValid = iCDate::isDate($Dat); + + if ($isValid) + { + $SingleDate = date('Y-m-d H:i', strtotime($Dat)); + array_push($AllDates, $SingleDate); + } + } + } + } + } + + // get Time Format + $timeformat = JComponentHelper::getParams('com_icagenda')->get('timeformat', '1'); + + $lang_time = ($timeformat == 1) ? 'H:i' : 'h:i A'; + + if ( ! empty($AllDates)) + { + sort($AllDates); + } + + foreach($AllDates as $date) + { + if (iCDate::isDate($date)) + { + $value_datetime = date('Y-m-d H:i:s', strtotime($date)); + + $options.= '
    ') . '
    ' + . JText::_('ICAGENDA_IS_NOT_CORRECTLY_INSTALLED'); + + // Get the message queue + $messages = $app->getMessageQueue(); + + $display_alert_message = false; + + // If we have messages + if (is_array($messages) && count($messages)) + { + // Check each message for the one we want + foreach ($messages as $key => $value) + { + if ($value['message'] == $alert_message) + { + $display_alert_message = true; + } + } + } + + if (!$display_alert_message) + { + $app->enqueueMessage($alert_message, 'error'); + } + + return false; + } + else + { + return true; + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/class/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/class/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/class/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/customfields/customfields.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/customfields/customfields.php new file mode 100644 index 00000000..3d17c331 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/customfields/customfields.php @@ -0,0 +1,864 @@ +slug; + + if ($cf->slug == 'core_email' + && $iCparams->get('emailConfirm', 1)) + { + $listSlugs[]= 'core_email2'; + } + } + + return $listSlugs; + } + + return array(); + } + + /** + * Gets the custom fields for this event (frontend) + * + * @param $parentForm (1 = registration form; 2 = event form) + * $customForm (filtering by selected custom field groups) (since 3.6.0) + * + * @return object list + * + * @since 3.4.0 + */ + public static function getCustomfields($parentForm, $customForm = array()) + { + $app = JFactory::getApplication(); + $id = $app->input->getInt('id'); + + // Get the database connector. + $db = JFactory::getDbo(); + + $list_slugs = array(); + + if ($id) + { + // Get the query from the database connector. + $query = $db->getQuery(true); + + // Build the query + $query->select('id, slug') + ->from($db->qn('#__icagenda_customfields').' AS cf'); + $query->where($db->qn('cf.parent_form').' = ' .$db->q($parentForm)); + + // Run Query + $db->setQuery($query); + + // Invoke the Query + $Customfields = $db->loadObjectList(); + + // Create array of custom fields slugs for this event + foreach ($Customfields as $cf) + { + $list_slugs[] = '"' . $cf->slug . '"'; + } + + $list_slugs = implode(',', $list_slugs); + } + + // Get the query from the database connector. + $query = $db->getQuery(true); + + // Build the query + $query->select('cf.*') + ->from($db->qn('#__icagenda_customfields').' AS cf'); + + if ($id && $list_slugs) + { + // Build the query + $query->select('cfd.value AS value') + ->leftJoin($db->qn('#__icagenda_customfields_data') . ' AS cfd' + . ' ON (' . $db->qn('cfd.parent_id') . ' = ' . (int)$id + . ' AND ' . $db->qn('cfd.slug') . ' = ' .$db->qn('cf.slug') . ')') + ->where($db->qn('cf.slug').' IN ('.$list_slugs.')'); + } + + $query->where($db->qn('cf.parent_form') . ' = ' . $db->q($parentForm)); + $query->where($db->qn('cf.state') . ' = 1'); + + $query->order('cf.ordering ASC'); + + $db->setQuery($query); + + $list = $db->loadObjectList(); + + // Invoke the query. + if ($list) + { + $customForm = ! is_array($customForm) ? explode(',', $customForm) : $customForm; + + foreach ($list AS $l) + { + $groups = ! is_array($l->groups) ? explode(',', $l->groups) : $l->groups; + + if ( ! array_intersect($customForm, $groups) + && ! in_array('', $groups)) + { + $key = array_search($l, $list); + + if ($key !== false) + { + unset($list[$key]); + } + } + } + + return $list; + } + + return false; + } + + /** + * Return the HTML body of Custom fields for this parent form (parent_id) + * + * @param $parentForm (1 = registration form; 2 = event form) + * $customForm (filtering by selected custom form ids) (since 3.6.0) + * + * @return HTML fields + * + * @since 3.4.0 + */ + public static function loader($parentForm, $customForm = null, $customFields = null) + { + $app = JFactory::getApplication(); + $iCparams = JComponentHelper::getParams('com_icagenda'); + + if ($parentForm == '1') + { + $model = new iCagendaModelRegistration; + $form = $model->getForm(); + } + else + { + $model = $app->isSite() ? new iCagendaModelSubmit : new iCagendaModelEvent; + $form = $model->getForm(); + } + +// $session = JFactory::getSession(); +// $custom_fields = $session->get('custom_fields'); +// $post = $session->get('ic_registration', ''); + + $customfields = $customFields + ? $customFields + : icagendaCustomfields::getCustomfields($parentForm, $customForm); + + // New 3.6.0 : Core iCagenda registration fields overrides + $iCagendaCoreFields = array('core_name', 'core_email', 'core_phone', 'core_date', 'core_people'); + + // Custom fields where options are needed + $options_required = array('list', 'radio'); + + $cf_display = ''; + + if ( $customfields ) + { + foreach ($customfields as $icf) + { + // Reset the label and input values. + $label = null; + $input = null; + +// if (empty($icf->value)) $icf->value = ''; + + $cf_type = $icf->type; + + // Setup iCagenda core registration fields overrides + if ($app->isSite() + && in_array($cf_type, $iCagendaCoreFields)) + { + $core_name = str_replace('core_', '', $icf->type); + $icf->slug = $core_name; + + switch ($icf->type) + { + case 'core_name': + $icf->type = 'text'; + $icf->required = 'true'; + break; + + case 'core_email': + $icf->type = 'email'; + $icf->required = $iCparams->get('emailRequired', 1) ? 'true' : 'false'; + $icf->field = 'id'; + $icf->filter = 'string'; + $icf->validate = 'email'; + break; + + case 'core_phone': + $icf->type = 'tel'; + $icf->required = $iCparams->get('phoneRequired', 0) ? 'true' : 'false'; + break; + + case 'core_date': + $icf->type = 'icagenda.registrationdates'; + break; + + case 'core_people': + $icf->type = 'icagenda.registrationpeople'; + break; + + default: + $icf->type = 'text'; + break; + } + + if ( $app->isSite() && $parentForm == 1 ) + { + $reg_data = $app->getUserState('com_icagenda.registration.data', array()); + $icf->value = isset($reg_data[$icf->slug]) ? trim($reg_data[$icf->slug]) : ''; + } + elseif ( $app->isSite() && $parentForm == 2 ) + { + $session = JFactory::getSession(); + $custom_fields = $session->get('custom_fields'); + $icf->value = isset($custom_fields[$icf->slug]) ? trim($custom_fields[$icf->slug]) : ''; + } + } + else + { + if ( $app->isSite() && $parentForm == 1 ) + { + $reg_data = $app->getUserState('com_icagenda.registration.data', array()); + $icf->value = isset($reg_data['custom_fields'][$icf->slug]) ? trim($reg_data['custom_fields'][$icf->slug]) : ''; + } + elseif ( $app->isSite() && $parentForm == 2 ) + { + $session = JFactory::getSession(); + $custom_fields = $session->get('custom_fields'); + $icf->value = isset($custom_fields[$icf->slug]) ? trim($custom_fields[$icf->slug]) : ''; + } + + // Keep this until Submit frontend refactory + $icf->slug = ($parentForm == 2 && $app->isSite()) + ? 'custom_fields[' . $icf->slug . ']' + : 'custom_fields][' . $icf->slug; + } + + // If type is list or radio, should have options. Other types, not needed. + if ((in_array($icf->type, $options_required) && $icf->options) + || ! in_array($icf->type, $options_required)) + { + switch ($icf->type) + { + case 'email': + $icf->validate = 'email'; + break; + + case 'spacer_label': + $icf->description = ''; + $icf->type = $app->isAdmin() ? 'hidden' : $icf->type; + $icf->class = $icf->options; + break; + + case 'spacer_description': + $icf->title = $icf->description; + $icf->description = ''; + $icf->type = $app->isAdmin() ? 'hidden' : $icf->type; + $icf->class = $icf->options; + break; + + default: + break; + } + + // Generate new form field element + $type_field = icagendaCustomfields::setupCustomField($icf); + + if ($type_field) + { + $form->setField($type_field); + + if ( ! in_array($icf->type, $iCagendaCoreFields) && isset($icf->value)) + { + $form->setValue($icf->slug, null, trim($icf->value)); + } + + if ($app->isAdmin() && ! in_array($cf_type, $iCagendaCoreFields)) + { + $label = $form->getLabel($icf->slug); + $input = $form->getInput($icf->slug); + + // Switch Joomla 2.5 / 3 + if (version_compare(JVERSION, '3.0', 'lt')) + { + $cf_display.= '
     ' . $label . $input . '
    '; + } + else + { + $cf_display.= JLayoutHelper::render('joomla.form.renderfield', + array('input' => $input, 'label' => $label, 'options' => '')); + } + } + } + + // If Override for core email, we set the email2 confirm + if ($cf_type == 'core_email' + && $iCparams->get('emailConfirm', 1)) + { + $form->setField($type_field); + $email2 = new ArrayObject(); + + $email2->slug = 'email2'; + $email2->type = 'email'; + $email2->title = JText::_('IC_FORM_EMAIL_CONFIRM_LBL'); + $email2->required = $iCparams->get('emailRequired', 1) ? 'true' : 'false'; + $email2->field = 'email'; + $email2->filter = 'string'; + $email2->message = JText::_('COM_ICAGENDA_FORM_VALIDATE_FIELD_EMAIL2_MESSAGE'); + $email2->validate = 'equals'; + $email2->options = JText::_('IC_FORM_EMAIL_CONFIRM_HINT'); + + // Generate new form field element + $type_field = icagendaCustomfields::setupCustomField($email2); + + if ($type_field) + { + $form->setField($type_field); + + if ( ! in_array($icf->type, $iCagendaCoreFields)) + { + $form->setValue($icf->slug, null, trim($icf->value)); + } + + if ($app->isAdmin() && ! in_array($cf_type, $iCagendaCoreFields)) + { + $label = $form->getLabel($icf->slug); + $input = $form->getInput($icf->slug); + + // Switch Joomla 2.5 / 3 + if (version_compare(JVERSION, '3.0', 'lt')) + { + $cf_display.= '
     ' . $label . $input . '
    '; + } + else + { + $cf_display.= JLayoutHelper::render('joomla.form.renderfield', + array('input' => $input, 'label' => $label, 'options' => '')); + } + } + } + } + } + } + + if ($app->isAdmin()) $cf_display.= '
    '; + } + elseif ($app->isAdmin()) + { + $cf_display.= '
    '; + $cf_display.= JText::_('COM_ICAGENDA_CUSTOMFIELDS_NONE'); + $cf_display.= '
    '; + } + elseif ($app->isSite()) + { + return false; + } + + return $app->isAdmin() ? $cf_display : true; + } + + /** + * Create a new SimpleXMLElement field element + * + * @return SimpleXMLElement + * + * @since 3.6.0 + */ + public static function setupCustomField($icf) + { + if ( ! isset($icf->slug)) return false; + + // Check if Gantry based template (Gantry is not compatible with all Joomla Form Fields) + $template = JFactory::getApplication()->getTemplate(); + $isGantry = is_dir(JPATH_ROOT . '/templates/' . $template . '/gantry/') || $template == 'gantry'; + + // Set field classes + switch ($icf->type) + { + case 'radio': + $class = $isGantry ? '' : 'btn-group'; + $labelclass = 'control-label'; + break; + + case 'list': + $class = 'select-large'; + $labelclass = ''; + break; + + default: +// $class = 'input-large'; + $class = ''; + $labelclass = ''; +// $size = '60'; + $size = '30'; + break; + } + + // Start the field + $type_field = new SimpleXMLElement(''); + + // Set the field attributes + $attributes = array( + 'name' => $icf->slug, + 'type' => $icf->type, + 'label' => $icf->title, + 'description' => isset($icf->description) ? $icf->description : '', + 'required' => isset($icf->required) ? $icf->required : '', + 'field' => isset($icf->field) ? $icf->field : '', + 'filter' => isset($icf->filter) ? $icf->filter : '', + 'validate' => isset($icf->validate) ? $icf->validate : '', + 'message' => isset($icf->message) ? $icf->message : '', + 'class' => isset($icf->class) ? $icf->class : $class, + 'labelclass' => $labelclass, + 'size' => isset($size) ? $size : '', + ); + + foreach ($attributes AS $attr => $value) + { + if ($value) + { + $type_field->addAttribute($attr, $value); + } + } + + // Set the field options (if exist) + if (isset($icf->options)) + { + if (in_array($icf->type, array('list', 'radio'))) + { + $opts_list = str_replace("\n", "##BREAK##", $icf->options); // Why i did this ?... :| + $opts_list = explode("##BREAK##", $opts_list); + + $options = array(); + $emptyValue = 0; + $default = ''; + + foreach ($opts_list as $opts) + { + $opt = explode("=", $opts); + $emptyValue = (trim($opt[0]) == '') ? $emptyValue+1 : $emptyValue; + $default = (isset($opt[2]) && ($default == '')) ? $opt[0] : $default; + + $options[trim($opt[0])] = isset($opt[1]) ? trim($opt[1]) : trim($opt[0]); + } + + // If default is set in options, set this one as selected. + if ($default != '') + { + $type_field->addAttribute('default', $default); + } + + // If no option set by default, and no option with an empty value, we add a default "Select an option". + if ($icf->type == 'list' + && $emptyValue == 0 + && $default == '') + { + $child = $type_field->addChild('option', '- ' . JText::_('IC_SELECT_AN_OPTION') . ' -'); + $child->addAttribute('value', ''); + } + + foreach ($options as $value => $label) + { + $child = $type_field->addChild('option', $label); + $child->addAttribute('value', trim($value)); + + if ($icf->type == 'list' + && isset($icf->value) && ! empty($icf->value) && trim($icf->value) == trim($value)) + { + $child->addAttribute('selected', 'selected'); + } + elseif ($icf->type == 'radio' + && isset($icf->value) && ! empty($icf->value) && trim($icf->value) == trim($value)) + { + $child->addAttribute('checked', 'checked'); + $child->addAttribute('class', 'btn active'); + } + } + } + else + { + // Set Placeholder + $type_field->addAttribute('hint', $icf->options); + } + } + + return $type_field; + } + + /** + * Create the HTML body of the custom fields + * + * @return object list + * + * @since 3.4.0 + * @DEPRECATED 3.6.0 + */ + public static function displayField($type = null, $title = null, $alias = null, + $slug = null, $description = null, $value = null, $options = null, $required = null) + { + $deprecated = 'Method displayField is deprecated. Use setupCustomField instead.'; + + return $deprecated; + } + + + /** + * Control if required Custom Fields is empty. + * + * @since 3.6.5 + */ + public static function requiredIsEmpty($custom_fields, $parentForm, $state = 1, $language = '*') + { + if (isset($custom_fields) && is_array($custom_fields)) + { + $requiredEmpty = array(); + + foreach ($custom_fields as $name => $value) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('title') + ->from($db->qn('#__icagenda_customfields')) + ->where($db->qn('slug') . ' = ' . $db->q($name)) + ->where($db->qn('required') . ' = 1') + ->where($db->qn('parent_form') . ' = ' . $db->q($parentForm)); + $db->setQuery($query); + $result = $db->loadResult(); + + if ($result && trim($value) == '') + { + $requiredEmpty[] = $result; + } + } + + if (count($requiredEmpty) > 0) + { + return $requiredEmpty; + } + + return false; + } + } + + /** + * Save Custom Fields to the database if at least one is filled + * or update existing data from custom fields. + * + * @since 3.4.0 + */ + public static function saveToData($custom_fields, $parent_id, $parentForm, $state = 1, $language = '*') + { + // Get the database connector. + $db = JFactory::getDbo(); + + if (isset($custom_fields) && is_array($custom_fields)) + { + foreach ( $custom_fields as $name => $value ) + { + $customfields_data = new stdClass(); + $customfields_data->slug = $name; + $customfields_data->value = $value; + $customfields_data->state = $state; + $customfields_data->parent_form = $parentForm; + $customfields_data->parent_id = $parent_id; + $customfields_data->language = $language; + + $query = $db->getQuery(true) + ->select('id') + ->from($db->qn('#__icagenda_customfields_data')) + ->where($db->qn('slug') . ' = ' . $db->q($customfields_data->slug)) + ->where($db->qn('parent_form') . ' = ' . $db->q($customfields_data->parent_form)) + ->where($db->qn('parent_id') . ' = ' . $db->q($customfields_data->parent_id)); + $db->setQuery($query); + $id_exists = $db->loadResult(); + + if ( ! $id_exists && (trim($customfields_data->value) != '')) + { + $db->insertObject( '#__icagenda_customfields_data', $customfields_data, 'id' ); + } + elseif (trim($customfields_data->value) == '') + { + $query = $db->getQuery(true); + + // Delete any empty slug records from the __icagenda_customfields_data table if exists + $conditions = array( + $db->quoteName('parent_id') . ' = ' . $db->quote($customfields_data->parent_id), + $db->quoteName('slug') . ' = ' . $db->quote($customfields_data->slug) + ); + + $query->delete($db->quoteName('#__icagenda_customfields_data')); + $query->where($conditions); + + $db->setQuery($query); + $db->execute($query); + + if ( ! $db->execute()) + { + return false; + } + } + else + { + $customfields_data->id = $id_exists; + $db->updateObject('#__icagenda_customfields_data', $customfields_data, 'id'); + } + } + } + } + + /** + * Delete Custom Fields from the database + * or update existing data from custom fields. + * + * @since 3.5.6 + */ + public static function deleteData($parent_id, $parentForm) + { + // Get the database connector. + $db = JFactory::getDbo(); + + // Delete any unwanted customfields records from the __icagenda_customfields_data table + $query = $db->getQuery(true); + $query->delete($db->qn('#__icagenda_customfields_data')); + $query->where('parent_id = ' . (int) $parent_id); + $query->where('parent_form = ' . (int) $parentForm); + + $db->setQuery($query); + $db->execute($query); + + if ( ! $db->execute()) + { + return false; + } + + return true; + } + + /** + * Clean Custom Fields from the database (fix for previous versions) + * + * @since 3.5.6 + */ + public static function cleanData($parentForm) + { + // Get the database connector. + $db = JFactory::getDbo(); + + // Get Registrations ids + if ($parentForm == 1) + { + $query = $db->getQuery(true) + ->select('id') + ->from($db->qn('#__icagenda_registration')); + $db->setQuery($query); + $list = $db->loadColumn(); + } + + // Get Events ids + elseif ($parentForm == 2) + { + // Get Registrations ids + $query = $db->getQuery(true) + ->select('id') + ->from($db->qn('#__icagenda_events')); + $db->setQuery($query); + $list = $db->loadColumn(); + } + + $parent_ids = isset($list) && is_array($list) ? implode(',', $list) : ''; + + // Delete any unwanted customfields records from the __icagenda_customfields_data table + $query = $db->getQuery(true); + $query->delete($db->qn('#__icagenda_customfields_data')); + $query->where('parent_form = ' . (int) $parentForm); + $query->where('parent_id NOT IN (' . $parent_ids . ')'); + + $db->setQuery($query); + $db->execute($query); + + if ( ! $db->execute()) + { + return false; + } + + return true; + } + + + /** + * Function to return list of custom fields depending on the item ID + * USED IN : Registrations Export + * + * @access public static + * @param $id item ID + * $parentForm (1 registration, 2 event edit) + * $state (if not defined, state is published ('1')) + * @return object list array of custom fields depending on the item ID + * + * @since 3.4.0 + */ + public static function getList($id, $parentForm = null, $state = null) + { + $filter_state = isset($state) ? $state : 1; + + // Create a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('cf.slug AS cf_slug, cfd.value AS cf_value, cfd.parent_id AS cf_parent_id, cf.title AS cf_title, cf.required AS cf_required') + ->from('#__icagenda_customfields AS cf') + ->leftJoin($db->qn('#__icagenda_customfields_data') . ' AS cfd' + . ' ON ' . $db->qn('cfd.parent_id') .' = ' . (int)$id + . ' AND ' . $db->qn('cf.slug') .' = ' . $db->qn('cfd.slug')) + ->where($db->qn('cf.state') . ' = ' . $db->q($filter_state)) + ->where($db->qn('cf.parent_form') . ' = ' . $db->q($parentForm)) + ->order('cf.ordering ASC'); + $db->setQuery($query); + $list = $db->loadObjectList(); + + if ($list) return $list; + + return false; + } + + /** + * Function to return a list of filled custom fields depending on the item ID + * + * @access public static + * @param $id item ID + * $parentForm (1 registration, 2 event edit) + * $state (if not defined, state is published ('1')) + * @return object list array of custom fields not empty depending on the item ID + * + * @since 3.4.0 + */ + public static function getListNotEmpty($id, $parentForm = null, $state = null) + { + $filter_state = isset($state) ? $state : 1; + + // Create a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('cfd.slug AS cf_slug, cfd.value AS cf_value, cfd.parent_id AS cf_parent_id, cf.title AS cf_title') + ->from('#__icagenda_customfields_data AS cfd') + ->leftJoin($db->qn('#__icagenda_customfields') . ' AS cf' + . ' ON ' . $db->qn('cf.slug') .' = ' . $db->qn('cfd.slug')) + ->where($db->qn('cf.state') . ' = ' . $db->q($filter_state)); + + if ($parentForm) + { + $query->where($db->qn('cfd.parent_form') . ' = ' . $db->q($parentForm)); + } + + $query->where($db->qn('cfd.parent_id') . ' = ' . (int)$id); + $query->order('cf.ordering ASC'); + $db->setQuery($query); + $list = $db->loadObjectList(); + + if ($list) return $list; + + return false; + } + + + /** + * Function to return list of custom fields depending on the parent form + * + * @access public static + * @param $parentForm (1 registration, 2 event edit) + * $customForm (filtering by selected custom field groups) (since 3.6.0) + * $state (if not defined, state is published ('1')) + * @return object list array of custom fields + * + * @since 3.4.0 + * @deprecated 3.6.0 + */ + public static function getListCustomFields($parentForm, $customForm = array(), $state = null) + { + $filter_state = isset($state) ? $state : 1; + + // Create a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('cf.*') + ->from('#__icagenda_customfields AS cf') + ->where($db->qn('state') . ' = ' . $db->q($filter_state)) + ->where($db->qn('parent_form') . ' = ' . $db->q($parentForm)) + ->order('ordering ASC'); + $db->setQuery($query); + $list = $db->loadObjectList(); + + // Invoke the query. + if ($list) + { + $customForm = ! is_array($customForm) ? explode(',', $customForm) : $customForm; + + foreach ($list AS $l) + { + $groups = ! is_array($l->groups) ? explode(',', $l->groups) : $l->groups; + + if ( ! array_intersect($customForm, $groups) + && ! in_array('', $groups)) + { + $key = array_search($l, $list); + + if ($key !== false) + { + unset($list[$key]); + } + } + } + + return $list; + } + + return array(); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/customfields/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/customfields/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/customfields/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/event/data.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/event/data.php new file mode 100644 index 00000000..8fe510f5 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/event/data.php @@ -0,0 +1,62 @@ +getQuery(true); + + // Build the query programatically (using chaining if desired). + $query->select('cfd.*, cf.*') + // Use the qn alias for the quoteName method to quote table names. + ->from($db->qn('#__icagenda_customfields_data') . ' AS cfd'); + + $query->leftJoin('#__icagenda_customfields AS cf ON cf.slug = cfd.slug'); + + $query->where($db->qn('cfd.parent_id') . ' = ' . (int) $id); + $query->where($db->qn('cfd.parent_form') . ' = 2'); + $query->where($db->qn('cf.parent_form') . ' = 2'); + $query->where($db->qn('cfd.state') . ' = 1'); + $query->where($db->qn('cf.state') . ' = 1'); + $query->where($db->qn('cfd.value') . ' NOT IN ("", "{}")'); + $query->order('cf.ordering ASC'); + + // Tell the database connector what query to run. + $db->setQuery($query); + + // Invoke the query or data retrieval helper. + return $db->loadObjectList(); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/event/event.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/event/event.php new file mode 100644 index 00000000..ed9cea57 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/event/event.php @@ -0,0 +1,1291 @@ +next) + || ($item->next <= JHtml::date('now', 'Y-m-d H:i:s') + || ! iCDate::isDate($item->next)) + ) + { + $reset = true; + } + + if ($reset) + { + $next_singleDates = $last_singleDates = ''; + $next_period = $last_period = ''; + + // Single Dates Check + $singleDates = iCString::isSerialized($item->dates) ? unserialize($item->dates) : array(); + + $upcomingSingleDates = array_filter( + $singleDates, + function($date) + { + return $date >= JHtml::date('now', 'Y-m-d H:i:s'); + } + ); + + if (count($upcomingSingleDates) > 0) + { + $next_singleDates = min($upcomingSingleDates); + $next_singleDates = iCDate::isDate($next_singleDates) ? $next_singleDates : ''; + } + else + { + $pastSingleDates = array_filter( + $singleDates, + function ($date) + { + return $date < JHtml::date('now', 'Y-m-d H:i:s'); + } + ); + + if (count($pastSingleDates) > 0) + { + $last_singleDates = max($pastSingleDates); + $last_singleDates = iCDate::isDate($last_singleDates) ? $last_singleDates : ''; + } + } + + + // Period Check + $weekdays = ! is_array($item->weekdays) ? explode(",", $item->weekdays) : $item->weekdays; + + if (count($weekdays) > 0) + { + $period_all_dates_array = iCDatePeriod::listDates($item->startdate, $item->enddate); + + $period_array = array(); + + foreach ($period_all_dates_array AS $date_in_weekdays) + { + $datetime_period_date = JHtml::date($date_in_weekdays, 'Y-m-d H:i', $eventTimeZone); + + if (in_array(date('w', strtotime($datetime_period_date)), $weekdays)) + { + $period_array[] = $datetime_period_date; + } + } + + $upcomingPeriodDates = array_filter( + $period_array, + function($date) + { + return $date >= JHtml::date('now', 'Y-m-d H:i:s'); + } + ); + + if (count($upcomingPeriodDates) > 0) + { + $next_period = min($upcomingPeriodDates); + $next_period = iCDate::isDate($next_period) ? $next_period : ''; + } + else + { + $last_period = iCDate::isDate($item->startdate) ? $item->startdate : ''; + } + } + else + { + if ($item->startdate >= JHtml::date('now', 'Y-m-d H:i:s')) + { + $next_period = iCDate::isDate($item->startdate) ? $item->startdate : ''; + } + elseif ($item->enddate >= JHtml::date('now', 'Y-m-d H:i:s')) + { + $next_period = iCDate::isDate($item->startdate) ? $item->startdate : ''; + } + else + { + $last_period = iCDate::isDate($item->startdate) ? $item->startdate : ''; + } + } + + + // Return Next + if ($next_singleDates && $next_period) + { + $next = min($next_singleDates, $next_period); + } + elseif ($next_singleDates) + { + $next = $next_singleDates; + } + elseif ($next_period) + { + $next = $next_period; + } + else + { + $next = max($last_singleDates, $last_period); + } + + if ($item->next != $next) + { + $item->next = $next; + + $db = Jfactory::getDbo(); + $query = $db->getQuery(true); + + $query->update('#__icagenda_events') + ->set($db->qn('next') . ' = ' . $db->q($next)) + ->where($db->qn('id') . ' = ' . (int) $item->id); + + $db->setQuery($query); + $db->query($query); + } + } + + return $item->next; + } + + /** + * Function to get Event Params + * + * @return JRegistry Event Params + * + * @since 3.6.0 + */ + public static function evtParams($params) + { + $evtParams = new JRegistry($params); + + return $evtParams; + } + + /** + * Function to return the back arrow button (No item needed) + * + * @return HTML + * + * @since 3.6.0 + */ + public static function backArrow($item = null) + { + $app = JFactory::getApplication(); + $jinput = $app->input; + $jview = $jinput->get('view'); + + // Get Current Itemid + $this_itemid = $jinput->getInt('Itemid', 0); + + // TODO: Remove jlayout control (3.6) + $jlayout = $jinput->get('layout', ''); + $layouts_array = array('event', 'registration'); + $layout = in_array($jlayout, $layouts_array) ? $jlayout : ''; + + $manageraction = $jinput->get('manageraction', ''); + $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; + + // RTL css if site language is RTL + $lang = JFactory::getLanguage(); + $back_icon = ($lang->isRTL()) ? 'iCicon iCicon-nextic' : 'iCicon iCicon-backic'; + + if ( ($layout != '' || $jview == 'event') + && strpos($referer,'registration') === false + && ! $manageraction) + { + if ($referer != "") + { + $BackArrow = ''; + } + else + { + $BackArrow = ''; + } + } + elseif ($manageraction || strpos($referer,'registration') !== false) + { + $BackArrow = ''; + } + else + { + $BackArrow = ''; + } + + // Header Message if event cancelled + $evtParams = self::getParams($item->id); + $cancellation_info = ''; + + if ($evtParams->get('event_cancelled')) + { + $text = JText::_('COM_ICAGENDA_EVENT_CANCELLED_TEXT'); + $description = $evtParams->get('event_cancelled_desc'); + + if ($evtParams->get('event_cancelled_customlabel')) + { + $text = JText::_($evtParams->get('event_cancelled_customlabel_text', 'COM_ICAGENDA_EVENT_CANCELLED_TEXT')); +// $class = $evtParams->get('event_cancelled_customlabel_css', $class); + } + + $cancellation_info = '
    ' + . '

    ' . $text . '

    ' + . '
    ' . $description . '
    ' + . '
    '; + } + + return $BackArrow . $cancellation_info; + } + + /** + * Set event Url + * + * @since 3.6.0 + */ + public static function url($id, $alias = null) + { + $app = JFactory::getApplication(); + $isSef = $app->getCfg('sef'); + $jinput = $app->input; + + $menuID = $jinput->get('Itemid', 0); + $date = $jinput->get('date', ''); + $view = $jinput->get('view', ''); + + // Get var 'event_date' set to session in event details view + $session = JFactory::getSession(); + $event_date = $session->get('event_date', ''); + + $event_slug = empty($alias) ? (int) $id : (int) $id . ':' . $alias; + $this_date = $event_date ? date('Y-m-d-H-i', strtotime($event_date)) : $date; + + $url = JRoute::_('index.php?option=com_icagenda&view=event&id=' . $event_slug . '&Itemid=' . (int) $menuID); + + if (is_numeric($menuID) && is_numeric($id) + && ! is_array($menuID) && ! is_array($id)) + { + $date_var = ($isSef == '1') ? '?date=' : '&date='; + $url = ($view != 'list' && $this_date) ? $url . $date_var . $this_date : $url; + } + else + { + $url = JRoute::_('index.php'); + } + + return $url; + } + + /** + * Title + Manager Icons + * + * @since 3.6.0 + * @todo Review and split into sub-functions + */ + public static function titleBar($i) + { + $jinput = JFactory::getApplication()->input; + + $this_itemid = $jinput->getInt('Itemid'); + $list_title_length = (int) JComponentHelper::getParams('com_icagenda')->get('list_title_length', ''); + + $i_title = icagendaRender::titleToFormat($i->title); + + $jlayout = $jinput->get('layout', ''); + $layouts_array = array('event', 'registration'); + $layout = in_array($jlayout, $layouts_array) ? $jlayout : ''; + + $mbString = extension_loaded('mbstring'); + + $title_length = $mbString ? mb_strlen($i_title, 'UTF-8') : strlen($i_title); + + if (empty($layout) + && ! empty($list_title_length)) + { + $title = $mbString + ? trim(mb_substr($i_title, 0, $list_title_length, 'UTF-8')) + : trim(substr($i_title, 0, $list_title_length)); + + $new_title_length = $mbString ? mb_strlen($title, 'UTF-8') : strlen($title); + + if ($new_title_length < $title_length) + { + $title.= '...'; + } + } + else + { + $title = $i_title; + } + + $approval = $i->approval; + + $event_slug = empty($i->alias) ? $i->id : $i->id . ':' . $i->alias; + + // Set Manager Actions Url + $managerActionsURL = 'index.php?option=com_icagenda&view=event&id=' . $event_slug . '&Itemid=' . $this_itemid; + + $unapproved = ''; + + $titleBar = ''; + + if ($title != NULL && $approval == 1) + { + $titleBar.= $title . ' ' . $unapproved; + } + elseif ($title != NULL && $approval != 1) + { + $titleBar.= $title; + } + + $eventIsCancelled = self::cancelledButton($i->id, 'btn btn-danger'); + + if ($eventIsCancelled) + { + $titleBar.= ' ' . $eventIsCancelled; + } + + return $titleBar; + } + + /** + * Return Event Cancelled button with infotip + * + * @since 3.7.12 + */ + public static function cancelledButton($id, $class = 'label label-important') + { + $evtParams = self::getParams($id); + + if ($evtParams->get('event_cancelled')) + { + $language = JFactory::getLanguage(); + $language->load('com_icagenda', JPATH_SITE, 'en-GB', false, true); + $language->load('com_icagenda', JPATH_SITE, null, true); + + $text = JText::_('COM_ICAGENDA_EVENT_CANCELLED_TEXT'); + $description = $evtParams->get('event_cancelled_desc'); + + if ($evtParams->get('event_cancelled_customlabel')) + { + $text = JText::_($evtParams->get('event_cancelled_customlabel_text', 'COM_ICAGENDA_EVENT_CANCELLED_TEXT')); + $class = $evtParams->get('event_cancelled_customlabel_css', $class); + } + + $title = $tipclass = $position = ''; + + if (!empty($description)) + { + if ($text && $text !== $description) + { + JHtml::_('bootstrap.popover'); + $tipclass = ' hasPopover'; + $title = ' title="' . htmlspecialchars(trim($text, ':')) . '"' + . ' data-content="'. htmlspecialchars($description) . '"'; + + if (!$position && JFactory::getLanguage()->isRtl()) + { + $position = ' data-placement="left" '; + } + } + else + { + JHtml::_('bootstrap.tooltip'); + $tipclass = ' hasTooltip'; + $title = ' title="' . JHtml::_('tooltipText', trim($text, ':'), JText::_($description), 0) . '"'; + $position = 'top'; + } + } + + $cancelledButton = '' . $text . ''; + + return $cancelledButton; + } + + return false; + } + + /** + * Next Date Text + * + * @since 3.6.0 + */ + public static function dateText($i) + { + $eventTimeZone = null; + + $dates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); // returns array + $period = iCString::isSerialized($i->period) ? unserialize($i->period) : array(); // returns array + $weekdays = $i->weekdays; + $startdatetime = iCDate::isDate($i->startdate) ? date('Y-m-d H:i', strtotime($i->startdate)) : ''; + + $site_date = JHtml::date('now', 'Y-m-d'); + $site_datetime = JHtml::date('now', 'Y-m-d H:i'); + + $alldates_array = array_merge($dates, $period); + $alldates = array_filter($alldates_array, function($var) {return $var == iCDate::isDate($var);}); + + $next_date = date('Y-m-d', strtotime($i->next)); + $next_datetime = date('Y-m-d H:i', strtotime($i->next)); + + $next_is_in_period = in_array($next_datetime, $period) ? true : false; + + $totDates = count($alldates); + + if ($totDates > 1 + && $next_date > $site_date) + { + rsort($alldates); + + $last_date = JHtml::date($alldates[0], 'Y-m-d', $eventTimeZone); + + if ( ! $next_is_in_period + && $last_date == $next_date) + { + $dateText = JText::_('COM_ICAGENDA_EVENT_DATE_LAST'); + } + elseif ( ! $next_is_in_period) + { + $dateText = JText::_('COM_ICAGENDA_EVENT_DATE_FUTUR'); + } + elseif ($next_is_in_period + && $weekdays == NULL) + { + $dateText = JText::_('COM_ICAGENDA_LEGEND_DATES'); + } + else + { + $dateText = JText::_('COM_ICAGENDA_EVENT_DATE'); + } + } + elseif ($totDates > 1 + && $next_date < $site_date) + { + if ($totDates == 2) + { + $dateText = $next_is_in_period + ? JText::_('COM_ICAGENDA_EVENT_DATE') + : JText::_('COM_ICAGENDA_EVENT_DATE_PAST'); + } + else + { + $dateText = ($next_is_in_period && $weekdays == NULL) + ? JText::_('COM_ICAGENDA_LEGEND_DATES') + : JText::_('COM_ICAGENDA_EVENT_DATE_PAST'); + } + } + elseif ($next_date == $site_date) + { + $dateText = ($next_is_in_period && ($next_datetime < $site_datetime || $next_datetime != $startdatetime)) + ? JText::_('COM_ICAGENDA_EVENT_DATE_PERIOD_NOW') + : JText::_('COM_ICAGENDA_EVENT_DATE_TODAY'); + } + else + { + $dateText = JText::_( 'COM_ICAGENDA_EVENT_DATE' ); + } + + return $dateText; + } + + /** + * Get Next Date (or Last Date) + * + * @since 3.4.0 + */ + public static function nextDate($evt, $i) + { + $eventTimeZone = null; + +// $singledates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); // returns array + $period = iCString::isSerialized($i->period) ? unserialize($i->period) : array(); // returns array + $startdatetime = $i->startdate; + $enddatetime = $i->enddate; + $weekdays = $i->weekdays; + + $site_date = JHtml::date('now', 'Y-m-d'); + $UTC_today_date = JHtml::date('now', 'Y-m-d', $eventTimeZone); + + $next_date = JHtml::date($evt, 'Y-m-d', $eventTimeZone); + $next_datetime = JHtml::date($evt, 'Y-m-d H:i', $eventTimeZone); + + $start_date = JHtml::date($i->startdate, 'Y-m-d', $eventTimeZone); + $end_date = JHtml::date($i->enddate, 'Y-m-d', $eventTimeZone); + + // Check if date from a period with weekdays has end time of the period set in next. +// $time_next_datetime = JHtml::date($next_datetime, 'H:i', $eventTimeZone); + $time_next_datetime = date('H:i', strtotime($next_datetime)); + $time_startdate = JHtml::date($i->startdate, 'H:i', $eventTimeZone); + $time_enddate = JHtml::date($i->enddate, 'H:i', $eventTimeZone); + + $data_next_datetime = date('Y-m-d H:i', strtotime($evt)); + + if ($next_date == $site_date + && $time_next_datetime == $time_enddate) + { + $next_datetime = $next_date . ' ' . $time_startdate; + } + + if ($period != NULL + && in_array($data_next_datetime, $period)) + { + $next_is_in_period = true; + } + else + { + $next_is_in_period = false; + } + + // Highlight event in progress + if ($next_date == $site_date) + { + $start_span = ''; + $end_span = ''; + } + else + { + $start_span = $end_span = ''; + } + + $separator = ' - '; + + // Format Next Date + if ($next_is_in_period + && ($start_date == $end_date || $weekdays != null)) + { + // Next in the period & (same start/end date OR one or more weekday selected) + $nextDate = $start_span; + $nextDate.= ''; + $nextDate.= icagendaRender::dateToFormat($evt); + $nextDate.= ''; + + if ($i->displaytime == 1) + { + $nextDate.= ' ' . icagendaRender::dateToTime($i->startdate) . ''; + + if (icagendaRender::dateToTime($i->startdate) != icagendaRender::dateToTime($i->enddate)) + { + $nextDate.= $separator . '' . icagendaRender::dateToTime($i->enddate) . ''; + } + } + + $nextDate.= $end_span; + } + elseif ($next_is_in_period + && ($weekdays == null)) + { + // Next in the period & different start/end date & no weekday selected + $start = ''; + $start.= icagendaRender::dateToFormat($i->startdate); + $start.= ''; + + $end = ''; + $end.= icagendaRender::dateToFormat($i->enddate); + $end.= ''; + + if ($i->displaytime == 1) + { + $start.= ' ' . icagendaRender::dateToTime($i->startdate) . ''; + + $end.= ' ' . icagendaRender::dateToTime($i->enddate) . ''; + } + + $nextDate = $start_span . $start . $separator . $end . $end_span; + } + else + { + // Next is a single date + $nextDate = $start_span; + $nextDate.= ''; + $nextDate.= icagendaRender::dateToFormat($evt); + $nextDate.= ''; + + if ($i->displaytime == 1) + { + $nextDate.= ' ' . icagendaRender::dateToTime($evt) . ''; + } + + $nextDate.= $end_span; + } + + return $nextDate; + } + + /* + * Function to detect if info details exist in an event, + * and to hide or show it depending of Options (display and access levels) + * + * @since 3.6.0 + */ + public static function infoDetails($item, $CUSTOM_FIELDS) + { + // Hide/Show Option + $infoDetails = JComponentHelper::getParams('com_icagenda')->get('infoDetails', 1); + + // Access Levels Option + $accessInfoDetails = JComponentHelper::getParams('com_icagenda')->get('accessInfoDetails', 1); + + if ( ($infoDetails == 1 && icagendaEvents::accessLevels($accessInfoDetails)) + && ( ($item->params->get('statutReg', '') == '1' && $item->params->get('maxReg')) + || $item->phone + || $item->email + || $item->website + || $item->address + || $item->file + || $CUSTOM_FIELDS ) + ) + { + return true; + } + + return false; + } + + /* + * Function to return a list of all single dates, HTML formatted. + * TO BE REFACTORED + * + * @since 3.6.0 + */ + public static function displayListSingleDates($item) + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + $timeformat = JFactory::getApplication()->getParams()->get('timeformat', 1); + + // Hide/Show Option + $SingleDates = $iCparams->get('SingleDates', 1); + + // Access Levels Option (to be checked!) +// $accessSingleDates = $iCparams->get('accessSingleDates', 1); + + // Order by Dates + $SingleDatesOrder = $iCparams->get('SingleDatesOrder', 1); + + // List Model + $SingleDatesListModel = $iCparams->get('SingleDatesListModel', 1); + + if ($SingleDates == 1) + { +// if ($this->accessLevels($accessSingleDates)) +// { + $days = iCString::isSerialized($item->dates) ? unserialize($item->dates) : array(); // returns array + + if ($SingleDatesOrder == 1) + { + rsort($days); + } + elseif ($SingleDatesOrder == 2) + { + sort($days); + } + + $totDates = count($days); + + if ($timeformat == 1) + { + $lang_time = 'H:i'; + } + else + { + $lang_time = 'h:i A'; + } + + // Detect if Singles Dates, and no single date with null value + $displayDates = false; + $nbDays = count($days); + + foreach ($days as $k => $d) + { + if (iCDate::isDate($d) && $nbDays != 0) + { + $displayDates = true; + } + } + + $daysUl = ''; + + if ($displayDates) + { + if ($SingleDatesListModel == '2') + { + $n = 0; + $daysUl.= '
    ' . JText::_('COM_ICAGENDA_LEGEND_DATES') . ': '; + + foreach ($days as $k => $d) + { + $n = $n+1; + $fd = icagendaRender::dateToFormat($d); + + $timeDate = ($item->displaytime == 1) + ? ' ' . date($lang_time, strtotime($d)) . '' + : ''; + + if ($n <= ($totDates-1)) + { + $daysUl.= '' . $fd . $timeDate . ' - '; + } + elseif ($n == $totDates) + { + $daysUl.= '' . $fd . $timeDate . ''; + } + } + + $daysUl.= '
    '; + } + else + { + $daysUl.= '
      '; + + foreach ($days as $k => $d) + { + $fd = icagendaRender::dateToFormat($d); + + $timeDate = ($item->displaytime == 1) + ? ' ' . date($lang_time, strtotime($d)) . '' + : ''; + + $daysUl.= '
    • ' . $fd . $timeDate . '
    • '; + } + + $daysUl.= '
    '; + } + } + + if ($totDates > '0') + { + return $daysUl; + } + else + { + return false; + } +// } +// else +// { +// return false; +// } + } + else + { + return false; + } + } + + /* + * Function to display the period text width formatted dates (eg. from 00-00-0000 to 00-00-0000). + * TO BE REFACTORED + * @TODO remove inline style html tags (check css and add class declarations) + * @TODO (3.7) remove old deprecated class names + * + * @since 3.6.0 + */ + public static function displayPeriodDates($item) + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + + // Hide/Show Option + $PeriodDates = $iCparams->get('PeriodDates', 1); + + // List Model + $SingleDatesListModel = $iCparams->get('SingleDatesListModel', 1); + + // First day of the week + $firstday_week_global = $iCparams->get('firstday_week_global', 1); + + // Predefined variables + $wdays = $showDays = $timeOneDay = $end = ''; + + // WeekDays + $weekdays = $item->weekdays; + $weekdaysall = empty($weekdays) ? true : false; + + if ($firstday_week_global == '1') + { + $weekdays_array = explode (',', $weekdays); + + if (in_array('0', $weekdays_array)) + { + $weekdays = str_replace('0', '', $weekdays); + $weekdays = $weekdays . ',7'; + } + } + + if ( ! $weekdaysall) + { + $weekdays_array = explode (',', $weekdays); + $wdaysArray = array(); + + foreach ($weekdays_array AS $wd) + { + if ($firstday_week_global != '1') + { + if ($wd == 0) $wdaysArray[] = JText::_('SUNDAY'); + } + if ($wd == 1) $wdaysArray[] = JText::_('MONDAY'); + if ($wd == 2) $wdaysArray[] = JText::_('TUESDAY'); + if ($wd == 3) $wdaysArray[] = JText::_('WEDNESDAY'); + if ($wd == 4) $wdaysArray[] = JText::_('THURSDAY'); + if ($wd == 5) $wdaysArray[] = JText::_('FRIDAY'); + if ($wd == 6) $wdaysArray[] = JText::_('SATURDAY'); + if ($firstday_week_global == '1') + { + if ($wd == 7) $wdaysArray[] = JText::_('SUNDAY'); + } + } + + $last = array_slice($wdaysArray, -1); + $first = join(', ', array_slice($wdaysArray, 0, -1)); + $both = array_filter(array_merge(array($first), $last)); + + // RTL css if site language is RTL + $lang = JFactory::getLanguage(); + $arrow_list = $lang->isRTL() ? '↵' : '↳'; + + $wdays = $arrow_list . ' ' . join(' & ', $both) . ''; + } + + if ($PeriodDates == 1 + && self::eventHasPeriod($item->period, $item->startdate, $item->enddate) + ) + { + $startDate = icagendaRender::dateToFormat($item->startdate); + $endDate = icagendaRender::dateToFormat($item->enddate); + $startTime = icagendaRender::dateToTime($item->startdate); + $endTime = icagendaRender::dateToTime($item->enddate); + + if ($startDate == $endDate) + { + $start = ''; + $start.= $startDate; + $start.= ''; + + if ($item->displaytime == 1) + { + $timeOneDay = '' . $startTime; + $timeOneDay.= ($startTime !== $endTime) ? ' - ' . $endTime : ''; + $timeOneDay.= ''; + } + } + else + { + $start = '' + . ucfirst(JText::_('COM_ICAGENDA_PERIOD_FROM')) + . ' '; + $start.= '' + . $startDate + . ''; + + if ($item->displaytime == 1) + { + $start.= ' ' + . $startTime + . ''; + } + + $end = '' + . JText::_('COM_ICAGENDA_PERIOD_TO') + . ' '; + $end.= '' + . $endDate + . ''; + + if ($item->displaytime == 1) + { + $end.= ' ' + . $endTime + . ''; + } + + $showDays = $wdays; + } + + // Horizontal List + if ($SingleDatesListModel == 2) + { + $period = '
    ' . JText::_('COM_ICAGENDA_EVENT_PERIOD') . ': '; + $period.= $start . ' ' . $end . ' ' . $timeOneDay; + + if ( ! empty($showDays)) + { + $period.= '
    ' . $showDays . ''; + } + + $period.= '
    '; + } + + // Vertical List + else + { + $period = '
    • '; + $period.= $start . ' ' . $end . ' ' . $timeOneDay; + + if ( ! empty($showDays)) + { + $period.= '
      ' . $showDays; + } + + $period.= '
    '; + } + + return $period; + } + else + { + return false; + } + } + + /* + * Function to check if period dates exist for this event + * + * @since 3.6.0 + */ + public static function eventHasPeriod($period, $startdate, $enddate) + { + $period_dates = iCString::isSerialized($period) ? unserialize($period) : array(); // returns array + + if (count($period_dates) > 0 + && iCDate::isDate($startdate) + && iCDate::isDate($enddate)) + { + return true; + } + + return false; + } + + /* + * Function to check if period is not finished + * + * @since 3.6.0 + */ + public static function periodIsNotFinished($enddate) + { + $eventTimeZone = null; + $datetime_today = JHtml::date('now', 'Y-m-d H:i'); + $datetime_enddate = JHtml::date($enddate, 'Y-m-d H:i', $eventTimeZone); + + if (strtotime($datetime_enddate) > strtotime($datetime_today)) + { + return true; + } + + return false; + } + + /* + * Function to set Meta-title for an event + * + * @since 3.6.0 + */ + public static function setMetaTitle($item) + { + $limit = '60'; + $metaTitle = iCFilterOutput::fullCleanHTML($item->title); + + if (strlen($metaTitle) > $limit) + { + $string_cut = substr($metaTitle, 0, $limit); + $last_space = strrpos($string_cut, ' '); + $string_ok = substr($string_cut, 0, $last_space); + $metaTitle = $string_ok; + } + + return $metaTitle; + } + + /* + * Function to set Meta-description for an event + * + * @since 3.6.0 + */ + public static function setMetaDesc($item) + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + $limit = $iCparams->get('char_limit_meta_description', '320'); + + $metaDesc = iCFilterOutput::fullCleanHTML($item->metadesc); + $metaDesc = (empty($metaDesc)) ? iCFilterOutput::fullCleanHTML($item->desc) : $metaDesc; + + if (strlen($metaDesc) > $limit) + { + $string_cut = substr($metaDesc, 0, $limit); + $last_space = strrpos($string_cut, ' '); + $string_ok = substr($string_cut, 0, $last_space); + $metaDesc = $string_ok; + } + + return $metaDesc; + } + + /* + * Function to return event Url + * + * @since 3.6.0 + */ + public static function eventURL($i) + { + $app = JFactory::getApplication(); + $jinput = $app->input; + + $itemID = $jinput->get('Itemid', '0'); + + $eventnumber = $i->id; + $event_slug = empty($i->alias) ? $i->id : $i->id . ':' . $i->alias; + $date = $i->next; + + // Get the "event" URL + $baseURL = JURI::base(); + $subpathURL = JURI::base(true); + + $baseURL = str_replace('/administrator', '', $baseURL); + $subpathURL = str_replace('/administrator', '', $subpathURL); + + $urlevent = str_replace('&','&', JRoute::_('index.php?option=com_icagenda&view=event&Itemid=' . (int) $itemID . '&id=' . $event_slug)); + + // Sub Path filtering + $subpathURL = ltrim($subpathURL, '/'); + + // URL Event Details filtering + $urlevent = ltrim($urlevent, '/'); + + if (substr($urlevent, 0, strlen($subpathURL)+1) == "$subpathURL/") + { + $urlevent = substr($urlevent, strlen($subpathURL)+1); + } + + $urlevent = rtrim($baseURL,'/') . '/' . ltrim($urlevent,'/'); + + $url = $urlevent; + + if (is_numeric($itemID) && is_numeric($eventnumber) + && ! is_array($itemID) && ! is_array($eventnumber) + ) + { + return $url; + } + else + { + $url = JRoute::_('index.php'); + + return JURI::base() . $url; + } + } + + /* + * Function to convert a datetime to URL alias + * (see iCDate::dateToAlias from iC Library for general function) + * + * @since 3.6.0 + */ + public static function urlDateVar($datetime) + { + if ( ! iCDate::isDate($datetime)) return false; + + $datetime = date('Y-m-d H:i', strtotime($datetime)); + $date_explode = explode(' ', $datetime); + + $dateAlias = $date_explode['0'] . '-' . str_replace(':', '-', $date_explode['1']); + + return $dateAlias; + } + + /* + * Function to convert a URL date alias in an SQL datetime string. + * + * @return string The date string in SQL datetime format. + * + * @since 3.6.0 + */ + public static function convertDateAliasToSQLDatetime($dateAlias) + { + if (strlen(iCDate::dateToNumeric($dateAlias)) != '12') return ''; + + $ex = explode('-', $dateAlias); + $datetime = (count($ex) == 5) + ? $ex['0'] . '-' . $ex['1'] . '-' . $ex['2'] . ' ' . $ex['3'] . ':' . $ex['4'] . ':00' + : ''; + + return $datetime; + } + + /* + * Function to generate the read more for introduction description + * + * @since 3.6.0 + */ + public static function readMore ($url, $desc, $content = '') + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + $limitGlobal = $iCparams->get('limitGlobal', 0); + + if ($limitGlobal == 1) + { + $limit = $iCparams->get('ShortDescLimit', '100'); + } + elseif ($limitGlobal == 0) + { + $customlimit = $iCparams->get('limit', '100'); + + $limit = is_numeric($customlimit) ? $customlimit : $iCparams->get('ShortDescLimit', '100'); + } + + $limit = is_numeric($limit) ? $limit : '1'; + + $readmore = ''; + + $readmore = ($limit <= 1) ? '' : $content; + $text = preg_replace('/]*>/Ui', '', $desc); + + if (strlen($text) > $limit) + { + $string_cut = substr($text, 0, $limit); + $last_space = strrpos($string_cut, ' '); + $string_ok = substr($string_cut, 0, $last_space); + $text = $string_ok . ' '; + $url = $url; + $text = '' . $readmore . ''; + } + else + { + $text = ''; + } + + return $text; + } + + /** + * Loads the list of filled custom fields for this event + * + * @return array + * + * @since 3.6.0 + */ + public static function getCustomFields($id = null) + { + $customFields = icagendaEventData::loadEventCustomFields($id); + + foreach ($customFields as $cf) + { + if ($cf->title && $cf->value) + { + switch ($cf->type) + { + case 'url': + $cf->value = iCRender::urlTag($cf->value); + break; + + case 'email': + $cf->value = JHtml::_('email.cloak', $cf->value); + break; + + default: + $cf->value = JText::_($cf->value); + break; + } + } + + $cf->title = JText::_($cf->title); + } + + return $customFields; + } + + /** + * Function to get custom field groups of an event + * + * @param integer $id Event id + * + * @return array + * + * @since 3.6.0 + */ + public static function getCustomfieldGroups($id = null) + { + // Create a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('e.params') + ->from('#__icagenda_events AS e') + ->where($db->qn('id') . ' = ' . $db->q($id)); + $db->setQuery($query); + + $result = json_decode($db->loadResult()); + + if (isset($result->custom_form)) + { + return $result->custom_form; + } + + return false; + } + + /** + * Function to get event params + * + * @param integer $id Event id + * + * @return object + * + * @since 3.6.5 + */ + public static function getParams($id = null) + { + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select('e.params') + ->from($db->qn('#__icagenda_events', 'e')) + ->where($db->qn('e.id') . ' = ' . (int) $id); + + $db->setQuery($query); + + $params = json_decode($db->loadResult(), true); + + $evtParams = new JRegistry($params); + + return $evtParams; + } + + public static function getCustomField($id, $field) + { + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select('d.value') + ->from($db->qn('#__icagenda_customfields_data', 'd')) + ->where($db->qn('d.parent_id') . ' = ' . (int) $id) + ->where($db->qn('d.slug') . ' = "'.$field.'"'); + + $db->setQuery($query); + return $db->loadResult(); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/event/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/event/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/event/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/events/data.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/events/data.php new file mode 100644 index 00000000..cce82414 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/events/data.php @@ -0,0 +1,1564 @@ +input; + $params = $app->getParams(); + + $search_filters = $params->get('search_filters', 0); + + if (!$moduleParams) { + $activeMenu = $app->getMenu()->getActive(); + + $menu_search_filters = $activeMenu + ? $activeMenu->params->get('search_filters') + : ''; + + $filters_mode = ($menu_search_filters == 1) + ? $params->get('filters_mode', 1) + : JComponentHelper::getParams('com_icagenda')->get('filters_mode', 1); + } else { + $menu_search_filters = '0'; + $filters_mode = ''; + } + + + // Filter time : upcoming, past, today... + $filterTime = ($filterTime == 'no') ? '0' : $filterTime; + + if ($menu_search_filters == 1) { + $filterTime = (isset($filterTime) || $filterTime == '0') + ? $filterTime + : (($menu_search_filters == 1) + ? $params->get('time', 1) + : JComponentHelper::getParams('com_icagenda')->get('time', 1)); + } else { + $filterTime = (isset($filterTime) || $filterTime == '0') + ? $filterTime + : $params->get('time', 1); + } + + // Dates display : all dates OR only next/last date per event + $datesDisplay = $datesDisplay ? $datesDisplay : $params->get('datesDisplay', 1); + + // Ordering : date order ASC OR DESC + $orderby = $orderby ? $orderby : $params->get('orderby', 2); + + // Filter category : multiple categories filtering + if ($mcatid !== 'all') { + $mcatid = $mcatid ? $mcatid : $params->get('mcatid', ''); + } + + // Set vars + $nodate = '0000-00-00 00:00:00'; + $ic_nodate = '0000-00-00 00:00'; + $eventTimeZone = null; + $datetime_today = JHtml::date('now', 'Y-m-d H:i'); // Joomla Time Zone + $date_today = JHtml::date('now', 'Y-m-d'); // Joomla Time Zone + + // Get Data + $db = Jfactory::getDbo(); + $query = $db->getQuery(true); + // $query->select('e.next, e.dates, e.startdate, e.enddate, e.period, e.weekdays, e.displaytime, e.id, e.catid'); + $query->select('e.*'); + $query->from('#__icagenda_events AS e'); + $query->leftJoin('#__icagenda_category AS c ON c.id = e.catid'); + $query->leftJoin('#__icagenda_customfields_data AS cfd ON cfd.parent_id = e.id'); + + // CATEGORY STATE Filtering + $query->where('c.state = 1'); + + // EVENT STATE Filtering + $query->where('e.state = 1'); + + // Search in current list (menu filtered list) + $currentListSearch = ($filters_mode == 1 && $search_filters); + + // Filter by category + if ($mcatid != 'all') { + // $filterCategory = $jinput->getInt('filter_category', ''); + $filterCategory = $moduleParams ? '' : $jinput->getInt('filter_category', ''); + + if (is_numeric($filterCategory) && !empty($filterCategory)) { + $query->where('e.catid = ' . $filterCategory . ''); + } elseif (is_array($filterCategory) && !empty($filterCategory) && !in_array('0', $filterCategory)) { + JArrayHelper::toInteger($filterCategory); + $categoryId = implode(',', $filterCategory); + $query->where('e.catid IN (' . $categoryId . ')'); + } + + // No category search filter active, use menu Filter by Category option + elseif (is_numeric($mcatid) && !empty($mcatid)) { + $query->where('e.catid = ' . $db->quote($mcatid)); + } elseif (is_array($mcatid) && !empty($mcatid) && !in_array('0', $mcatid)) { + JArrayHelper::toInteger($mcatid); + $list_catid = implode(',', $mcatid); + $query->where('e.catid IN (' . $list_catid . ')'); + } + + if ( + $jinput->get('filter_category') + && !$currentListSearch + && !$moduleParams + ) { + $filterTime = '0'; + } + } + + + // Frontend Search settings (not in modules) + if ($moduleParams) { + $filterFrom = ''; + $filterTo = ''; + $filterMonth = ''; + $filterYear = ''; + } else { + // Filter by search + $search = $jinput->getString('filter_search'); + + if (!empty($search)) { + // Check if Falang installed + $tag = JFactory::getLanguage()->getTag(); + $defaultSiteLang = JComponentHelper::getParams('com_languages')->get('site', 'en-GB'); + + //$falang = defined('FALANG_PATH'); + $falang = is_a($db, 'JFalangDatabase'); + + $falangSearch = ($falang && ($tag != $defaultSiteLang)); + + // Run Falang query if needed + if ($falang && $falangSearch) { + $query->join('LEFT', $db->quoteName('#__falang_content', 'f') . ' ON (' . $db->quoteName('f.reference_id') . ' = ' . $db->quoteName('e.id') . ')'); + $query->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON (' . $db->quoteName('f.language_id') . ' = ' . $db->quoteName('l.lang_id') . ')'); + $query->where('f.reference_table IN (' . $db->quote('icagenda_events') . ', ' . $db->quote('icagenda_category') . ', ' . $db->quote('icagenda_customfields_data') . ')'); + $query->where('l.lang_code in (' . $db->quote($tag) . ',' . $db->quote('*') . ')'); + } + + if (stripos($search, 'id:') === 0) { + $query->where('e.id = ' . (int) substr($search, 3)); + } elseif ($falang && $falangSearch) { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('( f.value LIKE ' . $search . ')'); + } else { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + + $query->where('( e.title LIKE ' . $search . + ' OR e.id LIKE ' . $search . + ' OR e.shortdesc LIKE ' . $search . + ' OR e.desc LIKE ' . $search . + ' OR e.place LIKE ' . $search . + ' OR e.address LIKE ' . $search . + ' OR e.city LIKE ' . $search . + ' OR e.country LIKE ' . $search . + ' OR c.title LIKE ' . $search . + ' OR cfd.value LIKE ' . $search . + ')'); + } + } + + // Get filters by dates + $filterFrom = $jinput->get('filter_from'); + $filterTo = $jinput->get('filter_to'); + $filterMonth = $jinput->getInt('filter_month'); + $filterYear = $jinput->getInt('filter_year'); + } + + // FEATURES Filtering + // $query->where(self::getFeaturesFilter()); + $query->where(icagendaEventsData::getFeaturesFilter($moduleParams)); + + // LANGUAGE Filtering + $query->where('e.language IN (' . $db->q(JFactory::getLanguage()->getTag()) . ',' . $db->q('*') . ')'); + + // ACCESS Filtering + $user = JFactory::getUser(); + $userID = $user->id; + $userLevels = $user->getAuthorisedViewLevels(); + $userGroups = $user->getAuthorisedGroups(); + + $groupid = JComponentHelper::getParams('com_icagenda')->get('approvalGroups', array("8")); + $groupid = is_array($groupid) ? $groupid : array($groupid); + + if (!in_array('8', $userGroups)) { + $useraccess = implode(', ', $userLevels); + $query->where('e.access IN (' . $useraccess . ')'); + } + + // APPROVAL RIGHTS Filtering + if ( + !array_intersect($userGroups, $groupid) + && !in_array('8', $userGroups) + ) { + $query->where('e.approval <> 1'); + } else { + $query->where('e.approval < 2'); + } + + // Prevents duplicated results when search in Falang category translations + $query->group('e.id'); + + $db->setQuery($query); + $list = $db->loadObjectList(); + + $list_all_dates = array(); + + foreach ($list as $i) { + $hasUpcomingDate = false; + + $i_id = $i->id; + $i_startdate = $i->startdate; + $i_enddate = $i->enddate; + $i_weekdays = $i->weekdays; + $i_dates = $i->dates; + $i_displaytime = $i->displaytime; + + // Declare AllDates array + $AllDatesDisplay = array(); + + // Get WeekDays Array + $WeeksDays = iCDatePeriod::weekdaysToArray($i_weekdays); + + // If Single Dates, added each one to All Dates for this event + $singledates = iCString::isSerialized($i_dates) ? unserialize($i_dates) : array(); + $singleDatesArray = array(); + + $no_filtering = '0'; + + foreach ($singledates as $sd) { + $isValid = iCDate::isDate($sd); + + if ($isValid) { + $date_Dat = JHtml::date($sd, 'Y-m-d', $eventTimeZone); + $SingleDate = JHtml::date($sd, 'Y-m-d H:i', $eventTimeZone); + + $data_SingleDate = date('Y-m-d H:i', strtotime($sd)); + + if (strtotime($sd) >= strtotime($datetime_today)) { + $hasUpcomingDate = true; + } + + // Frontend Filtering + if ( + !empty($filterFrom) + || !empty($filterTo) + || !empty($filterMonth) + || !empty($filterYear) + || !empty($search) + ) { + $dateToDisplay = true; + + $controlDate = $SingleDate; + + + // Filter by period - From + if (!empty($filterFrom) && $dateToDisplay) { + $dateToDisplay = (strtotime($controlDate) >= strtotime($filterFrom)) ? true : false; + } + + // Filter by period - To + if (!empty($filterTo) && $dateToDisplay) { + $dateToDisplay = (strtotime($controlDate) <= (strtotime($filterTo) + 86400)) ? true : false; + } + + // Filter by Month + if (!empty($filterMonth) && $dateToDisplay) { + $dateToDisplay = (date('n', strtotime($controlDate)) == $filterMonth) ? true : false; + } + + // Filter by Year + if (!empty($filterYear) && $dateToDisplay) { + $dateToDisplay = (date('Y', strtotime($controlDate)) == $filterYear) ? true : false; + } + + if ($currentListSearch && $dateToDisplay) { + $controlDate = $SingleDate; + + // (1) Filter Dates : Ongoing and Upcoming + if ($filterTime == 1) { + $dateToDisplay = (strtotime($controlDate) >= strtotime($date_today)) ? true : false; + } + // (2) Filter Dates : Past Dates + elseif ($filterTime == 2) { + $dateToDisplay = (strtotime($controlDate) < strtotime($datetime_today)) ? true : false; + } + // (3) Filter Dates : Upcoming + elseif ($filterTime == 3) { + $dateToDisplay = (strtotime($controlDate) > strtotime($datetime_today)) ? true : false; + } + // (4) Filter Dates : Ongoing Events today + elseif ($filterTime == 4) { + $dateToDisplay = ((strtotime($controlDate) >= strtotime($date_today)) + && (strtotime($controlDate) <= (strtotime($date_today) + 86400))) ? true : false; + } + } + + if ($dateToDisplay) { + $singleDatesArray[] = $data_SingleDate . '_' . $i_id; + } + } + + // All Dates for each event + elseif ($datesDisplay == 1) { + $singleDatesArray[] = $data_SingleDate . '_' . $i_id; + } + + // Current Today + elseif ( + $filterTime == 4 + && strtotime($SingleDate) >= strtotime($date_today) + ) { + $singleDatesArray[] = $data_SingleDate . '_' . $i_id; + } + + // Upcoming Events + elseif ( + $filterTime == 3 + && strtotime($SingleDate) > strtotime($datetime_today) + ) { + $singleDatesArray[] = $data_SingleDate . '_' . $i_id; + } + + // Past event + elseif ( + $filterTime == 2 + && strtotime($SingleDate) < strtotime($datetime_today) + ) { + $singleDatesArray[] = $data_SingleDate . '_' . $i_id; + } + + // Current and Upcoming Events + elseif ( + $filterTime == 1 + && strtotime($SingleDate) >= strtotime($date_today) + ) { + $singleDatesArray[] = $data_SingleDate . '_' . $i_id; + } + + // All Dates + elseif (!$filterTime) { + // All Upcoming dates + if (strtotime($SingleDate) >= strtotime($datetime_today)) { + $no_filtering = $no_filtering + 1; + + $singleDatesArray[] = $data_SingleDate . '_' . $i_id; + } + + // If no Upcoming dates, get the last date + elseif ( + $no_filtering == 0 + && strtotime($SingleDate) < strtotime($datetime_today) + ) { + $no_filtering = $no_filtering + 1; + + $singleDatesArray[] = $data_SingleDate . '_' . $i_id; + } + } + } + } + + if ( + $datesDisplay == 2 + && $filterTime == 2 + && count($singleDatesArray) > 0 + ) // Past Events + { + $AllDatesDisplay[] = max($singleDatesArray); + } elseif ( + $datesDisplay == 2 + && count($singleDatesArray) > 0 + ) { + $AllDatesDisplay[] = min($singleDatesArray); + } else { + $AllDatesDisplay = array_merge($AllDatesDisplay, $singleDatesArray); + } + + // If Period Dates, added each one to All Dates for this event (filter week Days, and if date not null) + $perioddates = iCDatePeriod::listDates($i_startdate, $i_enddate); + + $period_array = array(); + + foreach ($perioddates as $date_in_weekdays) { + if ( + in_array(date('w', strtotime($date_in_weekdays)), $WeeksDays) + && iCDate::isDate($date_in_weekdays) + ) { + $period_array[] = $date_in_weekdays; + } + } + + $only_startdate = ($i_weekdays || $i_weekdays == '0') ? false : true; + + $StDate = JHtml::date($i_startdate, 'Y-m-d H:i', $eventTimeZone); + $EnDate = JHtml::date($i_enddate, 'Y-m-d H:i', $eventTimeZone); + + $date_startdate = JHtml::date($i_startdate, 'Y-m-d', $eventTimeZone); + $date_enddate = JHtml::date($i_enddate, 'Y-m-d', $eventTimeZone); + $time_startdate = JHtml::date($i_startdate, 'H:i', $eventTimeZone); + $time_enddate = JHtml::date($i_enddate, 'H:i', $eventTimeZone); + + $data_StDate = date('Y-m-d H:i', strtotime($i_startdate)); + $data_time_startdate = date('H:i', strtotime($i_startdate)); + + if ( + isset($period_array) + && ($period_array != NULL && $period_array) + ) { + if ($only_startdate) { + // Frontend Filtering + if ( + !empty($filterFrom) + || !empty($filterTo) + || !empty($filterMonth) + || !empty($filterYear) + ) { + $dateToDisplay = true; + + // Full Period with no weekdays selected, ongoing events + $ongoing_filter = in_array($filterTime, array('1', '4')); + + if ( + $ongoing_filter + && in_array($date_today . ' ' . $time_startdate, $perioddates) + && strtotime($EnDate) >= strtotime($datetime_today) + && strtotime($StDate) <= strtotime($datetime_today) + ) { + $controlDate = $date_today; + } else { + $controlDate = $date_startdate; + } + + // Filter by period - From + if (!empty($filterFrom) && $dateToDisplay) { + // $dateToDisplay = (strtotime($controlDate) >= strtotime($filterFrom)) ? true : false; + $dateToDisplay = ((strtotime($controlDate) >= strtotime($filterFrom)) + || ($ongoing_filter + && (strtotime($controlDate) <= strtotime($filterFrom)) + && (strtotime($date_enddate) >= strtotime($filterFrom)) + ) + ) ? true : false; + } + + // Filter by period - To + if (!empty($filterTo) && $dateToDisplay) { + $dateToDisplay = (strtotime($controlDate) < (strtotime($filterTo) + 86400)) ? true : false; + } + + // Filter by Month and/or Year + if (!empty($filterMonth) || !empty($filterYear)) { + $new_startdate = new DateTime($i_startdate); + $new_enddate = new DateTime($i_enddate); + $start = $new_startdate->modify('first day of this month'); + $end = $new_enddate->modify('last day of this month'); + $interval = DateInterval::createFromDateString('1 month'); + $period = new DatePeriod($start, $interval, $end); + } + + // Filter by Month + if (!empty($filterMonth) && empty($filterYear) && $dateToDisplay) { + // $dateToDisplay = (date('n', strtotime($controlDate)) == $filterMonth) ? true : false; + + $months_period = array(''); + + foreach ($period as $dt) { + $months_period[] = $dt->format('n'); + } + + $dateToDisplay = in_array($filterMonth, $months_period); + } + + // Filter by Year + if (!empty($filterYear) && empty($filterMonth) && $dateToDisplay) { + // $dateToDisplay = (date('Y', strtotime($controlDate)) == $filterYear) ? true : false; + + $years_period = array(''); + + foreach ($period as $dt) { + $years_period[] = $dt->format('Y'); + } + + $dateToDisplay = in_array($filterYear, $years_period); + } + + // Filter by Month & Year + if (!empty($filterMonth) && !empty($filterYear) && $dateToDisplay) { + // $dateToDisplay = (date('Y', strtotime($controlDate)) == $filterYear) ? true : false; + + $monthsYears_period = array(''); + + foreach ($period as $dt) { + $monthsYears_period[] = $dt->format('n-Y'); + } + + $dateToDisplay = in_array($filterMonth . '-' . $filterYear, $monthsYears_period); + } + + if ($dateToDisplay) { + $AllDatesDisplay[] = $data_StDate . '_' . $i_id; + } + } else { + $AllDatesDisplay[] = $data_StDate . '_' . $i_id; + } + } else { + $dp = 0; + $count_period = count($period_array); + $cp = 0; + $no_filtering = 0; + + foreach ($period_array as $Dat) { + $date_Dat = JHtml::date($Dat, 'Y-m-d', $eventTimeZone); + $SingleDate = JHtml::date($Dat, 'Y-m-d H:i', $eventTimeZone); + + $data_date_Dat = date('Y-m-d', strtotime($Dat)); + $data_SingleDate = date('Y-m-d H:i', strtotime($Dat)); + + if (strtotime($Dat) >= strtotime($datetime_today)) { + $hasUpcomingDate = true; + } + + if ( + in_array(date('w', strtotime($Dat)), $WeeksDays) + && $dp == 0 + ) { + // Frontend Filtering + if ( + !empty($filterFrom) + || !empty($filterTo) + || !empty($filterMonth) + || !empty($filterYear) + || !empty($search) + ) { + $dateToDisplay = true; + + $controlDate = $date_Dat; + + + // Filter by period - From + if (!empty($filterFrom) && $dateToDisplay) { + $dateToDisplay = (strtotime($controlDate) >= strtotime($filterFrom)) ? true : false; + } + + // Filter by period - To + if (!empty($filterTo) && $dateToDisplay) { + $dateToDisplay = (strtotime($controlDate) <= strtotime($filterTo)) ? true : false; + } + + // Filter by Month + if (!empty($filterMonth) && $dateToDisplay) { + $dateToDisplay = (date('n', strtotime($controlDate)) == $filterMonth) ? true : false; + } + + // Filter by Year + if (!empty($filterYear) && $dateToDisplay) { + $dateToDisplay = (date('Y', strtotime($controlDate)) == $filterYear) ? true : false; + } + + if ($currentListSearch && $dateToDisplay) { + // Full Period with no weekdays selected, ongoing events + if ( + $only_startdate + && in_array($filterTime, array('1', '4')) + && in_array($date_get_datetime, $perioddates) + && strtotime($EnDate) >= strtotime($datetime_today) + && strtotime($StDate) <= strtotime($datetime_today) + ) { + $controlDate = $datetime_today; + } else { + $controlDate = $SingleDate; + } + + // (1) Filter Dates : Ongoing and Upcoming + if ($filterTime == 1) { + $dateToDisplay = (strtotime($controlDate) >= strtotime($date_today)) ? true : false; + } + // (2) Filter Dates : Past Dates + elseif ($filterTime == 2) { + $dateToDisplay = (strtotime($controlDate) < strtotime($datetime_today)) ? true : false; + } + // (3) Filter Dates : Upcoming + elseif ($filterTime == 3) { + $dateToDisplay = (strtotime($controlDate) > strtotime($datetime_today)) ? true : false; + } + // (4) Filter Dates : Ongoing Events today + elseif ($filterTime == 4) { + $dateToDisplay = ((strtotime($controlDate) >= strtotime($date_today)) + && (strtotime($controlDate) < (strtotime($date_today) + 86400))) ? true : false; + } + } + + if ($dateToDisplay) { + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } + } + + // Current Today and Upcoming Today + elseif ( + $filterTime == 4 + && strtotime($date_Dat) == strtotime($date_today) + ) { + if ( + $i_displaytime == 1 + && strtotime($date_Dat . ' ' . $time_enddate) >= strtotime($datetime_today) + ) { + $dp = ($datesDisplay == 2) ? $dp + 1 : 0; + + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } else { + $dp = ($datesDisplay == 2) ? $dp + 1 : 0; + + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } + } + + // Upcoming + elseif ( + $filterTime == 3 + && strtotime($SingleDate) > strtotime($datetime_today) + ) { + $dp = ($datesDisplay == 2) ? $dp + 1 : 0; + + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } + + // Past + elseif ( + $filterTime == 2 + && strtotime($date_Dat) < strtotime($date_today) + ) { + $dp = ($datesDisplay == 2) ? $dp + 1 : 0; + + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } + + // Current Today and Upcoming + elseif ($filterTime == 1) { + if ( + $i_displaytime == 1 + && strtotime($date_Dat . ' ' . $time_enddate) >= strtotime($datetime_today) + ) { + $dp = ($datesDisplay == 2) ? $dp + 1 : 0; + + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } elseif ( + $i_displaytime != 1 + && strtotime($date_Dat) >= strtotime($date_today) + ) { + $dp = ($datesDisplay == 2) ? $dp + 1 : 0; + + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } + } + + // No Filtering + elseif (!$filterTime) { + // All Upcoming dates + if (strtotime($SingleDate) >= strtotime($datetime_today)) { + $dp = ($datesDisplay == 2) ? $dp + 1 : 0; + $no_filtering = ($datesDisplay == 2) ? $no_filtering + 1 : 0; + + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } + + // If no Upcoming dates, get the last date + elseif ( + $no_filtering == 0 && $datesDisplay == 2 + && strtotime($SingleDate) < strtotime($datetime_today) + ) { + $dp = $dp + 1; + + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } + + // If display All Dates, get the last dates + elseif ( + $datesDisplay == 1 + && strtotime($SingleDate) < strtotime($datetime_today) + ) { + $dp = 0; + + $AllDatesDisplay[] = $data_SingleDate . '_' . $i_id; + } + } + } + } + } + } + + // If not All Dates display (select only one date for each event) + if ( + $datesDisplay == 2 + && count($AllDatesDisplay) > 0 + ) { + $ex_min = explode('_', min($AllDatesDisplay)); + $min_datetime = JHtml::date($ex_min[0], 'Y-m-d H:i', null); + $min_date = JHtml::date($ex_min[0], 'Y-m-d', null); + + $ex_max = explode('_', max($AllDatesDisplay)); + $max_date = JHtml::date($ex_max[0], 'Y-m-d H:i', null); + + if ($filterTime != '4') { + // Past Events and max date is upcoming + if ( + $filterTime == '2' + && $hasUpcomingDate + ) { + $AllDatesDisplay = array(); + } + + // min date is today or upcoming + elseif ( + $filterTime == '1' + && $min_datetime >= $date_today + ) { + $AllDatesDisplay = array(min($AllDatesDisplay)); + } + + // min date is upcoming + elseif ($min_datetime >= $datetime_today) { + $AllDatesDisplay = array(min($AllDatesDisplay)); + } + + // All events + elseif ($filterTime == '0') { + // min date in Period and upcoming + if ( + in_array($min_datetime, $period_array) + && $min_datetime >= $datetime_today + ) { + $AllDatesDisplay = array(min($AllDatesDisplay)); + } + + // min date is Single date and not past + elseif ( + !in_array($min_datetime, $period_array) + && ($min_datetime > $datetime_today) + ) { + $AllDatesDisplay = array(min($AllDatesDisplay)); + } + + // min date is Single date and past + else { + $AllDatesDisplay = array(max($AllDatesDisplay)); + } + } else { + $AllDatesDisplay = array(max($AllDatesDisplay)); + } + } else { + $AllDatesDisplay = array(min($AllDatesDisplay)); + } + } + + $AllDatesFilterTime = array(); + + + foreach ($AllDatesDisplay as $fD) { + $ex_date = explode('_', $fD); + $get_date = $ex_date['0']; + $date_get_date = JHtml::date($get_date, 'Y-m-d', $eventTimeZone); + $date_get_datetime = JHtml::date($get_date, 'Y-m-d H:i', $eventTimeZone); + $data_date_get_date = date('Y-m-d', strtotime($get_date)); + + // Frontend Filtering + if ( + !empty($filterFrom) + || !empty($filterTo) + || !empty($filterMonth) + || !empty($filterYear) + || !empty($search) + ) { + $dateToDisplay = true; + $controlDate = $date_get_date; + + // Filter by period - From + if (!empty($filterFrom) && $dateToDisplay) { + $dateToDisplay = (strtotime($controlDate) >= strtotime($filterFrom)) ? true : false; + } + + // Filter by period - To + if (!empty($filterTo) && $dateToDisplay) { + $dateToDisplay = (strtotime($controlDate) <= strtotime($filterTo)) ? true : false; + } + + // Filter by Month + if (!empty($filterMonth) && $dateToDisplay) { + $dateToDisplay = (date('n', strtotime($controlDate)) == $filterMonth) ? true : false; + } + + // Filter by Year + if (!empty($filterYear) && $dateToDisplay) { + $dateToDisplay = (date('Y', strtotime($controlDate)) == $filterYear) ? true : false; + } + + if ($currentListSearch) { + // Full Period with no weekdays selected, ongoing events + if ( + $only_startdate + && in_array($filterTime, array('1', '4')) + && in_array($date_get_datetime, $perioddates) + && strtotime($EnDate) >= strtotime($datetime_today) + && strtotime($StDate) <= strtotime($datetime_today) + ) { + $controlDate = $datetime_today; + } else { + $controlDate = $date_get_datetime; + } + + // (1) Filter Dates : Ongoing and Upcoming + if ($filterTime == 1) { + $dateToDisplay = (strtotime($controlDate) >= strtotime($date_today)) ? true : false; + } + // (2) Filter Dates : Past Dates + elseif ($filterTime == 2) { + $dateToDisplay = (strtotime($controlDate) < strtotime($datetime_today)) ? true : false; + } + // (3) Filter Dates : Upcoming + elseif ($filterTime == 3) { + $dateToDisplay = (strtotime($controlDate) > strtotime($datetime_today)) ? true : false; + } + // (4) Filter Dates : Ongoing Events today + elseif ($filterTime == 4) { + $dateToDisplay = ((strtotime($controlDate) >= strtotime($date_today)) + && (strtotime($controlDate) < (strtotime($date_today) + 86400))) ? true : false; + } + } + + if ($dateToDisplay) { + $AllDatesFilterTime[] = $fD; + } + } + + // (0) Filter Dates : All Dates + elseif ($filterTime == 0) { + // Period with no weekdays selected + if ( + in_array($get_date, $perioddates) + && $only_startdate + && !in_array($StDate . '_' . $i_id, $AllDatesFilterTime) + ) { + $AllDatesFilterTime[] = $data_StDate . '_' . $i_id; + } + + // Period with weekdays selected + elseif ( + in_array($get_date, $perioddates) + && !$only_startdate + ) { + $AllDatesFilterTime[] = $fD; + } + + // Single Dates + elseif (!in_array($get_date, $perioddates)) { + $AllDatesFilterTime[] = $fD; + } + } + + // (1) Filter Dates : Ongoing and Upcoming + elseif ($filterTime == 1) { + // Period with no weekdays selected + if ( + in_array($get_date, $perioddates) + && $only_startdate + && strtotime($EnDate) >= strtotime($datetime_today) + && !in_array($StDate . '_' . $i_id, $AllDatesFilterTime) + ) { + $AllDatesFilterTime[] = $data_StDate . '_' . $i_id; + } + + // Period with weekdays selected + elseif ( + in_array($get_date, $perioddates) + && !$only_startdate + ) { + // If display time, control end time of the day + if ( + $i_displaytime == 1 + && strtotime($date_get_date . ' ' . $time_enddate) >= strtotime($datetime_today) + ) { + $AllDatesFilterTime[] = $fD; + } + + // If do not display time, control start time of the day + elseif ( + $i_displaytime != 1 + && strtotime($date_get_date) >= strtotime($date_today) + ) { + $AllDatesFilterTime[] = $fD; + } + } + + // Single Dates + elseif ( + !in_array($get_date, $perioddates) + // && strtotime($get_date) >= strtotime($datetime_today) + // Changed because single dates have no end time, so admitted end time is midnight. + && strtotime($get_date) >= strtotime($date_today) + ) { + $AllDatesFilterTime[] = $fD; + } + } + + // (2) Filter Dates : Past Dates + elseif ($filterTime == 2) { + // Period with no weekdays selected + if ( + in_array($get_date, $perioddates) + && $only_startdate + && (strtotime($EnDate) < strtotime($datetime_today)) + ) { + $AllDatesFilterTime[] = $fD; + } + + // Period with weekdays selected + elseif ( + in_array($get_date, $perioddates) + && !$only_startdate + && strtotime($get_date) < strtotime($datetime_today) + && strtotime($date_get_date . ' ' . $time_enddate) < strtotime($datetime_today) + ) { + $AllDatesFilterTime[] = $fD; + } + + // Single Dates + elseif ( + !in_array($get_date, $perioddates) + && strtotime($get_date) < strtotime($datetime_today) + ) { + $AllDatesFilterTime[] = $fD; + } + } + + // (3) Filter Dates : Upcoming + elseif ($filterTime == 3) { + // Period with no weekdays selected + if ( + in_array($get_date, $perioddates) + && $only_startdate + && (strtotime($StDate) > strtotime($datetime_today)) + ) { + $AllDatesFilterTime[] = $fD; + } + + // Period with weekdays selected + elseif ( + in_array($get_date, $perioddates) + && !$only_startdate + && strtotime($get_date) > strtotime($datetime_today) + && strtotime($date_get_date . ' ' . $time_startdate) > strtotime($datetime_today) + ) { + $AllDatesFilterTime[] = $fD; + } + + // Single Dates + elseif ( + !in_array($get_date, $perioddates) + && strtotime($get_date) > strtotime($datetime_today) + ) { + $AllDatesFilterTime[] = $fD; + } + } + + // (4) Filter Dates : Ongoing Events today + elseif ($filterTime == 4) { + // Period with no weekdays selected + if ( + in_array($get_date, $perioddates) + && $only_startdate + && strtotime($EnDate) > strtotime($datetime_today) + && strtotime($StDate) < (strtotime($date_today) + 86400) + ) { + $AllDatesFilterTime[] = $data_date_get_date . ' ' . $data_time_startdate . '_' . $i_id; + } + + // Period with weekdays selected + elseif ( + in_array($get_date, $perioddates) + && !$only_startdate + && (strtotime($date_get_date) == strtotime($date_today) + && strtotime($date_get_date . ' ' . $time_enddate) < (strtotime($date_today) + 86400)) + ) { + $AllDatesFilterTime[] = $fD; + } + + // Single Dates + elseif ( + !in_array($get_date, $perioddates) + // && ( strtotime($get_date) >= strtotime($datetime_today) + // Changed because single dates have no end time, so admitted end time is midnight. + && (strtotime($get_date) >= strtotime($date_today) + && strtotime($get_date) < (strtotime($date_today) + 86400)) + ) { + $AllDatesFilterTime[] = $fD; + } + } + } + + $list_all_dates = array_merge($list_all_dates, $AllDatesFilterTime); + } + + if ($orderby == 2) { + sort($list_all_dates); + } else { + rsort($list_all_dates); + } + + return $list_all_dates; + } + + /** + * Get and update NEXT DATE + * + * @since 3.5.4 + */ + + public static function getNext() + { + $app = JFactory::getApplication(); + $params = $app->getParams(); + + // Get Settings + $filterTime = $params->get('time', 1); + + // Set vars + $nodate = '0000-00-00 00:00:00'; + $eventTimeZone = null; + $datetime_today = JHtml::date('now', 'Y-m-d H:i:s'); // Joomla Time Zone + $date_today = JHtml::date('now', 'Y-m-d'); // Joomla Time Zone + $time_today = JHtml::date('now', 'H:i:s'); // Joomla Time Zone + + // Preparing connection to db + $db = Jfactory::getDbo(); + + // Preparing the query + $query = $db->getQuery(true); + + $query->select('next AS tNext, dates AS tDates, startdate AS tStartdate, enddate AS tEnddate, + weekdays AS tWeekdays, id AS tId, state AS tState, access AS tAccess'); + $query->from('#__icagenda_events AS e'); + // $query->where(' e.state = 1 OR e.state = 0 '); + $query->where('e.state = 1'); + $query->where('e.next < ' . $db->quote($datetime_today) . ' AND e.next > (DATE(NOW() - INTERVAL 2 MONTH))'); + // $query->where('e.next < ' . $db->quote($datetime_today)); + $db->setQuery($query); + + $all_next_dates = $db->loadObjectList(); + + foreach ($all_next_dates as $nd) { + $nd_next = $nd->tNext; + $nd_id = $nd->tId; + $nd_state = $nd->tState; + $nd_dates = $nd->tDates; + $nd_startdate = $nd->tStartdate; + $nd_enddate = $nd->tEnddate; + $nd_weekdays = $nd->tWeekdays; + + // If Single Dates, added to all dates for this event + $singleDates = iCString::isSerialized($nd_dates) ? unserialize($nd_dates) : array(); + + $AllDates = array(); + + // Get WeekDays Array + $WeeksDays = iCDatePeriod::weekdaysToArray($nd_weekdays); + + if ( + isset($singleDates) + && $singleDates != NULL + && !in_array($nodate, $singleDates) + && !in_array('', $singleDates) + ) { + $AllDates = array_merge($AllDates, $singleDates); + } elseif (in_array('', $singleDates)) { + $datesarray = array(); + $nodate = array('0000-00-00 00:00'); + $datesmerger = array_push($datesarray, $nodate); + $DatesUpdate = serialize($nodate); + + $query = $db->getQuery(true); + $query->update('#__icagenda_events'); + $query->set("dates='" . (string)$DatesUpdate . "'"); + $query->where('id=' . (int)$nd_id); + $db->setQuery($query); + $db->query($query); + + $nosingledates = unserialize($DatesUpdate); + $AllDates = array_merge($AllDates, $nosingledates); + } + + $StDate = date('Y-m-d H:i', strtotime($nd_startdate)); + $EnDate = date('Y-m-d H:i', strtotime($nd_enddate)); + + $date_enddate = date('Y-m-d', strtotime($nd_enddate)); + $time_enddate = date('H:i', strtotime($nd_enddate)); + $date_startdate = date('Y-m-d', strtotime($nd_startdate)); + $time_startdate = date('H:i', strtotime($nd_startdate)); + + $perioddates = iCDatePeriod::listDates($nd_startdate, $nd_enddate); + + $only_startdate = ($nd_weekdays || $nd_weekdays == '0') ? false : true; + + if ( + isset($perioddates) + && $perioddates != NULL + ) { + // Period with no weekdays in Upcoming and Past options + if ( + $only_startdate + && ($filterTime == '3' || $filterTime == '2') + ) { + array_push($AllDates, $StDate); + } else { + foreach ($perioddates as $Dat) { + if (in_array(date('w', strtotime($Dat)), $WeeksDays)) { + $date_Dat = date('Y-m-d', strtotime($Dat)); + $SingleDate = date('Y-m-d H:i', strtotime($Dat)); + + if ($date_Dat == $date_today && $filterTime != 3) { + // Next in Period is today, so set end time + array_push($AllDates, $date_Dat . ' ' . $time_startdate); + } else { + array_push($AllDates, $SingleDate); + } + } + } + } + } + + rsort($AllDates); + + if ($AllDates == NULL) { + $next = '0000-00-00 00:00:00'; + } else { + $date_lastdate = date('Y-m-d', strtotime($AllDates[0])); + $datetime_lastdate = date('Y-m-d H:i:s', strtotime($AllDates[0])); + + $date_startdate = date('Y-m-d', strtotime($nd_startdate)); + $date_enddate = date('Y-m-d', strtotime($nd_enddate)); + + $time_startdate = date('H:i:s', strtotime($nd_startdate)); + $time_enddate = date('H:i:s', strtotime($nd_enddate)); + + $returnNext = $nd_next; + + $next_is_set = '0'; + + $today_upcoming_SD = '0'; + $upcoming_SD = '0'; + + foreach ($AllDates as $a) { + $tsdate_a = date('Y-m-d', strtotime($a)); + + if ($tsdate_a == $date_today) { + // All single dates today and not yet started + $today_upcoming_SD = (strtotime($a) > strtotime($datetime_today)) ? ($today_upcoming_SD + 1) : $today_upcoming_SD; + } + + if ($tsdate_a >= $datetime_today) { + // All upcoming single dates + $upcoming_SD = $upcoming_SD + 1; + } + } + + $total_today_SD = $today_upcoming_SD; + + foreach ($AllDates as $a) { + $tsdatetime_a = date('Y-m-d H:i:s', strtotime($a)); + $tsdate_a = date('Y-m-d', strtotime($a)); + + // Only past single dates + if ( + $datetime_lastdate < $datetime_today + && $date_lastdate != $date_today + && $next_is_set == '0' + ) { + $returnNext = date('Y-m-d H:i:s', strtotime($AllDates[0])); + $next_is_set = $next_is_set + 1; + } + + // The last date is today + elseif ( + $date_lastdate == $date_today + && $next_is_set == '0' + && $total_today_SD == 1 + ) { + // Period divided into days + if ( + $nd_startdate != $nodate + && $nd_enddate != $nodate + && in_array($a, $perioddates) + && !$only_startdate + ) { + $returnNext = date('Y-m-d', strtotime($nd_enddate)) . ' ' . $time_startdate; + $next_is_set = $next_is_set + 1; + } + + // Full period (from ... to ...) + elseif ( + $nd_startdate != $nodate + && $nd_enddate != $nodate + && in_array($a, $perioddates) + && $only_startdate + ) { + $returnNext = date('Y-m-d', strtotime($nd_startdate)) . ' ' . $time_startdate; + $next_is_set = $next_is_set + 1; + } + + // Single date + else { + if ($datetime_lastdate > $datetime_today) { + $today_upcoming_SD = $today_upcoming_SD - 1; + } + + if ( + $datetime_lastdate > $datetime_today + && $today_upcoming_SD == '0' + ) { + $returnNext = date('Y-m-d H:i:s', strtotime($AllDates[0])); + $next_is_set = $next_is_set + 1; + } + } + } + + // Multiple upcoming single dates + // elseif ($tsdatetime_a > $datetime_today) + // Changed because single dates have no end time, so admitted end time is midnight. + elseif ( + $tsdatetime_a > $date_today + && $next_is_set == '0' + ) { + // Remaining Today's upcoming dates + if ($tsdate_a == $date_today) { + if ($tsdatetime_a > $datetime_today) { + $today_upcoming_SD = $today_upcoming_SD - 1; + } + } + + // Remaining Upcoming dates + if ($tsdate_a >= $datetime_today) { + $upcoming_SD = $upcoming_SD - 1; + } + + if ( + $today_upcoming_SD == '0' + && $upcoming_SD == '0' + ) { + $returnNext = date('Y-m-d H:i:s', strtotime($a)); + $next_is_set = $next_is_set + 1; + } + } + } + + // Test End Date if Next Date or Last Date (3.1.5) + $date_returnNext = date('Y-m-d', strtotime($returnNext)); + $time_returnNext = date('H:i:s', strtotime($returnNext)); + + if (($date_enddate != '0000-00-00') + && ($date_today == $date_enddate || $date_today == $date_returnNext) + ) { + $time_LastTime = $time_startdate; + } else { + $time_LastTime = $time_returnNext; + } + + // Fix 3.1.12 (removed isset($tPeriod)) + if (($nd_enddate != $nodate) + && ($date_startdate < $date_today) + && ($date_enddate == $date_today) + && ($time_LastTime >= $time_today) + ) { + $returnNextPediod = date('Y-m-d', strtotime($nd_enddate)) . ' ' . $time_startdate; + } else { + $returnNextPediod = $returnNext; + } + + // Set next var + if (($date_returnNext == $date_enddate) + && ($date_enddate == $date_today) + ) { + $next = $returnNextPediod; + } elseif ( + strtotime($date_startdate) < strtotime($date_today) + && strtotime($date_enddate) >= strtotime($date_today) + && strtotime($time_enddate) != strtotime($time_returnNext) + && strtotime($time_LastTime) > strtotime($time_today) + ) { + $next = $date_returnNext . ' ' . date('H:i:s', strtotime($time_LastTime)); + } else { + $next = $returnNext; + } + } + // 3.1.12 Fixed and update events with bug + if ( + $nd_next == $nodate + && $nd_state == 0 + && $nd_startdate != $nodate + && $nd_enddate != $nodate + && strtotime($nd_enddate) >= strtotime($nd_startdate) + ) { + $next = $returnNext; + + $query = $db->getQuery(true); + $query->update('#__icagenda_events'); + $query->set('state=1'); + $query->where('id=' . (int)$nd_id); + $db->setQuery($query); + $db->query($query); + } + + if ($next != $nd_next) { + $query = $db->getQuery(true); + $query->update('#__icagenda_events'); + $query->set("next='" . $next . "'"); + $query->where('id=' . (int)$nd_id); + $db->setQuery($query); + $db->query($query); + } + } + } + + /** + * Returns the element of a SQL query WHERE clause to support filtering the selection of Events using Event Features + * + * Controlled by menu parameters: + * features_filter - array of Feature IDs + * features_incl_excl - indicates whether the Feature IDs are to be used to include or exclude Events + * features_any_all - indicates whether any Feature ID or all Feature IDs required to include or exclude an Event + * + * One or more sub-queries is referenced in a WHERE clause with IN() or NOT IN() to include or exclude Events. + * + * If any Feature ID in isolation is to include or exclude Event records then a single sub-query is used that + * uses a simple inner join between the feature and feature_xref tables to identify the distinct set of Event IDs + * linked to any one of the spacific Feature IDs. + * + * If all Feature IDs combined are required to include or exclude Events then separate sub-queries are used for + * each of the spacific Feature IDs. For this case, a more efficient option is available involving a direct join + * with either an inner or outer join, according to whether records are being included or excluded but this + * puts an unreasonable constraint on the overall syntax of the query. + */ + public static function getFeaturesFilter($params = null) + { + // Get the params + if (!$params) { + $app = JFactory::getApplication(); + $params = $app->getParams(); + } + + // Initialise a return value that can be included harmlessly in a WHERE clause, if necessary + $filter = ' TRUE '; + $featureids = $params->get('features_filter', ''); + + if (is_array($featureids) && !empty($featureids)) { + $db = Jfactory::getDbo(); + $incl_excl = $params->get('features_incl_excl', '1') == '1' ? '' : 'NOT'; + + if ($params->get('features_any_all', '1') == '1') { + // Any single Feature ID will include or exclude events + // Create comma separated list of Feature IDs + $featureids = implode(',', $featureids); + // Create a single sub-query + $sub_query = $db->getQuery(true); + $sub_query->select('fx.event_id') + ->from('#__icagenda_feature_xref AS fx') + ->innerJoin("#__icagenda_feature AS f ON fx.feature_id=f.id AND f.state=1 AND f.show_filter=1 AND f.id IN($featureids)"); + // Join the sub-query to the main query + $filter = "(e.id $incl_excl IN(" . (string) $sub_query . '))'; + } else { + // All Feature IDs combined will include or exclude events + // Create a separate sub-query for each of the Feature IDs + $sub_queries = array(); + + foreach ($featureids as $featureid) { + $sub_query = $db->getQuery(true); + $sub_query->select('fx.event_id') + ->from('#__icagenda_feature_xref AS fx') + ->innerJoin("#__icagenda_feature AS f ON fx.feature_id=f.id AND f.state=1 AND f.show_filter=1 AND f.id=$featureid"); + $sub_queries[] = "e.id $incl_excl IN(" . (string) $sub_query . ')'; + } + + // Combine the sub-queries depending on inclusion or exclusion of events + $filter = "(" . implode($incl_excl == 'NOT' ? " \nOR " : " \nAND ", $sub_queries) . ')'; + } + } + + return $filter; + } + + /** + * Return Array of all registrations from an event (date@@people) + * date : registered date + * people : nb of tickets for this registration + * + * @since 3.5.0 + * @version 3.6.6 + */ + public static function registeredList($id = null) + { + // Registrations total + $db = Jfactory::getDbo(); + $query = $db->getQuery(true); + $query->select('r.date AS date, r.period AS period, r.eventid AS eventid, r.people AS people'); + $query->from('#__icagenda_registration AS r'); + $query->where('r.state = 1'); + + if ($id) { + $query->where('r.eventid = ' . $db->q($id)); + } + + $db->setQuery($query); + $result = $db->loadObjectList(); + + $registeredList = array(); + + foreach ($result as $r) { + $reg_date = $r->date ? $r->date : 'period'; + $registeredList[] = $r->eventid . '@@' . $reg_date . '@@' . $r->period . '@@' . $r->people; + } + + return $registeredList; + } + + /** + * Return list of all dates (singles and period) from an event + * + * @since 3.5.0 (Not Yet Used) + */ + public static function thisEventDates($id) + { + // Set vars + $nodate = '0000-00-00 00:00:00'; + $ic_nodate = '0000-00-00 00:00'; + $eventTimeZone = null; + + // Get Data + $db = Jfactory::getDbo(); + $query = $db->getQuery(true); + $query->select('e.next, e.dates, e.startdate, e.enddate, e.period, e.weekdays, e.displaytime, e.id'); + $query->from('#__icagenda_events AS e'); + $query->leftJoin('#__icagenda_category AS c ON c.id = e.catid'); + $query->where('c.state = 1'); + $query->where('e.id = ' . $db->q($id)); + $db->setQuery($query); + $result = $db->loadObjectList(); + + // Get Data + $tId = $id; + $tDates = $result->dates; + $tStartdate = $result->startdate; + $tEnddate = $result->enddate; + $tWeekdays = $result->weekdays; + + // Declare AllDates array + $thisEventDates = array(); + + // Get WeekDays Array + $WeeksDays = iCDatePeriod::weekdaysToArray($tWeekdays); + + // If Single Dates, added each one to All Dates for this event + $singledates = unserialize($tDates); + + foreach ($singledates as $sd) { + $isValid = iCDate::isDate($sd); + + if ($isValid) { + array_push($thisEventDates, $sd); + } + } + + $perioddates = iCDatePeriod::listDates($tStartdate, $tEnddate, $eventTimeZone); + + if ( + isset($perioddates) + && $perioddates != NULL + ) { + foreach ($perioddates as $Dat) { + if (in_array(date('w', strtotime($Dat)), $WeeksDays)) { + $isValid = iCDate::isDate($Dat); + + if ($isValid) { + $SingleDate = date('Y-m-d H:i:s', strtotime($Dat)); + + array_push($thisEventDates, $SingleDate); + } + } + } + } + + return $thisEventDates; + } + + public static function getAllTimeZone($decrease = 0) + { + $zones_array = array(); + $timestamp = strtotime('-1 hour'); + foreach (timezone_identifiers_list() as $key => $zone) { + date_default_timezone_set($zone); + $zones_array[$key]['zone'] = $zone; + $zones_array[$key]['offset'] = (int) ((int) date('O', $timestamp)) / 100 - $decrease; + $zones_array[$key]['diff_from_GMT'] = 'GMT' . date('P', $timestamp); + $zones_array[$key]['id'] = date('O', $timestamp) / 100 - $decrease . '_' . $zone; + } + + return $zones_array; + } + + public static function changeDate($offset = 0, &$nextDate, &$endDate) + { + if ($offset != 0) { + if (strpos($offset, '.3') !== false || strpos($offset, '.45') !== false) { + if (strpos($offset, '.3') !== false) + $offset .= '0'; + + $prefix = substr($offset, 0, 1) == '-' ? '-' : '+'; + $minuteOffset = $text = explode('.', $offset, 2); + + $nextDate = new DateTime($nextDate); + $nextDate->modify($minuteOffset[0] . ' hours'); + $nextDate->modify($prefix . $minuteOffset[1] . ' minutes'); + + $endDate = new DateTime($endDate); + $endDate->modify($minuteOffset[0] . ' hours'); + $endDate->modify($prefix . $minuteOffset[1] . ' minutes'); + } else { + $nextDate = new DateTime($nextDate); + $nextDate->modify($offset . ' hours'); + + $endDate = new DateTime($endDate); + $endDate->modify($offset . ' hours'); + } + + $nextDate = $nextDate->format('Y-m-d H:i:s'); + $endDate = $endDate->format('Y-m-d H:i:s'); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/events/event.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/events/event.php new file mode 100644 index 00000000..7c2fef44 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/events/event.php @@ -0,0 +1,1277 @@ +next) + || ($item->next <= JHtml::date('now', 'Y-m-d H:i:s') + || ! iCDate::isDate($item->next)) + ) + { + $reset = true; + } + + if ($reset) + { + $next_singleDates = $last_singleDates = ''; + $next_period = $last_period = ''; + + // Single Dates Check + $singleDates = iCString::isSerialized($item->dates) ? unserialize($item->dates) : array(); + + $upcomingSingleDates = array_filter( + $singleDates, + function($date) + { + return $date >= JHtml::date('now', 'Y-m-d H:i:s'); + } + ); + + if (count($upcomingSingleDates) > 0) + { + $next_singleDates = min($upcomingSingleDates); + $next_singleDates = iCDate::isDate($next_singleDates) ? $next_singleDates : ''; + } + else + { + $pastSingleDates = array_filter( + $singleDates, + function ($date) + { + return $date < JHtml::date('now', 'Y-m-d H:i:s'); + } + ); + + if (count($pastSingleDates) > 0) + { + $last_singleDates = max($pastSingleDates); + $last_singleDates = iCDate::isDate($last_singleDates) ? $last_singleDates : ''; + } + } + + + // Period Check + $weekdays = ! is_array($item->weekdays) ? explode(",", $item->weekdays) : $item->weekdays; + + if (count($weekdays) > 0) + { + $period_all_dates_array = iCDatePeriod::listDates($item->startdate, $item->enddate); + + $period_array = array(); + + foreach ($period_all_dates_array AS $date_in_weekdays) + { + $datetime_period_date = JHtml::date($date_in_weekdays, 'Y-m-d H:i', $eventTimeZone); + + if (in_array(date('w', strtotime($datetime_period_date)), $weekdays)) + { + $period_array[] = $datetime_period_date; + } + } + + $upcomingPeriodDates = array_filter( + $period_array, + function($date) + { + return $date >= JHtml::date('now', 'Y-m-d H:i:s'); + } + ); + + if (count($upcomingPeriodDates) > 0) + { + $next_period = min($upcomingPeriodDates); + $next_period = iCDate::isDate($next_period) ? $next_period : ''; + } + else + { + $last_period = iCDate::isDate($item->startdate) ? $item->startdate : ''; + } + } + else + { + if ($item->startdate >= JHtml::date('now', 'Y-m-d H:i:s')) + { + $next_period = iCDate::isDate($item->startdate) ? $item->startdate : ''; + } + elseif ($item->enddate >= JHtml::date('now', 'Y-m-d H:i:s')) + { + $next_period = iCDate::isDate($item->startdate) ? $item->startdate : ''; + } + else + { + $last_period = iCDate::isDate($item->startdate) ? $item->startdate : ''; + } + } + + + // Return Next + if ($next_singleDates && $next_period) + { + $next = min($next_singleDates, $next_period); + } + elseif ($next_singleDates) + { + $next = $next_singleDates; + } + elseif ($next_period) + { + $next = $next_period; + } + else + { + $next = max($last_singleDates, $last_period); + } + + if ($item->next != $next) + { + $item->next = $next; + + $db = Jfactory::getDbo(); + $query = $db->getQuery(true); + + $query->update('#__icagenda_events') + ->set($db->qn('next') . ' = ' . $db->q($next)) + ->where($db->qn('id') . ' = ' . (int) $item->id); + + $db->setQuery($query); + $db->query($query); + } + } + + return $item->next; + } + + /** + * Function to get Event Params + * + * @return JRegistry Event Params + * + * @since 3.6.0 + */ + public static function evtParams($params) + { + $evtParams = new JRegistry($params); + + return $evtParams; + } + + /** + * Function to return the back arrow button (No item needed) + * + * @return HTML + * + * @since 3.6.0 + */ + public static function backArrow($item = null) + { + $app = JFactory::getApplication(); + $jinput = $app->input; + $jview = $jinput->get('view'); + + // Get Current Itemid + $this_itemid = $jinput->getInt('Itemid', 0); + + // TODO: Remove jlayout control (3.6) + $jlayout = $jinput->get('layout', ''); + $layouts_array = array('event', 'registration'); + $layout = in_array($jlayout, $layouts_array) ? $jlayout : ''; + + $manageraction = $jinput->get('manageraction', ''); + $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; + + // RTL css if site language is RTL + $lang = JFactory::getLanguage(); + $back_icon = ($lang->isRTL()) ? 'iCicon iCicon-nextic' : 'iCicon iCicon-backic'; + + if ( ($layout != '' || $jview == 'event') + && strpos($referer,'registration') === false + && ! $manageraction) + { + if ($referer != "") + { + $BackArrow = ''; + } + else + { + $BackArrow = ''; + } + } + elseif ($manageraction || strpos($referer,'registration') !== false) + { + $BackArrow = ''; + } + else + { + $BackArrow = ''; + } + + // Header Message if event cancelled + $evtParams = self::getParams($item->id); + $cancellation_info = ''; + + if ($evtParams->get('event_cancelled')) + { + $text = JText::_('COM_ICAGENDA_EVENT_CANCELLED_TEXT'); + $description = $evtParams->get('event_cancelled_desc'); + + if ($evtParams->get('event_cancelled_customlabel')) + { + $text = JText::_($evtParams->get('event_cancelled_customlabel_text', 'COM_ICAGENDA_EVENT_CANCELLED_TEXT')); +// $class = $evtParams->get('event_cancelled_customlabel_css', $class); + } + + $cancellation_info = '
    ' + . '

    ' . $text . '

    ' + . '
    ' . $description . '
    ' + . '
    '; + } + + return $BackArrow . $cancellation_info; + } + + /** + * Set event Url + * + * @since 3.6.0 + */ + public static function url($id, $alias = null) + { + $app = JFactory::getApplication(); + $isSef = $app->getCfg('sef'); + $jinput = $app->input; + + $menuID = $jinput->get('Itemid', 0); + $date = $jinput->get('date', ''); + $view = $jinput->get('view', ''); + + // Get var 'event_date' set to session in event details view + $session = JFactory::getSession(); + $event_date = $session->get('event_date', ''); + + $event_slug = empty($alias) ? (int) $id : (int) $id . ':' . $alias; + $this_date = $event_date ? date('Y-m-d-H-i', strtotime($event_date)) : $date; + + $url = JRoute::_('index.php?option=com_icagenda&view=event&id=' . $event_slug . '&Itemid=' . (int) $menuID); + + if (is_numeric($menuID) && is_numeric($id) + && ! is_array($menuID) && ! is_array($id)) + { + $date_var = ($isSef == '1') ? '?date=' : '&date='; + $url = ($view != 'list' && $this_date) ? $url . $date_var . $this_date : $url; + } + else + { + $url = JRoute::_('index.php'); + } + + return $url; + } + + /** + * Title + Manager Icons + * + * @since 3.6.0 + * @todo Review and split into sub-functions + */ + public static function titleBar($i) + { + $jinput = JFactory::getApplication()->input; + + $this_itemid = $jinput->getInt('Itemid'); + $list_title_length = (int) JComponentHelper::getParams('com_icagenda')->get('list_title_length', ''); + + $i_title = icagendaRender::titleToFormat($i->title); + + $jlayout = $jinput->get('layout', ''); + $layouts_array = array('event', 'registration'); + $layout = in_array($jlayout, $layouts_array) ? $jlayout : ''; + + $mbString = extension_loaded('mbstring'); + + $title_length = $mbString ? mb_strlen($i_title, 'UTF-8') : strlen($i_title); + + if (empty($layout) + && ! empty($list_title_length)) + { + $title = $mbString + ? trim(mb_substr($i_title, 0, $list_title_length, 'UTF-8')) + : trim(substr($i_title, 0, $list_title_length)); + + $new_title_length = $mbString ? mb_strlen($title, 'UTF-8') : strlen($title); + + if ($new_title_length < $title_length) + { + $title.= '...'; + } + } + else + { + $title = $i_title; + } + + $approval = $i->approval; + + $event_slug = empty($i->alias) ? $i->id : $i->id . ':' . $i->alias; + + // Set Manager Actions Url + $managerActionsURL = 'index.php?option=com_icagenda&view=event&id=' . $event_slug . '&Itemid=' . $this_itemid; + + $unapproved = ''; + + $titleBar = ''; + + if ($title != NULL && $approval == 1) + { + $titleBar.= $title . ' ' . $unapproved; + } + elseif ($title != NULL && $approval != 1) + { + $titleBar.= $title; + } + + $eventIsCancelled = self::cancelledButton($i->id, 'btn btn-danger'); + + if ($eventIsCancelled) + { + $titleBar.= ' ' . $eventIsCancelled; + } + + return $titleBar; + } + + /** + * Return Event Cancelled button with infotip + * + * @since 3.7.12 + */ + public static function cancelledButton($id, $class = 'label label-important') + { + $evtParams = self::getParams($id); + + if ($evtParams->get('event_cancelled')) + { + $language = JFactory::getLanguage(); + $language->load('com_icagenda', JPATH_SITE, 'en-GB', false, true); + $language->load('com_icagenda', JPATH_SITE, null, true); + + $text = JText::_('COM_ICAGENDA_EVENT_CANCELLED_TEXT'); + $description = $evtParams->get('event_cancelled_desc'); + + if ($evtParams->get('event_cancelled_customlabel')) + { + $text = JText::_($evtParams->get('event_cancelled_customlabel_text', 'COM_ICAGENDA_EVENT_CANCELLED_TEXT')); + $class = $evtParams->get('event_cancelled_customlabel_css', $class); + } + + $title = $tipclass = $position = ''; + + if (!empty($description)) + { + if ($text && $text !== $description) + { + JHtml::_('bootstrap.popover'); + $tipclass = ' hasPopover'; + $title = ' title="' . htmlspecialchars(trim($text, ':')) . '"' + . ' data-content="'. htmlspecialchars($description) . '"'; + + if (!$position && JFactory::getLanguage()->isRtl()) + { + $position = ' data-placement="left" '; + } + } + else + { + JHtml::_('bootstrap.tooltip'); + $tipclass = ' hasTooltip'; + $title = ' title="' . JHtml::_('tooltipText', trim($text, ':'), JText::_($description), 0) . '"'; + $position = 'top'; + } + } + + $cancelledButton = '' . $text . ''; + + return $cancelledButton; + } + + return false; + } + + /** + * Next Date Text + * + * @since 3.6.0 + */ + public static function dateText($i) + { + $eventTimeZone = null; + + $dates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); // returns array + $period = iCString::isSerialized($i->period) ? unserialize($i->period) : array(); // returns array + $weekdays = $i->weekdays; + $startdatetime = iCDate::isDate($i->startdate) ? date('Y-m-d H:i', strtotime($i->startdate)) : ''; + + $site_date = JHtml::date('now', 'Y-m-d'); + $site_datetime = JHtml::date('now', 'Y-m-d H:i'); + + $alldates_array = array_merge($dates, $period); + $alldates = array_filter($alldates_array, function($var) {return $var == iCDate::isDate($var);}); + + $next_date = date('Y-m-d', strtotime($i->next)); + $next_datetime = date('Y-m-d H:i', strtotime($i->next)); + + $next_is_in_period = in_array($next_datetime, $period) ? true : false; + + $totDates = count($alldates); + + if ($totDates > 1 + && $next_date > $site_date) + { + rsort($alldates); + + $last_date = JHtml::date($alldates[0], 'Y-m-d', $eventTimeZone); + + if ( ! $next_is_in_period + && $last_date == $next_date) + { + $dateText = JText::_('COM_ICAGENDA_EVENT_DATE_LAST'); + } + elseif ( ! $next_is_in_period) + { + $dateText = JText::_('COM_ICAGENDA_EVENT_DATE_FUTUR'); + } + elseif ($next_is_in_period + && $weekdays == NULL) + { + $dateText = JText::_('COM_ICAGENDA_LEGEND_DATES'); + } + else + { + $dateText = JText::_('COM_ICAGENDA_EVENT_DATE'); + } + } + elseif ($totDates > 1 + && $next_date < $site_date) + { + if ($totDates == 2) + { + $dateText = $next_is_in_period + ? JText::_('COM_ICAGENDA_EVENT_DATE') + : JText::_('COM_ICAGENDA_EVENT_DATE_PAST'); + } + else + { + $dateText = ($next_is_in_period && $weekdays == NULL) + ? JText::_('COM_ICAGENDA_LEGEND_DATES') + : JText::_('COM_ICAGENDA_EVENT_DATE_PAST'); + } + } + elseif ($next_date == $site_date) + { + $dateText = ($next_is_in_period && ($next_datetime < $site_datetime || $next_datetime != $startdatetime)) + ? JText::_('COM_ICAGENDA_EVENT_DATE_PERIOD_NOW') + : JText::_('COM_ICAGENDA_EVENT_DATE_TODAY'); + } + else + { + $dateText = JText::_( 'COM_ICAGENDA_EVENT_DATE' ); + } + + return $dateText; + } + + /** + * Get Next Date (or Last Date) + * + * @since 3.4.0 + */ + public static function nextDate($evt, $i) + { + $eventTimeZone = null; + +// $singledates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); // returns array + $period = iCString::isSerialized($i->period) ? unserialize($i->period) : array(); // returns array + $startdatetime = $i->startdate; + $enddatetime = $i->enddate; + $weekdays = $i->weekdays; + + $site_date = JHtml::date('now', 'Y-m-d'); + $UTC_today_date = JHtml::date('now', 'Y-m-d', $eventTimeZone); + + $next_date = JHtml::date($evt, 'Y-m-d', $eventTimeZone); + $next_datetime = JHtml::date($evt, 'Y-m-d H:i', $eventTimeZone); + + $start_date = JHtml::date($i->startdate, 'Y-m-d', $eventTimeZone); + $end_date = JHtml::date($i->enddate, 'Y-m-d', $eventTimeZone); + + // Check if date from a period with weekdays has end time of the period set in next. +// $time_next_datetime = JHtml::date($next_datetime, 'H:i', $eventTimeZone); + $time_next_datetime = date('H:i', strtotime($next_datetime)); + $time_startdate = JHtml::date($i->startdate, 'H:i', $eventTimeZone); + $time_enddate = JHtml::date($i->enddate, 'H:i', $eventTimeZone); + + $data_next_datetime = date('Y-m-d H:i', strtotime($evt)); + + if ($next_date == $site_date + && $time_next_datetime == $time_enddate) + { + $next_datetime = $next_date . ' ' . $time_startdate; + } + + if ($period != NULL + && in_array($data_next_datetime, $period)) + { + $next_is_in_period = true; + } + else + { + $next_is_in_period = false; + } + + // Highlight event in progress + if ($next_date == $site_date) + { + $start_span = ''; + $end_span = ''; + } + else + { + $start_span = $end_span = ''; + } + + $separator = ' - '; + + // Format Next Date + if ($next_is_in_period + && ($start_date == $end_date || $weekdays != null)) + { + // Next in the period & (same start/end date OR one or more weekday selected) + $nextDate = $start_span; + $nextDate.= ''; + $nextDate.= icagendaRender::dateToFormat($evt); + $nextDate.= ''; + + if ($i->displaytime == 1) + { + $nextDate.= ' ' . icagendaRender::dateToTime($i->startdate) . ''; + + if (icagendaRender::dateToTime($i->startdate) != icagendaRender::dateToTime($i->enddate)) + { + $nextDate.= $separator . '' . icagendaRender::dateToTime($i->enddate) . ''; + } + } + + $nextDate.= $end_span; + } + elseif ($next_is_in_period + && ($weekdays == null)) + { + // Next in the period & different start/end date & no weekday selected + $start = ''; + $start.= icagendaRender::dateToFormat($i->startdate); + $start.= ''; + + $end = ''; + $end.= icagendaRender::dateToFormat($i->enddate); + $end.= ''; + + if ($i->displaytime == 1) + { + $start.= ' ' . icagendaRender::dateToTime($i->startdate) . ''; + + $end.= ' ' . icagendaRender::dateToTime($i->enddate) . ''; + } + + $nextDate = $start_span . $start . $separator . $end . $end_span; + } + else + { + // Next is a single date + $nextDate = $start_span; + $nextDate.= ''; + $nextDate.= icagendaRender::dateToFormat($evt); + $nextDate.= ''; + + if ($i->displaytime == 1) + { + $nextDate.= ' ' . icagendaRender::dateToTime($evt) . ''; + } + + $nextDate.= $end_span; + } + + return $nextDate; + } + + /* + * Function to detect if info details exist in an event, + * and to hide or show it depending of Options (display and access levels) + * + * @since 3.6.0 + */ + public static function infoDetails($item, $CUSTOM_FIELDS) + { + // Hide/Show Option + $infoDetails = JComponentHelper::getParams('com_icagenda')->get('infoDetails', 1); + + // Access Levels Option + $accessInfoDetails = JComponentHelper::getParams('com_icagenda')->get('accessInfoDetails', 1); + + if ( ($infoDetails == 1 && icagendaEvents::accessLevels($accessInfoDetails)) + && ( ($item->params->get('statutReg', '') == '1' && $item->params->get('maxReg')) + || $item->phone + || $item->email + || $item->website + || $item->address + || $item->file + || $CUSTOM_FIELDS ) + ) + { + return true; + } + + return false; + } + + /* + * Function to return a list of all single dates, HTML formatted. + * TO BE REFACTORED + * + * @since 3.6.0 + */ + public static function displayListSingleDates($item) + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + $timeformat = JFactory::getApplication()->getParams()->get('timeformat', 1); + + // Hide/Show Option + $SingleDates = $iCparams->get('SingleDates', 1); + + // Access Levels Option (to be checked!) +// $accessSingleDates = $iCparams->get('accessSingleDates', 1); + + // Order by Dates + $SingleDatesOrder = $iCparams->get('SingleDatesOrder', 1); + + // List Model + $SingleDatesListModel = $iCparams->get('SingleDatesListModel', 1); + + if ($SingleDates == 1) + { +// if ($this->accessLevels($accessSingleDates)) +// { + $days = iCString::isSerialized($item->dates) ? unserialize($item->dates) : array(); // returns array + + if ($SingleDatesOrder == 1) + { + rsort($days); + } + elseif ($SingleDatesOrder == 2) + { + sort($days); + } + + $totDates = count($days); + + if ($timeformat == 1) + { + $lang_time = 'H:i'; + } + else + { + $lang_time = 'h:i A'; + } + + // Detect if Singles Dates, and no single date with null value + $displayDates = false; + $nbDays = count($days); + + foreach ($days as $k => $d) + { + if (iCDate::isDate($d) && $nbDays != 0) + { + $displayDates = true; + } + } + + $daysUl = ''; + + if ($displayDates) + { + if ($SingleDatesListModel == '2') + { + $n = 0; + $daysUl.= '
    ' . JText::_('COM_ICAGENDA_LEGEND_DATES') . ': '; + + foreach ($days as $k => $d) + { + $n = $n+1; + $fd = icagendaRender::dateToFormat($d); + + $timeDate = ($item->displaytime == 1) + ? ' ' . date($lang_time, strtotime($d)) . '' + : ''; + + if ($n <= ($totDates-1)) + { + $daysUl.= '' . $fd . $timeDate . ' - '; + } + elseif ($n == $totDates) + { + $daysUl.= '' . $fd . $timeDate . ''; + } + } + + $daysUl.= '
    '; + } + else + { + $daysUl.= '
      '; + + foreach ($days as $k => $d) + { + $fd = icagendaRender::dateToFormat($d); + + $timeDate = ($item->displaytime == 1) + ? ' ' . date($lang_time, strtotime($d)) . '' + : ''; + + $daysUl.= '
    • ' . $fd . $timeDate . '
    • '; + } + + $daysUl.= '
    '; + } + } + + if ($totDates > '0') + { + return $daysUl; + } + else + { + return false; + } +// } +// else +// { +// return false; +// } + } + else + { + return false; + } + } + + /* + * Function to display the period text width formatted dates (eg. from 00-00-0000 to 00-00-0000). + * TO BE REFACTORED + * @TODO remove inline style html tags (check css and add class declarations) + * @TODO (3.7) remove old deprecated class names + * + * @since 3.6.0 + */ + public static function displayPeriodDates($item) + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + + // Hide/Show Option + $PeriodDates = $iCparams->get('PeriodDates', 1); + + // List Model + $SingleDatesListModel = $iCparams->get('SingleDatesListModel', 1); + + // First day of the week + $firstday_week_global = $iCparams->get('firstday_week_global', 1); + + // Predefined variables + $wdays = $showDays = $timeOneDay = $end = ''; + + // WeekDays + $weekdays = $item->weekdays; + $weekdaysall = empty($weekdays) ? true : false; + + if ($firstday_week_global == '1') + { + $weekdays_array = explode (',', $weekdays); + + if (in_array('0', $weekdays_array)) + { + $weekdays = str_replace('0', '', $weekdays); + $weekdays = $weekdays . ',7'; + } + } + + if ( ! $weekdaysall) + { + $weekdays_array = explode (',', $weekdays); + $wdaysArray = array(); + + foreach ($weekdays_array AS $wd) + { + if ($firstday_week_global != '1') + { + if ($wd == 0) $wdaysArray[] = JText::_('SUNDAY'); + } + if ($wd == 1) $wdaysArray[] = JText::_('MONDAY'); + if ($wd == 2) $wdaysArray[] = JText::_('TUESDAY'); + if ($wd == 3) $wdaysArray[] = JText::_('WEDNESDAY'); + if ($wd == 4) $wdaysArray[] = JText::_('THURSDAY'); + if ($wd == 5) $wdaysArray[] = JText::_('FRIDAY'); + if ($wd == 6) $wdaysArray[] = JText::_('SATURDAY'); + if ($firstday_week_global == '1') + { + if ($wd == 7) $wdaysArray[] = JText::_('SUNDAY'); + } + } + + $last = array_slice($wdaysArray, -1); + $first = join(', ', array_slice($wdaysArray, 0, -1)); + $both = array_filter(array_merge(array($first), $last)); + + // RTL css if site language is RTL + $lang = JFactory::getLanguage(); + $arrow_list = $lang->isRTL() ? '↵' : '↳'; + + $wdays = $arrow_list . ' ' . join(' & ', $both) . ''; + } + + if ($PeriodDates == 1 + && self::eventHasPeriod($item->period, $item->startdate, $item->enddate) + ) + { + $startDate = icagendaRender::dateToFormat($item->startdate); + $endDate = icagendaRender::dateToFormat($item->enddate); + $startTime = icagendaRender::dateToTime($item->startdate); + $endTime = icagendaRender::dateToTime($item->enddate); + + if ($startDate == $endDate) + { + $start = ''; + $start.= $startDate; + $start.= ''; + + if ($item->displaytime == 1) + { + $timeOneDay = '' . $startTime; + $timeOneDay.= ($startTime !== $endTime) ? ' - ' . $endTime : ''; + $timeOneDay.= ''; + } + } + else + { + $start = '' + . ucfirst(JText::_('COM_ICAGENDA_PERIOD_FROM')) + . ' '; + $start.= '' + . $startDate + . ''; + + if ($item->displaytime == 1) + { + $start.= ' ' + . $startTime + . ''; + } + + $end = '' + . JText::_('COM_ICAGENDA_PERIOD_TO') + . ' '; + $end.= '' + . $endDate + . ''; + + if ($item->displaytime == 1) + { + $end.= ' ' + . $endTime + . ''; + } + + $showDays = $wdays; + } + + // Horizontal List + if ($SingleDatesListModel == 2) + { + $period = '
    ' . JText::_('COM_ICAGENDA_EVENT_PERIOD') . ': '; + $period.= $start . ' ' . $end . ' ' . $timeOneDay; + + if ( ! empty($showDays)) + { + $period.= '
    ' . $showDays . ''; + } + + $period.= '
    '; + } + + // Vertical List + else + { + $period = '
    • '; + $period.= $start . ' ' . $end . ' ' . $timeOneDay; + + if ( ! empty($showDays)) + { + $period.= '
      ' . $showDays; + } + + $period.= '
    '; + } + + return $period; + } + else + { + return false; + } + } + + /* + * Function to check if period dates exist for this event + * + * @since 3.6.0 + */ + public static function eventHasPeriod($period, $startdate, $enddate) + { + $period_dates = iCString::isSerialized($period) ? unserialize($period) : array(); // returns array + + if (count($period_dates) > 0 + && iCDate::isDate($startdate) + && iCDate::isDate($enddate)) + { + return true; + } + + return false; + } + + /* + * Function to check if period is not finished + * + * @since 3.6.0 + */ + public static function periodIsNotFinished($enddate) + { + $eventTimeZone = null; + $datetime_today = JHtml::date('now', 'Y-m-d H:i'); + $datetime_enddate = JHtml::date($enddate, 'Y-m-d H:i', $eventTimeZone); + + if (strtotime($datetime_enddate) > strtotime($datetime_today)) + { + return true; + } + + return false; + } + + /* + * Function to set Meta-title for an event + * + * @since 3.6.0 + */ + public static function setMetaTitle($item) + { + $limit = '60'; + $metaTitle = iCFilterOutput::fullCleanHTML($item->title); + + if (strlen($metaTitle) > $limit) + { + $string_cut = substr($metaTitle, 0, $limit); + $last_space = strrpos($string_cut, ' '); + $string_ok = substr($string_cut, 0, $last_space); + $metaTitle = $string_ok; + } + + return $metaTitle; + } + + /* + * Function to set Meta-description for an event + * + * @since 3.6.0 + */ + public static function setMetaDesc($item) + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + $limit = $iCparams->get('char_limit_meta_description', '320'); + + $metaDesc = iCFilterOutput::fullCleanHTML($item->metadesc); + $metaDesc = (empty($metaDesc)) ? iCFilterOutput::fullCleanHTML($item->desc) : $metaDesc; + + if (strlen($metaDesc) > $limit) + { + $string_cut = substr($metaDesc, 0, $limit); + $last_space = strrpos($string_cut, ' '); + $string_ok = substr($string_cut, 0, $last_space); + $metaDesc = $string_ok; + } + + return $metaDesc; + } + + /* + * Function to return event Url + * + * @since 3.6.0 + */ + public static function eventURL($i) + { + $app = JFactory::getApplication(); + $jinput = $app->input; + + $itemID = $jinput->get('Itemid', '0'); + + $eventnumber = $i->id; + $event_slug = empty($i->alias) ? $i->id : $i->id . ':' . $i->alias; + $date = $i->next; + + // Get the "event" URL + $baseURL = JURI::base(); + $subpathURL = JURI::base(true); + + $baseURL = str_replace('/administrator', '', $baseURL); + $subpathURL = str_replace('/administrator', '', $subpathURL); + + $urlevent = str_replace('&','&', JRoute::_('index.php?option=com_icagenda&view=event&Itemid=' . (int) $itemID . '&id=' . $event_slug)); + + // Sub Path filtering + $subpathURL = ltrim($subpathURL, '/'); + + // URL Event Details filtering + $urlevent = ltrim($urlevent, '/'); + + if (substr($urlevent, 0, strlen($subpathURL)+1) == "$subpathURL/") + { + $urlevent = substr($urlevent, strlen($subpathURL)+1); + } + + $urlevent = rtrim($baseURL,'/') . '/' . ltrim($urlevent,'/'); + + $url = $urlevent; + + if (is_numeric($itemID) && is_numeric($eventnumber) + && ! is_array($itemID) && ! is_array($eventnumber) + ) + { + return $url; + } + else + { + $url = JRoute::_('index.php'); + + return JURI::base() . $url; + } + } + + /* + * Function to convert a datetime to URL alias + * (see iCDate::dateToAlias from iC Library for general function) + * + * @since 3.6.0 + */ + public static function urlDateVar($datetime) + { + if ( ! iCDate::isDate($datetime)) return false; + + $datetime = date('Y-m-d H:i', strtotime($datetime)); + $date_explode = explode(' ', $datetime); + + $dateAlias = $date_explode['0'] . '-' . str_replace(':', '-', $date_explode['1']); + + return $dateAlias; + } + + /* + * Function to convert a URL date alias in an SQL datetime string. + * + * @return string The date string in SQL datetime format. + * + * @since 3.6.0 + */ + public static function convertDateAliasToSQLDatetime($dateAlias) + { + if (strlen(iCDate::dateToNumeric($dateAlias)) != '12') return ''; + + $ex = explode('-', $dateAlias); + $datetime = (count($ex) == 5) + ? $ex['0'] . '-' . $ex['1'] . '-' . $ex['2'] . ' ' . $ex['3'] . ':' . $ex['4'] . ':00' + : ''; + + return $datetime; + } + + /* + * Function to generate the read more for introduction description + * + * @since 3.6.0 + */ + public static function readMore ($url, $desc, $content = '') + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + $limitGlobal = $iCparams->get('limitGlobal', 0); + + if ($limitGlobal == 1) + { + $limit = $iCparams->get('ShortDescLimit', '100'); + } + elseif ($limitGlobal == 0) + { + $customlimit = $iCparams->get('limit', '100'); + + $limit = is_numeric($customlimit) ? $customlimit : $iCparams->get('ShortDescLimit', '100'); + } + + $limit = is_numeric($limit) ? $limit : '1'; + + $readmore = ''; + + $readmore = ($limit <= 1) ? '' : $content; + $text = preg_replace('/]*>/Ui', '', $desc); + + if (strlen($text) > $limit) + { + $string_cut = substr($text, 0, $limit); + $last_space = strrpos($string_cut, ' '); + $string_ok = substr($string_cut, 0, $last_space); + $text = $string_ok . ' '; + $url = $url; + $text = '' . $readmore . ''; + } + else + { + $text = ''; + } + + return $text; + } + + /** + * Loads the list of filled custom fields for this event + * + * @return array + * + * @since 3.6.0 + */ + public static function getCustomFields($id = null) + { + $customFields = icagendaEventData::loadEventCustomFields($id); + + foreach ($customFields as $cf) + { + if ($cf->title && $cf->value) + { + switch ($cf->type) + { + case 'url': + $cf->value = iCRender::urlTag($cf->value); + break; + + case 'email': + $cf->value = JHtml::_('email.cloak', $cf->value); + break; + + default: + $cf->value = JText::_($cf->value); + break; + } + } + + $cf->title = JText::_($cf->title); + } + + return $customFields; + } + + /** + * Function to get custom field groups of an event + * + * @param integer $id Event id + * + * @return array + * + * @since 3.6.0 + */ + public static function getCustomfieldGroups($id = null) + { + // Create a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('e.params') + ->from('#__icagenda_events AS e') + ->where($db->qn('id') . ' = ' . $db->q($id)); + $db->setQuery($query); + + $result = json_decode($db->loadResult()); + + if (isset($result->custom_form)) + { + return $result->custom_form; + } + + return false; + } + + /** + * Function to get event params + * + * @param integer $id Event id + * + * @return object + * + * @since 3.6.5 + */ + public static function getParams($id = null) + { + $db = JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select('e.params') + ->from($db->qn('#__icagenda_events', 'e')) + ->where($db->qn('e.id') . ' = ' . (int) $id); + + $db->setQuery($query); + + $params = json_decode($db->loadResult(), true); + + $evtParams = new JRegistry($params); + + return $evtParams; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/events/events.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/events/events.php new file mode 100644 index 00000000..8280b733 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/events/events.php @@ -0,0 +1,497 @@ +getQuery(true); + $query->select('e.state AS evtState, e.approval AS evtApproval, e.access AS evtAccess') + ->from($db->qn('#__icagenda_events').' AS e') + ->where($db->qn('e.id').' = '.$db->q($id)); + $query->select('v.title AS accessName') + ->join('LEFT', $db->quoteName('#__viewlevels') . ' AS v ON v.id = e.access'); + $db->setQuery($query); + $eventAccess = $db->loadObject(); + + if ($eventAccess) + { + return $eventAccess; + } + else + { + return false; + } + } + + /** + * Function to return feature Icons for an event + * + * @access public static + * @param $id - id of the event + * @return list array of feature icons + * + * @since 3.4.0 + */ + public static function featureIcons($id = null) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('DISTINCT f.icon, f.icon_alt'); + $query->from('`#__icagenda_feature_xref` AS fx'); + $query->innerJoin("`#__icagenda_feature` AS f ON fx.feature_id=f.id AND f.state=1 AND f.icon<>'-1'"); + $query->where('fx.event_id=' . $id); + $query->order('f.ordering DESC'); // Order descending because the icons are floated right + $db->setQuery($query); + $feature_icons = $db->loadObjectList(); + + return $feature_icons; + } + + /** + * Function to return footer list of events + * + * @since 3.4.0 + */ + public static function isListOfEvents() + { + $app = JFactory::getApplication(); + $params = $app->getParams(); + $list_of_events = $params->get('copy', ''); + $core = $params->get('icsys'); + $string = ''; + $string.= 'iCagenda'; + $string.= ''; + $icagenda = JText::sprintf('ICAGENDA_THANK_YOU_NOT_TO_REMOVE', $string); + $default = 'Powered by '; + $footer = '

    '; + $footer.= preg_match('/iCagenda/',$icagenda) ? $icagenda : $default . $string; + $footer.= '

    '; + + if ($list_of_events || $core == 'core') + { + echo $footer; + } + } + + /** + * DAY in Date Box (list of events) + * + * @since 3.5.0 + */ + public static function day($date, $item = null) + { + $eventTimeZone = null; + + $this_date = JHtml::date($date, 'Y-m-d H:i', $eventTimeZone); + $day_date = JHtml::date($date, 'd', $eventTimeZone); + $day_today = JHtml::date('now', 'd'); + $date_today = JHtml::date('now', 'Y-m-d'); + + if ($item) + { + $weekdays = $item->weekdays; + $period = unserialize($item->period); + $period = is_array($period) ? $period : array(); + $is_in_period = (in_array($this_date, $period)) ? true : false; + $startdate = $item->startdate; + $day_startdate = JHtml::date($startdate, 'd', $eventTimeZone); + $enddate = $item->enddate; + $day_enddate = JHtml::date($enddate, 'd', $eventTimeZone); + } + + if ($item && $is_in_period + && $weekdays == '' + && strtotime($startdate) <= strtotime($date_today) + && strtotime($enddate) >= strtotime($date_today) + ) + { + $day = ''; + + if ($day_today > $day_startdate) + { +// $day.= '' . $day_startdate . ' '; +// $day.= ''; + } + else + { +// $day.= '' . $day_startdate . ' '; +// $day.= ''; + } + +// $day.= '' . $day_today . ''; +// $day.= '' . $day_today . ''; + $day.= '' . $day_today . ''; +// $day.= $day_today; + + if ($day_today < $day_enddate) + { +// $day.= ''; +// $day.= ' ' . $day_enddate . ''; + } + else + { +// $day.= ''; +// $day.= '' . $day_enddate . ' '; + } + + return $day; + } + else + { + return $day_date; + } + } + + /** + * MONTH SHORT in Date Box (list of events) + * + * @since 3.5.0 + */ + public static function dateBox($date, $type, $ongoing = null) + { + $datetime_today = JHtml::date('now', 'Y-m-d H:i'); + + $month_date = iCDate::monthJoomla($date); + $month_today = iCDate::monthJoomla($datetime_today); + $monthshort_date = iCDate::monthShortJoomla($date); + $monthshort_today = iCDate::monthShortJoomla($datetime_today); + $year_date = JHtml::date($date, 'Y', null); + $year_today = JHtml::date('now', 'Y'); + + if ($ongoing) + { + switch($type) + { + case 'month': + $value = $month_today; + break; + + case 'monthshort': + $value = $monthshort_today; + break; + + case 'year': + $value = $year_today; + break; + + default : + $value = JHtml::date('now', $type, null); + break; + } + } + else + { + switch($type) + { + case 'month': + $value = $month_date; + break; + + case 'monthshort': + $value = $monthshort_date; + break; + + case 'year': + $value = $year_date; + break; + + default : + $value = JHtml::date($date, $type, null); + break; + } + } + + return $value; + } + +// DEPRECATED 3.6 (see icagendaRender::dateToTime) + /** + * Function to return time formated depending on AM/PM option + * Format Time (eg. 00:00 (AM/PM)) + * $oldtime to be removed (not used since 2.0.0) + * + * @since 3.4.1 + * @deprecated 3.6.0 TO BE REMOVED (after all old usage migrated to icagendaRender::dateToTime)! + */ + public static function dateToTimeFormat($evt, $oldtime = null) + { + $app = JFactory::getApplication(); + $params = $app->getParams(); + $timeformat = $params->get('timeformat', 1); + $eventTimeZone = null; + + $date_time = strtotime(JHtml::date($evt, 'Y-m-d H:i', $eventTimeZone)); + $t_time = date('H:i', $date_time); + + $time_format = ($timeformat == 1) ? '%H:%M' : '%I:%M %p'; + $lang_time = strftime($time_format, strtotime($t_time)); + + $time = ($oldtime != NULL && $t_time == '00:00') ? $oldtime : JText::_($lang_time); + + return $time; + } + + /** + * Function to return Auto Short Description (Full Description > Short) + * + * @version 3.6.6 + * @since 3.5.6 + */ + public static function shortDescription($text, $isModule = null, $option = null, $limit = null) + { +// $descdata = $text; +// $desc_full = self::deleteAllBetween('{', '}', $descdata); + $desc_full = $text; + + // Menu Options + $app = JFactory::getApplication(); + $params = $app->getParams(); + +// $limitGlobal = ! $isModule ? $params->get('limitGlobal', 0) : 1; +// $customlimit = ! $isModule ? $params->get('limit', '100') : false; + $limitGlobal = ! $isModule ? $params->get('limitGlobal', 0) : 0; + $customlimit = ! $isModule ? $params->get('limit', '100') : $limit; + + // Global Options Component iCagenda + $iCparams = JComponentHelper::getParams('com_icagenda'); + + if ($limitGlobal == 1) + { + $limit = $params->get('ShortDescLimit', '100'); + } + else + { + $limit_global_option = $iCparams->get('ShortDescLimit', '100'); + $limit = is_numeric($customlimit) ? $customlimit : $limit_global_option; + } + + // Html tags removal Global Option (component iCagenda) - Short Description + $Filtering_ShortDesc_Global = $iCparams->get('Filtering_ShortDesc_Global', ''); + $HTMLTags_ShortDesc_Global = $iCparams->get('HTMLTags_ShortDesc_Global', array()); + + // Get Module Option + $Filtering_ShortDesc_Module = $isModule ? $option : ''; + + /** + * START Filtering HTML method + */ + $limit = is_numeric($limit) ? $limit : false; + + // Gets length of the short desc, when not filtered + $limit_not_filtered = substr($desc_full, 0, $limit); + $text_length = strlen($limit_not_filtered); + + // Gets length of the short desc, after html filtering + $limit_filtered = preg_replace('/[\p{Z}\s]{2,}/u', ' ', $limit_not_filtered); + $limit_filtered = strip_tags($limit_filtered); + $text_short_length = strlen($limit_filtered); + + // Sets Limit + special tags authorized + $limit_short = $limit + ($text_length - $text_short_length); + + // Replaces all authorized html tags with tag strings + if (empty($Filtering_ShortDesc_Module) + && ($Filtering_ShortDesc_Global == '1') ) + { + $desc_full = str_replace('+', '@@', $desc_full); + $desc_full = in_array('1', $HTMLTags_ShortDesc_Global) ? str_replace('
    ', '+@br@', $desc_full) : $desc_full; + $desc_full = in_array('1', $HTMLTags_ShortDesc_Global) ? str_replace('
    ', '+@br@', $desc_full) : $desc_full; + $desc_full = in_array('1', $HTMLTags_ShortDesc_Global) ? str_replace('
    ', '+@br@', $desc_full) : $desc_full; + $desc_full = in_array('2', $HTMLTags_ShortDesc_Global) ? str_replace('', '+@b@', $desc_full) : $desc_full; + $desc_full = in_array('2', $HTMLTags_ShortDesc_Global) ? str_replace('', '@bc@', $desc_full) : $desc_full; + $desc_full = in_array('3', $HTMLTags_ShortDesc_Global) ? str_replace('', '@strong@', $desc_full) : $desc_full; + $desc_full = in_array('3', $HTMLTags_ShortDesc_Global) ? str_replace('', '@strongc@', $desc_full) : $desc_full; + $desc_full = in_array('4', $HTMLTags_ShortDesc_Global) ? str_replace('', '@i@', $desc_full) : $desc_full; + $desc_full = in_array('4', $HTMLTags_ShortDesc_Global) ? str_replace('', '@ic@', $desc_full) : $desc_full; + $desc_full = in_array('5', $HTMLTags_ShortDesc_Global) ? str_replace('', '@em@', $desc_full) : $desc_full; + $desc_full = in_array('5', $HTMLTags_ShortDesc_Global) ? str_replace('', '@emc@', $desc_full) : $desc_full; + $desc_full = in_array('6', $HTMLTags_ShortDesc_Global) ? str_replace('', '@u@', $desc_full) : $desc_full; + $desc_full = in_array('6', $HTMLTags_ShortDesc_Global) ? str_replace('', '@uc@', $desc_full) : $desc_full; + } + elseif ( $Filtering_ShortDesc_Module == '2' + || (($Filtering_ShortDesc_Global == '') && empty($Filtering_ShortDesc_Module)) ) + { + $desc_full = '@i@'.$desc_full.'@ic@'; + $limit_short = $limit_short + 7; + } + else + { + $desc_full = $desc_full; + } + + // Removes HTML tags + $desc_nohtml = strip_tags($desc_full); + + // Replaces all sequences of two or more spaces, tabs, and/or line breaks with a single space + $desc_nohtml = preg_replace('/[\p{Z}\s]{2,}/u', ' ', $desc_nohtml); + + // Replaces all spaces with a single + + $desc_nohtml = str_replace(' ', '+', $desc_nohtml); + + if (strlen($desc_nohtml) > $limit_short) + { + // Cuts full description, to get short description + $string_cut = substr($desc_nohtml, 0, $limit_short); + + // Detects last space of the short description + $last_space = strrpos($string_cut, '+'); + + // Cuts the short description after last space + $string_ok = substr($string_cut, 0, $last_space); + + // Counts number of tags converted to string, and returns lenght + $nb_br = substr_count($string_ok, '+@br@'); + $nb_plus = substr_count($string_ok, '@@'); + $nb_bopen = substr_count($string_ok, '@b@'); + $nb_bclose = substr_count($string_ok, '@bc@'); + $nb_strongopen = substr_count($string_ok, '@strong@'); + $nb_strongclose = substr_count($string_ok, '@strongc@'); + $nb_iopen = substr_count($string_ok, '@i@'); + $nb_iclose = substr_count($string_ok, '@ic@'); + $nb_emopen = substr_count($string_ok, '@em@'); + $nb_emclose = substr_count($string_ok, '@emc@'); + $nb_uopen = substr_count($string_ok, '@u@'); + $nb_uclose = substr_count($string_ok, '@uc@'); + + // Replaces tag strings with html tags + $string_ok = str_replace('@br@', '
    ', $string_ok); + $string_ok = str_replace('@b@', '', $string_ok); + $string_ok = str_replace('@bc@', '', $string_ok); + $string_ok = str_replace('@strong@', '', $string_ok); + $string_ok = str_replace('@strongc@', '', $string_ok); + $string_ok = str_replace('@i@', '', $string_ok); + $string_ok = str_replace('@ic@', '', $string_ok); + $string_ok = str_replace('@em@', '', $string_ok); + $string_ok = str_replace('@emc@', '', $string_ok); + $string_ok = str_replace('@u@', '', $string_ok); + $string_ok = str_replace('@uc@', '', $string_ok); + $string_ok = str_replace('+', ' ', $string_ok); + $string_ok = str_replace('@@', '+', $string_ok); + + $text = $string_ok; + + // Close html tags if not closed + if ($nb_bclose < $nb_bopen) $text = $string_ok.'
    '; + if ($nb_strongclose < $nb_strongopen) $text = $string_ok.''; + if ($nb_iclose < $nb_iopen) $text = $string_ok.''; + if ($nb_emclose < $nb_emopen) $text = $string_ok.''; + if ($nb_uclose < $nb_uopen) $text = $string_ok.''; + + $return_text = $text.' '; + + $descShort = $limit ? $return_text : ''; + } + else + { + $desc_full = $desc_nohtml; + $desc_full = str_replace('@br@', '
    ', $desc_full); + $desc_full = str_replace('@b@', '', $desc_full); + $desc_full = str_replace('@bc@', '', $desc_full); + $desc_full = str_replace('@strong@', '', $desc_full); + $desc_full = str_replace('@strongc@', '', $desc_full); + $desc_full = str_replace('@i@', '', $desc_full); + $desc_full = str_replace('@ic@', '', $desc_full); + $desc_full = str_replace('@em@', '', $desc_full); + $desc_full = str_replace('@emc@', '', $desc_full); + $desc_full = str_replace('@u@', '', $desc_full); + $desc_full = str_replace('@uc@', '', $desc_full); + $desc_full = str_replace('+', ' ', $desc_full); + $desc_full = str_replace('@@', '+', $desc_full); + + $descShort = $limit ? $desc_full : ''; + } + /** END Filtering HTML function */ + + return $descShort; + } + + /** + * Function to check if user has access rights to defined access + * + * $accessLevel Access level of the item to check User Permissions + * + * If in super user group, always allowed + */ + static public function accessLevels($accessLevel) + { + // Get User Access Levels + $user = JFactory::getUser(); + $userLevels = $user->getAuthorisedViewLevels(); + $userGroups = $user->getAuthorisedGroups(); + + // Control: if access level, or Super User + if (in_array($accessLevel, $userLevels) + || in_array('8', $userGroups)) + { + return true; + } + + return false; + } + + /** + * Process a string in a JOOMLA_TRANSLATION_STRING standard. + * This method processes a string and replaces all accented UTF-8 characters by unaccented + * ASCII-7 "equivalents" and the string is uppercase. Spaces replaced by underscore. + * + * @param string $string String to process + * + * @return string Processed string + * + * @since 3.3.3 + */ + public static function deleteAllBetween($start, $end, $string) + { + $startPos = strpos($string, $start); + $endPos = strpos($string, $end); + + if (!$startPos || !$endPos) + { + return $string; + } + + $textToDelete = substr($string, $startPos, ($endPos + strlen($end)) - $startPos); + + return str_replace($textToDelete, '', $string); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/events/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/events/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/events/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/configtermsdefault.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/configtermsdefault.php new file mode 100644 index 00000000..ee6d27c9 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/configtermsdefault.php @@ -0,0 +1,58 @@ +'; + $html[] = '
    '; + $html[] = ' ' . JText::sprintf('COM_ICAGENDA_TERMS_IMPORTANT_INFOS', $this->description) . '
    '; + $html[] = '
    ' . JText::_('COM_ICAGENDA_SUBMIT_TOS_TYPE_DEFAULT_LBL') . '
    ' . $this->description . '
    '; + $html[] = '
    ' . JText::_($this->description) . '
    '; + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/customfieldgroups.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/customfieldgroups.php new file mode 100644 index 00000000..e8804e7b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/customfieldgroups.php @@ -0,0 +1,306 @@ +input; + $view = $jinput->get('view', ''); + $id = $jinput->get('id', ''); + + $value = isset($this->value) ? $this->value : ''; + + $getOptions = $this->getOptions(); + + $options = array(); + + foreach ($getOptions as $opt) + { + $options[] = JHTML::_('select.option', $opt->value, $opt->option); + } + + $attr = ''; + + // Initialize some field attributes. + $attr .= $this->multiple ? ' multiple' : ''; + $attr .= ! empty($this->class) ? ' class="' . $this->class . '"' : ''; + $attr .= count($options) + ? ' data-placeholder="' . JText::_('COM_ICAGENDA_CUSTOMFIELD_GROUPS_SELECT') . '"' + : ' data-placeholder="' . JText::_('COM_ICAGENDA_CUSTOMFIELD_GROUPS_NONE') . '"'; + + $html = '
    ' . JHtml::_('select.genericlist', $options, $this->name, $attr, 'value', 'text', $value) . '
    '; + + // Custom Field Groups Manager + $html.= '
    '; + + $html.= '
    '; + $html.= '' . JText::_('COM_ICAGENDA_CUSTOMFIELD_GROUPS_MANAGER_LABEL') . ''; + $html.= '
    '; + + // Add a new group + $html.= '
    '; + $html.= JText::_('COM_ICAGENDA_CUSTOMFIELD_GROUPS_ADD_LABEL') . '
    '; + $html.= '
    '; + $html.= ' '; + $html.= ''; + $html.= '
    '; + $html.= '
    '; + $html.= '
    '; + + // Delete an existing group + $html.= '
    '; + $html.= JText::_('COM_ICAGENDA_CUSTOMFIELD_GROUPS_DELETE_LABEL') . '
    '; + $html.= '
    '; + $html.= ''; + $html.= ''; + $html.= '
    '; + $html.= '
    '; + $html.= '
    '; + + $html.= '
    '; + + // ShowOn script for Joomla 2.5, extended to Joomla 3 up to version 3.4.1 to patch Joomla bug(*). + // * Issue if usage of 'multiple' and 'showon' (not working) xml attributes for same form field in Joomla 3.2.4 > 3.4.1 + if (version_compare(JVERSION, '3.4.1', 'le')) + { + JFactory::getDocument()->addScriptDeclaration(' + jQuery(document).ready(function($) { + var parent_form = $("#jform_parent_form"); + if (parent_form.val() == "1") { + $("#cf_groups").show(); + $("#jform_groups-lbl").show(); + $("#groups-select").show(); + $("#groups-manager").show(); + } else { + $("#cf_groups").hide(); + $("#jform_groups-lbl").hide(); + $("#groups-select").hide(); + $("#groups-manager").hide(); + } + $(parent_form).on("change",function(e){ + if (parent_form.val() == "1") { + $("#cf_groups").show(300); + $("#jform_groups-lbl").show(300); + $("#groups-select").show(300); + $("#groups-manager").show(300); + } else { + $("#cf_groups").hide(300); + $("#jform_groups-lbl").hide(); + $("#groups-select").hide(300); + $("#groups-manager").hide(300); + } + }); + }); + '); + } + ?> + + + addStyleDeclaration(' + '); + + return $html; + } + + /** + * Method to get the field options. + * + * @return array The field option objects. + * @since 3.6.0 + */ + protected function getOptions() + { + $options = array(); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('f.*'); + $query->from($db->qn('#__icagenda_filters') . ' AS f'); + $query->where($db->qn('type') . ' = "customfield"'); + $query->where($db->qn('filter') . ' = "groups"'); + $query->where($db->qn('state') . ' = 1'); + + $query->order('f.option ASC'); + + // Get the options. + $db->setQuery($query); + + $options = $db->loadObjectList(); + + // Check for a database error. + if ($db->getErrorNum()) + { + throw new Exception($db->getErrorMsg(), 500); + } + + return $options; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/customform.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/customform.php new file mode 100644 index 00000000..66061e52 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/customform.php @@ -0,0 +1,92 @@ +value) ? $this->value : ''; + + $options = array(); + + foreach($this->getOptions() as $opt) + { + $options[] = JHTML::_('select.option', $opt->value, $opt->option); + } + + return JHtml::_('select.genericlist', $options, $this->name, 'class="inputbox" multiple', 'value', 'text', $value); + } + + /** + * Method to get the field options. + * + * @return array The field option objects. + * @since 3.6.0 + */ + protected function getOptions() + { + $options = array(); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('f.*'); + $query->from($db->qn('#__icagenda_filters') . ' AS f'); + $query->where($db->qn('type') . ' = "customfield"'); + $query->where($db->qn('filter') . ' = "groups"'); + $query->where($db->qn('state') . ' = 1'); + + $query->order('f.option ASC'); + + // Get the options. + $db->setQuery($query); + + $options = $db->loadObjectList(); + + // Check for a database error. + if ($db->getErrorNum()) + { + throw new Exception($db->getErrorMsg(), 500); + } + + return $options; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/registrationdates.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/registrationdates.php new file mode 100644 index 00000000..f255f4c7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/registrationdates.php @@ -0,0 +1,171 @@ +item = $model->getItem(); + + $item = $this->item; + $typeReg = $item->params->get('typeReg', ''); + + // Get date from url if set, and from session if set + $url_date = $app->input->get('date', ''); + $session_date = $session->get('session_date', ''); + + if ($url_date) + { + $ex_date = explode('-', $url_date); + $defaultDate = $ex_date[0] . '-' . $ex_date[1] . '-' . $ex_date[2] . ' ' . $ex_date[3] . ':' . $ex_date[4] . ':00'; + } + else + { + $defaultDate = $session_date; + } + +// $session->set('session_date', ''); + + $value = ! empty($this->value) ? $this->value : $defaultDate; + + $html = ''; + + // Return Select list of dates + if ($typeReg == 1) + { + $options = array(); + + if ( ! $this->getOptions()) return false; + + if (count($this->getOptions()) > 1) + { + foreach ($this->getOptions() as $opt) + { + $date_get = explode('@@', $opt); + $date_value = $date_get[0]; + $date_option = $date_get[1]; +// $options[] = JHTML::_('select.option', $opt->value, $opt->option); + $options[] = JHtml::_('select.option', $date_value, $date_option); + } + + $html.= JHtml::_('select.genericlist', $options, $this->name, 'class="select-large"', 'value', 'text', $value, $this->id); + + $html.= ''; + + return $html; + } + else + { + foreach ($this->getOptions() as $opt) + { + $date_get = explode('@@', $opt); + $date_value = $date_get[0]; + $date_option = $date_get[1]; + } + + $html.= ''; + $html.= '
    ' . $date_option . '
    '; + + return $html; + } + } + + // Return for all dates + else + { + $html.= '
    '; + + $EVENT_SINGLE_DATES = icagendaEvent::displayListSingleDates($item); + $EVENT_PERIOD = icagendaEvent::displayPeriodDates($item); + + if ($EVENT_PERIOD) + { + $html.= $EVENT_PERIOD; + } + + if ($EVENT_SINGLE_DATES) + { + $html.= $EVENT_SINGLE_DATES; + } + + $html.= ''; + $html.= '
    '; + + return $html; + } + } + + /** + * Method to get the field options. + * + * @return array The field option objects. + * @since 3.6.0 + */ + protected function getOptions() + { + $options = array(); + + if ($this->item) + { + $options = icagendaRegistration::formDatesList($this->item); + } + + return $options; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/registrationpeople.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/registrationpeople.php new file mode 100644 index 00000000..79c82356 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/registrationpeople.php @@ -0,0 +1,104 @@ +getItem(); + $tickets = isset($item->default_tickets) ? $item->default_tickets : $item->tickets; + + $options = array(); + $i = ''; + + // Ajax update of number of tickets bookable per registration, depending on date selected. + JFactory::getDocument()->addScriptDeclaration(' + jQuery(document).ready(function($) { + var date = $("#jform_date"); + $(date).change(function() { + var selectedDate = $(date).val().replace(/ /g, "space").replace(/:/g, "_"); + $.ajax({ + type: "POST", + url: "index.php?option=com_icagenda&task=registration.ticketsBookable", + data: { + eventID: "' . $item->id . '", + regDate: selectedDate, + typeReg: "' . $item->params->get('typeReg', '1') . '", + maxReg: "' . $item->params->get('maxReg', '1000000') . '", + tickets: "' . $item->tickets . '" + }, + dataType: "text" + }) + .done(function( data ) { + var tickets = parseInt(data), + sel = $( "#' . $this->id . '" ); + sel.empty(); + for (var i = 1; i <= tickets; i++) { + $selected = (i == "' . $this->value . '") ? " selected" : ""; + sel.append($("").attr("value",i).text(i)); + } + }) + .fail(function( data ) { + if ( data.responseCode ) { + console.log( data.responseCode ); + } + }); + }) + }); + '); + + for ($i = 1; $i <= $tickets; $i++) + { + $options[] = JHtml::_('select.option', $i, $i); + } + + if ($tickets > 1) + { + return JHtml::_('select.genericlist', $options, $this->name, 'class="select-large"', 'value', 'text', $this->value, $this->id); + } + else + { + return ''; + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/registrationterms.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/registrationterms.php new file mode 100644 index 00000000..a0a3ed4c --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/registrationterms.php @@ -0,0 +1,122 @@ +getItem(); + + // Get the site name + $sitename = $app->getCfg('sitename'); + + // Terms options + $terms_Type = $item->params->get('terms_Type', ''); + $termsArticle = $item->params->get('termsArticle', ''); + $termsContent = $item->params->get('termsContent', ''); + + $DEFAULT_STRING = JText::_('COM_ICAGENDA_REGISTRATION_TERMS'); + $default = str_replace('[SITENAME]', $sitename, $DEFAULT_STRING); + $article = 'index.php?option=com_content&view=article&id=' . $termsArticle . '&tmpl=component'; + $custom = $termsContent; + + $html = ''; + $html.= '
    ' . JText::_('COM_ICAGENDA_TERMS_AND_CONDITIONS') . '
    '; + $html.= '
    '; + + if ($terms_Type == 1) + { + $html.= ''; + } + elseif ($terms_Type == 2) + { + $html.= $custom; + } + else + { + $html.= $default; + } + + return '
    ' . $html; + } + + /** + * Method to get the field input markup. + * + * @return string The field input markup. + * @since 3.6.0 + */ + protected function getInput() + { + // Initialize some field attributes. + $class = ! empty($this->class) ? ' class="' . $this->class . '"' : ''; + $disabled = $this->disabled ? ' disabled' : ''; + $value = ! empty($this->default) ? $this->default : '0'; + $required = $this->required ? ' required aria-required="true"' : ''; + $autofocus = $this->autofocus ? ' autofocus' : ''; + $checked = $this->checked || ! empty($this->value) ? ' checked' : ''; + + // Initialize JavaScript field attributes. + $onclick = ! empty($this->onclick) ? ' onclick="' . $this->onclick . '"' : ''; + $onchange = ! empty($this->onchange) ? ' onchange="' . $this->onchange . '"' : ''; + + $html = ''; + + // Terms of Service + $checkbox = ''; + + $html.= '

    '; + $html.= '
    '; + $html.= ''; + $html.= '
    '; + $html.= '
    '; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/terms.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/terms.php new file mode 100644 index 00000000..ff455ba0 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/field/terms.php @@ -0,0 +1,243 @@ +getItem(); + + // Get the site name + $sitename = $app->getCfg('sitename'); + + // Terms options + $terms_type = $item->params->get('terms_type', ''); + $termsArticle = $item->params->get('termsArticle', ''); + $termsContent = $item->params->get('termsContent', ''); + + $DEFAULT_STRING = JText::_('COM_ICAGENDA_REGISTRATION_TERMS'); + + $default = str_replace('[SITENAME]', $sitename, $DEFAULT_STRING); + $article = 'index.php?option=com_content&view=article&id=' . $termsArticle . '&tmpl=component'; + $custom = $termsContent; + + $html = ''; + + $legend = ''; + $legend .= ' ' . JText::_('COM_ICAGENDA_REGISTRATION_CONSENT_TERMS_LABEL'); + $legend .= ''; + + $html .= $legend; + + $html .= '
    '; + + if ($terms_type == 1) + { + $html .= ''; + } + elseif ($terms_type == 2) + { + $html .= $custom; + } + elseif ($terms_type == 3) + { + $html .= $default; + } + else + { + return '
    ' . $legend . '
    '; + } + + return '
    ' . $html; + } + + /** + * Method to get the field input markup for check boxes. + * + * @return string The field input markup. + * + * @since 3.7.0 + */ + protected function getInput() + { + // True if the field has 'value' set. In other words, it has been stored, don't use the default values. + $hasValue = (isset($this->value) && ! empty($this->value)); + + // Initialize some field attributes. + $class = ! empty($this->class) ? ' class="checkboxes ' . trim($this->class) . '"' : ' class="checkboxes"'; + $checkedOptions = explode(',', (string) $this->checkedOptions); + $required = $this->required ? ' required aria-required="true"' : ''; + $autofocus = $this->autofocus ? ' autofocus' : ''; + + // Including fallback code for HTML5 non supported browsers. + JHtml::_('jquery.framework'); + JHtml::_('script', 'system/html5fallback.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); + + // Get the field options. + $options = $this->getOptions(); + + /** + * The format of the input tag to be filled in using sprintf. + * %1 - id + * %2 - name + * %3 - value + * %4 = any other attributes + */ + $format = ''; + + // Start the checkbox field output. + $html = '
    '; + + + $app = JFactory::getApplication(); + $params = $app->getParams(); + + $terms_type = $params->get('terms_type', ''); + $termsArticle = $params->get('termsArticle', ''); + $termsContent = $params->get('termsContent', ''); + + + if ($params->get('terms_mode', '') == 1) // IN DEV. + { + if (in_array($terms_type, array(1,2,3))) + { + // Terms Modal link + $terms_link = '' + . $this->title + . ''; + } + else + { + $terms_link = JText::sprintf('COM_ICAGENDA_REGISTRATION_CONSENT_TERMS_OF_THIS_WEBSITE', $this->title); + } + + if ($terms_type == 1) + { + // Terms Modal: Article + $html .= JHtml::_( + 'bootstrap.renderModal', + 'ModalTerms' . $this->id, + array( + 'title' => $this->title, + 'url' => 'index.php?option=com_content&view=article&id=' . $termsArticle . '&tmpl=component', + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '', + ) + ); + } + elseif ($terms_type == 2) + { + // Terms Modal: Custom Content + $termsContentModal = array( + 'selector' => 'ModalTerms' . $this->id, + 'params' => array( + 'title' => $this->title, + 'footer' => '', + ), + 'body' => $termsContent, + ); + + $html .= JLayoutHelper::render('joomla.modal.main', $termsContentModal); + } + elseif ($terms_type == 3) + { + // Terms Modal: Custom Content + $termsContentModal = array( + 'selector' => 'ModalTerms' . $this->id, + 'params' => array( + 'title' => $this->title, + 'footer' => '', + ), + 'body' => JText::_('COM_ICAGENDA_REGISTRATION_TERMS'), + ); + + $html .= JLayoutHelper::render('joomla.modal.main', $termsContentModal); + } + } + else + { + $terms_link = JText::sprintf('COM_ICAGENDA_REGISTRATION_CONSENT_TERMS_OF_THIS_WEBSITE', $this->title); + } + + + foreach ($options as $i => $option) + { + // Initialize some option attributes. + $checked = in_array((string) $option->value, $checkedOptions, true) ? 'checked' : ''; + + // In case there is no stored value, use the option's default state. + $checked = ( ! $hasValue && $option->checked) ? 'checked' : $checked; + $optionClass = ! empty($option->class) ? 'class="' . $option->class . '"' : ''; + $optionDisabled = ! empty($option->disable) || $this->disabled ? 'disabled' : ''; + + // Initialize some JavaScript option attributes. + $onclick = ! empty($option->onclick) ? 'onclick="' . $option->onclick . '"' : ''; + $onchange = ! empty($option->onchange) ? 'onchange="' . $option->onchange . '"' : ''; + + $oid = $this->id . $i; + $value = htmlspecialchars($option->value, ENT_COMPAT, 'UTF-8'); + $attributes = array_filter(array($checked, $optionClass, $optionDisabled, $onchange, $onclick)); + +// $html .= '
    '; + + return $html; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/form.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/form.php new file mode 100644 index 00000000..fbcafe98 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/form.php @@ -0,0 +1,381 @@ +getTag() == 'fa-IR') ? '_jalali' : ''; + + if ($app->isAdmin()) + { + $params = JComponentHelper::getParams('com_icagenda'); + } + elseif ($app->isSite()) + { + $params = $app->getParams(); + } + + $submit_periodDisplay = $params->get('submit_periodDisplay', 1); + $submit_datesDisplay = $params->get('submit_datesDisplay', 1); + + JText::script('COM_ICAGENDA_REGISTRATION_NO_EVENT_SELECTED_ALERT'); + JText::script('COM_ICAGENDA_FORM_NC'); + JText::script('COM_ICAGENDA_FORM_NO_DATES_ALERT'); + JText::script('COM_ICAGENDA_TERMS_AND_CONDITIONS_NOT_CHECKED_REGISTRATION'); + JText::script('COM_ICAGENDA_ALERT_TEXT_EXCEEDS_CHARACTER_LIMIT'); + + $prefix_id = $app->isAdmin() ? 'jform_' : ''; + + // Copyleft function strpos + // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: Onno Marsman + // + bugfixed by: Daniel Esteban + // + improved by: Brett Zamir (http://brett-zamir.me) + // + edited by: Cyril Rezé (http://www.joomlic.com) + // * example 1: strpos('Kevin van Zonneveld', 'e', 5); + // * returns 1: 14 + + $ic_script = array(); + + if ( $app->isSite() ) + { + $ic_script[] = ' function iCheckForm() {'; + $ic_script[] = ' var agree = document.getElementById("formAgree");'; + + if ($parent_form == 2) + { + $ic_script[] = ' if (agree.checked) {'; + $ic_script[] = ' document.getElementById("tos").value = "checked";'; + $ic_script[] = ' }'; + } + } + elseif ( $app->isAdmin() ) + { + $ic_script[] = 'jQuery(document).ready(function() {'; + $ic_script[] = ' Joomla.submitbutton = function(task) {'; + } + + if ($parent_form == 1 && $app->isAdmin()) + { + $ic_script[] = ' var eventid = document.getElementById("' . $prefix_id . 'eventid_id");'; + $ic_script[] = ' if ((eventid.value == "") && (task != "' . $parent_name . '.cancel")) {'; + $ic_script[] = ' alert(Joomla.JText._("COM_ICAGENDA_REGISTRATION_NO_EVENT_SELECTED_ALERT"));'; + $ic_script[] = ' return false;'; + $ic_script[] = ' }'; + } + + if ($parent_form == 2) + { + $ic_script[] = ' function strpos (haystack, needle, offset) {'; + $ic_script[] = ' var i = (haystack + "").indexOf(needle, (offset || 0));'; + $ic_script[] = ' return i === -1 ? false : i;'; + $ic_script[] = ' }'; + + $ic_script[] = ' var nodate = "0";'; + $ic_script[] = ' var noserialdate = \'a:1:{i:0;s:19:"0000-00-00 00:00:00";}\';'; + $ic_script[] = ' var noserialdate2 = \'a:1:{i:0;s:16:"0000-00-00 00:00";}\';'; + $ic_script[] = ' var emptydatetime = "0000-00-00 00:00:00";'; + + if ($submit_periodDisplay && $app->isSite()) + { + $ic_script[] = ' var startDate = document.getElementById("startdate' . $id_suffix . '");'; + $ic_script[] = ' var endDate = document.getElementById("enddate' . $id_suffix . '");'; + $ic_script[] = ' var isValidStartDate = strpos(startDate.value, nodate, 0);'; + $ic_script[] = ' var isValidEndDate = strpos(endDate.value, nodate, 0);'; + } + elseif ($app->isAdmin()) + { + $ic_script[] = ' var startDate = document.getElementById("startdate' . $id_suffix . '");'; + $ic_script[] = ' var endDate = document.getElementById("enddate' . $id_suffix . '");'; + $ic_script[] = ' var isValidStartDate = strpos(startDate.value, nodate, 0);'; + $ic_script[] = ' var isValidEndDate = strpos(endDate.value, nodate, 0);'; + } + if ($submit_datesDisplay && $app->isSite()) + { + $ic_script[] = ' var Dates = document.getElementById("' . $prefix_id . 'dates_id");'; + $ic_script[] = ' var isValidSingleDate = strpos(Dates.value, nodate, 2);'; + } + elseif ($app->isAdmin()) + { + $ic_script[] = ' var Dates = document.getElementById("' . $prefix_id . 'dates_id");'; + $ic_script[] = ' var isValidSingleDate = strpos(Dates.value, nodate, 2);'; + } + + $ic_script[] = ' if ('; + + if ($submit_datesDisplay && $app->isSite()) + { + $ic_script[] = ' ( !isValidSingleDate'; + $ic_script[] = ' || (Dates.value == noserialdate && isValidSingleDate)'; + $ic_script[] = ' || (Dates.value == noserialdate2 && isValidSingleDate)'; + $ic_script[] = ' || Dates.value == "" )'; + } + elseif ($app->isAdmin()) + { + $ic_script[] = ' ( !isValidSingleDate'; + $ic_script[] = ' || (Dates.value == noserialdate && isValidSingleDate)'; + $ic_script[] = ' || (Dates.value == noserialdate2 && isValidSingleDate)'; + $ic_script[] = ' || Dates.value == "" )'; + } + + if ($submit_periodDisplay && $submit_datesDisplay && $app->isSite()) + { + $ic_script[] = ' && '; + } + + if ($submit_periodDisplay && $app->isSite()) + { + $ic_script[] = ' ( (!isValidStartDate || (startDate.value == emptydatetime)) )'; + } + elseif ($app->isAdmin()) + { + $ic_script[] = ' && ( (!isValidStartDate || (startDate.value == emptydatetime)) )'; + } + + if ($app->isAdmin()) $ic_script[] = ' && ( task != "' . $parent_name . '.cancel" ) '; + + $ic_script[] = ' ) {'; + $ic_script[] = ' alert(Joomla.JText._("COM_ICAGENDA_FORM_NO_DATES_ALERT"));'; + $ic_script[] = ' document.getElementById("message_error").innerHTML = "' + . JText::_("COM_ICAGENDA_FORM_NO_DATES_ALERT") . '";'; + $ic_script[] = ' document.getElementById("form_errors").style.display = "block";'; + + if ($submit_periodDisplay && $app->isSite()) + { + $ic_script[] = ' document.getElementById("startdate' . $id_suffix . '").value = emptydatetime;'; + $ic_script[] = ' document.getElementById("enddate' . $id_suffix . '").value = emptydatetime;'; + $ic_script[] = ' document.getElementById("startdate' . $id_suffix . '").addClass("ic-date-invalid");'; + $ic_script[] = ' document.getElementById("enddate' . $id_suffix . '").addClass("ic-date-invalid");'; + } + elseif ($app->isAdmin()) + { + $ic_script[] = ' document.getElementById("startdate' . $id_suffix . '").value = emptydatetime;'; + $ic_script[] = ' document.getElementById("enddate' . $id_suffix . '").value = emptydatetime;'; + $ic_script[] = ' document.getElementById("startdate' . $id_suffix . '").addClass("ic-date-invalid");'; + $ic_script[] = ' document.getElementById("enddate' . $id_suffix . '").addClass("ic-date-invalid");'; + } + + if ($submit_datesDisplay && $app->isSite()) + { + $ic_script[] = ' document.getElementById("dTable' . $id_suffix . '").addClass("ic-date-invalid");'; + } + elseif ($app->isAdmin()) + { + $ic_script[] = ' document.getElementById("dTable' . $id_suffix . '").addClass("ic-date-invalid");'; + } + + $ic_script[] = ' scroll_to = document.getElementById("ic-dates-fieldset");'; + $ic_script[] = ' scroll_to.scrollIntoView();'; + $ic_script[] = ' return false;'; + $ic_script[] = ' }'; + $ic_script[] = ' else {'; + + if ($app->isSite()) + { + // Disable submit button after first click + $ic_script[] = ' + jQuery(function($) { + $("#submitevent").one("submit", function() { + $(this).find(\'button[type="submit"]\') + .attr("disabled","disabled") + .css({ + "background-color": "transparent", + "color": "grey" + }); + $("#submit").addClass("ic-loader"); + }); + }); + '; + } + + $ic_script[] = ' document.getElementById("form_errors").style.display = "none";'; + + if ($submit_periodDisplay && $app->isSite()) + { + $ic_script[] = ' document.getElementById("startdate' . $id_suffix . '").removeClass("ic-date-invalid");'; + $ic_script[] = ' document.getElementById("enddate' . $id_suffix . '").removeClass("ic-date-invalid");'; + } + elseif ($app->isAdmin()) + { + $ic_script[] = ' document.getElementById("startdate' . $id_suffix . '").removeClass("ic-date-invalid");'; + $ic_script[] = ' document.getElementById("enddate' . $id_suffix . '").removeClass("ic-date-invalid");'; + } + + if ($submit_datesDisplay && $app->isSite()) + { + $ic_script[] = ' document.getElementById("dTable' . $id_suffix . '").removeClass("ic-date-invalid");'; + } + elseif ($app->isAdmin()) + { + $ic_script[] = ' document.getElementById("dTable' . $id_suffix . '").removeClass("ic-date-invalid");'; + } + + $ic_script[] = ' }'; + + if ($submit_periodDisplay && $app->isSite()) + { + $ic_script[] = ' if (isValidStartDate && !isValidEndDate) {'; + $ic_script[] = ' document.getElementById("enddate' . $id_suffix . '").value = startDate.value;'; + $ic_script[] = ' }'; + } + elseif ($app->isAdmin()) + { + $ic_script[] = ' if (isValidStartDate && !isValidEndDate) {'; + $ic_script[] = ' document.getElementById("enddate' . $id_suffix . '").value = startDate.value;'; + $ic_script[] = ' }'; + } + } + +// $customfields = icagendaCustomfields::getCustomfields($parent_form); + +// if ($customfields && $app->isAdmin()) +// { +// $options_required = array('list', 'radio'); + +// foreach ($customfields as $icf) +// { + // If type is list or radio, should have options. All, field required. +// if (((in_array($icf->type, $options_required) && $icf->options) +// || ! in_array($icf->type, $options_required)) +// && $icf->required) +// { +// $ic_script[] = ' var ' . $icf->slug . '_slug = document.getElementById("' . $icf->slug . '_slug");'; +// $ic_script[] = ' if ( ( ' . $icf->slug . '_slug.value == "" ) '; + +// if ($app->isAdmin()) $ic_script[] = ' && ( task != "' . $parent_name . '.cancel" ) '; + +// $ic_script[] = ' ) {'; +// $ic_script[] = ' alert(Joomla.JText._("COM_ICAGENDA_FORM_NC"));'; +// $ic_script[] = ' document.getElementById("message_error").innerHTML = "' +// . JText::sprintf("COM_ICAGENDA_FORM_VALIDATE_FIELD_REQUIRED_NAME", $icf->title) . '";'; +// $ic_script[] = ' document.getElementById("form_errors").style.display = "block";'; +// $ic_script[] = ' document.getElementById("' . $icf->alias . '_alias").addClass("ic-field-invalid");'; +// $ic_script[] = ' document.getElementById("' . $icf->slug . '_slug").addClass("ic-field-invalid");'; +// $ic_script[] = ' scroll_to = document.getElementById("' . $icf->alias . '_alias");'; +// $ic_script[] = ' scroll_to.scrollIntoView();'; +// $ic_script[] = ' return false;'; +// $ic_script[] = ' }'; +// $ic_script[] = ' else {'; +// $ic_script[] = ' document.getElementById("form_errors").style.display = "none";'; +// $ic_script[] = ' document.getElementById("' . $icf->alias . '_alias").removeClass("ic-field-invalid");'; +// $ic_script[] = ' document.getElementById("' . $icf->slug . '_slug").removeClass("ic-field-invalid");'; +// $ic_script[] = ' }'; +// } +// } +// } + + if ($app->isAdmin()) + { + $ic_script[] = ' if (task == "' . $parent_name . '.cancel"'; + $ic_script[] = ' || document.formvalidator.isValid(document.id("' . $parent_name . '-form")))'; + $ic_script[] = ' {'; + $ic_script[] = ' // do field validation'; + $ic_script[] = ' Joomla.submitform(task, document.getElementById("' . $parent_name . '-form"));'; + $ic_script[] = ' }'; + $ic_script[] = ' else {'; + $ic_script[] = ' alert("' . JText::_("JGLOBAL_VALIDATION_FORM_FAILED") . '");'; + $ic_script[] = ' }'; + } + + if ($app->isSite()) + { + $ic_script[] = ' if (!agree.checked) {'; + if ($parent_form == 1) $ic_script[] = ' alert(Joomla.JText._("COM_ICAGENDA_TERMS_AND_CONDITIONS_NOT_CHECKED_REGISTRATION"));'; + if ($parent_form == 2) $ic_script[] = ' alert(Joomla.JText._("COM_ICAGENDA_TERMS_OF_SERVICE_NOT_CHECKED_SUBMIT_EVENT"));'; + $ic_script[] = ' scroll_to = document.getElementById("content");'; + $ic_script[] = ' scroll_to.scrollIntoView();'; + $ic_script[] = ' return false;'; + $ic_script[] = ' }'; + } + + $ic_script[] = ' }'; + + if ($app->isAdmin()) + { + $ic_script[] = '});'; + } + + return implode("\n", $ic_script); + } + + /** + * Function to set timepicker.js and date function strings of translation + * + * @access public static + * + * @since 3.4.1 + */ + static public function loadDateTimePickerJSLanguage() + { + // icdates.js Strings of Translation + JText::script('COM_ICAGENDA_DELETE_DATE'); + + // timepicker.js Strings of Translation + JText::script('JANUARY'); + JText::script('FEBRUARY'); + JText::script('MARCH'); + JText::script('APRIL'); + JText::script('MAY'); + JText::script('JUNE'); + JText::script('JULY'); + JText::script('AUGUST'); + JText::script('SEPTEMBER'); + JText::script('OCTOBER'); + JText::script('NOVEMBER'); + JText::script('DECEMBER'); + + JText::script('SA'); + JText::script('SU'); + JText::script('MO'); + JText::script('TU'); + JText::script('WE'); + JText::script('TH'); + JText::script('FR'); + + JText::script('COM_ICAGENDA_TP_CURRENT'); + JText::script('COM_ICAGENDA_TP_CLOSE'); + JText::script('COM_ICAGENDA_TP_TITLE'); + JText::script('COM_ICAGENDA_TP_TIME'); + JText::script('COM_ICAGENDA_TP_HOUR'); + JText::script('COM_ICAGENDA_TP_MINUTE'); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/form/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/form/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/googlemaps/googlemaps.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/googlemaps/googlemaps.php new file mode 100644 index 00000000..0a9ad191 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/googlemaps/googlemaps.php @@ -0,0 +1,204 @@ +get('GoogleMaps', 1); + + // Access Levels Option + $accessGoogleMaps = $iCparams->get('accessGoogleMaps', 1); + + $markerLat = self::lat($item); + $markerLng = self::lng($item); + + if ($GoogleMaps == 1 + && icagendaEvents::accessLevels($accessGoogleMaps) + && (($markerLat != NULL && $markerLng != NULL) || ($item->address && $iCparams->get('maps_service', '') == '2')) + ) + { + return true; + } + + return false; + } + + /** + * Function to return Google Map (frontend only) + * + * @since 3.6.0 + */ + static public function map($item) + { + $params = JFactory::getApplication()->getParams(); + $map_width = $params->get('m_width', '100%'); + $map_height = $params->get('m_height', '300px'); + $mapID = $item->id; + + $iCparams = JComponentHelper::getParams('com_icagenda'); + $maps_service = $iCparams->get('maps_service', ''); + + $iCgmap = ''; + + if ($maps_service == '2') + { + $embedKey = $iCparams->get('googlemaps_embed_key', ''); + + $iCgmap.= '
    '; + $iCgmap.= ''; + $iCgmap.= '
    '; + } + elseif ($maps_service == '3') + { + $markerLat = self::lat($item); + $markerLng = self::lng($item); + + $iCgmap.= '
    '; + $iCgmap.= '
    '; + $iCgmap.= ''; + } + + return $maps_service ? $iCgmap : JText::_('COM_ICAGENDA_MAPS_SERVICE_NOT_AVAILABLE'); + } + + /** + * Function to return Latitude + * + * @since 3.6.0 + */ + static public function lat($item) + { + // Convert old coordinate value to latitude + if ($item->coordinate != NULL + && $item->lat == '0.0000000000000000') + { + $ex = explode(', ', $item->coordinate); + + $latitude = $ex[0]; + } + else + { + $latitude = ($item->lat != '0.0000000000000000') ? $item->lat : NULL; + } + + return $latitude; + } + + /** + * Function to return Longitude + * + * @since 3.6.0 + */ + static public function lng($item) + { + if ($item->coordinate != NULL + && $item->lng == '0.0000000000000000') + { + $ex = explode(', ', $item->coordinate); + + $longitude = $ex[1]; + } + else + { + $longitude = ($item->lng != '0.0000000000000000') ? $item->lng : NULL; + } + + return $longitude; + } + + /** + * Load Google Maps Scripts. + * + * @param type show (display map) or edit (create and set map values) + * + * @since 3.6.0 + */ + public static function loadGMapScripts($type = 'show') + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + $maps_service = $iCparams->get('maps_service', ''); + + if ($maps_service == '3') + { + // Google Maps api V3 + $document = JFactory::getDocument(); + $scripts = array_keys($document->_scripts); + $gmapApiLoaded = false; + + for ($i = 0; $i < count($scripts); $i++) + { + if ( stripos($scripts[$i], 'maps.googleapis.com') !== false + && stripos($scripts[$i], 'maps.gstatic.com') !== false ) + { + $gmapApiLoaded = true; + } + } + + if ( ! $gmapApiLoaded) + { + $curlang = $document->language; + $lang = substr($curlang, 0, 2); + $key = $iCparams->get('googlemaps_browser_key', ''); + $client_id = $iCparams->get('googlemaps_client_id', ''); + $client = (substr($client_id, 0, 4) === 'gme-') ? $client_id : 'gme-' . $client_id; + + // Google Maps API variables + $apiLang = '?language=' . trim($lang); + $apiLib = '&librairies=places'; + $apiKey = ($key && ! $client_id) ? '&key=' . trim($key) : ''; + $apiClient = $client_id ? '&client=' . trim($client) : ''; + + $document->addScript('https://maps.googleapis.com/maps/api/js' . $apiLang . $apiLib . $apiKey . $apiClient); + } + + if ($type == 'show') + { + JHtml::script('com_icagenda/icmap-front.js', false, true); + } + else + { + JHtml::script('com_icagenda/icmap.js', false, true); + } + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/googlemaps/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/googlemaps/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/googlemaps/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/info/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/info/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/info/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/info/info.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/info/info.php new file mode 100644 index 00000000..dfde5fc8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/info/info.php @@ -0,0 +1,49 @@ +get('release', ''); + $icsys = $params->get('icsys', 'core'); + + $icagenda = 'iCagenda ' . strtoupper($icsys) . ' ' . $release; + + if ($icsys == 'core') + { + $icagenda.= ' by Jooml!C - https://www.joomlic.com'; + } + + echo ""; + + return true; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/list/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/list/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/list/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/list/list.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/list/list.php new file mode 100644 index 00000000..8353d2b8 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/list/list.php @@ -0,0 +1,359 @@ +input; + + $getpage = $jinput->get('page', '1'); + + $params = $app->getParams(); + + $time = $params->get('time', '1'); + $headerList = $params->get('headerList', 1); + + if ($search) + { + $header_title = JText::_('COM_ICAGENDA_HEADER_SEARCH_TITLE'); + $header_many = JText::sprintf('COM_ICAGENDA_HEADER_SEARCH_MANY_EVENTS', $total); + $header_one = JText::sprintf('COM_ICAGENDA_HEADER_SEARCH_ONE_EVENT', $total); + $header_noevt = JText::_('COM_ICAGENDA_HEADER_SEARCH_NO_EVENT'); + } + elseif ($time == '0') + { + // COM_ICAGENDA_ALL + $header_title = JText::_('COM_ICAGENDA_HEADER_ALL_TITLE'); + $header_many = JText::sprintf('COM_ICAGENDA_HEADER_ALL_MANY_EVENTS', $total); + $header_one = JText::sprintf('COM_ICAGENDA_HEADER_ALL_ONE_EVENT', $total); + $header_noevt = JText::_('COM_ICAGENDA_HEADER_ALL_NO_EVENT'); + } + elseif ($time == '1') + { + // COM_ICAGENDA_OPTION_TODAY_AND_UPCOMING + $header_title = JText::_('COM_ICAGENDA_HEADER_TODAY_AND_UPCOMING_TITLE'); + $header_many = JText::sprintf('COM_ICAGENDA_HEADER_TODAY_AND_UPCOMING_MANY_EVENTS', $total); + $header_one = JText::sprintf('COM_ICAGENDA_HEADER_TODAY_AND_UPCOMING_ONE_EVENT', $total); + $header_noevt = JText::_('COM_ICAGENDA_HEADER_TODAY_AND_UPCOMING_NO_EVENT'); + } + elseif ($time == '2') + { + // COM_ICAGENDA_OPTION_PAST + $header_title = JText::_('COM_ICAGENDA_HEADER_PAST_TITLE'); + $header_many = JText::sprintf('COM_ICAGENDA_HEADER_PAST_MANY_EVENTS', $total); + $header_one = JText::sprintf('COM_ICAGENDA_HEADER_PAST_ONE_EVENT', $total); + $header_noevt = JText::_('COM_ICAGENDA_HEADER_PAST_NO_EVENT'); + } + elseif ($time == '3') + { + // COM_ICAGENDA_OPTION_FUTURE + $header_title = JText::_('COM_ICAGENDA_HEADER_UPCOMING_TITLE'); + $header_many = JText::sprintf('COM_ICAGENDA_HEADER_UPCOMING_MANY_EVENTS', $total); + $header_one = JText::sprintf('COM_ICAGENDA_HEADER_UPCOMING_ONE_EVENT', $total); + $header_noevt = JText::_('COM_ICAGENDA_HEADER_UPCOMING_NO_EVENT'); + } + elseif ($time == '4') + { + // COM_ICAGENDA_OPTION_TODAY + $header_title = JText::_('COM_ICAGENDA_HEADER_TODAY_TITLE'); + $header_many = JText::sprintf('COM_ICAGENDA_HEADER_TODAY_MANY_EVENTS', $total); + $header_one = JText::sprintf('COM_ICAGENDA_HEADER_TODAY_ONE_EVENT', $total); + $header_noevt = JText::_('COM_ICAGENDA_HEADER_TODAY_NO_EVENT'); + } + + $report = $report2 = ''; + + if ($total == 1) + { + $report.= '' . $header_one . ''; + } + elseif ($total == 0) + { + $report.= '' . $header_noevt . ''; + } + elseif ($total > 1) + { + $report.= '' . $header_many . ''; + } + + $num = $number_per_page; + + // No display if number does not exist + $pages = ($num == NULL) ? 1 : ceil($total/$num); + + $page_nb = $getpage; + + if ($getpage == NULL) + { + $page_nb = 1; + } + + $report2.= ($pages <= 1) + ? '' + : ' - ' . JText::_('COM_ICAGENDA_EVENTS_PAGE') . ' ' + . $page_nb . ' / ' . $pages . ''; + + // Tag for header title depending of show_page_heading setting + $menuItem = $app->getMenu()->getActive(); + + if (is_object($menuItem) + && $menuItem->params->get('show_page_heading', 1)) + { + $tag = 'h2'; + } + else + { + $tag = 'h1'; + } + + $pageNotFound = '

    ' + . JText::_('COM_ICAGENDA_PAGE_NOT_FOUND') + . '

    ' + . ''; + + // Display Header: title & subtitle + if ($headerList == 1) + { + $header = '
    '; + $header.= '<' . $tag . ' class="ic-header-title">' . $header_title . ''; + $header.= ($getpage <= $pages || $getpage == '1') + ? '
    ' . $report . ' ' . $report2 . '
    ' + : $pageNotFound; + } + + // Display Header: only title + elseif ($headerList == 2) + { + $header = '
    '; + $header.= '<' . $tag . ' class="ic-header-title">' . $header_title . ''; + $header.= ($getpage <= $pages || $getpage == '1') + ? (($search || $total == 0) + ? '
    ' . $report . '
    ' + : '') + : $pageNotFound; + } + + // Display Header: only subtitle + elseif ($headerList == 3) + { + $header = '
    '; + $header.= ($getpage <= $pages || $getpage == '1') + ? '
    ' . $report . ' ' . $report2 . '
    ' + : $pageNotFound; + } + + // Display Header: none + else + { + $header = ($getpage <= $pages || $getpage == '1') + ? (($search || $total == 0) + ? '

    ' . $report . '
    ' + : '
    ') + : $pageNotFound; + } + + $header.='
    '; + $header.= '
    '; + + return $header; + } + + /** + * Function to return pagination for list of events + * + * @since 3.6.0 + */ + public static function pagination($count_items, $arrowtext, $number_per_page, $pagination) + { + $app = JFactory::getApplication(); + $jinput = $app->input; + $getpage = $jinput->get('page', 1); + + // If number of pages < or = 1, no display of pagination + if (($count_items / $number_per_page) <= 1) + { + $nav = ''; + } + else + { + // Total pages + $pages = ($number_per_page == NULL) ? 1 : ceil($count_items / $number_per_page); + + // Set display none if page does not exist to hide pagination + $style = ($getpage > ceil($count_items / $number_per_page)) + ? ' style="display: none;"' + : ''; + + /* Pagination */ + if ($getpage == 1) + { + $nav = '
    '; + } + elseif ($getpage == $pages) + { + $nav = '
    '; + } + else + { + $nav = '
    '; + } + + // In the case of text next/prev + // If no text, use w3c recommendation on accessibility: https://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/C7 + $textNext = ($arrowtext == 1) + ? JText::_('JNEXT') . ' ' + : '' . JText::_('JNEXT') . ''; + + $textBack = ($arrowtext == 1) + ? ' ' . JText::_('JPREV') + : '' . JText::_('JPREV') . ''; + + // Style CSS + $style_goto_page = 'ic-go-to-page'; + $style_goto_btn = 'ic-btn ic-btn-small'; + $style_current_page = 'ic-current-page'; + $style_current_btn = 'ic-btn ic-btn-info ic-active'; + + // Set page numbers for previous and next + $pageBack = ($getpage > 2) ? '&page=' . ($getpage - 1) : ''; + $pageNext = '&page=' . ($getpage + 1); + + // Set Input vars to URL after filtering + $listUrl = 'index.php?option=com_icagenda&view=list'; + + $Itemid = $jinput->get('Itemid', ''); + $listUrl.= $Itemid ? '&Itemid=' . $Itemid : ''; + + $vars = array( + 'filter_search' => '', + 'filter_from' => '', + 'filter_to' => '', + 'filter_category' => '', + 'filter_month' => '', + 'filter_year' => '', + ); + + $filters = $jinput->getArray($vars); + + foreach ($filters as $key => $value) + { + if ($value) + { + $listUrl.= '&' . $key . '=' . $value; + } + } + + // Set Prev and Next buttons + $iC_btnPrev = ''; + + $iC_btnNext = ''; + + // Display PREVIOUS button + if ($pages > 1 + && ($getpage > 1 && $getpage <= $pages)) + { + $nav.= $iC_btnPrev; + } + + // Display pages navigation + if ($pagination == 1) + { + $nav.= '
    '; + + + // Generate pagination + for ($i = 1 ; $i <= $pages ; $i++) + { + if ($i==1 || (($getpage-5) < $i && $i < ($getpage+5)) || $i==$pages) + { + if ($i == $pages && $getpage < ($pages-5)) + { + $nav.= '...'; + } + + $pageVar = ($i > 1) ? '&page=' . $i : ''; + + if ($i == $getpage) + { + $nav.= '' + . '' . $i . '' + . ''; + } + else + { + $nav.= '' + . '' + . $i + . '' + . ''; + } + + if ($i == 1 && $getpage > 6) + { + $nav.= '...'; + } + } + } + + $nav.= '
    '; + } + + // Display NEXT button + if ($pages > 1 + && $getpage < $pages) + { + $nav.= $iC_btnNext; + } + + $nav.= '
    '; + } + + return $nav; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/manager/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/manager/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/manager/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/manager/manager.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/manager/manager.php new file mode 100644 index 00000000..e6453f4b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/manager/manager.php @@ -0,0 +1,245 @@ +input; + + // Get Current Itemid + $this_itemid = $jinput->getInt('Itemid'); + + // Set Manager Actions Url + $event_slug = empty($item->alias) ? $item->id : $item->id . ':' . $item->alias; + $managerActionsURL = 'index.php?option=com_icagenda&view=event&id=' . $event_slug . '&Itemid=' . $this_itemid; + + // Set Email Notification Url to event + $linkEmailUrl = JURI::base() . 'index.php?option=com_icagenda&view=event&id=' . $event_slug . '&Itemid=' . $this_itemid; + + // Get Approval Status + $approved = $item->approval; + + // Get User groups allowed to approve event submitted + $groupid = JComponentHelper::getParams('com_icagenda')->get('approvalGroups', array("8")); + + $groupid = is_array($groupid) ? $groupid : array($groupid); + + // Get User Infos + $user = JFactory::getUser(); + + $icid = $user->get('id'); + $icu = $user->get('username'); + $icp = $user->get('password'); + + // Get User groups of the user logged-in + $userGroups = $user->getAuthorisedGroups(); + + $baseURL = JURI::base(); + $subpathURL = JURI::base(true); + + $baseURL = str_replace('/administrator', '', $baseURL); + $subpathURL = str_replace('/administrator', '', $subpathURL); + + $urlcheck = str_replace('&','&', JRoute::_('administrator/index.php?option=com_icagenda&view=events') . '&icu=' . $icu . '&icp=' . $icp . '&filter_search=' . $item->id); + + // Sub Path filtering + $subpathURL = ltrim($subpathURL, '/'); + + // URL Event Check filtering + $urlcheck = ltrim($urlcheck, '/'); + + if (substr($urlcheck, 0, strlen($subpathURL)+1) == "$subpathURL/") + { + $urlcheck = substr($urlcheck, strlen($subpathURL)+1); + } + + $urlcheck = rtrim($baseURL, '/') . '/' . ltrim($urlcheck, '/'); + + $icu_approve = $jinput->get('manageraction', ''); + + if (version_compare(JVERSION, '3.0', 'lt')) + { + $approveIcon = ''; + } + else + { + $approveIcon = ''; + } + + $approval_msg = JText::sprintf('COM_ICAGENDA_APPROVE_AN_EVENT_NOTICE', $approveIcon); + $approval_title = JText::_('COM_ICAGENDA_APPROVE_AN_EVENT_LBL'); + $approval_type = 'notice'; + + $jlayout = $jinput->get('layout', ''); + $layouts_array = array('event', 'registration'); + $icu_layout = in_array($jlayout, $layouts_array) ? $jlayout : ''; + + if ( array_intersect($userGroups, $groupid) + || in_array('8', $userGroups) ) + { + if ($approved == 1) + { + if (version_compare(JVERSION, '3.0', 'lt')) + { + $approvalButton = '' + . '
    ' + . ''; + } + else + { + $approvalButton = '' + . '' + . ''; + } + + if ($icu_approve != 'approve') + { + $app->enqueueMessage($approval_msg, $approval_title, $approval_type); + } + + if ($icu_approve == 'approve' + && $jinput->get('view', '') == 'event') + { + $db = Jfactory::getDbo(); + $query = $db->getQuery(true); + $query->clear(); + $query->update('#__icagenda_events'); + $query->set('approval = 0'); + $query->where(' id = ' . (int) $item->id); + $db->setQuery((string) $query); + $db->query($query); + + $approveSuccess = '"' . $item->title . '"'; + $alertmsg = JText::sprintf('COM_ICAGENDA_APPROVED_SUCCESS', $approveSuccess); + $alerttitle = JText::_('COM_ICAGENDA_APPROVED'); + $alerttype = 'success'; + $approvedLink = JRoute::_($managerActionsURL); + + self::approvalNotification($item->created_by_email, $item->username, $item->title, $linkEmailUrl); + + // Plugin Event handler 'iCagendaOnNewEvent' + // JOOMLA 3.x/2.5 SWITCH + if (version_compare(JVERSION, '3.0', 'ge')) + { + $dispatcher = JEventDispatcher::getInstance(); + } + else + { + $dispatcher = JDispatcher::getInstance(); + } + + JPluginHelper::importPlugin('icagenda'); + + $dispatcher->trigger('iCagendaOnNewEvent', array($item)); + + // System Message Approval + $app->enqueueMessage($alertmsg, $alerttitle, $alerttype); + } + else + { + return $approvalButton; + } + } + else + { + return false; + } + } + else + { + return false; + } + } + + /** + * Function to send approval notification emails + * + * @since 3.6.0 + */ + public static function approvalNotification($creatorEmail, $eventUsername, $eventTitle, $eventLink) + { + $app = JFactory::getApplication(); + + // Load Joomla Config Mail Options + $sitename = $app->getCfg('sitename'); + $mailfrom = $app->getCfg('mailfrom'); + $fromname = $app->getCfg('fromname'); + + // Create User Mailer + $approvedmailer = JFactory::getMailer(); + + // Set Sender of Notification Email + $approvedmailer->setSender(array( $mailfrom, $fromname )); + + // Set Recipient of Notification Email + $approvedmailer->addRecipient($creatorEmail); + + // Set Subject of Notification Email + $approvedsubject = JText::sprintf('COM_ICAGENDA_APPROVED_USEREMAIL_SUBJECT', $eventTitle); + $approvedmailer->setSubject($approvedsubject); + + // Set Body of Notification Email + $approvedbodycontent = JText::sprintf('COM_ICAGENDA_SUBMISSION_ADMIN_EMAIL_HELLO', $eventUsername) . ',

    '; + $approvedbodycontent.= JText::sprintf('COM_ICAGENDA_APPROVED_USEREMAIL_BODY_INTRO', $sitename) . '

    '; +// $approvedbodycontent.= JText::_('COM_ICAGENDA_APPROVED_USEREMAIL_EVENT_LINK').'
    '; + + $eventLink_html = '
    ' . $eventLink . ''; + $approvedbodycontent.= JText::sprintf('COM_ICAGENDA_APPROVED_USEREMAIL_EVENT_LINK', $eventLink_html).'

    '; + +// $approvedbodycontent.= '' . $eventLink . '

    '; + $approvedbodycontent.= '
    ' . JText::_('COM_ICAGENDA_APPROVED_USEREMAIL_EVENT_LINK_INFO') . '

    '; + + $approvedbody = rtrim($approvedbodycontent); + + $approvedmailer->isHTML(true); + + // JDocs: When sending HTML emails you should normally set the Encoding to base64 + // in order to avoid unwanted characters in the output. + // See https://docs.joomla.org/Sending_email_from_extensions + $approvedmailer->Encoding = 'base64'; // JDocs Sending HTML Email + + $approvedmailer->setBody($approvedbody); + + // Send User Notification Email + if (isset($creatorEmail)) + { + $send = $approvedmailer->Send(); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/menus/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/menus/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/menus/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/menus/menus.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/menus/menus.php new file mode 100644 index 00000000..709039aa --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/menus/menus.php @@ -0,0 +1,403 @@ +getParams(); + + $options_time = JComponentHelper::getParams('com_icagenda')->get('time', '0'); + + // List all menu items linking to list of events + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('m.title, m.published, m.id, m.params, m.language') + ->from('#__menu AS m') + ->where( "(m.link = 'index.php?option=com_icagenda&view=list') AND (m.published = 1)" ); + + if (JLanguageMultilang::isEnabled()) + { + $query->where('m.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + $db->setQuery($query); + $link = $db->loadObjectList(); + + $iC_list_menus = array(); + + foreach ($link as $iClistMenu) + { + $menuitemid = $iClistMenu->id; + + if ($menuitemid) + { + $menu = $app->getMenu(); + $menuparams = $menu->getParams($menuitemid); + + $mcatid = $menuparams->get('mcatid', ''); + $menufilter = ($menuparams->get('time', '') != '') + ? $menuparams->get('time') + : $options_time; + + if (is_array($mcatid)) + { + $mcatid = implode(',', $mcatid); + } + + array_push($iC_list_menus, $menuitemid . '_' . $mcatid . '_' . $menufilter); + } + } + + return $iC_list_menus; + } + + /** + * Function to return all published 'List of Events' menu items + * + * @access public static + * @param none + * @return array of menu item info this way : Itemid-mcatid-lang + * + * @since 3.4.0 + */ + public static function iClistMenuItems() + { + $app = JFactory::getApplication(); + + // List all menu items linking to list of events + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + $query->select('m.title, m.published, m.id, m.params, m.language') + ->from('#__menu AS m') + ->where( "(m.link = 'index.php?option=com_icagenda&view=list') AND (m.published = 1)" ); + + if (JLanguageMultilang::isEnabled()) + { + $query->where('m.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); + } + + $query->order('m.id ASC'); + + $db->setQuery($query); + $iC_list_menu_items = $db->loadObjectList(); + + if ($iC_list_menu_items) + { + return $iC_list_menu_items; + } + else + { + return array(); + } + } + + /** + * Function to return menu Itemid to display an event + * + * @access public static + * @return menu Itemid + * + * @since 3.5.7 + */ + public static function thisEventItemid($date, $category, $array_menuitems = null) + { + $iC_list_menus = $array_menuitems ? $array_menuitems : self::iClistMenuItemsInfo(); + + $datetime_today = JHtml::date('now', 'Y-m-d H:i'); + $date_today = JHtml::date('now', 'Y-m-d'); + + // set menu link for each event (itemID) depending of category and/or language + $onecat = $multicat = '0'; + $link_one = $link_multi = ''; + + $menu_IDs_category = array(); + $menu_IDs_all = array(); + $itemID_is_set = 0; + + foreach ($iC_list_menus as &$iCm) + { + $value = explode('_', $iCm); + $iCmenu_id = $value['0']; + $iCmenu_mcatid = $value['1']; + $iCmenu_filter = $value['2']; + + $iCmenu_mcatid_array = ! is_array($iCmenu_mcatid) ? explode(',', $iCmenu_mcatid) : array(); + + // Menu can display past events + if ($iCmenu_filter == 2 + && strtotime($date) < strtotime($datetime_today) + && ! $itemID_is_set) + { + // If menu category filter is set, and item category is in filtered categories + if (in_array($category, $iCmenu_mcatid_array)) + { + $menu_IDs_category[] = $iCmenu_id; + $itemID_is_set = $itemID_is_set + 1; + } + elseif ( ! $iCmenu_mcatid) + { + $menu_IDs_all[] = $iCmenu_id; + } + } + + // Menu can display today's events + elseif ($iCmenu_filter == 4 + && strtotime($date) > strtotime($date_today) + && strtotime($date) < strtotime("+1 DAY", strtotime($date_today)) + && ! $itemID_is_set) + { + // If menu category filter is set, and item category is in filtered categories + if (in_array($category, $iCmenu_mcatid_array)) + { + $menu_IDs_category[] = $iCmenu_id; + $itemID_is_set = $itemID_is_set + 1; + } + elseif ( ! $iCmenu_mcatid) + { + $menu_IDs_all[] = $iCmenu_id; + } + } + + // Menu can display today's events and upcoming events + elseif ($iCmenu_filter == 1 + && strtotime($date) >= strtotime($date_today) + && ! $itemID_is_set) + { + // If menu category filter is set, and item category is in filtered categories + if (in_array($category, $iCmenu_mcatid_array)) + { + $menu_IDs_category[] = $iCmenu_id; + $itemID_is_set = $itemID_is_set + 1; + } + elseif ( ! $iCmenu_mcatid) + { + $menu_IDs_all[] = $iCmenu_id; + } + } + + // Menu can display upcoming events + elseif ($iCmenu_filter == 3 + && strtotime($date) > strtotime($datetime_today) + && ! $itemID_is_set) + { + // If menu category filter is set, and item category is in filtered categories + if (in_array($category, $iCmenu_mcatid_array)) + { + $menu_IDs_category[] = $iCmenu_id; + $itemID_is_set = $itemID_is_set + 1; + } + elseif ( ! $iCmenu_mcatid) + { + $menu_IDs_all[] = $iCmenu_id; + } + } + + // Menu can display all events + elseif ($iCmenu_filter == '0' + && ! $itemID_is_set) + { + // If menu category filter is set, and item category is in filtered categories + if (in_array($category, $iCmenu_mcatid_array)) + { + $menu_IDs_category[] = $iCmenu_id; + $itemID_is_set = $itemID_is_set + 1; + } + elseif ( ! $iCmenu_mcatid) + { + $menu_IDs_all[] = $iCmenu_id; + } + } + + if ($iCmenu_mcatid) + { + $nb_cat_filter = count($iCmenu_mcatid_array); + + for ($i = $category; in_array($i, $iCmenu_mcatid_array); $i++) + { + if ($nb_cat_filter == 1) + { + $link_one = $iCmenu_id; + } + elseif ($nb_cat_filter > 1) + { + $link_multi = $iCmenu_id; + } + } + } + } + + if (count($menu_IDs_category)) + { + if ($link_one) + { + $linkid = $link_one; + } + elseif ($link_multi) + { + $linkid = $link_multi; + } + else + { + $linkid = $menu_IDs_category[0]; + } + } + elseif (count($menu_IDs_all)) + { + $linkid = $menu_IDs_all[0]; + } + else + { +// $linkid = '#'; + $linkid = null; + } + + return $linkid; + } + + /** + * Function to return menu Itemid to display an event + * + * @access public static + * @return menu Itemid + * + * @since 3.6.4 + */ + public static function displayEventItemid($Itemid, $event_filters) + { + $menu_filters = self::getFiltersMenuItem($Itemid); + $datetime_today = JHtml::date('now', 'Y-m-d H:i'); + $date_today = JHtml::date('now', 'Y-m-d'); + $linkid = null; + + $iCmenu_id = $Itemid; + $iCmenu_time = $menu_filters['time']; + $iCmenu_mcatid = ! is_array($menu_filters['mcatid']) + ? explode(',', $menu_filters['mcatid']) + : $menu_filters['mcatid']; + + $event_date = $event_filters['date']; + $event_category = $event_filters['catid']; + + // Language and Access not currently used as items already filtered in frontend + $event_language = $event_filters['language']; + $event_access = $event_filters['access']; + + // If menu category filter is set, and item category is in filtered categories OR No category filter (display all) + if (in_array($event_category, $iCmenu_mcatid) + || in_array('', $iCmenu_mcatid)) + { + // Menu can display past events + if ($iCmenu_time == 2 + && strtotime($event_date) < strtotime($datetime_today) + ) + { + $linkid = $iCmenu_id; + } + + // Menu can display today's events + elseif ($iCmenu_time == 4 + && strtotime($event_date) > strtotime($date_today) + && strtotime($event_date) < strtotime("+1 DAY", strtotime($date_today)) + ) + { + $linkid = $iCmenu_id; + } + + // Menu can display today's events and upcoming events + elseif ($iCmenu_time == 1 + && strtotime($event_date) >= strtotime($date_today) + ) + { + $linkid = $iCmenu_id; + } + + // Menu can display upcoming events + elseif ($iCmenu_time == 3 + && strtotime($event_date) > strtotime($datetime_today) + ) + { + $linkid = $iCmenu_id; + } + + // Menu can display all events + elseif ($iCmenu_time == '0') + { + $linkid = $iCmenu_id; + } + } + + return $linkid; + } + + /** + * Function to return filtering settings of one menu item + * + * @access public static + * @param none + * @return array of menu item info this way : Itemid-mcatid-lang + * + * @since 3.6.4 + */ + public static function getFiltersMenuItem($Itemid) + { + if ($Itemid) + { + $app = JFactory::getApplication(); + $menu = $app->getMenu(); + $menuItem = $menu->getItem($Itemid); + $menuParams = $menu->getParams($Itemid); + + $iCparams_time = JComponentHelper::getParams('com_icagenda')->get('time', '0'); + + $mcatid = $menuParams->get('mcatid', ''); + $time = ($menuParams->get('time', '') != '') + ? $menuParams->get('time') + : $iCparams_time; + $language = $menuItem->language; + $access = $menuItem->access; + + $ItemidFilters = array( + 'mcatid' => $mcatid, + 'time' => $time, + 'language' => $language, + 'access' => $access, + ); + + return $ItemidFilters; + } + + return false; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/params/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/params/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/params/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/params/params.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/params/params.php new file mode 100644 index 00000000..883eff11 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/params/params.php @@ -0,0 +1,96 @@ +get('icsys', 'core'); + + if ($icsys == 'pro') + { + jimport('joomla.user.helper'); + + $crypt1 = JUserHelper::genRandomPassword(2); + $crypt2 = JUserHelper::genRandomPassword(2); + $salt_8 = JUserHelper::genRandomPassword(8); + $salt_16 = JUserHelper::genRandomPassword(16); + $salt_32 = JUserHelper::genRandomPassword(32); + + $password = $params->get('password', ''); + + $is_crypted = substr_count($password, '$'); + + if ($is_crypted != 3 && strlen($password) != 0) + { + $encoded = base64_encode($password); // Encode Password Data Storage + + if (strlen($encoded) > 32) + { + $salt1 = $salt_16; + $salt2 = $salt_8; + } + elseif (strlen($encoded) < 32 && strlen($encoded) > 16) + { + $salt1 = $salt_16; + $salt2 = $salt_8; + } + else + { + $salt1 = $salt_32; + $salt2 = $salt_16; + } + + $pass_encoded = '$' . $crypt1 . '$' . $crypt2 . '$' . $salt1 . '.' . $encoded . '/' . $salt2; + $password = $pass_encoded; + + // Get the params and set the new values + $params->set('password', $password); + + // Get a new database query instance + $db = JFactory::getDBO(); + $query = $db->getQuery(true); + + // Build the query + $query->update('#__extensions AS a'); + $query->set('a.params = ' . $db->quote((string)$params)); + $query->where('a.element = "com_icagenda"'); + + // Execute the query + $db->setQuery($query); + $db->query(); + } + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/registration/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/registration/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/registration/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/registration/participants.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/registration/participants.php new file mode 100644 index 00000000..99155d47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/registration/participants.php @@ -0,0 +1,596 @@ +get('RegButtonLink', ''); + + // Hide/Show Option + $participantList = $iCparams->get('participantList', 0); + + // Access Levels Option + $accessParticipantList = $iCparams->get('accessParticipantList', 1); + + if ($participantList == 1 + && ! $regLink + && icagendaEvents::accessLevels($accessParticipantList) + ) + { + return $participantList; + } + + return false; + } + + /** + * Function to display title List of Participants (if no slide effect) + * + * @since 3.6.0 + */ + static public function listTitle($item) + { + $params = JFactory::getApplication()->getParams(); + + // Get Option if usage of iCagenda registration form for this event + $evtParams = icagendaEvent::evtParams($item); + $regLink = $evtParams->get('RegButtonLink', ''); + + $participantList = $params->get('participantList', 0); + $participantSlide = $params->get('participantSlide', ''); + + $registration = $item->params->get('statutReg', ''); + + if ($participantSlide == 0 + && $registration == 1 + && $participantList == 1 + && ! $regLink + ) + { + return JText::_('COM_ICAGENDA_EVENT_LIST_OF_PARTICIPANTS'); + } + } + + /** + * Function to display list of participants + * TO BE REFACTORED (in process) + * + * @since 3.6.0 + * @version 3.6.6 + */ + static public function registeredUsers($i) + { + $app = JFactory::getApplication(); + $input = $app->input; + + $eventTimeZone = null; + + // Get Component PARAMS + $iCparams = JComponentHelper::getParams('com_icagenda'); + + // Get Type Registration (for all dates or per date) + $typeReg = $i->params->get('typeReg', 1); + + // Preparing connection to db + $db = JFactory::getDbo(); + + // Preparing the query + $query = $db->getQuery(true); + $query->select(' r.id AS regID, r.userid AS userid, r.name AS registeredUsers, r.date as regDate, r.people as regPeople, r.email as regEmail, + u.name AS name, u.username AS username, GROUP_CONCAT(ua.user_action) AS user_action') + ->from('#__icagenda_registration AS r') + ->leftJoin('#__users as u ON u.id = r.userid') + ->leftJoin('#__icagenda_user_actions as ua ON ua.parent_id = r.id') + ->group('r.id, ua.parent_id') + ->where('r.eventid = ' . (int) $i->id) + ->where('r.state = 1'); + + // Get var event date alias if set or var 'event_date' set to session in event details view + $session = JFactory::getSession(); + $event_date = $session->get('event_date', ''); + $get_date = $input->get('date', ($event_date ? date('Y-m-d-H-i', strtotime($event_date)) : '')); + + // Convert to SQL datetime if set, or return empty. + $dateday = icagendaEvent::convertDateAliasToSQLDatetime($get_date); + + // Registration type: by single date/period (1) + if ($dateday && $typeReg == 1) + { +// $query->where('r.date = ' . $db->q($dateday)); // This is the good logic if correctly set + $query->where('(r.date = ' . $db->q($dateday) . ' OR (r.date = "" AND r.period = 1))'); + } + elseif ( ! $dateday && $typeReg == 1) + { +// $query->where('r.date = "" AND r.period = 0'); // This is the good logic if correctly set + $query->where('r.date = ""'); + } + + $db->setQuery($query); + + $registeredUsers = $db->loadObjectList(); + $nbusers = count($registeredUsers); +// $nbusers = $i->registered; + $nbmax = $nbusers-1; + $registration = $i->params->get('statutReg', ''); + $n = '0'; + + // Slide Params + $participantList = $iCparams->get('participantList', 0); + $participantSlide = $iCparams->get('participantSlide', 1); + $participantDisplay = $iCparams->get('participantDisplay', 1); + $fullListColumns = $iCparams->get('fullListColumns', 'tiers'); + + // logged-in Users: Name/User Name Option + $nameJoomlaUser = $iCparams->get('nameJoomlaUser', 1); + + $this_date = JHtml::date($dateday, 'Y-m-d H:i', $eventTimeZone); + + // Start List of Participants + jimport( 'joomla.html.html.sliders' ); + $slider_c = ''; + + $list_participants = ''; + + if ($participantList == 1 && $registration == 1) + { + $n_list='names_noslide'; + + // Check Admin / Organiser permissions to access registration data + $organiser_rights = JFactory::getUser()->authorise('icagenda.access.registrations', 'com_icagenda'); + + + if ($participantSlide == 1) + { + $n_list = 'names_slide'; + $slider_c = 'class="pane-slider content"'; + + $list_participants.= JHtml::_('sliders.start', 'icagenda', array('useCookie'=>0, 'startOffset'=>-1, 'startTransition'=>1)); + $list_participants.= JHtml::_('sliders.panel', JText::_('COM_ICAGENDA_EVENT_LIST_OF_PARTICIPANTS'), 'slide1'); + } + + foreach ($registeredUsers as $reguser) + { + $this_reg_date = strtotime($reguser->regDate) + ? JHtml::date($reguser->regDate, 'Y-m-d H:i', $eventTimeZone) + : $reguser->regDate; + + if ( ($this_reg_date == $this_date) + || ($typeReg == 2) + ) + { + $n = $n+1; + } + + // Registration by dates, and registration date is not filled + elseif ($typeReg == 1 + && ! $this_reg_date) + { + $n = $n+1; + } + } + + if ($nbusers == NULL || ($n == 0 && ! empty($get_date))) + { + $list_participants.= '
    '; + $list_participants.= ' ' . JText::_('COM_ICAGENDA_NO_REGISTRATION') . ' '; + $list_participants.= '
    '; + } + + // Full display + elseif ($participantDisplay == 1) + { + $column = isset($fullListColumns) ? $fullListColumns : 'tiers'; + + $list_participants.= '
    '; + + foreach ($registeredUsers as $reguser) + { + $this_reg_date = strtotime($reguser->regDate) + ? JHtml::date($reguser->regDate, 'Y-m-d H:i', $eventTimeZone) + : $reguser->regDate; + + if ( ($this_reg_date == $this_date || empty($get_date)) + || $typeReg == 2 + || ($typeReg == 1 && ! $this_reg_date) + ) + { + // Get participant privacy consents + $user_actions = explode(',', $reguser->user_action); + + // Get Name consent + $name_consents = array(); + +// foreach ($user_actions AS $k => $action) +// { +// $ex_action = explode('__', $action); + +// if ($ex_action[0] == 'consent_name' +// && isset($ex_action[1])) +// { +// $name_consents = explode('_', $ex_action[1]); +// } +// } + + if (in_array('consent_name_public', $user_actions)) $name_consents = array('public'); + if (in_array('consent_name_users', $user_actions)) $name_consents = array('users'); + + $force_name_visibility = $iCparams->get('participant_name_consent', ''); + + if ($force_name_visibility == '0') + { + $participant_name_visibility = $iCparams->get('participant_name_visibility', ''); + + if ($participant_name_visibility == 1) + { + $name_consents = array('public'); + } + elseif ($participant_name_visibility == 2) + { + $name_consents = array('users'); + } + } + + if (in_array('public', $name_consents) + || (in_array('users', $name_consents) && JFactory::getUser()->id > 0)) + { + // Get Username and name (To check: Is it needed ?) + if ( ! empty($reguser->userid)) + { + $data_name = $reguser->name; + $data_username = $reguser->username; + + if ($nameJoomlaUser == 1) + { + $reguser->registeredUsers = $reguser->registeredUsers; + } + else + { + $reguser->registeredUsers = $data_username; + } + } + + $participant_name = $reguser->registeredUsers; + } + elseif($organiser_rights) + { + // Information to be extended for logged-in user with admin/organiser permissions... + $participant_name = $reguser->registeredUsers; + } + else + { + $participant_name = JText::_('IC_ANONYMOUS'); + } + + // Get Gravatar consent + if (in_array('consent_gravatar', $user_actions)) + { + $avatar = md5(strtolower(trim($reguser->regEmail))); + $participant_avatar = '' . $participant_name . ''; + } + else + { + $participant_avatar = ''; + } + + $regDate = ''; + + + // Test if registered date before 3.3.3 could be converted + if (strtotime($reguser->regDate)) + { + // Control if date valid format (Y-m-d H:i) + $datetime_format = 'Y-m-d H:i:s'; + $datetime_input = $reguser->regDate; + $datetime_input = trim($datetime_input); + $datetime_is_valid = date($datetime_format, strtotime($datetime_input)) == $datetime_input; + + if ($datetime_is_valid) // New Data value (since 3.3.3) + { + $ex_reg_datetime_db = explode (' ', $datetime_input); + $registered_date = icagendaRender::dateToFormat(date('Y-m-d', strtotime($ex_reg_datetime_db['0']))); + $reg_time_get = isset($ex_reg_datetime_db['1']) ? $ex_reg_datetime_db['1'] : ''; + } + else // Test if old date format (before 3.3.3) could be converted. If not, displays old format. + { + $ex_reg_datetime = explode (' - ', trim($reguser->regDate)); + + // Control if date valid format (Y-m-d) - Means could be converted + $date_format = 'Y-m-d H:i:s'; + $date_input = $ex_reg_datetime['0']; + $date_input = trim($date_input); + $date_str = strtotime($date_input); + $date_is_valid = date($date_format, $date_str) == $date_input; + + if ($date_is_valid) + { + $registered_date = icagendaRender::dateToFormat(date('Y-m-d', $date_str)); + } + else + { + $registered_date = $ex_reg_datetime['0']; + } + + $reg_time_get = isset($ex_reg_datetime['1']) ? $ex_reg_datetime['1'] : ''; + } + + $regDate.= $registered_date; + + if ($reg_time_get) + { + $regDate.= ' - ' . date('H:i', strtotime($reg_time_get)); + } + } + else + { + $regDate.= $reguser->regDate; + } + + // Display List of Participants + if ($n <= $nbmax || $n == $nbusers) + { + $list_participants.= '' + . '' + . ''; + + $list_participants.= ''; + + $list_participants.= ''; + + $list_participants.= '
    '; + $list_participants.= $participant_avatar; + $list_participants.= '' + . '' . $participant_name . '' + . ' (' . $reguser->regPeople . ')
    ' + . '' . $regDate . '' + . '
    '; + } + } + } + + $list_participants.= '
    '; + } + + // Avatar display + elseif ($participantDisplay == 2) + { + $list_participants.= '
    '; + + foreach ($registeredUsers as $reguser) + { + $this_reg_date = strtotime($reguser->regDate) + ? JHtml::date($reguser->regDate, 'Y-m-d H:i', $eventTimeZone) + : $reguser->regDate; + + if ( ($this_reg_date == $this_date || empty($get_date)) + || $typeReg == 2 + || ($typeReg == 1 && ! $this_reg_date) + ) + { + // Get participant privacy consents + $user_actions = explode(',', $reguser->user_action); + + // Get Name consent + $name_consents = array(); + +// foreach ($user_actions AS $k => $action) +// { +// $ex_action = explode('__', $action); + +// if ($ex_action[0] == 'consent_name' +// && isset($ex_action[1])) +// { +// $name_consents = explode('_', $ex_action[1]); +// } +// } + + if (in_array('consent_name_public', $user_actions)) $name_consents = array('public'); + if (in_array('consent_name_users', $user_actions)) $name_consents = array('users'); + + $force_name_visibility = $iCparams->get('participant_name_consent', ''); + + if ($force_name_visibility == '0') + { + $participant_name_visibility = $iCparams->get('participant_name_visibility', ''); + + if ($participant_name_visibility == 1) + { + $name_consents = array('public'); + } + elseif ($participant_name_visibility == 2) + { + $name_consents = array('users'); + } + } + + if (in_array('public', $name_consents) + || (in_array('users', $name_consents) && JFactory::getUser()->id > 0)) + { + // Get Username and name (To check: Is it needed ?) + if ( ! empty($reguser->userid)) + { + $data_name = $reguser->name; + $data_username = $reguser->username; + + if ($nameJoomlaUser == 1) + { + $reguser->registeredUsers = $reguser->registeredUsers; + } + else + { + $reguser->registeredUsers = $data_username; + } + } + + $participant_name = $reguser->registeredUsers; + } + elseif($organiser_rights) + { + // Information to be extended for logged-in user with admin/organiser permissions... + $participant_name = $reguser->registeredUsers; + } + else + { + $participant_name = JText::_('IC_ANONYMOUS'); + } + + // Get Gravatar consent + if (in_array('consent_gravatar', $user_actions)) + { + $avatar = md5(strtolower(trim($reguser->regEmail))); + $participant_avatar = '' . $participant_name . ''; + } + else + { + $participant_avatar = ''; + } + + if ($n <= $nbmax || $n == $nbusers) + { + $list_participants.= '
    ' . $participant_avatar . '
    ' . $participant_name . '
    '; + } + } + } + $list_participants.= '
    '; + } + + // Name/username display + elseif ($participantDisplay == 3) + { + $list_participants.= '
    '; + $list_participants.= '
    '; + + $list_username = ''; + + foreach ($registeredUsers as $reguser) + { + $this_reg_date = strtotime($reguser->regDate) + ? JHtml::date($reguser->regDate, 'Y-m-d H:i', $eventTimeZone) + : $reguser->regDate; + + if ( ($this_reg_date == $this_date ||empty($get_date)) + || $typeReg == 2 + || ($typeReg == 1 && ! $this_reg_date) + ) + { + // Get participant privacy consents + $user_actions = explode(',', $reguser->user_action); + + // Get Name consent + $name_consents = array(); + +// foreach ($user_actions AS $k => $action) +// { +// $ex_action = explode('__', $action); + +// if ($ex_action[0] == 'consent_name' +// && isset($ex_action[1])) +// { +// $name_consents = explode('_', $ex_action[1]); +// } +// } + + if (in_array('consent_name_public', $user_actions)) $name_consents = array('public'); + if (in_array('consent_name_users', $user_actions)) $name_consents = array('users'); + + $force_name_visibility = $iCparams->get('participant_name_consent', ''); + + if ($force_name_visibility == '0') + { + $participant_name_visibility = $iCparams->get('participant_name_visibility', ''); + + if ($participant_name_visibility == 1) + { + $name_consents = array('public'); + } + elseif ($participant_name_visibility == 2) + { + $name_consents = array('users'); + } + } + + if (in_array('public', $name_consents) + || (in_array('users', $name_consents) && JFactory::getUser()->id > 0)) + { + // Get Username and name (To check: Is it needed ?) + if ( ! empty($reguser->userid)) + { + $data_name = $reguser->name; + $data_username = $reguser->username; + + if ($nameJoomlaUser == 1) + { + $reguser->registeredUsers = $reguser->registeredUsers; + } + else + { + $reguser->registeredUsers = $data_username; + } + } + + $participant_name = $reguser->registeredUsers; + } + elseif($organiser_rights) + { + // Information to be extended for logged-in user with admin/organiser permissions... + $participant_name = $reguser->registeredUsers; + } + else + { + $participant_name = JText::_('IC_ANONYMOUS'); + } + + + $list_username.= $participant_name . ', '; + } + } + + $list_participants.= trim($list_username, ", "); + + $list_participants.= '
    '; + $list_participants.= '
    '; + } + + if ($participantSlide == 1) + { + $list_participants.= JHtml::_('sliders.end'); + } + } + else + { + $list_participants.= ''; + } + + return $list_participants; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/registration/registration.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/registration/registration.php new file mode 100644 index 00000000..05477606 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/registration/registration.php @@ -0,0 +1,1257 @@ +getQuery(true); + + $query->select('sum(' . $db->qn('r.people') . ') AS total') + ->from($db->qn('#__icagenda_registration', 'r')) + ->where($db->qn('r.eventid') . ' = ' . (int) $eventID) + ->where($db->qn('r.state') . ' = 1'); + + // Registration type: by single date/period (1) + if ($regDate && $typeReg == 1) + { +// $query->where('r.date = ' . $db->q($regDate)); // This is the good logic if correctly set + $query->where('(r.date = ' . $db->q($regDate) . ' OR (r.date = "" AND r.period = 1))'); + } + elseif ( ! $regDate && $typeReg == 1) + { +// $query->where('r.date = "" AND r.period = 0'); // This is the good logic if correctly set + $query->where('r.date = ""'); + } + + // Registration type: all dates (2) +// else +// { +// $query->where('r.date = "" AND r.period = 1'); +// } + + $db->setQuery($query); + + $total = $db->loadResult(); + + return $total; + } + + /** + * Function to get list of registered people per date/period for one event + * Not Use: BETA + * + * @since 3.6.6 + */ + public static function getListRegisteredTotal($eventID) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('sum(' . $db->qn('r.people') . ') AS people, r.date AS date, r.period AS period') + ->from($db->qn('#__icagenda_registration', 'r')) + ->where($db->qn('r.eventid') . ' = ' . (int) $eventID) + ->where($db->qn('r.state') . ' = 1') + ->group('r.date'); + + $db->setQuery($query); + + $list = $db->loadObjectList(); + + return $list; + } + + /** + * Function to get available tickets for one event/date + * + * @since 3.6.5 + */ + public static function getTicketsAvailable($eventID, $regDate, $typeReg = '1', $maxReg = '1000000') + { + $regDate = ($typeReg == 1) ? $regDate : ''; + $registered = self::getRegisteredTotal($eventID, $regDate, $typeReg); + $ticketsAvailable = ($maxReg - $registered); + + if ($ticketsAvailable < 0) $ticketsAvailable = '0'; + + return $ticketsAvailable; + } + + /** + * Function to get list of available tickets per date/period for one event + * Not Use: BETA + * + * @since 3.6.6 + */ + public static function getListTicketsAvailable($eventID, $typeReg = '1', $maxReg = '1000000') + { + $listDatesTicketsAvailable = array(); + + $listRegisteredTotal = self::getListRegisteredTotal($eventID); + + foreach ($listRegisteredTotal as $k => $v) + { + $listDatesTicketsAvailable[$v->date] = ($maxReg - $v->people); + } + + return $listDatesTicketsAvailable; + } + + /** + * Function to get max number of tickets bookable (people) for one event/date + * + * @since 3.6.5 + */ + public static function getTicketsBookable($eventID, $regDate, $typeReg = '1', $maxReg = '1000000', $tickets = '5') + { + $ticketsAvailable = self::getTicketsAvailable($eventID, $regDate, $typeReg, $maxReg); + + if ($ticketsAvailable > $tickets) + { + return $tickets; + } + else + { + return $ticketsAvailable; + } + } + + /** + * Function to return dates drop list for registrable dates + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + * version 3.6.5 + * + * @TODO set option/value to array + * @TODO migrate HTML rendering fot options text to form field type getOptions ($type = registrationdates) + */ + public static function formDatesList($item) + { + $app = JFactory::getApplication(); + $params = $app->getParams(); + $iCparams = JComponentHelper::getParams('com_icagenda'); + + $eventTimeZone = null; + $date_today = JHtml::date('now', 'Y-m-d'); + $date_time_today = JHtml::date('now', 'Y-m-d H:i'); + $allDates = self::eventAllDates($item); + $timeformat = $params->get('timeformat', 1); + $perioddates = iCDatePeriod::listDates($item->startdate, $item->enddate, $eventTimeZone); + +// $evtParams = icagendaEvent::evtParams($item->params); + $typeReg = $item->params->get('typeReg', '1'); + $max_tickets = $item->params->get('maxReg', '1000000'); + $regDeadline = $item->params->get('reg_deadline', 1); + + // Check the period if individual dates + $only_startdate = ($item->weekdays || $item->weekdays == '0') ? false : true; + + $lang_time = ($timeformat == 1) ? 'H:i' : 'h:i A'; + + sort($allDates); + + $p = 0; + +// print_r(self::getListTicketsAvailable($item->id, $typeReg, $max_tickets)); +// TEST $listTicketsAvailable = $item->listTicketsAvailable; + + $upDays = array(); + + foreach ($allDates as $k => $d) + { + $date_control = JHtml::date($d, 'Y-m-d H:i', $eventTimeZone); + + if ($only_startdate && in_array($date_control, $perioddates)) + { + $is_full_period = true; + $datetime_date = ($regDeadline == 2) + ? date('Y-m-d H:i:s', strtotime($item->enddate)) + : date('Y-m-d H:i:s', strtotime($item->startdate)); + $datetime_check = $datetime_date; + } + else + { + $is_full_period = false; + $datetime_date = date('Y-m-d H:i:s', strtotime($d)); + $datetime_check = ($regDeadline == 2) + ? date('Y-m-d', strtotime($d)) . ' 23:59:59' + : date('Y-m-d H:i:s', strtotime($d)); + } + + $regDate = $is_full_period ? '' : $datetime_date; + $nb_tickets_left = self::getTicketsBookable($item->id, $regDate, $typeReg, $max_tickets, $item->params->get('maxNbTicketsPerReg', 5)); + +// TEST $nb_tickets_left = isset($listTicketsAvailable[$regDate]) ? $listTicketsAvailable[$regDate] : $max_tickets; + + $date_today_compare = ($item->displaytime == 1) ? $date_time_today : $date_today; + + if (strtotime($datetime_check) > strtotime($date_today_compare) + && $nb_tickets_left > 0) + { + // Removed for now, as gives confusion (nb of maximum tickets for one registration to selected date) +// $tickets_left = ($max_tickets != '1000000') ? ' (✓' . $nb_tickets_left . ')' : ''; + $tickets_left = ''; + + if ($is_full_period) + { + if ($p == 0) + { + if (icagendaRender::dateToFormat($item->startdate) == icagendaRender::dateToFormat($item->enddate)) + { + $upDays[$k] = '@@' . strip_tags(icagendaRender::dateToFormat($item->startdate)) . $tickets_left; + } + else + { + $upDays[$k] = '@@' . strip_tags(icagendaRender::dateToFormat($item->startdate)) . ' ➜ ' . strip_tags(icagendaRender::dateToFormat($item->enddate)) . $tickets_left; + } + + $p = $p+1; + } + } + else + { + $date = strip_tags(icagendaRender::dateToFormat($d)); + + $event_time = ($item->displaytime == 1) ? ' - ' . date($lang_time, strtotime($datetime_date)) : ''; + + $upDays[$k] = $datetime_date . '@@' . $date . $event_time . $tickets_left; + } + } + } + + return $upDays; + } + + /** + * Function to get option setting for max nb of tickets per registration + * + * @since 3.6.0 (Migrated from 3.5) + * version 3.6.5 + */ + public static function maxNbTicketsPerReg($params) + { + $iCparams = JComponentHelper::getParams('com_icagenda'); + + $useGlobal = $params->get('maxRlistGlobal', ''); + $evt_maxRlist = $params->get('maxRlist', '5'); + + // Control and edit param values to iCagenda v3 + if ($useGlobal == '1') $useGlobal = ''; + elseif ($useGlobal == '0') $useGlobal = '2'; + + if ($useGlobal == '2') + { + $maxNbTicketsPerReg = $evt_maxRlist; + } + else + { + $maxNbTicketsPerReg = $iCparams->get('maxRlist', '5'); + } + + return $maxNbTicketsPerReg; + } + + + + + /** + * Function pre-formated to display Register button and registered bubble + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + * version 3.6.5 + */ + static public function reg($i) + { + $statutReg = $i->params->get('statutReg', ''); + $regDeadline = $i->params->get('reg_deadline', 1); + $RegButtonText = $i->params->get('RegButtonText', ''); + $typeReg = $i->params->get('typeReg', '1'); + $regLink = $i->params->get('RegButtonLink', ''); + + $accessReg = self::accessReg($i); + $availableDates = self::upcomingDatesBooking($i); + $ticketsCouldBeBooked = self::ticketsCouldBeBooked($i); + + $registered = isset($i->registered) ? $i->registered : '0'; + + // Initialize controls + $date_today = JHtml::date('now', 'Y-m-d'); + $date_time_today = JHtml::date('now', 'Y-m-d H:i'); + + $access = '0'; + $control = ''; + $TextRegBt = ''; + + $period = unserialize($i->period); + $period = is_array($period) ? $period : array(); + $only_startdate = ($i->weekdays || $i->weekdays == '0') ? false : true; + $datetime_startdate = JHtml::date($i->startdate, 'Y-m-d H:i', null); + + // Get var event date alias if set or var 'event_date' set to session in event details view + $session = JFactory::getSession(); + $event_date = $session->get('event_date', ''); + $get_date = JFactory::getApplication()->input->get('date', ($event_date ? date('Y-m-d-H-i', strtotime($event_date)) : '')); + + if ($get_date) + { + // Convert to SQL datetime if set, or return empty. + $dateday = icagendaEvent::convertDateAliasToSQLDatetime($get_date); + + $date_is_upcoming = (strtotime($dateday) > strtotime($date_time_today)) ? true : false; + + $is_full_period = false; + + // If registration until end date + if ($regDeadline == 2) + { + if (in_array($dateday, $period)) + { + // Case Single Date from period (weekdays): + $endDatetime = date('Y-m-d', strtotime($dateday)) . ' ' . date('H:i:s', strtotime($i->enddate)); + } + else + { + // Case Single Date: + $endDatetime = date('Y-m-d', strtotime($dateday)) . ' 23:59:59'; + } + } + else + { + $startDatetime = date('Y-m-d H:i', strtotime($dateday)); + } + } + else + { + if ($only_startdate && in_array($datetime_startdate, $period)) + { + $is_full_period = true; + } + else + { + $is_full_period = false; + } + + if (count($period) > 0 + && $only_startdate + && (strtotime($datetime_startdate) < strtotime($date_time_today)) + ) + { + $date_is_upcoming = false; + } + else + { + $date_is_upcoming = true; + } + + // If registration until end date + if ($regDeadline == 2) + { + if ($is_full_period) + { + $endDatetime = date('Y-m-d H:i:s', strtotime($i->enddate)); + } + else + { + $endDatetime = date('Y-m-d', strtotime($date_today)) . ' ' . date('H:i:s', strtotime($i->enddate)); + } + } + else + { + $startDatetime = date('Y-m-d H:i', strtotime($i->startdate)); + } + } + + // Access Control + $user = JFactory::getUser(); + $userLevels = $user->getAuthorisedViewLevels(); + + if ($i->params->get('RegButtonText')) + { + $TextRegBt = $i->params->get('RegButtonText'); + } + elseif ($RegButtonText) + { + $TextRegBt = $RegButtonText; + } + else + { + $TextRegBt = JText::_( 'COM_ICAGENDA_REGISTRATION_REGISTER'); + } + + $regButton_type = ''; // DEV. NOT IN USE + + if ($regButton_type == 'button') // DEV. NOT IN USE + { + $doc = JFactory::getDocument(); + $style = '.regis_button {' + . 'text-transform: none !important;' + . 'padding: 10px 14px 10px;' + . '-webkit-border-radius: 10px;' + . '-moz-border-radius: 10px;' + . 'border-radius: 10px;' + . 'color: #FFFFFF;' + . 'background-color: #D90000;' + . '*background-color: #751616;' + . 'background-image: -ms-linear-gradient(top,#D90000,#751616);' + . 'background-image: -webkit-gradient(linear,0 0,0 100%,from(#D90000),to(#751616));' + . 'background-image: -webkit-linear-gradient(top,#D90000,#751616);' + . 'background-image: -o-linear-gradient(top,#D90000,#751616);' + . 'background-image: linear-gradient(top,#D90000,#751616);' + . 'background-image: -moz-linear-gradient(top,#D90000,#751616);' + . 'background-repeat: repeat-x;' + . 'filter: progid:dximagetransform.microsoft.gradient(startColorstr="#D90000",endColorstr="#751616",GradientType=0);' + . 'filter: progid:dximagetransform.microsoft.gradient(enabled=false);' + . '*zoom: 1;' + . '-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);' + . '-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);' + . 'box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);' + . '}' + . '.regis_button:hover {' + . 'color: #F9F9F9;' + . 'background-color: #b60000;' + . '*background-color: #531111;' + . 'background-image: -ms-linear-gradient(top,#b60000,#531111);' + . 'background-image: -webkit-gradient(linear,0 0,0 100%,from(#b60000),to(#531111));' + . 'background-image: -webkit-linear-gradient(top,#b60000,#531111);' + . 'background-image: -o-linear-gradient(top,#b60000,#531111);' + . 'background-image: linear-gradient(top,#b60000,#531111);' + . 'background-image: -moz-linear-gradient(top,#b60000,#531111);' + . 'background-repeat: repeat-x;' + . 'filter: progid:dximagetransform.microsoft.gradient(startColorstr="#b60000",endColorstr="#531111",GradientType=0);' + . 'filter: progid:dximagetransform.microsoft.gradient(enabled=false);' + . '*zoom: 1;' + . '}'; + $doc->addStyleDeclaration( $style ); + } + + + if ($statutReg == 1) + { + $formDatesList = self::formDatesList($i); + $dates_bookable = $formDatesList ? $formDatesList : array(); + $this_event_url = JURI::getInstance()->toString(); + + $cleanurl = preg_replace('/&date=[^&]*/', '', $this_event_url); + $cleanurl = preg_replace('/\?date=[^\?]*/', '', $cleanurl); + + $isSef = JFactory::getApplication()->getCfg('sef'); + $date_var = ($isSef == 1) ? '?date=' :'&date='; + + $select_date = '
    '; + + foreach ($dates_bookable AS $d) + { + $ex_d = explode('@@', $d); + $date_url = date('Y-m-d-H-i', strtotime($ex_d[0])); + + $select_date.= ''; + + // If the date bookable is the current next date (DEPRECATED ?) + $is_next = ($date_url == date('Y-m-d-H-i', strtotime($i->next))) ? true : false; + } + + $select_date.= '
    '; + + /* + * Buttons HTML + */ + // Button Register OK + $btn_register_ok = ''; + $btn_register_ok.= '
    '; + $btn_register_ok.= ' ' . $TextRegBt; + $btn_register_ok.= '
    '; + $btn_register_ok.= '
    '; + + // Button Register Private + $btn_register_vip = ''; + $btn_register_vip.= '
    '; + $btn_register_vip.= ' ' . $TextRegBt; + $btn_register_vip.= '
    '; + $btn_register_vip.= '
    '; + + // Button Select Date + $btn_select_date = ''; + $btn_select_date.= '
    '; + $btn_select_date.= ' ' . JText::_('COM_ICAGENDA_REGISTRATION_DATE_NO_TICKETS_LEFT'); + $btn_select_date.= '
    '; + $btn_select_date.= '
    '; + $btn_select_date.= '' . JText::_('COM_ICAGENDA_REGISTRATION_REGISTER_ANOTHER_DATE') . ''; + $btn_select_date.= '
    '; + + // Button Registration Close + $btn_reg_close = '
    '; + $btn_reg_close.= ' ' . JText::_('COM_ICAGENDA_REGISTRATION_CLOSED'); + $btn_reg_close.= '
    '; + + // Button Registration Complete + $btn_reg_complete = '
    '; + $btn_reg_complete.= ' ' . JText::_('COM_ICAGENDA_REGISTRATION_EVENT_FULL'); + $btn_reg_complete.= '
    '; + + + $reg_button = '
    '; + + // Available date(s) (boolean) and ticket(s) available for this event (boolean) + if ($availableDates + && $ticketsCouldBeBooked + ) + { + if (in_array($accessReg, $userLevels)) + { + if ($i->registered == self::maxReg($i)) + { + if ($typeReg != '2') + { + $reg_button.= $btn_select_date; + } + else + { + $reg_button.= $btn_reg_close; + } + } + +// elseif ($date_is_upcoming +// || $is_next) + elseif ($date_is_upcoming) + { + $reg_button.= $btn_register_ok; + } + + // Registration Until end date (if registration for all dates, allow to register to a past date) + elseif ($regDeadline == 2 + && (strtotime($endDatetime) > strtotime($date_time_today) || $typeReg == 2) + ) + { + $reg_button.= $btn_register_ok; + } + + + elseif ($regDeadline == 1 + && strtotime($startDatetime) < strtotime($date_time_today) + ) + { + if ($typeReg != '2' && $availableDates) + { + $reg_button.= $btn_select_date; + } + else + { + $reg_button.= $btn_reg_close; + } + } + + else + { + $reg_button.= $btn_select_date; + } + } + else + { + $reg_button.= $btn_register_vip; + } + } + + // Available date(s) (boolean) but no ticket left (boolean) + elseif ($availableDates + && ! $ticketsCouldBeBooked + ) + { + if ( ! $date_is_upcoming && $typeReg == 2) + { + $reg_button.= $btn_reg_close; + } + elseif ( ! $date_is_upcoming && $typeReg == 1) + { + $reg_button.= $btn_reg_complete; + } + else + { + $reg_button.= $btn_select_date; + } + } + elseif ( ! $availableDates) + { + $reg_button.= $btn_reg_close; + } + else + { + return false; + } + + if ( ! $regLink) + { + $reg_button.= ' '; + $reg_button.= '
    ' . $registered . '
    '; + } + + $reg_button.= '
    '; + } + else + { + return false; + } + + return $reg_button; + } + + /** + * Function to return Registration Status for this event + * + * @todo check and remove from library, as not needed in modules or list + * DEPRECATED 3.6.0 : use now $item->params (global + event params merged) + */ + static public function statutReg($item) + { + $params = JFactory::getApplication()->getParams(); + $gstatutReg = $params->get('statutReg', ''); + + $evtParams = icagendaEvent::evtParams($item->params); + $evtstatutReg = $evtParams->get('statutReg', ''); + + // Control and edit param values to iCagenda v3 + if ($evtstatutReg == '2') + { + $evtstatutReg = '0'; + } + + $statutReg = ($evtstatutReg != '') ? $evtstatutReg : $gstatutReg; + + return $statutReg; + } + + /** + * Function to return Registration Access Level for this event + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + */ + static public function accessReg($item) + { + $reg_form_access = JComponentHelper::getParams('com_icagenda')->get('reg_form_access', 1); +// $evtParams = icagendaEvent::evtParams($item); + $accessReg = $item->params->get('accessReg', $reg_form_access); + + return $accessReg; + } + + /** + * Function return true if upcoming dates for Booking + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + */ + public static function upcomingDatesBooking($item) + { + if (count(self::formDatesList($item)) > 0) + { + return true; + } + + return false; + } + + /** + * Ticket(s) could be booked + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + */ + static public function ticketsCouldBeBooked($i) + { + $eventTimeZone = null; + $date_today = JHtml::date('now', 'Y-m-d'); + $datetime_today = JHtml::date('now', 'Y-m-d H:i'); + $allDates = self::eventAllDates($i); + $maxReg = $i->params->get('maxReg', '1000000'); + $typeReg = $i->params->get('typeReg', '1'); + $perioddates = iCDatePeriod::listDates($i->startdate, $i->enddate, $eventTimeZone); + $regDeadline = $i->params->get('reg_deadline', 1); + + // Check the period if individual dates + $only_startdate = ($i->weekdays || $i->weekdays == '0') ? false : true; + + sort($allDates); + + // If registration for all dates, and not registration until end of event, no registration if past date(s) + if ($typeReg == '2' + && $regDeadline != 2) + { + foreach ($allDates as $k => $d) + { + if (strtotime($d) < strtotime($datetime_today)) + { + return false; + } + } + } + + $total_tickets_bookable = 0; + + foreach ($allDates as $k => $d) + { + $date_control = JHtml::date($d, 'Y-m-d H:i', $eventTimeZone); + $is_in_period = in_array($date_control, $perioddates) ? true : false; + + if ($only_startdate && $is_in_period) + { + $is_full_period = true; + } + else + { + $is_full_period = false; + } + + $datetime_date = date('Y-m-d H:i:s', strtotime($d)); + $datetime_startdate = date('Y-m-d H:i:s', strtotime($i->startdate)); + $datetime_enddate = date('Y-m-d H:i:s', strtotime($i->enddate)); + + // Nb of tickets left + $nb_tickets_left = $maxReg - $i->registered; + + // is Full period (& reg.type for all dates) & reg.limit until start date + if ($is_full_period + && $typeReg == 2 + && $regDeadline == 1 + && (strtotime($datetime_startdate) < strtotime($date_today)) + ) + { + $total_tickets_bookable = 0; + } + + // is Full period & reg.limit until end dates + elseif ($is_full_period + && $regDeadline == 2 + && (strtotime($datetime_enddate) <= strtotime($datetime_today)) + ) + { + $total_tickets_bookable = 0; + } + + // timestamp datetime > timestamp today date & reg.limit until start date + elseif ($regDeadline == 1 + && strtotime($d) > strtotime($date_today)) + { + if ($nb_tickets_left > 0) + { + $total_tickets_bookable = $total_tickets_bookable + $nb_tickets_left; + } + } + + // is in period & timestamp datetime > timestamp today date & reg.limit until end date + elseif ($regDeadline == 2 + && $is_in_period + && strtotime(date('Y-m-d', strtotime($d)) . ' ' . date('H:i', strtotime($datetime_enddate))) > strtotime($datetime_today) + ) + { + if ($nb_tickets_left > 0) + { + $total_tickets_bookable = $total_tickets_bookable + $nb_tickets_left; + } + } + + // is single date & timestamp date > timestamp today date & reg.limit until end date + elseif ($regDeadline == 2 + && ! $is_in_period + && strtotime(date('Y-m-d', strtotime($d))) > strtotime($date_today) + ) + { + if ($nb_tickets_left > 0) + { + $total_tickets_bookable = $total_tickets_bookable + $nb_tickets_left; + } + } + } + + if ($total_tickets_bookable > 0) + { + return true; + } + + return false; + } + + /** + * Function to list all dates of an event + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + * version 3.6.6 + */ + static public function eventAllDates($i) + { + // Declare eventAllDates array + $eventAllDates = array(); + + // Get WeekDays Array + $WeeksDays = iCDatePeriod::weekdaysToArray($i->weekdays); + + // If Single Dates, added each one to All Dates for this event + $singledates = iCString::isSerialized($i->dates) ? unserialize($i->dates) : array(); + + foreach ($singledates as $sd) + { + $isValid = iCDate::isDate($sd); + + if ( $isValid ) + { + array_push($eventAllDates, date('Y-m-d H:i:s', strtotime($sd))); + } + } + + $perioddates = iCDatePeriod::listDates($i->startdate, $i->enddate); + + if ( (isset ($perioddates)) + && ($perioddates != NULL) ) + { + foreach ($perioddates as $Dat) + { + if (in_array(date('w', strtotime($Dat)), $WeeksDays)) + { + $isValid = iCDate::isDate($Dat); + + if ($isValid) + { + $SingleDate = date('Y-m-d H:i:s', strtotime($Dat)); + + array_push($eventAllDates, $SingleDate); + } + } + } + } + + return $eventAllDates; + } + + /** + * Function to get number of tickets booked (for one date of the event) + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + */ + public static function nbTicketsBooked($event_id, $date = null, $typeReg = 1, $is_full_period = false) + { + // Registrations total + $db = Jfactory::getDbo(); + $query = $db->getQuery(true); + $query->select('sum(r.people) AS count'); + $query->from('#__icagenda_registration AS r'); + $query->where('r.state = 1'); + + $query->where('r.eventid = ' . $db->q($event_id)); + + // Get nb of tickets booked for the date only if registration per date + if ($typeReg != 2) + { + // Single date + if ($date && ! $is_full_period) + { + $query->where('r.date = ' . $db->q($date)); + } + + // Full Period (DEPRECATED 3.7) + else + { + $query->where('r.date = "" AND r.period = 0'); + } + } + + $db->setQuery($query); + + $result = $db->loadResult(); + + return $result; + } + + /** + * Function to get link to registration page + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + */ + public static function regUrl($i) + { + $app = JFactory::getApplication(); + $isSef = $app->getCfg('sef'); + $params = $app->getParams(); + $Itemid = $app->input->get('Itemid'); + $date = $app->input->get('date', ''); + $this_itemid = $params->get('itemid', $Itemid); + + $event_slug = empty($i->alias) ? $i->id : $i->id . ':' . $i->alias; + $date_var = ($isSef == '1') ? '?date=' : '&date='; + $date_slug = $date ? $date_var . $date : ''; + + $icagenda_form = JRoute::_('index.php?option=com_icagenda&view=registration&id=' . $event_slug + . '&Itemid=' . (int) $this_itemid) +// . $date_slug + ; + +// $evtParams = icagendaEvent::evtParams($i->params); + $regLink = $i->params->get('RegButtonLink', ''); + $regLinkArticle = $i->params->get('RegButtonLink_Article', $icagenda_form); + $regLinkUrl = $i->params->get('RegButtonLink_Url', $icagenda_form); + $RegButtonTarget = $i->params->get('RegButtonTarget', '0'); + + if ($RegButtonTarget == 1) + { + $browserTarget = '_blank'; + } + else + { + $browserTarget = '_parent'; + } + + if ($regLink == 1 && is_numeric($regLinkArticle)) + { + $regUrl = JRoute::_('index.php?option=com_content&view=article&id=' . $regLinkArticle) . '" rel="nofollow" target="' . $browserTarget; + } + elseif ($regLink == 2) + { + $regUrl = iCUrl::urlParsed($regLinkUrl) . '" rel="nofollow" target="' . $browserTarget; + } + else + { + $regUrl = $icagenda_form . '" rel="nofollow" target="' . $browserTarget; + } + + return $regUrl; + } + + /** + * Function Max Nb Tickets (Control if set) + * + * @todo check and remove if not needed in modules or list + * DEPRECATED 3.6.0 : do not use $item->params (global + event params merged) + */ + static public function maxNbTickets($item) + { + $evtParams = icagendaEvent::evtParams($item->params); + $maxNbTickets = $evtParams->get('maxReg', '1000000'); + + if ($maxNbTickets != '1000000' + && self::statutReg($item) == '1') + { + return $maxNbTickets; + } + } + + /** + * Function to check a valid email address + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + */ + static public function validEmail($email) + { + $isValid = true; + $atIndex = strrpos($email, "@"); + + if (is_bool($atIndex) && !$atIndex) + { + $isValid = false; + } + else + { + $domain = substr($email, $atIndex+1); + $local = substr($email, 0, $atIndex); + $localLen = strlen($local); + $domainLen = strlen($domain); + + if ($localLen < 1 || $localLen > 64) + { + // local part length exceeded + $isValid = false; + } + elseif ($domainLen < 1 || $domainLen > 255) + { + // domain part length exceeded + $isValid = false; + } + elseif ($local[0] == '.' || $local[$localLen-1] == '.') + { + // local part starts or ends with '.' + $isValid = false; + } + elseif (preg_match('/\\.\\./', $local)) + { + // local part has two consecutive dots + $isValid = false; + } + elseif (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain)) + { + // character not valid in domain part + $isValid = false; + } + elseif (preg_match('/\\.\\./', $domain)) + { + // domain part has two consecutive dots + $isValid = false; + } + elseif (!preg_match('/^(\\\\.|[A-Za-z0-9!#%&`_=\\/$\'*+?^{}|~.-])+$/', str_replace("\\\\","",$local))) + { + // character not valid in local part unless + // local part is quoted + if (!preg_match('/^"(\\\\"|[^"])+"$/', str_replace("\\\\","",$local))) + { + $isValid = false; + } + } + + // Check the domain name + if ($isValid + && ! self::is_valid_domain_name($domain)) + { + return false; + } + + // Uncommented below to have PHP run a proper DNS check (risky on shared hosts!) + /** + if ($isValid && !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A"))) { + // domain not found in DNS + $isValid = false; + } + /**/ + } + + return $isValid; + } + + /** + * Function to check if a domain is valid + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + */ + static public function is_valid_domain_name($domain_name) + { + $pieces = explode(".", $domain_name); + + foreach ($pieces as $piece) + { + if (!preg_match('/^[a-z\d][a-z\d-]{0,62}$/i', $piece) + || preg_match('/-$/', $piece)) + { + return false; + } + } + + return true; + } + + + + + // TO BE CHECKED + + /** + * Function Max Registrations per event (OLD before 3.2.8, for use with old theme packs or custom one) + * + * Keep for B/C : DEPRECATED! (edit: still used... to be checked...) + */ + static public function maxReg($item) + { + $maxReg = $item->params->get('maxReg', '1000000'); + + return $maxReg; + } + + + + /** + * DEPRECATED: to be removed 3.7.0 + */ + + /** + * Ticket(s) booked + * + * @since 3.6.0 (Migrated from 3.5 - TO BE REVIEWED) + * + * @deprecated 3.6.5 - @removed 3.7.0 + */ + static public function totalRegistered($i) + { + $app = JFactory::getApplication(); + $session = JFactory::getSession(); + + $eventTimeZone = null; + $date_today = JHtml::date('now', 'Y-m-d'); + $allDates = self::eventAllDates($i); + $evtParams = icagendaEvent::evtParams($i->params); + $typeReg = $evtParams->get('typeReg', ''); + $perioddates = iCDatePeriod::listDates($i->startdate, $i->enddate, $eventTimeZone); + + // Check the period if individual dates + $only_startdate = ($i->weekdays || $i->weekdays == '0') ? false : true; + + sort($allDates); + + $total_tickets_booked = 0; + + // Get date from url if set, and from session if set + $url_date = $app->input->get('date', ''); + $session_date = $session->get('session_date', ''); + + if ($url_date) + { + $ex_date = explode('-', $url_date); + $defaultDate = (count($ex_date) == 5) + ? $ex_date[0] . '-' . $ex_date[1] . '-' . $ex_date[2] . ' ' . $ex_date[3] . ':' . $ex_date[4] . ':00' + : ''; + } + else + { + $defaultDate = $session_date; + } + + $this_date = ! empty($defaultDate) ? JHtml::date($defaultDate, 'Y-m-d H:i:s', $eventTimeZone) : null; + + // By Single Dates (registration type is not for all dates of the events) + if ($typeReg != 2) + { + foreach ($allDates as $k => $d) + { + $date_control = JHtml::date($d, 'Y-m-d H:i', $eventTimeZone); + + if ($only_startdate && in_array($date_control, $perioddates)) + { + $is_full_period = true; + } + else + { + $is_full_period = false; + } + + $datetime_date = date('Y-m-d H:i:s', strtotime($d)); + $nb_tickets = self::getNbTicketsBooked($datetime_date, $i->registered, $i->id, $is_full_period); + + // NO Date in URL - FULL PERIOD (no weekdays) - Date IS in the PERIOD + if ( ! $defaultDate && $only_startdate && in_array($date_control, $perioddates)) + { + $total_tickets_booked = $nb_tickets; + } + + // Date in URL - FULL PERIOD (no weekdays) - Date IS NOT in the PERIOD + elseif ($defaultDate && $only_startdate && ! in_array($date_control, $perioddates)) + { + if ($nb_tickets > 0 + && strtotime($this_date) == strtotime($datetime_date)) + { + $total_tickets_booked = $total_tickets_booked + $nb_tickets; + } + + // Only one date for registration, and the setting option of event is set to list of dates (equals "for all dates of event) + elseif (count($allDates) == 1) + { + $nb_tickets = self::getNbTicketsBooked(null, $i->registered, $i->id, $is_full_period); + $total_tickets_booked = $total_tickets_booked + $nb_tickets; + } + } + + // Date in URL - PERIOD is Individual DATES (weekdays selected) + elseif ($defaultDate && ! $only_startdate) + { + if ($nb_tickets > 0 + && strtotime($this_date) == strtotime($datetime_date)) + { + $total_tickets_booked = $total_tickets_booked + $nb_tickets; + } + } + + // NO Date in URL (all tickets for the events, not taking into account the dates) + elseif ( ! $defaultDate) + { + if ($nb_tickets > 0) + { + $total_tickets_booked = self::getNbTicketsBooked(null, $i->registered, $i->id, $is_full_period); + } + } + } + } + else + { + $nb_tickets = self::getNbTicketsBooked('period', $i->registered, $i->id); + + $total_tickets_booked = $nb_tickets; + } + + return $total_tickets_booked; + } + + /** + * Function to get number of tickets booked (for one date) + * + * @since 3.6.0 (Migrated from 3.5) + * + * @deprecated 3.6.5 - @removed 3.7.0 + */ + public static function getNbTicketsBooked($date, $event_registered, $event_id = null, $date_control = null) + { + $eventTimeZone = null; + $event_registered = is_array($event_registered) ? $event_registered : array(); + $nb_registrations = 0; + + // Get Date if set in url as var + $get_date = JFactory::getApplication()->input->get('date', null); + + if ( ! $get_date && $date_control) + { + $get_date = null; + } + + foreach ($event_registered AS $reg) + { + $ex_reg = explode('@@', $reg); // eventid@@date@@people + + if ( ! $date || $date == 'period') + { + $nb_registrations = $nb_registrations + $ex_reg[2]; + } + elseif ($get_date + && $event_id == $ex_reg[0] + && date('Y-m-d H:i', strtotime($date)) == date('Y-m-d H:i', strtotime($ex_reg[1])) + ) + { + $nb_registrations = $nb_registrations + $ex_reg[2]; + } + elseif ( ! $get_date + && $event_id == $ex_reg[0] + && $ex_reg[1] == 'period' + ) + { + $nb_registrations = $nb_registrations + $ex_reg[2]; + } + elseif ( ! $get_date + && $event_id == $ex_reg[0] + && date('Y-m-d H:i', strtotime($date)) == date('Y-m-d H:i', strtotime($ex_reg[1])) + ) + { + $nb_registrations = $nb_registrations + $ex_reg[2]; + } + } + + return $nb_registrations; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/render/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/render/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/render/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/render/render.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/render/render.php new file mode 100644 index 00000000..18873fd0 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/render/render.php @@ -0,0 +1,174 @@ +get('titleTransform', ''); + $mbString = extension_loaded('mbstring'); + + // Escape the output. + $title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8'); + + if ($text_transform == 1) + { + $titleFormat = $mbString ? iCString::mb_ucfirst(mb_strtolower($title)) : ucfirst(strtolower($title)); + + return $titleFormat; + } + elseif ($text_transform == 2) + { + $titleFormat = $mbString ? mb_convert_case($title, MB_CASE_TITLE, "UTF-8") : ucwords(strtolower($title)); + + return $titleFormat; + } + elseif ($text_transform == 3) + { + $titleFormat = $mbString ? mb_strtoupper($title, "UTF-8") : strtoupper($title); + + return $titleFormat; + } + elseif ($text_transform == 4) + { + $titleFormat = $mbString ? mb_strtolower($title, "UTF-8") : strtolower($title); + + return $titleFormat; + } + + return $title; + } + + /** + * Function to return formatted date (using globalization from iC Library) + * + * @since 3.6.0 + */ + static public function dateToFormat($date) + { + if (iCDate::isDate($date)) + { + // Date Format Option (Global Component Option) + $date_format_global = JComponentHelper::getParams('com_icagenda')->get('date_format_global', 'Y - m - d'); + + // Date Format Option (Menu Option) + $date_format_menu = JFactory::getApplication()->getParams()->get('format', ''); + + // Set Date Format option to be used + $format = $date_format_menu ? $date_format_menu : $date_format_global; + + // Separator Option + $separator = JFactory::getApplication()->getParams()->get('date_separator', ' '); + + if ( ! is_numeric($format)) + { + // Update old Date Format options of versions before 2.1.7 + $format = str_replace(array('nosep', 'sepb', 'sepa'), '', $format); + $format = str_replace('.', ' .', $format); + $format = str_replace(',', ' ,', $format); + } + + $dateFormatted = iCGlobalize::dateFormat($date, $format, $separator); + + return $dateFormatted; + } + else + { + return false; + } + } + + /** + * Function to return formatted time + * + * @since 3.6.0 + */ + static public function dateToTime($date) + { + if (iCDate::isDate($date)) + { + $eventTimeZone = null; + $datetime = JHtml::date($date, 'Y-m-d H:i', $eventTimeZone); + $timeformat = JComponentHelper::getParams('com_icagenda')->get('timeformat', 1); + + $lang_time = ($timeformat == 1) ? 'H:i' : 'h:i A'; + + $time = date($lang_time, strtotime($datetime)); + + return $time; + } + + return false; + } + + /** + * Function to return Email Cloaked TAG + * + * @since 3.6.8 + */ + static public function emailTag($email) + { + $plugin = JPluginHelper::getPlugin('content', 'emailcloak'); + + if ($plugin) + { + $params = new JRegistry($plugin->params); + $mode = $params->get('mode', 1); + + return JHtml::_('email.cloak', $email, $mode); + } + + return $email; + } + + /** + * Function to return Website TAG + * + * @since 3.6.0 + */ + static public function websiteTag($url) + { + $targetOption = JComponentHelper::getParams('com_icagenda')->get('targetLink', ''); + $target = ! empty($targetOption) ? '_blank' : '_parent'; + + $link = iCUrl::urlParsed($url, 'scheme'); + + return '' . $url . ''; + } + + /** + * Function to return File attachment TAG + * + * @since 3.6.0 + */ + static public function fileTag($file) + { + return '' . JText::_('COM_ICAGENDA_EVENT_DOWNLOAD') . ''; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/joomla25.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/joomla25.php new file mode 100644 index 00000000..cc9e5ed5 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/joomla25.php @@ -0,0 +1,71 @@ +_scripts); + $scriptFound = false; + $count_scripts = count($scripts); + + for ($i = 0; $i < $count_scripts; $i++) + { + if (stripos($scripts[$i], 'jquery.min.js') !== false + || stripos($scripts[$i], 'jquery.js') !== false) + { + $scriptFound = true; + } + } + + // jQuery Library Loader + if ( ! $scriptFound) + { + // Load jQuery, if not loaded before + if ( ! $app->get('jquery')) + { + $app->set('jquery', true); + + // Add jQuery Library + $document->addScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); + JHtml::script('com_icagenda/jquery.noconflict.js', false, true); + } + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/style.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/style.php new file mode 100644 index 00000000..eafdb5fa --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/style.php @@ -0,0 +1,151 @@ +get('largewidththreshold', 0); + $mbString = extension_loaded('mbstring'); + + if ($largethreshold > 0) + { + $css_contents = @file_get_contents( + JPATH_ROOT . "/components/com_icagenda/themes/packs/$template/css/{$template}_{$type}_large.css"); + + $css = preg_replace('!/\*.*?\*/!s', '', $css_contents); + $size_css = $mbString ? mb_strlen($css) : strlen($css); + +// if (is_string($css) && !empty($css) && ($size_css > 10)) +// { + $media_css .= "\n@media screen and (min-width:{$largethreshold}px){\n{$css}\n}\n"; + $max_threshold = $largethreshold - 1; +// } + } + + $mediumthreshold = (int) $com_params->get('mediumwidththreshold', 0); + + if ($mediumthreshold > 0) + { + $css_contents = @file_get_contents( + JPATH_ROOT . "/components/com_icagenda/themes/packs/$template/css/{$template}_{$type}_medium.css"); + + $css = preg_replace('!/\*.*?\*/!s', '', $css_contents); + $size_css = $mbString ? mb_strlen($css) : strlen($css); + +// if (is_string($css) && !empty($css) && ($size_css > 10)) +// { + $upper_limit = $max_threshold > 0 ? " and (max-width:{$max_threshold}px)" : ''; + $media_css .= "\n@media screen and (min-width:{$mediumthreshold}px)$upper_limit{\n{$css}\n}\n"; + $max_threshold = $mediumthreshold - 1; +// } + } + + $smallthreshold = (int) $com_params->get('smallwidththreshold', 0); + + if ($smallthreshold > 0) + { + $css_contents = @file_get_contents( + JPATH_ROOT . "/components/com_icagenda/themes/packs/$template/css/{$template}_{$type}_small.css"); + + $css = preg_replace('!/\*.*?\*/!s', '', $css_contents); + $size_css = $mbString ? mb_strlen($css) : strlen($css); + +// if (is_string($css) && !empty($css) && ($size_css > 10)) +// { + $upper_limit = $max_threshold > 0 ? " and (max-width:{$max_threshold}px)" : ''; + $media_css .= "\n@media screen and (min-width:{$smallthreshold}px)$upper_limit{\n{$css}\n}\n"; + $max_threshold = $smallthreshold - 1; +// } + + $css_contents = @file_get_contents( + JPATH_ROOT . "/components/com_icagenda/themes/packs/$template/css/{$template}_{$type}_xsmall.css"); + + $css = preg_replace('!/\*.*?\*/!s', '', $css_contents); + $size_css = $mbString ? mb_strlen($css) : strlen($css); + +// if (is_string($css) && !empty($css) && ($size_css > 10)) +// { + $smallthreshold--; + $media_css .= "\n@media screen and (max-width:{$smallthreshold}px){\n{$css}\n}\n"; +// } + } + + return $media_css; + } + + /** + * Write the CSS to the document header + * + * @param string &$css The CSS to be written to the document + * + * @return void + */ + public static function writeMediaCss(&$css) + { + if (!empty($css)) + { + $document = JFactory::getDocument(); + $document->addStyleDeclaration($css); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/theme.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/theme.php new file mode 100644 index 00000000..e64fe857 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/theme/theme.php @@ -0,0 +1,329 @@ + - ', $list); + $setlist = ' - '.$im_list.' '; + } + else + { + $im_list = implode('
  • ', $list); + $setlist = '
    • '.$im_list.'
    '; + } + + $title = 'COM_ICAGENDA_THEME_PACKS_COMPATIBILITY'; + $description = 'COM_ICAGENDA_THEME_PACKS_INCOMPATIBLE_ALERT'; + + // Set Alert Message + $alert = array(); + + if (count($list) >= 1) + { + $alert[] = '
    '; + $alert[] = ''.JText::_( $title ).''; + $alert[] = '

    '; + $alert[] = JText::sprintf( $description, '' . JText::_($functionnality) . '' ); + if ($info_url) $alert[] = ' ' .JText::_( 'IC_MORE_INFORMATION' ). ''; + $alert[] = '

    '; + + $alert[] = '

    '; + $alert[] = $setlist; + $alert[] = '

    '; + + $alert[] = '
    '; + } + + $alert_message = implode("\n", $alert); + + $app->enqueueMessage($alert_message, 'warning'); + } + } + + /* + * Function to check if 'string' is defined inside the file THEME_$file.php for each Theme Pack. + * + * @return list of incompatible Theme Packs. + * + * @since 3.4.0 + */ + static public function incompatibleList($string, $file_name) + { + $array_themes = Array(); + + $dirname = JPATH_SITE.'/components/com_icagenda/themes/packs'; + + if (ini_get('allow_url_fopen') && file_exists($dirname)) + { + $handle = opendir($dirname); + + while (false !== ($theme = readdir($handle))) + { + if ( !is_file($dirname.$theme) + && $theme!= '.' + && $theme!='..' + && $theme!='index.php' + && $theme!='index.html' + && $theme!='.DS_Store' + && $theme!='.thumbs' ) + { + $day_php = $dirname . '/' . $theme . '/' . $theme . '_day.php'; + $event_php = $dirname . '/' . $theme . '/' . $theme . '_event.php'; + $events_php = $dirname . '/' . $theme . '/' . $theme . '_events.php'; + $registration_php = $dirname . '/' . $theme . '/' . $theme . '_registration.php'; + + $array_files_php = array($day_php, $event_php, $events_php, $registration_php); + + $count = 0; + + foreach ($array_files_php AS $file_php) + { + if (iCFile::hasString($string, $file_php)) + { + $count = $count+1; + } + } + + if ($count < 1) + { + array_push($array_themes, $theme); + } + } + } + + $handle = closedir($handle); + } + + sort($array_themes); + + if ($array_themes) return $array_themes; + + return false; + } + + /* + * Function to load the 'list' template of the current Theme Pack. + * + * @return Path of the 'list' template. + * + * @since 3.6.0 + */ + static public function getThemeLayout($theme, $layout) + { + $app = JFactory::getApplication(); + + $theme_dir = '/components/com_icagenda/themes/packs/'; + + switch($layout) + { + // List + case 'list': + $file_template_events = JPATH_SITE . $theme_dir . $theme . '/' . $theme . '_events.php'; +// $file_template_list = JPATH_SITE . $theme_dir . $template . '/' . $template . '_list.php'; + $file_default_layout = JPATH_SITE . $theme_dir . 'default/default_events.php'; + + // List template (4.0.0) +// if (file_exists($file_template_list)) +// { +// $theme_list_tpl = $file_template_list; +// } + + // Events template (before 4.0.0) - DEPRECATED +// elseif ( ! file_exists($file_template_list) +// && file_exists($file_template_events)) +// { + if (file_exists($file_template_events)) + { + $theme_layout = $file_template_events; + } + + // No list template found in selected theme pack, so we load 'default' theme pack + else + { + $theme_layout = $file_default_layout; + } + break; + + // Event + case 'event': + $file_layout_event = JPATH_SITE . $theme_dir . $theme . '/' . $theme . '_event.php'; + $file_default_layout = JPATH_SITE . $theme_dir . 'default/default_event.php'; + + // Event layout + if (file_exists($file_layout_event)) + { + $theme_layout = $file_layout_event; + } + + // No event layout found in selected theme pack, so we load 'default' theme pack + else + { + $theme_layout = $file_default_layout; + } + break; + + // Registration + case 'registration': + $file_layout_registration = JPATH_SITE . $theme_dir . $theme . '/' . $theme . '_registration.php'; + $file_default_layout = JPATH_SITE . $theme_dir . 'default/default_registration.php'; + + // Registration layout + if (file_exists($file_layout_registration)) + { + $theme_layout = $file_layout_registration; + } + + // No registration layout found in selected theme pack, so we load 'default' theme pack + else + { + $theme_layout = $file_default_layout; + } + break; + } + + $error = ''; + + if ( ( ! $theme || $theme != 'default') + && ($theme_layout == $file_default_layout) + && file_exists($file_default_layout) ) + { + $error = 'alert'; + } + elseif ( ($theme_layout == $file_default_layout) + && ! file_exists($file_default_layout)) + { + $error = 'error'; + } + elseif (iCFile::hasString('stamp', $theme_layout)) + { + $error = 'deprecated'; + } + + $layout = array($theme_layout, $error); + + return $layout; + } + + /* + * Function to load the current Theme Pack component css file(s). + * + * @return loads css file(s). + * + * @since 3.6.0 + */ + static public function loadComponentCSS($template) + { + $document = JFactory::getDocument(); + $lang = JFactory::getLanguage(); + + $theme_dir = '/components/com_icagenda/themes/packs/'; + + $file_component_css = JPATH_SITE . $theme_dir . $template . '/css/' . $template . '_component.css'; + + // Setting component css file to load + if ( file_exists($file_component_css) ) + { + $css_component = $theme_dir . $template . '/css/' . $template . '_component.css'; + $css_com_rtl = $theme_dir . $template . '/css/' . $template . '_component-rtl.css'; + } + else + { + $css_component = $theme_dir . 'default/css/default_component.css'; + $css_com_rtl = $theme_dir . 'default/css/default_component-rtl.css'; + } + + // Theme pack component css + $document->addStyleSheet( JURI::base( true ) . $css_component ); + + // RTL css if site language is RTL + if ( $lang->isRTL() + && file_exists( JPATH_SITE . $css_com_rtl) ) + { + $document->addStyleSheet( JURI::base( true ) . $css_com_rtl ); + } + + $app = JFactory::getApplication(); + $params = $app->getParams(); + $list_of_events = $params->get('copy', ''); + $core = $params->get('icsys'); + $string = ''; + $string.= 'iCagenda'; + $string.= ''; + $icagenda = JText::sprintf('ICAGENDA_THANK_YOU_NOT_TO_REMOVE', $string); + $default = 'Powered by '; + $footer = '

    '; + $footer.= preg_match('/iCagenda/',$icagenda) ? $icagenda : $default . $string; + $footer.= '

    '; + + if ($list_of_events || $core == 'core') + { + echo $footer; + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/thumb/index.html b/deployed/icagenda/administrator/components/com_icagenda/utilities/thumb/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/thumb/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/utilities/thumb/thumb.php b/deployed/icagenda/administrator/components/com_icagenda/utilities/thumb/thumb.php new file mode 100644 index 00000000..a7e8bd79 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/utilities/thumb/thumb.php @@ -0,0 +1,135 @@ +get('thumb_large'); + $width = is_numeric($thumbOptions[0]) ? $thumbOptions[0] : '900'; + $height = is_numeric($thumbOptions[1]) ? $thumbOptions[1] : '600'; + $quality = is_numeric($thumbOptions[2]) ? $thumbOptions[2] : '100'; + $crop = !empty($thumbOptions[3]) ? true : false; + + // Generate large thumb if not exist + $sizeLarge = iCThumbGet::thumbnail($image, $thumbsPath, 'themes', $width, $height, $quality, $crop, 'ic_large', $type, $checksize); + + return $sizeLarge; + } + + /** + * Return the MEDIUM thumbnail from an image + * Generated by iCagenda with Global Options settings + * + * @since 3.4.0 + */ + static public function sizeMedium($image, $type = null, $checksize = null) + { + $thumbsPath = self::iCagendaImagesPath(); + + // Options Medium Size + $thumbOptions = JComponentHelper::getParams('com_icagenda')->get('thumb_medium'); + $width = is_numeric($thumbOptions[0]) ? $thumbOptions[0] : '300'; + $height = is_numeric($thumbOptions[1]) ? $thumbOptions[1] : '300'; + $quality = is_numeric($thumbOptions[2]) ? $thumbOptions[2] : '100'; + $crop = !empty($thumbOptions[3]) ? true : false; + + // Generate medium thumb if not exist + $sizeMedium = iCThumbGet::thumbnail($image, $thumbsPath, 'themes', $width, $height, $quality, $crop, 'ic_medium', $type, $checksize); + + return $sizeMedium; + } + + /** + * Return the SMALL thumbnail from an image + * Generated by iCagenda with Global Options settings + * + * @since 3.4.0 + */ + static public function sizeSmall($image, $type = null, $checksize = null) + { + $thumbsPath = self::iCagendaImagesPath(); + + // Options Small Size + $thumbOptions = JComponentHelper::getParams('com_icagenda')->get('thumb_small'); + $width = is_numeric($thumbOptions[0]) ? $thumbOptions[0] : '100'; + $height = is_numeric($thumbOptions[1]) ? $thumbOptions[1] : '100'; + $quality = is_numeric($thumbOptions[2]) ? $thumbOptions[2] : '100'; + $crop = !empty($thumbOptions[3]) ? true : false; + + // Generate small thumb if not exist + $sizeSmall = iCThumbGet::thumbnail($image, $thumbsPath, 'themes', $width, $height, $quality, $crop, 'ic_small', $type, $checksize); + + return $sizeSmall; + } + + /** + * Return the SMALL thumbnail from an image + * Generated by iCagenda with Global Options settings + * + * @since 3.4.0 + */ + static public function sizeXSmall($image, $type = null, $checksize = null) + { + $thumbsPath = self::iCagendaImagesPath(); + + // Options XSmall Size + $thumbOptions = JComponentHelper::getParams('com_icagenda')->get('thumb_xsmall'); + $width = is_numeric($thumbOptions[0]) ? $thumbOptions[0] : '48'; + $height = is_numeric($thumbOptions[1]) ? $thumbOptions[1] : '48'; + $quality = is_numeric($thumbOptions[2]) ? $thumbOptions[2] : '80'; + $crop = !empty($thumbOptions[3]) ? true : false; + + // Generate xsmall thumb if not exist + $sizeXSmall = iCThumbGet::thumbnail($image, $thumbsPath, 'themes', $width, $height, $quality, $crop, 'ic_xsmall', $type, $checksize); + + return $sizeXSmall; + } + + /** + * Return the iCagenda images path + * + * @since 3.4.0 + */ + static public function iCagendaImagesPath() + { + // Get media path + $params_media = JComponentHelper::getParams('com_media'); + $image_path = $params_media->get('image_path', 'images'); + + // Paths to thumbs folder + $thumbsPath = $image_path . '/icagenda/thumbs'; + + return $thumbsPath; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/categories/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/categories/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/categories/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/categories/tmpl/default.php b/deployed/icagenda/administrator/components/com_icagenda/views/categories/tmpl/default.php new file mode 100644 index 00000000..0c130855 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/categories/tmpl/default.php @@ -0,0 +1,415 @@ +authorise('icagenda.access.categories', 'com_icagenda')) +{ + $user = JFactory::getUser(); + $userId = $user->get('id'); + $listOrder = $this->escape($this->state->get('list.ordering')); + $listDirn = $this->escape($this->state->get('list.direction')); + $canOrder = $user->authorise('core.edit.state', 'com_icagenda'); + + $saveOrder = $listOrder == 'a.ordering'; + + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::_('behavior.tooltip'); + JHtml::_('script','system/multiselect.js',false,true); + } + else + { + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + JHtml::_('bootstrap.tooltip'); + JHtml::_('behavior.multiselect'); + JHtml::_('formbehavior.chosen', 'select'); + JHtml::_('dropdown.init'); + + $extension = $this->escape($this->state->get('filter.extension')); + + $archived = $this->state->get('filter.published') == 2 ? true : false; + $trashed = $this->state->get('filter.published') == -2 ? true : false; + + if ($saveOrder) + { + $saveOrderingUrl = 'index.php?option=com_icagenda&task=categories.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'categoriesList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); + } + //$sortFields = $this->getSortFields(); + $sortFields = array(); // Alchemy - tmp bug fix + ?> + + + +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + + +
    + +
    + +
    +
    +
    + + + +
    + +
    + + +
    +
    + + pagination->getLimitBox(); ?> +
    + + +
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + items[0]->ordering)) { ?> + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_icagenda'); + $canEdit = $user->authorise('core.edit', 'com_icagenda'); + $canCheckin = $user->authorise('core.manage', 'com_icagenda'); + $canChange = $user->authorise('core.edit.state', 'com_icagenda'); +// $canEditOwn = $user->authorise('core.edit.own', 'com_icagenda') && $item->created_by == $userId; + $canEditOwn = $user->authorise('core.edit.own', 'com_icagenda'); + ?> + items as $i => $item) : + $orderkey = array_search($item->id, $this->ordering[$item->parent_id]); + $canEdit = $user->authorise('core.edit', $extension . '.category.' . $item->id); + $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canEditOwn = $user->authorise('core.edit.own', $extension . '.category.' . $item->id) && $item->created_user_id == $userId; + $canChange = $user->authorise('core.edit.state', $extension . '.category.' . $item->id) && $canCheckin; + + // Get the parents of item for sorting + if ($item->level > 1) + { + $parentsStr = ""; + $_currentParentId = $item->parent_id; + $parentsStr = " " . $_currentParentId; + for ($i2 = 0; $i2 < $item->level; $i2++) + { + foreach ($this->ordering as $k => $v) + { + $v = implode("-", $v); + $v = "-".$v."-"; + if (strpos($v, "-" . $_currentParentId . "-") !== false) + { + $parentsStr .= " " . $k; + $_currentParentId = $k; + break; + } + } + } + } + else + { + $parentsStr = ""; + } +*/ + ?> + + + + + + + + + + + + + + + items[0]->state)) { ?> + + + + + + + + + + + + items[0]->ordering)) { ?> + + + + + + + items[0]->id)) { ?> + + + + + +
    + ', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?> + + + + + + + + + + + + items, 'filesave.png', 'categories.saveorder'); ?> + + + +
    + pagination->getListFooter(); ?> +
    + + + + + + + + + + + + id); ?> + + state, $i, 'categories.', $canChange, 'cb'); ?> + +
    +
    +
    + checked_out) : ?> + editor, $item->checked_out_time, 'categories.', $canCheckin); ?> + + language == '*'):?> + + + language ? $this->escape($item->language) : JText::_('JUNDEFINED'); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + +
    + + + +
    + id, 'category.'); + JHtml::_('dropdown.divider'); + if ($item->state) : + JHtml::_('dropdown.unpublish', 'cb' . $i, 'categories.'); + else : + JHtml::_('dropdown.publish', 'cb' . $i, 'categories.'); + endif; + +// if ($item->featured) : +// JHtml::_('dropdown.unfeatured', 'cb' . $i, 'categories.'); +// else : +// JHtml::_('dropdown.featured', 'cb' . $i, 'categories.'); +// endif; + + JHtml::_('dropdown.divider'); + + if ($archived) : + JHtml::_('dropdown.unarchive', 'cb' . $i, 'categories.'); + else : + JHtml::_('dropdown.archive', 'cb' . $i, 'categories.'); + endif; + + if ($item->checked_out) : + JHtml::_('dropdown.checkin', 'cb' . $i, 'categories.'); + endif; + + if ($trashed) : + JHtml::_('dropdown.untrash', 'cb' . $i, 'categories.'); + else : + JHtml::_('dropdown.trash', 'cb' . $i, 'categories.'); + endif; + + // Render dropdown list + echo JHtml::_('dropdown.render'); + ?> +
    + + + +
    + + + + pagination->orderUpIcon($i, true, 'categories.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'categories.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, true, 'categories.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'categories.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" /> + + ordering; ?> + + + id; ?> +
    + +
    + + + + + +
    +
    + + enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/categories/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/categories/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/categories/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/categories/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/categories/view.html.php new file mode 100644 index 00000000..e74c43c4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/categories/view.html.php @@ -0,0 +1,177 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + + if (version_compare(JVERSION, '3.0', 'ge')) + { + $this->sidebar = JHtmlSidebar::render(); + } + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @since 1.0 + */ + protected function addToolbar() + { + require_once JPATH_COMPONENT . '/helpers/icagenda.php'; + + $state = $this->get('State'); + $user = JFactory::getUser(); + $userId = $user->get('id'); + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_TITLE_CATEGORIES'), 'categories.png'); + } + else + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_TITLE_CATEGORIES') . '', 'folder'); + } + + $icTitle = JText::_('COM_ICAGENDA_TITLE_CATEGORIES'); + + $document = JFactory::getDocument(); + $app = JFactory::getApplication(); + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + //Check if the form exists before showing the add/edit buttons + $formPath = JPATH_COMPONENT_ADMINISTRATOR.'/views/category'; + + if (file_exists($formPath)) + { + if ($canDo->get('core.create')) + { + JToolBarHelper::addNew('category.add', 'JTOOLBAR_NEW'); + } + + if ($canDo->get('core.edit')) + { + JToolBarHelper::editList('category.edit', 'JTOOLBAR_EDIT'); + } + } + + if ($canDo->get('core.edit.state')) + { + if (isset($this->items[0]->state)) + { + JToolBarHelper::divider(); + JToolBarHelper::custom('categories.publish', 'publish.png', 'publish_f2.png', 'JTOOLBAR_PUBLISH', true); + JToolBarHelper::custom('categories.unpublish', 'unpublish.png', 'unpublish_f2.png', 'JTOOLBAR_UNPUBLISH', true); + } + else + { + // If this component does not use state then show a direct delete button as we can not trash + JToolBarHelper::deleteList('', 'categories.delete', 'JTOOLBAR_DELETE'); + } + + if (isset($this->items[0]->state)) + { + JToolBarHelper::divider(); + JToolBarHelper::archiveList('categories.archive', 'JTOOLBAR_ARCHIVE'); + } + + if (isset($this->items[0]->checked_out)) + { + JToolBarHelper::custom('categories.checkin', 'checkin.png', 'checkin_f2.png', 'JTOOLBAR_CHECKIN', true); + } + } + + // Show trash and delete for components that uses the state field + if (isset($this->items[0]->state)) + { + if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + JToolBarHelper::deleteList('', 'categories.delete','JTOOLBAR_EMPTY_TRASH'); + JToolBarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + JToolBarHelper::trash('categories.trash','JTOOLBAR_TRASH'); + JToolBarHelper::divider(); + } + } + + if ($canDo->get('core.admin')) + { + JToolBarHelper::preferences('com_icagenda'); + } + + if (version_compare(JVERSION, '3.0', 'ge')) + { + JHtmlSidebar::setAction('index.php?option=com_icagenda&view=categories'); + + JHtmlSidebar::addFilter( + JText::_('JOPTION_SELECT_PUBLISHED'), + 'filter_published', + JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.state'), true) + ); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/category/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/category/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/category/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/category/tmpl/edit.php b/deployed/icagenda/administrator/components/com_icagenda/views/category/tmpl/edit.php new file mode 100644 index 00000000..eb1802f6 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/category/tmpl/edit.php @@ -0,0 +1,333 @@ +authorise('icagenda.access.categories', 'com_icagenda')) +{ + $bootstrapType = '1'; + $CategoryTag ='category'; + $CategoryTitle = JText::_('COM_ICAGENDA_TITLE_CATEGORY', true); + $DescTag = 'desc'; + $DescTitle = JText::_('COM_ICAGENDA_LEGEND_DESC', true); + $PublishingTag = 'publishing'; + $PublishingTitle = JText::_('JGLOBAL_FIELDSET_PUBLISHING', true); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + jimport('joomla.html.html.tabs'); + + $iCmapDisplay = '3'; + + $icPanCategory = JText::_('COM_ICAGENDA_TITLE_CATEGORY'); + $icPanDesc = JText::_('COM_ICAGENDA_LEGEND_DESC'); + $icPanPublishing = JText::_('JGLOBAL_FIELDSET_PUBLISHING'); + $startPane = 'tabs.start'; + $addPanel = 'tabs.panel'; + $endPanel = 'tabs.end'; + $endPane = 'tabs.end'; + $CategoryTag1 = $CategoryTag; + $CategoryTag2 = $CategoryTitle; + $DescTag1 = $DescTag; + $DescTag2 = $DescTitle; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + + // Joomla 3 + else + { + JHtml::_('formbehavior.chosen', 'select'); + jimport('joomla.html.html.bootstrap'); + + $icPanCategory = 'icTab'; + $icPanDesc = 'icTab'; + $icPanPublishing = 'icTab'; + + if ($bootstrapType == '1') + { + $iCmapDisplay = '1'; + $startPane = 'bootstrap.startTabSet'; + $addPanel = 'bootstrap.addTab'; + $endPanel = 'bootstrap.endTab'; + $endPane = 'bootstrap.endTabSet'; + $CategoryTag1 = $CategoryTag; + $CategoryTag2 = $CategoryTitle; + $DescTag1 = $DescTag; + $DescTag2 = $DescTitle; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + elseif ($bootstrapType == '2') + { + $iCmapDisplay = '2'; + $startPane = 'bootstrap.startAccordion'; + $addPanel = 'bootstrap.addSlide'; + $endPanel = 'bootstrap.endSlide'; + $endPane = 'bootstrap.endAccordion'; + $CategoryTag1 = $CategoryTitle; + $CategoryTag2 = $CategoryTag; + $DescTag1 = $DescTitle; + $DescTag2 = $DescTag; + $PublishingTag1 = $PublishingTitle; + $PublishingTag2 = $PublishingTag; + } + } + ?> + + + +
    + +
    + + + + + + + +
    +

    + item->id) ? JText::_('COM_ICAGENDA_LEGEND_NEW_CATEGORY') : JText::sprintf('COM_ICAGENDA_LEGEND_EDIT_CATEGORY', $this->item->id); ?> iCagenda +

    +

    + + +

    +
    + +
     
    + + + +
    +
    + + + 'category')); ?> + + + + +
    +

    item->id) ? JText::_('COM_ICAGENDA_LEGEND_NEW_CATEGORY') : JText::sprintf('COM_ICAGENDA_LEGEND_EDIT_CATEGORY', $this->item->id); ?>

    +
    +
    +
    +
    +
    + form->getLabel('title'); ?> +
    +
    + form->getInput('title'); ?> +
    +
    +
    +
    +
    +
    + form->getLabel('color'); ?> +
    +
    + form->getInput('color'); ?> +
    +
    +
    +
    +
    + + + + + + + + +
    +

    +
    +
    +
    +

    + form->getInput('desc'); ?> +
    +
    +
    + + + + + +
    +

    +
    +
    +
    +
    +
    + form->getLabel('alias'); ?> +
    +
    + form->getInput('alias'); ?> +
    +
    +
    +
    + form->getLabel('id'); ?> +
    +
    + form->getInput('id'); ?> +
    +
    + +
    +
    + form->getLabel('checked_out'); ?> +
    +
    + form->getInput('checked_out'); ?> +
    +
    +
    +
    + form->getLabel('checked_out_time'); ?> +
    +
    + form->getInput('checked_out_time'); ?> +
    +
    +
    +
    +
    + + + + + +
    + + +
    +

    +
    +
    +
    + form->getLabel('state'); ?> +
    +
    + form->getInput('state'); ?> +
    + +
    + +
    + +
    + +
    +
    + + + +
    + + enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/category/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/category/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/category/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/category/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/category/view.html.php new file mode 100644 index 00000000..ef0019f4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/category/view.html.php @@ -0,0 +1,122 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + $jinput = $app->input; + + $jinput->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $isNew = ($this->item->id == 0); + + if (isset($this->item->checked_out)) + { + $checkedOut = ! ($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + } + else + { + $checkedOut = false; + } + + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_NEW_CATEGORY') : 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_EDIT_CATEGORY'), 'category.png'); + } + else + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_NEW_CATEGORY') . '' : 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_EDIT_CATEGORY') . '' , $isNew ? 'new' : 'pencil-2'); + } + + $icTitle = $isNew ? JText::_('COM_ICAGENDA_LEGEND_NEW_CATEGORY') : JText::_('COM_ICAGENDA_LEGEND_EDIT_CATEGORY'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + // If not checked out, can save the item. + if ( ! $checkedOut && ($canDo->get('core.edit')||($canDo->get('core.create')))) + { + JToolBarHelper::apply('category.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('category.save', 'JTOOLBAR_SAVE'); + } + + if ( ! $checkedOut && ($canDo->get('core.create'))){ + JToolBarHelper::custom('category.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + + // If an existing item, can save to a copy. + if ( ! $isNew && $canDo->get('core.create')) + { + JToolBarHelper::custom('category.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); + } + + if (empty($this->item->id)) + { + JToolBarHelper::cancel('category.cancel', 'JTOOLBAR_CANCEL'); + } + else + { + JToolBarHelper::cancel('category.cancel', 'JTOOLBAR_CLOSE'); + } + + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/customfield/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/customfield/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/customfield/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/customfield/tmpl/edit.php b/deployed/icagenda/administrator/components/com_icagenda/views/customfield/tmpl/edit.php new file mode 100644 index 00000000..7803450e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/customfield/tmpl/edit.php @@ -0,0 +1,560 @@ +authorise('icagenda.access.customfields', 'com_icagenda')) +{ + $bootstrapType = '1'; + $PanelOne_Tag = 'customfield'; + $PanelOne_Title = JText::_('COM_ICAGENDA_CUSTOMFIELD_PANEL_TITLE', true); + $PanelTwo_Tag = 'desc'; + $PanelTwo_Title = JText::_('COM_ICAGENDA_LEGEND_DESC', true); + $PublishingTag = 'publishing'; + $PublishingTitle = JText::_('JGLOBAL_FIELDSET_PUBLISHING', true); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + jimport( 'joomla.html.html.tabs' ); + + $iCmapDisplay = '3'; + + $icPanFirst = JText::_('COM_ICAGENDA_CUSTOMFIELD_PANEL_TITLE'); + $icPanDesc = JText::_('COM_ICAGENDA_LEGEND_DESC'); + $icPanPublishing = JText::_('JGLOBAL_FIELDSET_PUBLISHING'); + $startPane = 'tabs.start'; + $addPanel = 'tabs.panel'; + $endPanel = 'tabs.end'; + $endPane = 'tabs.end'; + $PanelOne_Tag1 = $PanelOne_Tag; + $PanelOne_Tag2 = $PanelOne_Title; + $PanelTwo_Tag1 = $PanelTwo_Tag; + $PanelTwo_Tag2 = $PanelTwo_Title; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + + // Joomla 3 + else + { + JHtml::_('formbehavior.chosen', 'select'); + jimport('joomla.html.html.bootstrap'); + + $icPanFirst = 'icTab'; + $icPanDesc = 'icTab'; + $icPanPublishing = 'icTab'; + + if ($bootstrapType == '1') + { + $iCmapDisplay = '1'; + $startPane = 'bootstrap.startTabSet'; + $addPanel = 'bootstrap.addTab'; + $endPanel = 'bootstrap.endTab'; + $endPane = 'bootstrap.endTabSet'; + $PanelOne_Tag1 = $PanelOne_Tag; + $PanelOne_Tag2 = $PanelOne_Title; + $PanelTwo_Tag1 = $PanelTwo_Tag; + $PanelTwo_Tag2 = $PanelTwo_Title; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + elseif ($bootstrapType == '2') + { + $iCmapDisplay = '2'; + $startPane = 'bootstrap.startAccordion'; + $addPanel = 'bootstrap.addSlide'; + $endPanel = 'bootstrap.endSlide'; + $endPane = 'bootstrap.endAccordion'; + $PanelOne_Tag1 = $PanelOne_Title; + $PanelOne_Tag2 = $PanelOne_Tag; + $PanelTwo_Tag1 = $PanelTwo_Title; + $PanelTwo_Tag2 = $PanelTwo_Tag; + $PublishingTag1 = $PublishingTitle; + $PublishingTag2 = $PublishingTag; + } + } + ?> + + + +
    + +
    + + + + + + + +
    +

    + item->id) ? JText::_('COM_ICAGENDA_CUSTOMFIELD_LEGEND_NEW') : JText::sprintf('COM_ICAGENDA_CUSTOMFIELD_LEGEND_EDIT', $this->item->id); ?> iCagenda +

    +

    + + +

    +
    + +
     
    + + + + +
    +
    + + + 'customfield')); ?> + + + + +
    +

    item->id) ? JText::_('COM_ICAGENDA_CUSTOMFIELD_LEGEND_NEW') : JText::sprintf('COM_ICAGENDA_CUSTOMFIELD_LEGEND_EDIT', $this->item->id); ?>

    +
    +

    +
    +
    +
    +
    + form->getLabel('parent_form'); ?> +
    +
    + form->getInput('parent_form'); ?> +
    +
    +
    +
    +
    +
    + form->getLabel('type'); ?> +
    +
    + form->getInput('type'); ?> +
    +
    +
    +
    +
    +
    +
    + + + form->getInput('spacer_settings'); ?> + + form->renderField('spacer_settings'); ?> + + + + +
    +
    + form->getLabel('title'); ?> +
    +
    + form->getInput('title'); ?> +
    +
    + + form->renderField('title'); ?> + + + +
    +
    + form->getLabel('slug'); ?> +
    +
    + form->getInput('slug'); ?> +
    +
    + + form->renderField('slug'); ?> + + + + + + + form->renderField('groups'); ?> + +
    +
    + + + form->getInput('spacer_options'); ?> + + form->renderField('spacer_options'); ?> + + + +
    +
    + form->getLabel('options'); ?> +
    +
    + form->getInput('options'); ?> +
    +
    + + form->renderField('placeholder'); ?> + form->renderField('spacer_class'); ?> + form->renderField('options'); ?> + + + +
    +
    + form->getLabel('required'); ?> +
    +
    + form->getInput('required'); ?> +
    +
    + + form->renderField('required'); ?> + +
    +
    +
    +
    + + + + + + + + +
    +

    +
    +
    +
    +

    + form->getInput('description'); ?> +
    +
    +
    + + + + + +
    +

    +
    +
    +
    +
    +
    + form->getLabel('id'); ?> +
    +
    + form->getInput('id'); ?> +
    +
    +
    +
    + form->getLabel('alias'); ?> +
    +
    + form->getInput('alias'); ?> +
    +
    +
    + form->getLabel('created'); ?> +
    + form->getInput('created'); ?> +
    +
    +
    + form->getLabel('created_by'); ?> +
    + form->getInput('created_by'); ?> +
    +
    +
    + form->getLabel('created_by_alias'); ?> +
    + form->getInput('created_by_alias'); ?> +
    +
    +
    + form->getLabel('modified'); ?> +
    + form->getInput('modified'); ?> +
    +
    +
    + form->getLabel('modified_by'); ?> +
    + form->getInput('modified_by'); ?> +
    +
    +
    +
    + form->getLabel('checked_out'); ?> +
    +
    + form->getInput('checked_out'); ?> +
    +
    +
    +
    + form->getLabel('checked_out_time'); ?> +
    +
    + form->getInput('checked_out_time'); ?> +
    +
    +
    +
    +
    + + + + + +
    + + +
    +

    +
    +
    +
    + form->getLabel('state'); ?> +
    +
    + form->getInput('state'); ?> +
    +
    + + + +
    + +
    + +
    + + + +
    + + _scripts); + $scriptFound = false; + $scriptuiFound = false; + + for ($i = 0; $i < count($scripts); $i++) + { + if (stripos($scripts[$i], 'jquery.min.js') !== false) + { + $scriptFound = true; + } + if (stripos($scripts[$i], 'jquery.js') !== false) + { + $scriptFound = true; + } + if (stripos($scripts[$i], 'jquery-ui.min.js') !== false) + { + $scriptuiFound = true; + } + } + + // jQuery Library Loader + if (!$scriptFound) + { + // load jQuery, if not loaded before + if (!$app->get('jquery')) + { + $app->set('jquery', true); + // add jQuery + $document->addScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/jquery.noconflict.js' ); + } + } + + if (!$scriptuiFound) + { + $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); + } + + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/template.js' ); + } + else + { + JHtml::_('bootstrap.framework'); + JHtml::_('jquery.framework'); + } + + $js = ' + (function($){ + $(window).load(function(){ + + var $parent_form = $("#jform_parent_form").val(); + + if ($parent_form !== "1") { + removeOverrideOptions(); + updateTypeList(); + } else { + updateTypeList(); + } + + $("#jform_parent_form").on("change",function(e) { + + var $parent_form = $("#jform_parent_form").val(); + + if ($parent_form === "") { + $("#jform_slug-lbl").css("display", "none"); + $("#jform_slug").css("display", "none"); + } else { + $("#jform_slug-lbl").css("display", "block"); + $("#jform_slug").css("display", "block"); + } + + if ($parent_form !== "1") { + removeOverrideOptions(); + } else { + addOverrideOptions(); + } + + updateTypeList(); + }) + + function addOverrideOptions() { + $("#jform_type").append(""); + $("#jform_type").append(""); + $("#jform_type").append(""); + $("#jform_type").append(""); + $("#jform_type").append(""); + } + + function removeOverrideOptions() { + $("#jform_type option[value=\"core_name\"]").remove(); + $("#jform_type option[value=\"core_email\"]").remove(); + $("#jform_type option[value=\"core_phone\"]").remove(); + $("#jform_type option[value=\"core_date\"]").remove(); + $("#jform_type option[value=\"core_people\"]").remove(); + } + + function updateTypeList() { + $("#jform_type option").each( + function(){ + var arr = $(this).html().split("::"); + if (arr[1]) { + var jtext = arr[1] == "NAME" ? "' . JText::_('COM_ICAGENDA_REGISTRATION_NAME') . '" : + arr[1] == "EMAIL" ? "' . JText::_('COM_ICAGENDA_REGISTRATION_EMAIL') . '" : + arr[1] == "PHONE" ? "' . JText::_('COM_ICAGENDA_REGISTRATION_PHONE') . '" : + arr[1] == "DATE" ? "' . JText::_('COM_ICAGENDA_REGISTRATION_DATE') . '" : + arr[1] == "TICKETS" ? "' . JText::_('COM_ICAGENDA_REGISTRATION_TICKETS') . '" : + $(this).html(); + } + var html = arr[1] ? "' . JText::_('COM_ICAGENDA_LABEL_OVERRIDE') . ' "+jtext : arr[0]; + $(this).html(html); + } + ); + + $("#jform_type").trigger("liszt:updated"); + } + + }); + + })(jQuery); + '; + + JFactory::getDocument()->addScriptDeclaration($js); +} +else +{ + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/customfield/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/customfield/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/customfield/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/customfield/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/customfield/view.html.php new file mode 100644 index 00000000..9a150077 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/customfield/view.html.php @@ -0,0 +1,121 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + $jinput = $app->input; + + $jinput->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $isNew = ($this->item->id == 0); + + if (isset($this->item->checked_out)) + { + $checkedOut = ! ($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + } + else + { + $checkedOut = false; + } + + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_CUSTOMFIELD_LEGEND_NEW') : 'iCagenda - ' . JText::_('COM_ICAGENDA_CUSTOMFIELD_LEGEND_EDIT'), 'category.png'); + } + else + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_CUSTOMFIELD_LEGEND_NEW') . '' : 'iCagenda - ' . JText::_('COM_ICAGENDA_CUSTOMFIELD_LEGEND_EDIT') . '' , $isNew ? 'new' : 'pencil-2'); + } + + $icTitle = $isNew ? JText::_('COM_ICAGENDA_CUSTOMFIELD_LEGEND_NEW') : JText::_('COM_ICAGENDA_CUSTOMFIELD_LEGEND_EDIT'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + // If not checked out, can save the item. + if ( ! $checkedOut && ($canDo->get('core.edit')||($canDo->get('core.create')))) + { + JToolBarHelper::apply('customfield.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('customfield.save', 'JTOOLBAR_SAVE'); + } + + if ( ! $checkedOut && ($canDo->get('core.create'))) + { + JToolBarHelper::custom('customfield.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + + // If an existing item, can save to a copy. + if ( ! $isNew && $canDo->get('core.create')) + { + JToolBarHelper::custom('customfield.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); + } + + if (empty($this->item->id)) + { + JToolBarHelper::cancel('customfield.cancel', 'JTOOLBAR_CANCEL'); + } + else + { + JToolBarHelper::cancel('customfield.cancel', 'JTOOLBAR_CLOSE'); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/customfields/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/customfields/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/customfields/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/customfields/tmpl/default.php b/deployed/icagenda/administrator/components/com_icagenda/views/customfields/tmpl/default.php new file mode 100644 index 00000000..d39e60f0 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/customfields/tmpl/default.php @@ -0,0 +1,529 @@ +authorise('icagenda.access.customfields', 'com_icagenda')) +{ + // Check Theme Packs Compatibility + if (class_exists('icagendaTheme')) icagendaTheme::checkThemePacks(); + + $user = JFactory::getUser(); + $userId = $user->get('id'); + $listOrder = $this->escape($this->state->get('list.ordering')); + $listDirn = $this->escape($this->state->get('list.direction')); + $canOrder = $user->authorise('core.edit.state', 'com_icagenda'); + + $saveOrder = $listOrder == 'cf.ordering'; + + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::_('behavior.tooltip'); + JHtml::_('script','system/multiselect.js',false,true); + } + else + { + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + JHtml::_('bootstrap.tooltip'); + JHtml::_('behavior.multiselect'); + JHtml::_('formbehavior.chosen', 'select'); + JHtml::_('dropdown.init'); + + $extension = $this->escape($this->state->get('filter.extension')); + $archived = $this->state->get('filter.published') == 2 ? true : false; + $trashed = $this->state->get('filter.published') == -2 ? true : false; + + if ($saveOrder) + { + $saveOrderingUrl = 'index.php?option=com_icagenda&task=customfields.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'customfieldsList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); + } + $sortFields = array(); + ?> + + + +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + + +
    + + + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    + +
    +
    + + + +
    + + + +
    + + +
    + +
    + + pagination->getLimitBox(); ?> +
    + +
    +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + items[0]->ordering)) { ?> + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + authorise('core.create', 'com_icagenda'); + $canEdit = $user->authorise('core.edit', 'com_icagenda'); + $canCheckin = $user->authorise('core.manage', 'com_icagenda'); + $canChange = $user->authorise('core.edit.state', 'com_icagenda'); + $canEditOwn = $user->authorise('core.edit.own', 'com_icagenda'); + + // Custom Field Groups list + $groups = array(); + + if ($item->groups) + { + $cf_groups = $this->cfGroups; + $array_groups = explode(',', $item->groups); + $groups = array(); + + foreach ($cf_groups as $key) + { + if (in_array($key->value, $array_groups)) + { + $groups[]= $key->option; + } + } + } + + $overrideCore = (str_replace('core_', '', $item->type) !== $item->type) ? true : false; + $separator = (str_replace('spacer_', '', $item->type) !== $item->type) ? true : false; + + if ($overrideCore) + { + $rowStyle = ' style="background: #d9edf7; color: #31708f;"'; + } + elseif ($separator) + { + $rowStyle = ' style="background: #e9e9e9; color: #333;"'; + } + else + { + $rowStyle = ''; + } +// Yellow $rowStyle = $overrideCore ? ' style="background: #fcf8e3; color: #8a6d3b;"' : ''; +// Red $rowStyle = $overrideCore ? ' style="background: #f2dede; color: #a94442;"' : ''; +// Green $rowStyle = $overrideCore ? ' style="background: #dff0d8; color: #3c763d;"' : +// ($item->parent_form == 2 ? ' style="background: #d9edf7;"' : ''); +// $rowClass = $overrideCore ? ' info' : ''; + ?> + + + + + + + + + + + + + + + + + items[0]->state)) { ?> + + + + + + + + + + + > + parent_form == 1) : ?> + + ' . JText::_('COM_ICAGENDA_CUSTOMFIELD_PARENT_REGISTRATION_FORM') . ''; ?> + + + ' . count($groups) . ''; ?> + + + parent_form == 2) : ?> + ' . JText::_('COM_ICAGENDA_CUSTOMFIELD_PARENT_EVENT_EDIT') . ''; ?> + + + + + + + + + + + + + + + + + items[0]->ordering)) { ?> + + + + + + + + items[0]->id)) { ?> + + + + + + +
    + ', 'cf.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?> + + + + + + + + + + + + + + + + + + + + items, 'filesave.png', 'customfields.saveorder'); ?> + + + +
    + pagination->getListFooter(); ?> +
    > + + + + + + + + + + + > + id); ?> + > + state, $i, 'customfields.', $canChange, 'cb'); ?> + > +
    + checked_out) : ?> + editor, $item->checked_out_time, 'customfields.', $canCheckin); ?> + + language == '*'):?> + + + language ? $this->escape($item->language) : JText::_('JUNDEFINED'); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + + + slug) : ?> + + escape($item->slug) . ')'; ?> + + + + +
    + + + +
    + id, 'customfield.'); + JHtml::_('dropdown.divider'); + + if ($item->state) : + JHtml::_('dropdown.unpublish', 'cb' . $i, 'customfields.'); + else : + JHtml::_('dropdown.publish', 'cb' . $i, 'customfields.'); + endif; + + JHtml::_('dropdown.divider'); + + if ($archived) : + JHtml::_('dropdown.unarchive', 'cb' . $i, 'customfields.'); + else : + JHtml::_('dropdown.archive', 'cb' . $i, 'customfields.'); + endif; + + if ($item->checked_out) : + JHtml::_('dropdown.checkin', 'cb' . $i, 'customfields.'); + endif; + + if ($trashed) : + JHtml::_('dropdown.untrash', 'cb' . $i, 'customfields.'); + else : + JHtml::_('dropdown.trash', 'cb' . $i, 'customfields.'); + endif; + + // Render dropdown list + echo JHtml::_('dropdown.render'); + ?> +
    + +
    > + slug) : ?> + escape($item->slug); ?> + + > + groups) : ?> + '; + echo implode(' ', array_values($groups)); + echo ''; + ?> + + > + type) : ?> + type); + $type_prefix = isset($type_ex[1]) ? $type_ex[0] : ''; + $type_label = ($type_prefix == 'core') + ? JText::_('COM_ICAGENDA_LABEL_OVERRIDE') + : JText::_('COM_ICAGENDA_LABEL_SPACER'); + $type = in_array($type_prefix, array('core', 'spacer')) +// ? str_replace($type_prefix . '_', '' , $item->type) + ? JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_' . strtoupper(str_replace($type_prefix . '_', '' , $item->type))) + : JText::_('COM_ICAGENDA_CUSTOMFIELD_TYPE_' . strtoupper($item->type)); + if ($type_prefix) : + echo '' . $type_label . ''; + endif; + ?> + escape($type); ?> + + > + + + + ' . JText::_('JGLOBAL_USE_GLOBAL') . ''; ?> + required == 1) : ?> + ' . JText::_('JYES') . ''; ?> + + ' . JText::_('JNO') . ''; ?> + + > + + + + pagination->orderUpIcon($i, true, 'customfields.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'customfields.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, true, 'customfields.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'customfields.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + ordering . '" ' . $disabled . ' class="text-area-order" />'; ?> + + ordering; ?> + + > + id; ?> +
    + +
    + + + + + +
    +
    + +enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/customfields/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/customfields/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/customfields/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/customfields/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/customfields/view.html.php new file mode 100644 index 00000000..969c02a9 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/customfields/view.html.php @@ -0,0 +1,200 @@ +params = JComponentHelper::getParams('com_icagenda'); + + $this->state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->cfGroups = $this->get('CustomFieldGroups'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + + if (version_compare(JVERSION, '3.0', 'ge')) + { + $this->sidebar = JHtmlSidebar::render(); + } + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @since 3.4.0 + */ + protected function addToolbar() + { + require_once JPATH_COMPONENT . '/helpers/icagenda.php'; + + $state = $this->get('State'); + $user = JFactory::getUser(); + $userId = $user->get('id'); + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_CUSTOMFIELDS'), 'customfields.png'); + } + else + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_CUSTOMFIELDS') . '', 'list-2'); + } + + $icTitle = JText::_('COM_ICAGENDA_CUSTOMFIELDS'); + + $document = JFactory::getDocument(); + $app = JFactory::getApplication(); + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + // Check if the form exists before showing the add/edit buttons + $formPath = JPATH_COMPONENT_ADMINISTRATOR.'/views/customfield'; + + if (file_exists($formPath)) + { + if ($canDo->get('core.create')) + { + JToolBarHelper::addNew('customfield.add','JTOOLBAR_NEW'); + } + + if ($canDo->get('core.edit')) + { + JToolBarHelper::editList('customfield.edit','JTOOLBAR_EDIT'); + } + } + + if ($canDo->get('core.edit.state')) + { + if (isset($this->items[0]->state)) + { + JToolBarHelper::divider(); + JToolBarHelper::custom('customfields.publish', 'publish.png', 'publish_f2.png','JTOOLBAR_PUBLISH', true); + JToolBarHelper::custom('customfields.unpublish', 'unpublish.png', 'unpublish_f2.png', 'JTOOLBAR_UNPUBLISH', true); + } + else + { + // If this component does not use state then show a direct delete button as we can not trash + JToolBarHelper::deleteList('', 'customfields.delete','JTOOLBAR_DELETE'); + } + + if (isset($this->items[0]->state)) + { + JToolBarHelper::divider(); + JToolBarHelper::archiveList('customfields.archive','JTOOLBAR_ARCHIVE'); + } + + if (isset($this->items[0]->checked_out)) + { + JToolBarHelper::custom('customfields.checkin', 'checkin.png', 'checkin_f2.png', 'JTOOLBAR_CHECKIN', true); + } + } + + // Show trash and delete for components that uses the state field + if (isset($this->items[0]->state)) + { + if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + JToolBarHelper::deleteList('', 'customfields.delete','JTOOLBAR_EMPTY_TRASH'); + JToolBarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + JToolBarHelper::trash('customfields.trash','JTOOLBAR_TRASH'); + JToolBarHelper::divider(); + } + } + + if ($canDo->get('core.admin')) + { + JToolBarHelper::preferences('com_icagenda'); + } + + if (version_compare(JVERSION, '3.0', 'ge')) + { + JHtmlSidebar::setAction('index.php?option=com_icagenda&view=customfields'); + + JHtmlSidebar::addFilter( + JText::_('JOPTION_SELECT_PUBLISHED'), + 'filter_published', + JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.state'), true) + ); + + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_CUSTOMFIELDS_FILTER_OPTION_SELECT_PARENT_FORM'), + 'filter_parent_form', + JHtml::_('select.options', $this->get('ParentForm'), 'value', 'text', $this->state->get('filter.parent_form'), true) + ); + + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_CUSTOMFIELDS_FILTER_OPTION_SELECT_GROUP'), + 'filter_group', + JHtml::_('select.options', $this->get('Groups'), 'value', 'text', $this->state->get('filter.group'), true) + ); + + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_CUSTOMFIELDS_FILTER_OPTION_SELECT_TYPE'), + 'filter_type', + JHtml::_('select.options', $this->get('FieldTypes'), 'value', 'text', $this->state->get('filter.type'), true) + ); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/download/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/download/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/download/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/download/tmpl/default.php b/deployed/icagenda/administrator/components/com_icagenda/views/download/tmpl/default.php new file mode 100644 index 00000000..846aa1ea --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/download/tmpl/default.php @@ -0,0 +1,80 @@ + + + +
    +
    + + form->getFieldset() as $field) : ?> +
    + hidden) : ?> +
    + label; ?> +
    + +
    + input; ?> +
    +
    + +
    + + +
    +
    + + + + 'bottom')); +?> +
    +
    + + form->getFieldset() as $field) : ?> + form->renderField($field->fieldname); ?> + + + + +
    +
    + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/download/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/download/tmpl/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/download/tmpl/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/download/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/download/view.html.php new file mode 100644 index 00000000..98e46bf1 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/download/view.html.php @@ -0,0 +1,49 @@ +form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + parent::display($tpl); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/event/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/event/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/event/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/event/tmpl/edit.php b/deployed/icagenda/administrator/components/com_icagenda/views/event/tmpl/edit.php new file mode 100644 index 00000000..79ecfd73 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/event/tmpl/edit.php @@ -0,0 +1,1274 @@ +authorise('icagenda.access.events', 'com_icagenda') + && defined('IC_LIBRARY')) +{ + $iCparams = JComponentHelper::getParams('com_icagenda'); + $maps_service = $iCparams->get('maps_service', ''); + + + $bootstrapType = '1'; + + $EventTag = 'event'; + $EventTitle = JText::_('COM_ICAGENDA_TITLE_EVENT', true); + + $DatesTag = 'dates'; + $DatesTitle = JText::_('COM_ICAGENDA_LEGEND_DATES', true); + + $DescTag = 'desc'; + $DescTitle = JText::_('COM_ICAGENDA_LEGEND_DESC', true); + + $InfosTag = 'infos'; + $InfosTitle = JText::_('COM_ICAGENDA_LEGEND_INFORMATION', true); + + $GooglemapTag = 'googlemap'; + $GooglemapTitle = JText::_('COM_ICAGENDA_LEGEND_GOOGLE_MAPS', true); + + $RegistrationsTag = 'registrations'; + $RegistrationsTitle = JText::_('COM_ICAGENDA_REGISTRATIONS_LABEL', true); + + $OptionsTag = 'options'; + $OptionsTitle = JText::_('JOPTIONS', true); + + $PublishingTag = 'publishing'; + $PublishingTitle = JText::_('JGLOBAL_FIELDSET_PUBLISHING', true); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::_('behavior.formvalidation'); + JHtml::_('behavior.keepalive'); + + jimport( 'joomla.html.html.tabs' ); + + $iCmapDisplay = '3'; + + $icPanEvent = JText::_('COM_ICAGENDA_TITLE_EVENT', true); + $icPanDates = JText::_('COM_ICAGENDA_LEGEND_DATES', true); + $icPanDesc = JText::_('COM_ICAGENDA_LEGEND_DESC', true); + $icPanInfos = JText::_('COM_ICAGENDA_LEGEND_INFORMATION', true); + $icPanGooglemap = JText::_('COM_ICAGENDA_LEGEND_GOOGLE_MAPS', true); + $icPanRegistrations = JText::_('COM_ICAGENDA_REGISTRATIONS_LABEL', true); + $icPanOptions = JText::_('JOPTIONS', true); + $icPanPublishing = JText::_('JGLOBAL_FIELDSET_PUBLISHING', true); + $startPane = 'tabs.start'; + $addPanel = 'tabs.panel'; + $endPanel = 'tabs.end'; + $endPane = 'tabs.end'; + $EventTag1 = $EventTag; + $EventTag2 = $EventTitle; + $DatesTag1 = $DatesTag; + $DatesTag2 = $DatesTitle; + $DescTag1 = $DescTag; + $DescTag2 = $DescTitle; + $InfosTag1 = $InfosTag; + $InfosTag2 = $InfosTitle; + $GooglemapTag1 = $GooglemapTag; + $GooglemapTag2 = $GooglemapTitle; + $RegistrationsTag1 = $RegistrationsTag; + $RegistrationsTag2 = $RegistrationsTitle; + $OptionsTag1 = $OptionsTag; + $OptionsTag2 = $OptionsTitle; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + + // Joomla 3 + else + { + JHtml::_('behavior.tooltip'); + + if (version_compare(JVERSION, '3.4.0', 'lt')) + { + JHtml::_('behavior.formvalidation'); + } + else + { + JHtml::_('behavior.formvalidator'); + } + + JHtml::_('behavior.keepalive'); + JHtml::_('formbehavior.chosen', 'select'); + + jimport('joomla.html.html.bootstrap'); + + $icPanEvent = 'icTab'; + $icPanDates = 'icTab'; + $icPanDesc = 'icTab'; + $icPanInfos = 'icTab'; + $icPanGooglemap = 'icTab'; + $icPanRegistrations = 'icTab'; + $icPanOptions = 'icTab'; + $icPanPublishing = 'icTab'; + + if ($bootstrapType == '1') + { + $iCmapDisplay = '1'; + $startPane = 'bootstrap.startTabSet'; + $addPanel = 'bootstrap.addTab'; + $endPanel = 'bootstrap.endTab'; + $endPane = 'bootstrap.endTabSet'; + $EventTag1 = $EventTag; + $EventTag2 = $EventTitle; + $DatesTag1 = $DatesTag; + $DatesTag2 = $DatesTitle; + $DescTag1 = $DescTag; + $DescTag2 = $DescTitle; + $InfosTag1 = $InfosTag; + $InfosTag2 = $InfosTitle; + $GooglemapTag1 = $GooglemapTag; + $GooglemapTag2 = $GooglemapTitle; + $RegistrationsTag1 = $RegistrationsTag; + $RegistrationsTag2 = $RegistrationsTitle; + $OptionsTag1 = $OptionsTag; + $OptionsTag2 = $OptionsTitle; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + elseif ($bootstrapType == '2') + { + $iCmapDisplay = '2'; + $startPane = 'bootstrap.startAccordion'; + $addPanel = 'bootstrap.addSlide'; + $endPanel = 'bootstrap.endSlide'; + $endPane = 'bootstrap.endAccordion'; + $EventTag1 = $EventTitle; + $EventTag2 = $EventTag; + $DatesTag1 = $DatesTitle; + $DatesTag2 = $DatesTag; + $DescTag1 = $DescTitle; + $DescTag2 = $DescTag; + $InfosTag1 = $InfosTitle; + $InfosTag2 = $InfosTag; + $GooglemapTag1 = $GooglemapTitle; + $GooglemapTag2 = $GooglemapTag; + $RegistrationsTag1 = $RegistrationsTitle; + $RegistrationsTag2 = $RegistrationsTag; + $OptionsTag1 = $OptionsTitle; + $OptionsTag2 = $OptionsTag; + $PublishingTag1 = $PublishingTitle; + $PublishingTag2 = $PublishingTag; + } + } + + $params = $this->form->getFieldsets('params'); + + // ZOOM + $zoom = '1'; + // HYBRID, ROADMAP, SATELLITE, TERRAIN + $mapTypeId = 'ROADMAP'; + + $coords = '0, 0'; + $oldcoordinate = $this->item->coordinate; + $lat = $this->item->lat; + $lng = $this->item->lng; + + if (($oldcoordinate == NULL) && ($lat == '0') && ($lng == '0')) + { + $zoom = '1'; + } + // Notes: zoomControl: false, mapTypeControl: false + + // Control of dates if valid (Alert Messages) + $messagealert = ''; + $alert = ''; + $nodate = '0000-00-00 00:00:00'; + $nextget = $this->item->next; + + if ($nextget == '-3600' + || $nextget == $nodate) + { + $messagealert = '

    ' . JText::_('COM_ICAGENDA_FORM_ALERT_UNPUBLISHED') . '

    '; + + if (($this->item->startdate == $nodate) && ($this->item->enddate != $nodate)) + { + $messagealert.= '

    ' . JText::_('COM_ICAGENDA_FORM_ERROR_NO_STARTDATE') . '


    '; + } + if (($this->item->enddate == $nodate) && ($this->item->startdate != $nodate)) + { + $messagealert.= '

    ' . JText::_('COM_ICAGENDA_FORM_ERROR_NO_ENDDATE') . '


    '; + } + if (($this->item->enddate < $this->item->startdate) + && (($this->item->next != '-3600') || ($this->item->next != $nodate))) + { + $messagealert.= '

    ' . JText::_('COM_ICAGENDA_FORM_ERROR_INVALID_PERIOD') . '


    '; + } + } + else + { + if (($this->item->startdate == $nodate) && ($this->item->enddate != $nodate)) + { + $alert.= '

    ' . JText::_('COM_ICAGENDA_FORM_ERROR_NO_STARTDATE') . '


    '; + } + if (($this->item->enddate == $nodate) && ($this->item->startdate != $nodate)) + { + $alert.= '

    ' . JText::_('COM_ICAGENDA_FORM_ERROR_NO_ENDDATE') . '


    '; + } + if (($this->item->enddate < $this->item->startdate) + && (($this->item->next != '-3600') || ($this->item->next != $nodate))) + { + $alert.= '

    ' . JText::_('COM_ICAGENDA_FORM_ERROR_INVALID_PERIOD') . '


    '; + } + } + ?> + + + + + + +
    +
    + + + + + + + item->id) ? '1' : '0'; + ?> +
    +

    + '; ?> + item->id) ? JText::_('COM_ICAGENDA_LEGEND_NEW_EVENT') : JText::sprintf('COM_ICAGENDA_LEGEND_EDIT_EVENT', $this->item->id); ?> iCagenda +

    +

    + + +

    +
    + +
     
    + + +
    + +
    + ' . JText::_('COM_ICAGENDA_FORM_WARNING') . '' . $messagealert; ?> +
    + + +
    + +
    + +
    + + +
    +
    + + + 'event')); ?> + + + + +
    +

    + item->id) ? JText::_('COM_ICAGENDA_LEGEND_NEW_EVENT') : JText::sprintf('COM_ICAGENDA_LEGEND_EDIT_EVENT', $this->item->id); ?> +

    +
    +
    +
    +
    +
    + form->getLabel('title'); ?> +
    +
    + form->getInput('title'); ?> +
    +
    +
    +
    + form->getLabel('catid'); ?> +
    +
    + form->getInput('catid'); ?> +
    +
    +
    + +
    + form->renderField('image'); ?> +
    + +
    +
    + +
    +
    +
    + form->getLabel('image'); ?> +
    +
    + form->getInput('image'); ?> +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + + + + + + + +
    +

    + +
    +
    +
    +

    +
    +
    + form->getLabel('startdate'); ?> +
    +
    + form->getInput('startdate'); ?> +
    +
    +
    +
    + form->getLabel('enddate'); ?> +
    +
    + form->getInput('enddate'); ?> +
    +
    + +
    +
    +

     

    +
    +
    + form->getLabel('weekdays'); ?> +
    +
    + form->getInput('weekdays'); ?> +
    +
    + +
    +
    +

    + +
    +
    + +
    +
    +
    +
    +
    +

    +
    + form->getInput('dates'); ?> +
    +
    +
    +
    +
    +
    +
    +
    + form->getLabel('displaytime'); ?> +
    +
    + form->getInput('displaytime'); ?> +
    +
    +
    +
    + form->getLabel('next'); ?> +
    +
    + form->getInput('next'); ?> +
    +
    +
    +
    +
    + + ' + .JHtml::_('sliders.start', 'info-slider', array('useCookie'=>0, 'startOffset'=>-1, 'startTransition'=>1)) + .JHtml::_('sliders.panel', JText::_('COM_ICAGENDA_DATES_HELP'), 'slide1') + .'
    ' + .'
      ' + .'
      '. JText::_('COM_ICAGENDA_DATES_HELP_INTRO').'

      ' + .'
      '. JText::_('COM_ICAGENDA_LEGEND_SINGLE_DATES').'
      ' + .'
      ► '. JText::_('COM_ICAGENDA_DATES_HELP_LINE1').'
      ' + .'
      '. JText::_('COM_ICAGENDA_DATES_HELP_EXAMPLE1').'

      ' + .'
      ► '. JText::_('COM_ICAGENDA_DATES_HELP_LINE2').'
      ' + .'
      '. JText::_('COM_ICAGENDA_DATES_HELP_EXAMPLE2').'

      ' + .'
      '. JText::_('COM_ICAGENDA_LEGEND_PERIOD_DATES').'
      ' + .'
      ► '. JText::_('COM_ICAGENDA_DATES_HELP_LINE3').'
      ' + .'
      '. JText::_('COM_ICAGENDA_DATES_HELP_EXAMPLE3').'

      ' + .'
      '. JText::_('COM_ICAGENDA_LEGEND_PERIOD_DATES').' & '. JText::_('COM_ICAGENDA_LEGEND_SINGLE_DATES').'
      ' + .'
      ► '. JText::_('COM_ICAGENDA_DATES_HELP_LINE4').'
      ' + .'
      '. JText::_('COM_ICAGENDA_DATES_HELP_EXAMPLE4').'

      ' + .'
      ► '. JText::_('COM_ICAGENDA_DATES_HELP_LINE5').'
      ' + .'
      '. JText::_('COM_ICAGENDA_DATES_HELP_EXAMPLE5').'

      ' + .'
    ' + .'
    ' + .JHtml::_('sliders.end') + .'
    '; + ?> +
    + + + + + + +
    +

    +
    +
    +

    +
    + form->getInput('shortdesc'); ?> +
    +
    +
    +

    + form->getInput('desc'); ?> +
    +
    +
    +

    +
    + form->getInput('metadesc'); ?> +
    +
    + + + + + + +
    +

    +
    +
    +
    +

    +
    +
    + form->getLabel('place'); ?> +
    +
    + form->getInput('place'); ?> +
    +
    +
    +

    +
    +
    + form->getLabel('email'); ?> +
    +
    + form->getInput('email'); ?> +
    +
    +
    +
    + form->getLabel('phone'); ?> +
    +
    + form->getInput('phone'); ?> +
    +
    +
    +
    + form->getLabel('website'); ?> +
    +
    + form->getInput('website'); ?> +
    +
    +
    +

    +
    +
    + form->getLabel('file'); ?> +
    +
    + form->getInput('file'); ?> +
    +
    +
    +
    +
    +

    +
    +
    + form->getLabel('features'); ?> +
    +
    + form->getInput('features'); ?> +
    +
    +
    +

    + +
    +
    +
    + + + + + + +
    +

    +
    +
    + +
    +
    +
    +
    + form->getLabel('address'); ?> +
    +
    + form->getInput('address'); ?> +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    + form->getLabel('address'); ?> +
    +
    +
    + form->getInput('address'); ?> + +
    +
    +
    +
    +
    + item->address) : ?> + get('googlemaps_embed_key', '') . '&q=' . urlencode(strip_tags($this->item->address)) . '" allowfullscreen>'; ?> + +
    + +
    + +
    + +

    +
    + +
    +
    +
    + +
    +
    +
    + form->getLabel('address'); ?> +
    +
    + form->getInput('address'); ?> +
    +
    +
    + form->getInput('city'); ?> +
    +
    + form->getInput('country'); ?> +
    +
    + form->getInput('lat'); ?> +
    +
    + form->getInput('lng'); ?> +
    + + +
    +
    +
    +
    +

    Map

    + +
    + +
    +
    +
    +
    + + + +
    +
    + + + + +
    +

    +
    +
    + $fieldSet) : ?> + + description) && trim($fieldSet->description)) : ?> +

    escape(JText::_($fieldSet->description));?>

    + +
    +

    escape(JText::_($fieldSet->label)); ?>

    + form->getFieldset($name) as $field) : ?> +
    +
    + label; ?> +
    +
    + load('com_icagenda', JPATH_SITE, 'en-GB', true); + $language->load('com_icagenda', JPATH_SITE, null, true); + + if (($field->name == 'jform[params][statutReg]') && ($field->value == '2')) + { + echo ''; + } + elseif ($field->name == 'jform[params][maxRlistGlobal]') + { + if ($field->value == '1') + { + echo ''; + } + elseif ($field->value == '0') + { + echo ''; + } + else + { + echo $field->input; + } + } + else + { + echo $field->input; + } + ?> +
    +
    + +
    + + +
    +
    + + + + + +
    +

    +
    +
    + $fieldSet) : ?> + + description) && trim($fieldSet->description)) : ?> +

    escape(JText::_($fieldSet->description));?>

    + +
    +

    escape(JText::_($fieldSet->label)); ?>

    + form->getFieldset($name) as $field) : ?> +
    +
    + label; ?> +
    +
    + load('com_icagenda', JPATH_SITE, 'en-GB', true); + $language->load('com_icagenda', JPATH_SITE, null, true); + echo $field->input; + ?> +
    +
    + +
    + + +
    +
    + + + + + +
    +

    +
    +
    + $fieldSet) : ?> + + description) && trim($fieldSet->description)) : ?> +

    escape(JText::_($fieldSet->description));?>

    + +
    +

    escape(JText::_($fieldSet->label)); ?>

    + form->getFieldset($name) as $field) : ?> + renderField(); ?> + +
    + + +
    +
    +
    +
    +
    + form->getLabel('alias'); ?> +
    +
    + form->getInput('alias'); ?> +
    +
    +
    +
    + form->getLabel('id'); ?> +
    +
    + form->getInput('id'); ?> +
    +
    +
    +
    + form->getLabel('created'); ?> +
    +
    + form->getInput('created'); ?> +
    +
    +
    +
    + form->getLabel('created_by'); ?> +
    +
    + form->getInput('created_by'); ?> +
    +
    +
    +
    + form->getLabel('created_by_alias'); ?> +
    +
    + form->getInput('created_by_alias'); ?> +
    +
    +
    +
    + form->getLabel('modified'); ?> +
    +
    + form->getInput('modified'); ?> +
    +
    +
    +
    + form->getLabel('modified_by'); ?> +
    +
    + form->getInput('modified_by'); ?> +
    +
    +
    +
    + form->getLabel('checked_out'); ?> +
    +
    + form->getInput('checked_out'); ?> +
    +
    +
    +
    + form->getLabel('checked_out_time'); ?> +
    +
    + form->getInput('checked_out_time'); ?> +
    +
    + item->site_itemid)) : ?> +

    escape(JText::_('COM_ICAGENDA_FORM_FRONTEND_OPTIONS'));?>

    +
    +
    +
    + form->getLabel('site_itemid'); ?> +
    +
    + form->getInput('site_itemid'); ?> +
    +
    +
    +
    + form->getLabel('username'); ?> +
    +
    + form->getInput('username'); ?> +
    +
    + + +
    +
    +
    + + + + + + +
    + + +
    +

    +
    +
    +
    + form->getLabel('state'); ?> +
    +
    + form->getInput('state'); ?> +
    +
    +
    +
    + form->getLabel('approval'); ?> +
    +
    + form->getInput('approval'); ?> +
    +
    +
    +
    + form->getLabel('access'); ?> +
    +
    + form->getInput('access'); ?> +
    +
    +
    +
    + form->getLabel('language'); ?> +
    +
    + form->getInput('language'); ?> +
    +
    +
    +
    + form->getLabel('hits'); ?> +
    +
    + form->getInput('hits'); ?> +
    +
    + + +
    + +
    + +
    +
    + item->state=='0'; + } + ?> +
    + + +
    +
    + + + get('timeformat', 1) == 2) ? 'true' : ''; + $firstDay = $iCparams->get('firstday_week_global', 1); + ?> + + + + + + + + addScriptDeclaration($iCheckForm); + + // CSS files which could be overridden into your site template. (eg. /templates/my_template/css/com_icagenda/icagenda-back.css) + JHtml::stylesheet( 'com_icagenda/icagenda.css', false, true ); + JHtml::stylesheet( 'com_icagenda/jquery-ui-1.8.17.custom.css', false, true ); + + $ic_style = 'div.tip img.media-preview {display:none}'; + $document->addStyleDeclaration($ic_style); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::stylesheet('com_icagenda/template.j25.css', false, true); + JHtml::stylesheet('com_icagenda/icagenda-back.j25.css', false, true); + + JHtml::_('behavior.framework'); + + // load jQuery, if not loaded before (NEW VERSION IN 1.2.6) + $scripts = array_keys($document->_scripts); + $scriptFound = false; + $scriptuiFound = false; + $mapsgooglescriptFound = false; + for ($i = 0; $i < count($scripts); $i++) + { + if (stripos($scripts[$i], 'jquery.min.js') !== false) + { + $scriptFound = true; + } + // load jQuery, if not loaded before as jquery - added in 1.2.7 + if (stripos($scripts[$i], 'jquery.js') !== false) + { + $scriptFound = true; + } + if (stripos($scripts[$i], 'jquery-ui.min.js') !== false) + { + $scriptuiFound = true; + } + if (stripos($scripts[$i], 'maps.google') !== false) + { + $mapsgooglescriptFound = true; + } + } + + // jQuery Library Loader + if (!$scriptFound) + { + // load jQuery, if not loaded before + if (!$app->get('jquery')) + { + $app->set('jquery', true); + // add jQuery + $document->addScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/jquery.noconflict.js' ); + } + } + + if (!$scriptuiFound) + { + $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); + } + + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/template.js' ); + } + else + { + JHtml::_('bootstrap.framework'); + JHtml::_('jquery.framework'); + + // Change jQuery UI version from 1.9.2 to 1.8.23 to prevent a conflict in tooltip that appeared since Joomla 3.1.4 +// $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); + $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js'); +// JHtml::_('jquery.ui', array('core', 'sortable')); + } + + if ($maps_service == '3') + { + // Google Maps Javascript API V3 + icagendaGooglemaps::loadGMapScripts('edit'); + } + + /** + * Script files which could be overridden into your site template. + * (eg. /templates/my_template/js/com_icagenda/FILE_NAME.js) + */ + JHtml::script( 'com_icagenda/timepicker.js', false, true ); + JHtml::script( 'com_icagenda/icdates.js', false, true ); + JHtml::script( 'com_icagenda/icform.js', false, true ); +} +else +{ + if (defined('IC_LIBRARY')) $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/event/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/event/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/event/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/event/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/event/view.html.php new file mode 100644 index 00000000..fc8f6c1b --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/event/view.html.php @@ -0,0 +1,159 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + $icagenda_categories = class_exists('icagendaCategories') ? icagendaCategories::getList('1') : false; + + if ($icagenda_categories) + { + $this->addToolbar(); + } + else + { + $app = JFactory::getApplication(); + + $app->enqueueMessage(JText::_('COM_ICAGENDA_ALERT_NO_CATEGORY_PUBLISHED') + . '

    ' + . JText::_('COM_ICAGENDA_LEGEND_NEW_CATEGORY') . '' + . ' ' + . JText::_('ICCATEGORIES') + . '', 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=events')); + } + + parent::display($tpl); + + icagendaForm::loadDateTimePickerJSLanguage(); + + JHtml::stylesheet( 'com_icagenda/icagenda.css', false, true ); + } + + /** + * Add the page title and toolbar. + * + * @since 1.0 + */ + protected function addToolbar() + { + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + $jinput = $app->input; + + $jinput->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $userId = $user->get('id'); + $isNew = ($this->item->id == 0); + $checkedOut = ! ($this->item->checked_out == 0 || $this->item->checked_out == $userId); + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_NEW_EVENT') + : 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_EDIT_EVENT'), + 'event'); + } + else + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_NEW_EVENT') . '' + : 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_EDIT_EVENT') . '', + $isNew ? 'new' : 'pencil-2'); + } + + $icTitle = $isNew ? JText::_('COM_ICAGENDA_LEGEND_NEW_EVENT') : JText::_('COM_ICAGENDA_LEGEND_EDIT_EVENT'); + + $sitename = $app->getCfg('sitename'); + $title = $sitename . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + // Build the actions for new and existing records. + if ($isNew) + { + // For new records, check the create permission. + if ($canDo->get('core.create')) + { + JToolBarHelper::apply('event.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('event.save', 'JTOOLBAR_SAVE'); + JToolBarHelper::custom('event.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + + JToolBarHelper::cancel('event.cancel', 'JTOOLBAR_CANCEL'); + } + else + { + // Can't save the record if it's checked out. + if ( ! $checkedOut) + { + // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. + if ($canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId)) + { + // We can save the new record + JToolBarHelper::apply('event.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('event.save', 'JTOOLBAR_SAVE'); + + // We can save this record, but check the create permission to see + // if we can return to make a new one. + if ($canDo->get('core.create')) + { + JToolBarHelper::custom('event.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + } + } + + // If checked out, we can still save + if ($canDo->get('core.create')) + { + JToolBarHelper::custom('event.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); + } + + JToolBarHelper::cancel('event.cancel', 'JTOOLBAR_CLOSE'); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/events/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/events/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/events/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/events/tmpl/default.php b/deployed/icagenda/administrator/components/com_icagenda/views/events/tmpl/default.php new file mode 100644 index 00000000..aef8462e --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/events/tmpl/default.php @@ -0,0 +1,724 @@ +get('id'); +$listOrder = $this->state->get('list.ordering'); +$listDirn = $this->state->get('list.direction'); +$canOrder = $user->authorise('core.edit.state', 'com_icagenda'); +$saveOrder = $listOrder == 'e.ordering'; + +// Switch Joomla 2.5 / 3.x +if (version_compare(JVERSION, '3.0', 'lt')) +{ + JHtml::_('behavior.tooltip'); +} +else +{ + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + JHtml::_('bootstrap.tooltip'); + JHtml::_('formbehavior.chosen', 'select'); + JHtml::_('dropdown.init'); + + $archived = $this->state->get('filter.published') == 2 ? true : false; + $trashed = $this->state->get('filter.published') == -2 ? true : false; + + if ($saveOrder) + { + $saveOrderingUrl = 'index.php?option=com_icagenda&task=events.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'eventsList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); + } +} + +// Check if GD is enabled +if (extension_loaded('gd') && function_exists('gd_info')) +{ + $thumb_generator = $this->params->get('thumb_generator', 1); +// echo "It looks like GD is installed"; +} +else +{ + $thumb_generator = 0; + +// throw new Exception(JText::_('COM_ICAGENDA_PHP_ERROR_GD'), 101); + $app->enqueueMessage(JText::_('COM_ICAGENDA_PHP_ERROR_GD'), 'warning'); +} + +// Check if fopen is allowed +$fopen = true; +$result = ini_get('allow_url_fopen'); + +if (empty($result)) +{ + $fopen = false; + +// throw new Exception(JText::_('COM_ICAGENDA_PHP_ERROR_FOPEN'), 101); + $app->enqueueMessage(JText::_('COM_ICAGENDA_PHP_ERROR_FOPEN'), 'warning'); +} + +// 3.3.3 +$sortFields = array(); +?> +
    +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + + + + +
    + +
    + + + + + + + +
    +
    +
    + + + + +
    + +
    + + +
    +
    + + pagination->getLimitBox(); ?> +
    +
    +
    + + + + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + items[0]->ordering)) { ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + authorise('core.create', 'com_icagenda'); + $canEdit = $user->authorise('core.edit', 'com_icagenda'); + $canCheckin = $user->authorise('core.manage', 'com_icagenda') || $item->checked_out == $userId || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_icagenda') && $canCheckin; + $canEditOwn = $user->authorise('core.edit.own', 'com_icagenda') && $item->created_by == $userId; +// $canEditOwn = $user->authorise('core.edit.own', 'com_icagenda.events.'.$item->id) && $item->created_by == $userId; + + // Get Access Names + $db = JFactory::getDBO(); + $db->setQuery( + 'SELECT `title`' . + ' FROM `#__viewlevels`' . + ' WHERE `id` = '. (int) $item->access + ); + $access_title = $db->loadObject()->title; + + // Get Today and Next Date (Y-m-d) + $eventTimeZone = null; + $today = JHtml::date('now', 'Y-m-d'); + $nextdate = JHtml::date($item->next, 'Y-m-d', $eventTimeZone); + $isDate = iCDate::isDate($item->next); + ?> + + + + + + + + + + + + items[0]->state)) : ?> + + + + + + + + + + + + + + + + + + items[0]->ordering)) : ?> + + + + + + + + + + + + + + + + + + + items[0]->id)) : ?> + + + + + ' . JText::_( 'JACTION_EDIT' ) . ''; + $savetx = '' . JText::_( 'JSAVE' ) . ''; + + foreach ($this->items as $i => $item) + { + if (($item->asset_id == '0') && ($item->state == '-2')) + { + $ia = $ia+1; + $front_submit = '1'; + } + } + + if ($front_submit == 1 && $ia == 1) + { + $app->enqueueMessage(JText::sprintf( 'COM_ICAGENDA_TRASH_FRONTEND_SUBMITTED_1', $edittx, $savetx ), 'notice'); + } + elseif ($front_submit == 1 && $ia > 1) + { + $app->enqueueMessage(JText::sprintf( 'COM_ICAGENDA_TRASH_FRONTEND_SUBMITTED', $edittx, $savetx ), 'notice'); + } + + foreach ($this->items as $i => $item) + { + if ($item->asset_id == '0' && $item->state == '-2') + { + $editLink = 'index.php?option=com_icagenda&task=event.edit&id=' . $item->id; + $msg = '- ' . $item->title . ' [' . $item->id . '] : ' . JText::_('JACTION_EDIT') . ''; + $type = JText::_('JGLOBAL_LIST').' :'; + } + if ( ! empty($msg)) + { + $app->enqueueMessage($msg, $type); + } + } + } + ?> + + + +
    + ', 'e.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?> + + + + + + + + + + | + + + + + + + + items, 'filesave.png', 'events.saveorder'); ?> + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + + + + + + + + + + + + id); ?> + + id); + + if ($eventIsCancelled) + { + echo $eventIsCancelled; + } + + // Control of dates if valid + elseif ( ! $isDate) + { + echo '

    '; + echo '' . JText::_('COM_ICAGENDA_NO_VALID_DATE') . ''; + if ($item->state == '1') + { + //$state = 0; + $db = Jfactory::getDbo(); + $query = $db->getQuery(true); + $query->clear(); + $query->update(' #__icagenda_events '); + $query->set(' state = 0 ' ); + $query->where(' id = ' . (int) $item->id ); + $db->setQuery((string)$query); + $db->query($query); + } + } + else + { + echo JHtml::_('jgrid.published', $item->state, $i, 'events.', $canChange, 'cb'); + } + ?> +
    + approval ) ? 0 : 1; + echo JHtml::_('jgrid.state', JHtmlEvents::approveEvents(), $approved, $i, 'events.', (boolean) $approved); + ?> + approval, $i, 'events.'); ?> + approval, $i); ?> + approval, $i, 'events', $canChange, 'cb'); ?> + +
    + image) && ($thumb_generator == 1)) + { + // Get media path + $params_media = JComponentHelper::getParams('com_media'); + $image_path = $params_media->get('image_path', 'images'); + + // Paths to thumbs folder + $thumbsPath = $image_path.'/icagenda/thumbs'; + + // Large Size Options + $l_thumbOptions = $this->params->get('thumb_large'); + $l_width = is_numeric($l_thumbOptions[0]) ? $l_thumbOptions[0] : '900'; + $l_height = is_numeric($l_thumbOptions[1]) ? $l_thumbOptions[1] : '600'; + $l_quality = is_numeric($l_thumbOptions[2]) ? $l_thumbOptions[2] : '100'; + $l_crop = ! empty($l_thumbOptions[3]) ? true : false; + + // Medium Size Options + $m_thumbOptions = $this->params->get('thumb_medium'); + $m_width = is_numeric($m_thumbOptions[0]) ? $l_thumbOptions[0] : '300'; + $m_height = is_numeric($m_thumbOptions[1]) ? $l_thumbOptions[1] : '300'; + $m_quality = is_numeric($m_thumbOptions[2]) ? $l_thumbOptions[2] : '100'; + $m_crop = ! empty($m_thumbOptions[3]) ? true : false; + + // Small Size Options + $s_thumbOptions = $this->params->get('thumb_small'); + $s_width = is_numeric($s_thumbOptions[0]) ? $s_thumbOptions[0] : '100'; + $s_height = is_numeric($s_thumbOptions[1]) ? $s_thumbOptions[1] : '100'; + $s_quality = is_numeric($s_thumbOptions[2]) ? $s_thumbOptions[2] : '100'; + $s_crop = ! empty($s_thumbOptions[3]) ? true : false; + + // XSmall Size Options + $xs_thumbOptions = $this->params->get('thumb_xsmall'); + $xs_width = is_numeric($xs_thumbOptions[0]) ? $xs_thumbOptions[0] : '48'; + $xs_height = is_numeric($xs_thumbOptions[1]) ? $xs_thumbOptions[1] : '48'; + $xs_quality = is_numeric($xs_thumbOptions[2]) ? $xs_thumbOptions[2] : '80'; + $xs_crop = ! empty($xs_thumbOptions[3]) ? true : false; + + // Generate large thumb if not exist + iCThumbGet::thumbnail($item->image, $thumbsPath, 'themes', + $l_width, $l_height, $l_quality, $l_crop, 'ic_large', null, true); + + // Generate medium thumb if not exist + iCThumbGet::thumbnail($item->image, $thumbsPath, 'themes', + $m_width, $m_height, $m_quality, $m_crop, 'ic_medium'); + + // Generate small thumb if not exist + iCThumbGet::thumbnail($item->image, $thumbsPath, 'themes', + $s_width, $s_height, $s_quality, $s_crop, 'ic_small'); + + // Generate x-small thumb if not exist + iCThumbGet::thumbnail($item->image, $thumbsPath, 'themes', + $xs_width, $xs_height, $xs_quality, $xs_crop, 'ic_xsmall'); + + // Sub-folder Destination ($thumbsPath / 'subfolder' /) + $subFolder = 'system'; + + // Display thumbnail in admin events list + echo iCThumbGet::thumbnailImgTagLinkModal($item->image, $thumbsPath, $subFolder, '120', '100', '100', false); + } + elseif ($item->image + && $thumb_generator == 0) + { + if (filter_var($item->image, FILTER_VALIDATE_URL)) + { + echo ''; + echo ''; + } + else + { + echo ''; + echo ''; + } + } + else + { + echo ''; + } + // END iCthumb + ?> +
    +
    +
    + checked_out) : ?> + editor, $item->checked_out_time, 'events.', $canCheckin); ?> + + language == '*'):?> + + + language ? $this->escape($item->language) : JText::_('JUNDEFINED'); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + +
    + escape($item->category); ?> +
    + place) OR ($item->city) OR ($item->country)) : ?> +

    + place) : ?> +

    + escape($item->place); ?> +
    + + city) : ?> +
    + escape($item->city); ?> +
    + + country) : ?> +
    + escape($item->country); ?> +
    +

    + + + site_itemid)) : ?> + +
    + escape($item->site_itemid); ?> +
    +
    + +
    + + + + +
    + id, 'event.'); + JHtml::_('dropdown.divider'); + + if ($item->state) : + JHtml::_('dropdown.unpublish', 'cb' . $i, 'events.'); + else : + JHtml::_('dropdown.publish', 'cb' . $i, 'events.'); + endif; + +// if ($item->featured) : +// JHtml::_('dropdown.unfeatured', 'cb' . $i, 'events.'); +// else : +// JHtml::_('dropdown.featured', 'cb' . $i, 'events.'); +// endif; + + JHtml::_('dropdown.divider'); + + if ($archived) : + JHtml::_('dropdown.unarchive', 'cb' . $i, 'events.'); + else : + JHtml::_('dropdown.archive', 'cb' . $i, 'events.'); + endif; + + if ($item->checked_out) : + JHtml::_('dropdown.checkin', 'cb' . $i, 'events.'); + endif; + + if ($trashed) : + JHtml::_('dropdown.untrash', 'cb' . $i, 'events.'); + else : + JHtml::_('dropdown.trash', 'cb' . $i, 'events.'); + endif; + + // Render dropdown list + echo JHtml::_('dropdown.render'); + } + ?> +
    + + + +
    + params->get('date_format_global', 'Y - m - d'); + $separator = $this->params->get('date_separator', ' '); + $eventDate = iCGlobalize::dateFormat($item->next, $date_format_global, $separator); + $eventTime = $item->displaytime ? ' - ' . JHtml::date($item->next, 'H:i', null) : ''; + $eventDate = $eventDate ? $eventDate : date('Y-m-d', strtotime($item->next)); + $dateshow = $eventDate . $eventTime; + + // Upcoming Next Date + if (iCDate::isDate($item->next)) + { + if ($nextdate > $today) + { + echo '
    '; + echo JText::_('COM_ICAGENDA_EVENTS_NEXT_FUTUR') . '
    '; + echo '
    ' . $dateshow . '
    '; + echo '
    '; + } + // Next Date is today + elseif ($nextdate == $today) + { + echo '
    '; + echo JText::_('COM_ICAGENDA_EVENTS_NEXT_TODAY') . '
    '; + echo '
    ' . $dateshow . '
    '; + echo '
    '; + } + elseif ($nextdate < $today) + { + echo '
    '; + echo JText::_('COM_ICAGENDA_EVENTS_NEXT_PAST') . '
    '; + echo '
    ' . $dateshow . '
    '; + echo '
    '; + } + } + else + { + echo '
    '; + echo JText::_('COM_ICAGENDA_EVENTS_NEXT_ALERT'); + echo '
    '; + } + ?> +
    + + + + pagination->orderUpIcon($i, true, 'events.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'events.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, true, 'events.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'events.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" /> + + ordering; ?> + + + escape($access_title); ?> + + username == '' && ! $item->created_by) + { + $undefined = '' . JText::_('JUNDEFINED') . ''; + echo $undefined; + } + elseif ( ! $item->created_by || ! $item->author_name) + { + echo $this->escape($item->username); + } + else + { + echo $this->escape($item->author_name); + echo ' [' . $this->escape($item->author_username) . ']'; + } + ?> + escape($username); ?> + created_by_alias) : ?> +

    + escape($item->created_by_alias)); ?> +

    + +
    + language == '*'):?> + + + language ? $this->escape($item->language) : JText::_('JUNDEFINED'); ?> + + + hits; ?> + + id; ?> +
    + + + + + + + +
    + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/events/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/events/tmpl/index.html new file mode 100644 index 00000000..b3e16a26 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/events/tmpl/index.html @@ -0,0 +1,5 @@ + + + + + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/events/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/events/view.html.php new file mode 100644 index 00000000..4b7824fe --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/events/view.html.php @@ -0,0 +1,271 @@ +params = JComponentHelper::getParams('com_icagenda'); + $this->state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + + $this->categories = $this->get('Categories'); + $this->upcoming = $this->get('Upcoming'); + $this->itemids = $this->get('MenuItemID'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + $icagenda_categories = class_exists('icagendaCategories') ? icagendaCategories::getList('1') : false; + + if ( ! $icagenda_categories) + { + $app->enqueueMessage( JText::_('COM_ICAGENDA_ALERT_NO_CATEGORY_PUBLISHED') + . '

    ' + . JText::_('COM_ICAGENDA_LEGEND_NEW_CATEGORY') . '' + . ' ' + . JText::_('ICCATEGORIES') + . '', 'warning' ); + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + + if (version_compare(JVERSION, '3.0', 'ge')) + { + $this->sidebar = JHtmlSidebar::render(); + } + } + + $canDo = iCagendaHelper::getActions(); + + if (defined('IC_LIBRARY') + && $canDo->get('icagenda.access.events')) + { + parent::display($tpl); + } + else + { + if (defined('IC_LIBRARY')) $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); + } + } + + /** + * Add the page title and toolbar. + * + * @since 1.6 + */ + protected function addToolbar() + { + require_once JPATH_COMPONENT . '/helpers/icagenda.php'; + + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + + $state = $this->get('State'); + $user = JFactory::getUser(); + $userId = $user->get('id'); + $canDo = iCagendaHelper::getActions(); + + $icagenda_categories = class_exists('icagendaCategories') ? icagendaCategories::getList() : false; + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_TITLE_EVENTS'), 'events.png'); + } + else + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_TITLE_EVENTS') . '', 'calendar'); + } + + $icTitle = JText::_('COM_ICAGENDA_TITLE_EVENTS'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + //Check if the form exists before showing the add/edit buttons + $formPath = JPATH_COMPONENT_ADMINISTRATOR . '/views/event'; + + if (file_exists($formPath) + && $icagenda_categories + ) + { + if ($canDo->get('core.create')) + { + JToolBarHelper::addNew('event.add','JTOOLBAR_NEW'); + } + + if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) + { + JToolBarHelper::editList('event.edit'); + } + + } + + if ($canDo->get('core.edit.state') + && $icagenda_categories + ) + { + if (isset($this->items[0]->state)) + { + JToolBarHelper::divider(); + JToolBarHelper::custom('events.publish', 'publish.png', 'publish_f2.png','JTOOLBAR_PUBLISH', true); + JToolBarHelper::custom('events.unpublish', 'unpublish.png', 'unpublish_f2.png', 'JTOOLBAR_UNPUBLISH', true); + } + else + { + // If this component does not use state then show a direct delete button as we can not trash + JToolBarHelper::deleteList('', 'events.delete','JTOOLBAR_DELETE'); + } + + if (isset($this->items[0]->state)) + { + JToolBarHelper::divider(); + JToolBarHelper::archiveList('events.archive','JTOOLBAR_ARCHIVE'); + } + + if (isset($this->items[0]->checked_out)) + { + JToolBarHelper::custom('events.checkin', 'checkin.png', 'checkin_f2.png', 'JTOOLBAR_CHECKIN', true); + } + } + + // Show trash and delete for components that uses the state field + if (isset($this->items[0]->state) + && $icagenda_categories + ) + { + if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + JToolBarHelper::deleteList('', 'events.delete','JTOOLBAR_EMPTY_TRASH'); + JToolBarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + JToolBarHelper::trash('events.trash','JTOOLBAR_TRASH'); + JToolBarHelper::divider(); + } + } + + if ($canDo->get('core.admin')) + { + JToolBarHelper::preferences('com_icagenda'); + } + + if (version_compare(JVERSION, '3.0', 'ge')) + { + JHtmlSidebar::setAction('index.php?option=com_icagenda&view=events'); + + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_SELECT_STATE'), + 'filter_published', + JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.state'), true) + ); + JHtmlSidebar::addFilter( + '- ' . JText::_('COM_ICAGENDA_EVENTS_APPROVAL') . ' -', + 'filter_approval', + JHtml::_('select.options', $this->get('approvalOptions'), 'value', 'text', $this->state->get('filter.approval'), true) + ); + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_SELECT_CATEGORY'), + 'filter_category', + JHtml::_('select.options', $this->get('Categories'), 'value', 'text', $this->state->get('filter.category'), true) + ); + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_SELECT_DATES'), + 'filter_upcoming', + JHtml::_('select.options', $this->get('Upcoming'), 'value', 'text', $this->state->get('filter.upcoming'), true) + ); + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_SELECT_SITE_ITEMID'), + 'filter_site_itemid', + JHtml::_('select.options', $this->get('MenuItemID'), 'value', 'text', $this->state->get('filter.site_itemid'), true) + ); + } + } + + /** + * Method to save the submitted ordering values for records via AJAX. + * + * @return void + * + * @since 3.0 + */ + public function saveOrderAjax() + { + // Get the input + $jinput = JFactory::getApplication()->input; + $pks = $jinput->post->get('cid', array(), 'array'); + $order = $jinput->post->get('order', array(), 'array'); + + // Sanitize the input + JArrayHelper::toInteger($pks); + JArrayHelper::toInteger($order); + + // Get the model + $model = $this->getModel(); + + // Save the ordering + $return = $model->saveorder($pks, $order); + + if ($return) + { + echo "1"; + } + + // Close the application + JFactory::getApplication()->close(); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/feature/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/feature/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/feature/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/feature/tmpl/edit.php b/deployed/icagenda/administrator/components/com_icagenda/views/feature/tmpl/edit.php new file mode 100644 index 00000000..14529ed2 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/feature/tmpl/edit.php @@ -0,0 +1,372 @@ +authorise('icagenda.access.features', 'com_icagenda')) +{ + $bootstrapType = '1'; + $PanelOne_Tag = 'feature'; + $PanelOne_Title = JText::_('COM_ICAGENDA_TITLE_FEATURE', true); + $PanelTwo_Tag = 'desc'; + $PanelTwo_Title = JText::_('COM_ICAGENDA_LEGEND_DESC', true); + $PublishingTag = 'publishing'; + $PublishingTitle = JText::_('JGLOBAL_FIELDSET_PUBLISHING', true); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + jimport( 'joomla.html.html.tabs' ); + + $iCmapDisplay = '3'; + + $icPanOne = JText::_('COM_ICAGENDA_TITLE_EVENT'); + $icPanTwo = JText::_('COM_ICAGENDA_LEGEND_DESC'); + $icPanPublishing = JText::_('JGLOBAL_FIELDSET_PUBLISHING'); + $startPane = 'tabs.start'; + $addPanel = 'tabs.panel'; + $endPanel = 'tabs.end'; + $endPane = 'tabs.end'; + $PanelOne_Tag1 = $PanelOne_Tag; + $PanelOne_Tag2 = $PanelOne_Title; + $PanelTwo_Tag1 = $PanelTwo_Tag; + $PanelTwo_Tag2 = $PanelTwo_Title; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + + // Joomla 3 + else + { + JHtml::_('formbehavior.chosen', 'select'); + jimport('joomla.html.html.bootstrap'); + + $icPanOne = 'icTab'; + $icPanTwo = 'icTab'; + $icPanPublishing = 'icTab'; + + if ($bootstrapType == '1') + { + $iCmapDisplay = '1'; + $startPane = 'bootstrap.startTabSet'; + $addPanel = 'bootstrap.addTab'; + $endPanel = 'bootstrap.endTab'; + $endPane = 'bootstrap.endTabSet'; + $PanelOne_Tag1 = $PanelOne_Tag; + $PanelOne_Tag2 = $PanelOne_Title; + $PanelTwo_Tag1 = $PanelTwo_Tag; + $PanelTwo_Tag2 = $PanelTwo_Title; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + if ($bootstrapType == '2') + { + $iCmapDisplay = '2'; + $startPane = 'bootstrap.startAccordion'; + $addPanel = 'bootstrap.addSlide'; + $endPanel = 'bootstrap.endSlide'; + $endPane = 'bootstrap.endAccordion'; + $PanelOne_Tag1 = $PanelOne_Title; + $PanelOne_Tag2 = $PanelOne_Tag; + $PanelTwo_Tag1 = $PanelTwo_Title; + $PanelTwo_Tag2 = $PanelTwo_Tag; + $PublishingTag1 = $PublishingTitle; + $PublishingTag2 = $PublishingTag; + } + } + ?> + + + +
    +
    + +
    +

    + item->id) ? JText::_('COM_ICAGENDA_LEGEND_NEW_FEATURE') : JText::sprintf('COM_ICAGENDA_LEGEND_EDIT_FEATURE', $this->item->id); ?> iCagenda +

    +

    + +

    +
    +
     
    + + +
    +
    + + + 'feature')); ?> + + + + +
    +

    + item->id) ? JText::_('COM_ICAGENDA_LEGEND_NEW_FEATURE') : JText::sprintf('COM_ICAGENDA_LEGEND_EDIT_FEATURE', $this->item->id); ?> +

    +
    +
    +
    +
    +
    + form->getLabel('title'); ?> +
    +
    + form->getInput('title'); ?> +
    +
    +
    +
    +
    +
    +
    +
    + form->getLabel('icon'); ?> +
    +
    + form->getInput('icon'); ?> +
    +
    +
    +
    +
    +
    +
    +
    + form->getLabel('new_icon'); ?> +
    +
    + form->getInput('new_icon'); ?> +
    +
    +
    +
    +
    +
    +
    +
    + form->getLabel('icon_alt'); ?> +
    +
    + form->getInput('icon_alt'); ?> +
    +
    +
    +
    +
    +
    +
    +
    + form->getLabel('show_filter'); ?> +
    +
    + form->getInput('show_filter'); ?> +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + +
    +

    + +

    +
    +
    +
    +
    +
    + form->getLabel('alias'); ?> +
    +
    + form->getInput('alias'); ?> +
    +
    +
    +
    + form->getLabel('id'); ?> +
    +
    + form->getInput('id'); ?> +
    +
    +
    +
    + form->getLabel('checked_out'); ?> +
    +
    + form->getInput('checked_out'); ?> +
    +
    +
    +
    + form->getLabel('checked_out_time'); ?> +
    +
    + form->getInput('checked_out_time'); ?> +
    +
    +
    +
    +
    + + + + + + + +
    + + + +
    + +

    + +

    +
    +
    +
    + form->getLabel('state'); ?> +
    +
    + form->getInput('state'); ?> +
    +
    + + +
    + +
    +
    +
    + + +
    +
    + + _scripts); + $scriptFound = false; + $scriptuiFound = false; + + for ($i = 0; $i < count($scripts); $i++) + { + if (stripos($scripts[$i], 'jquery.min.js') !== false) + { + $scriptFound = true; + } + if (stripos($scripts[$i], 'jquery.js') !== false) + { + $scriptFound = true; + } + if (stripos($scripts[$i], 'jquery-ui.min.js') !== false) + { + $scriptuiFound = true; + } + } + + // jQuery Library Loader + if (!$scriptFound) + { + // load jQuery, if not loaded before + if (!$app->get('jquery')) + { + $app->set('jquery', true); + // add jQuery + $document->addScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/jquery.noconflict.js' ); + } + } + + if (!$scriptuiFound) + { + $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); + } + + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/template.js' ); + } + else + { + JHtml::_('bootstrap.framework'); + JHtml::_('jquery.framework'); + } + + } +else +{ + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/feature/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/feature/tmpl/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/feature/tmpl/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/feature/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/feature/view.html.php new file mode 100644 index 00000000..0c116799 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/feature/view.html.php @@ -0,0 +1,122 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + $jinput = $app->input; + + $jinput->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $isNew = ($this->item->id == 0); + + if (isset($this->item->checked_out)) + { + $checkedOut = ! ($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + } + else + { + $checkedOut = false; + } + + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_NEW_FEATURE') : 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_EDIT_FEATURE'), 'feature.png'); + } + else + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_NEW_FEATURE') . '' : 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_EDIT_FEATURE') . '' , $isNew ? 'new' : 'pencil-2'); + } + + $icTitle = $isNew ? JText::_('COM_ICAGENDA_LEGEND_NEW_FEATURE') : JText::_('COM_ICAGENDA_LEGEND_EDIT_FEATURE'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + // If not checked out, can save the item. + if ( ! $checkedOut && ($canDo->get('core.edit')||($canDo->get('core.create')))) + { + JToolBarHelper::apply('feature.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('feature.save', 'JTOOLBAR_SAVE'); + } + + if ( ! $checkedOut && ($canDo->get('core.create'))) + { + JToolBarHelper::custom('feature.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + + // If an existing item, can save to a copy. + if ( ! $isNew && $canDo->get('core.create')) + { + JToolBarHelper::custom('feature.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); + } + + if (empty($this->item->id)) + { + JToolBarHelper::cancel('feature.cancel', 'JTOOLBAR_CANCEL'); + } + else + { + JToolBarHelper::cancel('feature.cancel', 'JTOOLBAR_CLOSE'); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/features/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/features/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/features/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/features/tmpl/default.php b/deployed/icagenda/administrator/components/com_icagenda/views/features/tmpl/default.php new file mode 100644 index 00000000..bb93a718 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/features/tmpl/default.php @@ -0,0 +1,411 @@ +authorise('icagenda.access.features', 'com_icagenda')) +{ + // Check Theme Packs Compatibility + if (class_exists('icagendaTheme')) icagendaTheme::checkThemePacks(); + + $user = JFactory::getUser(); + $userId = $user->get('id'); + $listOrder = $this->escape($this->state->get('list.ordering')); + $listDirn = $this->escape($this->state->get('list.direction')); + $canOrder = $user->authorise('core.edit.state', 'com_icagenda'); + $saveOrder = $listOrder == 'a.ordering'; + + if(version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::_('behavior.tooltip'); + JHtml::_('script','system/multiselect.js',false,true); + } + else + { + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + JHtml::_('bootstrap.tooltip'); + JHtml::_('behavior.multiselect'); + JHtml::_('formbehavior.chosen', 'select'); + JHtml::_('dropdown.init'); + + $extension = $this->escape($this->state->get('filter.extension')); + + $archived = $this->state->get('filter.published') == 2 ? true : false; + $trashed = $this->state->get('filter.published') == -2 ? true : false; + + if ($saveOrder) + { + $saveOrderingUrl = 'index.php?option=com_icagenda&task=features.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'featuresList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); + } + + $sortFields = array(); + ?> + + + get('image_path', 'images'); + ?> + +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + + +
    + +
    + +
    +
    +
    + + + +
    + +
    + + +
    +
    + + pagination->getLimitBox(); ?> +
    +
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + items[0]->ordering)) { ?> + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_icagenda'); + $canEdit = $user->authorise('core.edit', 'com_icagenda'); + $canCheckin = $user->authorise('core.manage', 'com_icagenda'); + $canChange = $user->authorise('core.edit.state', 'com_icagenda'); + $canEditOwn = $user->authorise('core.edit.own', 'com_icagenda'); + ?> + + + + + + + + + + + + + + + + + items[0]->state)) { ?> + + + + + + + + + + + + + + + + + + + + items[0]->ordering)) { ?> + + + + + + + + items[0]->id)) { ?> + + + + + + + + +
    + ', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?> + + + + + + + + + + + + + + + + items, 'filesave.png', 'features.saveorder'); ?> + + + +
    + pagination->getListFooter(); ?> +
    + + + + + + + + + + + + id); ?> + + state, $i, 'features.', $canChange, 'cb'); ?> + +
    + checked_out) : ?> + editor, $item->checked_out_time, 'features.', $canCheckin); ?> + + language == '*'):?> + + + language ? $this->escape($item->language) : JText::_('JUNDEFINED'); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + +
    + + + + + +
    + id, 'feature.'); + JHtml::_('dropdown.divider'); + if ($item->state) : + JHtml::_('dropdown.unpublish', 'cb' . $i, 'features.'); + else : + JHtml::_('dropdown.publish', 'cb' . $i, 'features.'); + endif; + + JHtml::_('dropdown.divider'); + + if ($archived) : + JHtml::_('dropdown.unarchive', 'cb' . $i, 'features.'); + else : + JHtml::_('dropdown.archive', 'cb' . $i, 'features.'); + endif; + + if ($item->checked_out) : + JHtml::_('dropdown.checkin', 'cb' . $i, 'features.'); + endif; + + if ($trashed) : + JHtml::_('dropdown.untrash', 'cb' . $i, 'features.'); + else : + JHtml::_('dropdown.trash', 'cb' . $i, 'features.'); + endif; + + // Render dropdown list + echo JHtml::_('dropdown.render'); + ?> +
    + + + +
    +
    + icon . '" alt="[' . $item->icon . ']" />'; ?> + icon == -1 ? JText::_('JOPTION_DO_NOT_USE') : $item->icon; ?> +
    +
    +
    + escape($item->icon_alt) ?> +
    +
    +
    + +
    +
    + + + + pagination->orderUpIcon($i, true, 'features.orderup', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'features.orderdown', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + pagination->orderUpIcon($i, true, 'features.orderdown', 'JLIB_HTML_MOVE_UP', $ordering); ?> + pagination->orderDownIcon($i, $this->pagination->total, true, 'features.orderup', 'JLIB_HTML_MOVE_DOWN', $ordering); ?> + + + + class="text-area-order" /> + + ordering; ?> + + + id; ?> +
    +
    + + + + + +
    +
    + +enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/features/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/features/tmpl/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/features/tmpl/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/features/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/features/view.html.php new file mode 100644 index 00000000..a22f0605 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/features/view.html.php @@ -0,0 +1,177 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + + if(version_compare(JVERSION, '3.0', 'ge')) + { + $this->sidebar = JHtmlSidebar::render(); + } + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @since 3.4.0 + */ + protected function addToolbar() + { + require_once JPATH_COMPONENT . '/helpers/icagenda.php'; + + $state = $this->get('State'); + $user = JFactory::getUser(); + $userId = $user->get('id'); + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_TITLE_FEATURES'), 'features.png'); + } + else + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_TITLE_FEATURES') . '', 'folder'); + } + + $icTitle = JText::_('COM_ICAGENDA_TITLE_FEATURES'); + + $document = JFactory::getDocument(); + $app = JFactory::getApplication(); + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + // Check if the form exists before showing the add/edit buttons + $formPath = JPATH_COMPONENT_ADMINISTRATOR . '/views/feature'; + + if (file_exists($formPath)) + { + if ($canDo->get('core.create')) + { + JToolBarHelper::addNew('feature.add','JTOOLBAR_NEW'); + } + + if ($canDo->get('core.edit')) + { + JToolBarHelper::editList('feature.edit','JTOOLBAR_EDIT'); + } + } + + if ($canDo->get('core.edit.state')) + { + if (isset($this->items[0]->state)) + { + JToolBarHelper::divider(); + JToolBarHelper::custom('features.publish', 'publish.png', 'publish_f2.png','JTOOLBAR_PUBLISH', true); + JToolBarHelper::custom('features.unpublish', 'unpublish.png', 'unpublish_f2.png', 'JTOOLBAR_UNPUBLISH', true); + } + else + { + // If this component does not use state then show a direct delete button as we can not trash + JToolBarHelper::deleteList('', 'features.delete','JTOOLBAR_DELETE'); + } + + if (isset($this->items[0]->state)) + { + JToolBarHelper::divider(); + JToolBarHelper::archiveList('features.archive','JTOOLBAR_ARCHIVE'); + } + + if (isset($this->items[0]->checked_out)) + { + JToolBarHelper::custom('features.checkin', 'checkin.png', 'checkin_f2.png', 'JTOOLBAR_CHECKIN', true); + } + } + + // Show trash and delete for components that uses the state field + if (isset($this->items[0]->state)) + { + if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + JToolBarHelper::deleteList('', 'features.delete','JTOOLBAR_EMPTY_TRASH'); + JToolBarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + JToolBarHelper::trash('features.trash','JTOOLBAR_TRASH'); + JToolBarHelper::divider(); + } + } + + if ($canDo->get('core.admin')) + { + JToolBarHelper::preferences('com_icagenda'); + } + + if(version_compare(JVERSION, '3.0', 'ge')) + { + JHtmlSidebar::setAction('index.php?option=com_icagenda&view=features'); + + JHtmlSidebar::addFilter( + JText::_('JOPTION_SELECT_PUBLISHED'), + 'filter_published', + JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.state'), true) + ); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/tmpl/color.php b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/tmpl/color.php new file mode 100644 index 00000000..daadac75 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/tmpl/color.php @@ -0,0 +1,122 @@ +Legend'.$line."
    \n"; + break; + + case '?': + $ret .= "
    ".trim(substr($line,2))."
    \n"; + break; + + case '!': + $ret .= "\t".'
  • !
    ' + . htmlentities(trim(substr($line,2))) . "
  • \n"; + break; + + case '1': + $ret .= "\t".'
  • '.trim(substr($line,2))."
  • \n"; + break; + + case '+': + $ret .= "\t".'
  • +
    ' + . htmlentities(trim(substr($line,2))) . "
  • \n"; + break; + + case '-': + $ret .= "\t".'
  • -
    ' + . htmlentities(trim(substr($line,2))) . "
  • \n"; + break; + + case '~': + $ret .= "\t".'
  • ~
    ' + . htmlentities(trim(substr($line,2))) . "
  • \n"; + break; + + case '#': + $ret .= "\t".'
  • #
    ' + . htmlentities(trim(substr($line,2))) . "
  • \n"; + break; + +// case 'H': +// $ret .= "\t".'
  • #
    HIGH
    ' +// . htmlentities(trim(substr($line,2))) . "
  • \n"; +// break; + + case '*': + $ret .= "\t".'

    ' . htmlentities(trim(substr($line,2))) . "

    \n"; + break; + + case '$': + $ret .= ""; + $ret .= "

      " . substr($line,2) . " [ PRO Testing ]

    \n"; + $ret .= "
      \n"; + break; + + // End + case ';': + $ret .= "
    "; + break; + + default: + + if(!empty($ret)) + { + $ret .= ""; + if($onlyLast) return $ret; + } + + if(!$onlyLast) $ret .= "

      $line

    \n"; + + $ret .= "
      \n"; + break; + } + } + + return $ret; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/tmpl/default.php b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/tmpl/default.php new file mode 100644 index 00000000..d84dffa7 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/tmpl/default.php @@ -0,0 +1,927 @@ +get('id'); + +$params = JComponentHelper::getParams( 'com_icagenda' ); +$version = $params->get('version'); +$icsys = $params->get('icsys'); +$translator = JText::_('COM_ICAGENDA_TRANSLATOR'); + +if (version_compare(phpversion(), '5.3.10', '<')) +{ + $JoomlaRecommended = '5.4 +'; + + // Get Application + $app = JFactory::getApplication(); + + $icon_warning = (version_compare(JVERSION, '3.0', 'lt')) ? '' : ''; + + $php_warning_msg = ' ' . JText::sprintf('COM_ICAGENDA_YOUR_PHP_VERSION_IS', phpversion()) . '
      '; + $php_warning_msg.= JText::sprintf('COM_ICAGENDA_PHP_VERSION_JOOMLA_RECOMMENDED', $JoomlaRecommended); + $php_warning_msg.= ' ( ' . JText::_('IC_READMORE') . ': '; + $php_warning_msg.= 'enqueueMessage( $icon_warning . $php_warning_msg, 'error' ); +} +?> +
      + + +
      +
      +
      +
      + + +
      + authorise('icagenda.access.registrations', 'com_icagenda') + || $user->authorise('icagenda.access.newsletter', 'com_icagenda') ) : ?> + + + authorise('icagenda.access.customfields', 'com_icagenda') + || $user->authorise('icagenda.access.features', 'com_icagenda') ) : ?> + + +
      + +
      + authorise('core.admin', 'com_icagenda') + || $user->authorise('icagenda.access.themes', 'com_icagenda') ) : ?> + + + authorise('core.admin', 'com_icagenda') ) : ?> +
      + + + + + + + + + + +
      +

      +
      + + + +
      +
      + +
      + + +
      + + +
      +
      +
      +
      +
      + + getQuery(true); + //$query->select('version AS icv, releasedate AS icd')->from('#__icagenda')->where('id = 1'); + //$query->select('version AS icv, releasedate AS icd')->from('#__icagenda')->where('id = 2'); + $query->select('version AS icv, releasedate AS icd, params AS icp')->from('#__icagenda')->where('id = 3'); + $db->setQuery($query); + $result = $db->loadObject(); + $release = $result->icv; + $date = $result->icd; + $icp = json_decode( $result->icp, true ); + + if ($icsys == 'pro') + { + $app = JFactory::getApplication(); + $welcome_pro = $app->input->get('welcome', ''); + + // Get Current URL + $thisURL = JURI::getInstance()->toString(); + + $return_cp = 'index.php?option=com_icagenda'; + + if ($welcome_pro == -1) + { + $this->saveDefault($welcome_pro, 'msg_procp', '-1'); + $app->enqueueMessage(JText::_('COM_ICAGENDA_WELCOME_HIDE_SUCCESS'), 'message'); + $app->redirect($return_cp); + } + elseif ($welcome_pro == 1) + { + $this->saveDefault($welcome_pro, 'msg_procp', '1'); +// $app->enqueueMessage(JText::_('COM_ICAGENDA_WELCOME_SHOW_SUCCESS'), 'message'); + $app->redirect($return_cp); + } + + $options_link = version_compare(JVERSION, '3.0', 'ge') + ? ' : ' + . JText::_('JTOOLBAR_OPTIONS') . '' + : '.'; + ?> + + +
      +
      + + enqueueMessage('

      ' . JText::sprintf('COM_ICAGENDA_PRO_WELCOME', 'iCagenda PRO') . '

      ' + . '

      ' . JText::sprintf('COM_ICAGENDA_PRO_WELCOME_PRO_ACCOUNT_INFO', 'iCagenda PRO', 'pro.joomlic.com') . '

      ' + . '

      ' . JText::sprintf('COM_ICAGENDA_PRO_WELCOME_PRO_NOTIFICATION_EMAILS', 'info(at)joomlic.com') . '

      ' + . '

      ' . JText::sprintf('COM_ICAGENDA_PRO_WELCOME_PRO_NOTIFICATION_EMAILS_FIRST', 'Pro JoomliC') . '
      ' + . JText::_('COM_ICAGENDA_PRO_WELCOME_PRO_NOTIFICATION_EMAILS_SECOND') . '
      ' + . JText::_('COM_ICAGENDA_PRO_WELCOME_PRO_CHECK_YOUR_EMAIL') . '

      ' + . '

      ' . JText::sprintf('COM_ICAGENDA_PRO_WELCOME_PRO_FIRST_LOGIN_1', 'pro.joomlic.com') . '
      ' + . JText::sprintf('COM_ICAGENDA_PRO_WELCOME_PRO_FIRST_LOGIN_2', 'pro.joomlic.com') . '
      ' + . JText::sprintf('COM_ICAGENDA_PRO_WELCOME_PRO_OPTIONS', $options_link) . '

      ' + . '

      ' . JText::sprintf('COM_ICAGENDA_PRO_WELCOME_PRO_ID_1', 'iCagenda PRO') . '

      ' + . '

      ' . JText::_('COM_ICAGENDA_PRO_WELCOME_CONTACT') . '
      ' + . JText::sprintf('COM_ICAGENDA_PRO_WELCOME_SUPPORT', 'Pro Ticket System') . '

      ' + . '

      ' . JText::_('COM_ICAGENDA_PRO_WELCOME_NOTE') . '

      ' + . '' + , 'message'); + ?> + + + +
      + logo_icagenda +
      +
      +

      + iCagenda +

      +
      +
      +

      + +

      +
      + +
      +
      + +
      + +
       
      + +
      + |    + + +
      +
      + +
      +
      + + +
      + +
      + + +
       
      +
       
      + + +addStyleDeclaration(' + #canvas-holder { + width: 90%; + margin: 5%; + } + @media(min-width:768px) { + #canvas-holder { + width: 40%; + margin: 10px 5%; + } + } +'); + +$charts = array( + 'categoryStats' => JText::sprintf('COM_ICAGENDA_STATS_TOP_CATEGORIES_LBL', '10') . + '
      ' . JText::_('COM_ICAGENDA_STATS_BASED_ON_ALL_EVENTS_HITS') . '', + 'eventStats' => JText::sprintf('COM_ICAGENDA_STATS_TOP_EVENTS_LBL', '10') . + '
      ' . JText::_('COM_ICAGENDA_STATS_ON_EVENT_HITS') . '', + ); + +$mbString = extension_loaded('mbstring'); +?> + +
      + + $title) : ?> +
      +

      + eventHitsTotal) : ?> + + + + +
      + + {$chart} AS $v) + { + $percent = $this->eventHitsTotal ? ($v->hits / $this->eventHitsTotal) : 0; + + $script[]= ' {'; + $script[]= ($chart == 'categoryStats') + ? ' value: ' . round(( $percent * 100 ), 2) . ',' + : ' value: ' . $v->hits . ','; + $script[]= ' color: "' . $v->cat_color . '",'; + $script[]= ' highlight: "#777777",'; + + $label_length = $mbString ? mb_strlen($v->stats_label, 'UTF-8') : strlen($v->stats_label); + $label_cut = $mbString ? mb_substr($v->stats_label, 0, 20, 'UTF-8') : substr($v->stats_label, 0, 20); + + $stats_label = $label_cut; + $stats_label .= ($label_length > 20) ? '...' : ''; + + $script[]= ' label: "' . addslashes($stats_label) . '"'; + $script[]= ' },'; + + $legend_data = addslashes($v->cat_title) . '@@' . $v->cat_color; + + if ( ! in_array($legend_data, $legend)) + { + $legend[]= $legend_data; + } + } + + sort($legend); + + $script[]= ' ];'; + + $script[]= 'var options = {'; + $script[]= ' animationEasing : "easeInOutBack",'; + $script[]= ' animationSteps : 60,'; + $script[]= ' responsive : true,'; + $script[]= ' segmentStrokeColor : "#f5f5f5",'; + $script[]= ($chart == 'categoryStats') + ? ' percentageInnerCutout : 0, tooltipTemplate: "<%if (label){%><%=label%> | <%}%><%= value %>%"' + : ' percentageInnerCutout : 50'; + $script[]= '}'; + + $script[]= ' var ctx' . $chart . ' = document.getElementById("' . $chart . '_area").getContext("2d");'; + $script[]= ' var myNewChart = new Chart(ctx' . $chart . ').Doughnut(data, options);'; + + if ($this->eventHitsTotal) + { + echo ''; + } + ?> + + + +
      + +
      + + +
      +
      +
      +
      + +
      + +
       
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +

      42 

      +

      + '; + } + ?> + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + + + Tooltip + +

      +
      +
      +
      +
      + +
      +
      + + + + + + + +
      + + + + + + + +
      +
      +
      + +
      + +
      +
      +
      +
      + Copyright ©2012- joomlic.com -  +  Joomla! Extensions Directory. +
      +
      +
      + +
      +
      +
      +
      + diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/view.html.php new file mode 100644 index 00000000..c4e1df08 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/icagenda/view.html.php @@ -0,0 +1,168 @@ +authorise('core.admin', 'com_icagenda')) +{ + JToolBarHelper::preferences('com_icagenda'); +} + +/** + * View class for a list of iCagenda. + */ +class iCagendaViewicagenda extends JViewLegacy +{ + /** + * Display the view + */ + public function display($tpl = null) + { + $document = JFactory::getDocument(); + + $this->categoryStats = $this->get('CategoryStats'); + $this->eventStats = $this->get('EventStats'); + $this->eventHitsTotal = $this->get('EventHitsTotal'); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::stylesheet('com_icagenda/template.j25.css', false, true); + JHtml::stylesheet('com_icagenda/icagenda-back.j25.css', false, true); + + JHTML::_('behavior.tooltip'); + JHTML::_('behavior.modal'); + + $document->addScript(JURI::root( true ) . '/media/com_icagenda/js/template.js'); + + jimport('joomla.filesystem.path'); + } + // Joomla 3 + else + { + JHtml::_('behavior.modal'); + } + + // Add Charts.js + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/Chart.min.js' ); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + require_once JPATH_COMPONENT . '/helpers/icagenda.php'; + + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + + $state = $this->get('State'); + $canDo = iCagendaHelper::getActions($state->get('filter.category_id')); + + //JToolBarHelper::title(JText::_('COM_ICAGENDA_TITLE_ICAGENDA_IMAGE')); + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title(JText::_('COM_ICAGENDA_TITLE_ICAGENDA_IMAGE')); + } + else + { + $logo_icagenda_url = '../media/com_icagenda/images/iconicagenda36.png'; + + if (file_exists($logo_icagenda_url)) + { + $logo_icagenda = 'iCagenda'; + } + else + { + $logo_icagenda = 'iCagenda :: ' . JText::_('COM_ICAGENDA_TITLE_ICAGENDA') . ''; + } + + JToolBarHelper::title($logo_icagenda, 'icagenda'); + } + + $icTitle = JText::_('COM_ICAGENDA_TITLE_ICAGENDA'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + } + + /** + * Save iCagenda Params + * + * Update Database + * + * @since 3.3.8 + */ + public function saveDefault($var, $name, $value) + { + if ($var) + { + $params[$name] = $value; + + $this->updateParams( $params ); + } + } + + /** + * Update iCagenda Params + * + * Update Database + * + * @since 3.3.8 + */ + protected function updateParams($params_array) + { + // Read the existing component value(s) + $db = JFactory::getDbo(); + $db->setQuery('SELECT params FROM #__icagenda WHERE id = "3"'); + + $params = json_decode( $db->loadResult(), true ); + + // Add the new variable(s) to the existing one(s) + foreach ( $params_array as $name => $value ) + { + $params[ (string) $name ] = $value; + } + + // Store the combined new and existing values back as a JSON string + $paramsString = json_encode( $params ); + + $db->setQuery('UPDATE #__icagenda SET params = ' . + $db->quote( $paramsString ) . ' WHERE id = "3"' ); + $db->query(); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/info/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/info/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/info/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/info/tmpl/default.php b/deployed/icagenda/administrator/components/com_icagenda/views/info/tmpl/default.php new file mode 100644 index 00000000..7823e4f3 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/info/tmpl/default.php @@ -0,0 +1,247 @@ +get('id'); + +$db = JFactory::getDbo(); +$query = $db->getQuery(true); +$query->select('version AS icv, releasedate AS icd')->from('#__icagenda')->where('id = 3'); +$db->setQuery($query); +$result = $db->loadObject(); +$version = $result->icv; +$date = $result->icd; +?> + +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + +
      +
      +
      +
      +
      +

      + +

      +
       
      +

      + +

      +

      + Ervin Bizjak, Bong, Giuseppe Bosco, Carosouza, Davor Čolić, doorknob, Reinhard Ekker, elirezo, jedi, jowe3, JonxDuo, KISweb, kredo9, macedorl, Kai Metsävainio, mussool, NicoDeluxe, Rickard Norberg, Andrzej Opejda, Régis, Tom-Henning, Rikard Tømte Reitan, Vlad Shuh, Leland Vandervort, Wilfred van Dijk, Roland van Wanrooy, David White ... +

      +

      +
      + af-ZA  Afrikaans (South Africa) : Isileth
      + ar-AA  Arabic (Unitag) : haneen2013, fkinanah, Specialist
      + eu-ES  Basque (Spain) : Bizkaitarra
      + bg-BG  Bulgarian (Bulgaria) : bimbongr
      + ca-ES  Catalan (Spain) : Mussool, EduardAymerich, Figuerolero
      + zh-CN  Chinese (China) : Foxyman
      + zh-TW  Chinese (Taiwan) : jedi, hkce, rowdytang
      + hr-HR  Croatian (Croatia) : Davor Čolić (cdavor)
      + cz-CZ  Czech (Czech Republic) : Bongovo (bong)
      + dk-DK  Danish (Denmark) : olewolf.dk, torbenspetersen, hvitnov, dannikrstnsn, AhmadHamid, poulfrom
      + nl-NL  Dutch (Netherlands) : Molenwal1, AnneM, Walldorff, Mario Guagliardo, wfvdijk, robert.kleinpeter
      + en-GB  English (United Kingdom) : Lyr!C
      + en-US  English (United States) : Lyr!C
      + eo  Esperanto : Amema, Anita_Dagmarsdotter
      + et-EE  Estonian (Estonia) : Reijo, Eraser
      + fi-FI  Finnish (Finland) : Kai Metsävainio (metska)
      + fr-FR  French (France) : Lyr!C
      + gl-ES  Galician (Spain) : XanVFR, Xnake
      + de-DE  German (Germany) : grisuu, mPino, bmbsbr, Wasilis, chuerner, cordi_allemand
      + el-GR  Greek (Greece) : E.Gkana-D.Kontogeorgis (elinag), kost36, rinenweb, mbini
      + hu-HU  Hungarian (Hungary) : Halilaci, magicf, Cerbo, PKH, mester93
      + it-IT  Italian (Italy) : Giuseppe Bosco (giusebos)
      + ja-JP  Japanese (Japan) : nagata
      + lv-LV  Latvian (Latvia) : kredo9
      + lt-LT  Lithuanian (Lithuania) : ahxoohx
      + lb-LU  Luxembourgish (Luxembourg) : Superjhemp
      + mk-MK  Macedonian (Macedonia) : Strumjan (Ilija Iliev)
      + nb-NO  Norwegian Bokmål (Norway) : Rikard Tømte Reitan (Rikrei)
      + fa-IR  Persian (Iran) : Arash Rezvani (al3n.nvy)
      + pl-PL  Polish (Poland) : mbsrz, KISweb, gienio22, traktor, niewidzialny
      + pt-BR  Portuguese (Brazil) : Carosouza, alxaraujo
      + pt-PT  Portuguese (Portugal) : LFGM, macedorl, horus68
      + ro-RO  Romanian (Romania) : hat, mester93
      + ru-RU  Russian (Russia) : nshash, MSV
      + sr-YU  Serbian (latin) : Nenad Mihajlović (nenadm)
      + sk-SK  Slovak (Slovakia) : ischindl, J.Ribarszki
      + sl-SI  Slovenian (Slovenia) : erbi (Ervin Bizjak)
      + es-ES  Spanish (Spain) : elerizo, mPino, albertodg, adolf64, Goncatín, claugardia, sterroso
      + sv-SE  Swedish (Sweden) : Rickard Norberg (metska), Amema, osignell, kricke
      + th-TH  Thai (Thailand) : nightlight, rattanachai.ha
      + tr-TR  Turkish (Turkey) : harikalarkutusu, farukzeynep, kemalokmen
      + uk  Ukrainian (Ukraine) : Vlad Shuh (slv54)
      +
      +
      +
      +
      +
      +
      +
      +
      + logo_icagenda +
      +
      +

      + iCagenda  +

      +
      +
      +

      + +

      +
      +
       
      +
       
      +
       
      +
       
      +
       
      +
       
      + +

      +

      +
      + Cyril Rezé (Lyr!C) | www.joomlic.com +

      +

      +
      + Giuseppe Bosco (giusebos) | www.newideasproject.com +

      +

      + +

      + Doorknob : +
        + +
      • Features
      • +
      • Responsive Screen Threshold Widths (media css)
      • +
      • jQuery.highlightToday.js (module calendar)
      • +
        +
      +
      +
      + Tom-Henning (MaW) : +
        + +
      • iCalcreator integration (Add to iCal/Outlook)
      • +
        +
      +
      +

      +

      +

      + +

      +

      +

      + © 2012 - Cyril Rezé / Jooml!C
      + www.Jooml!C.com +

      +

      +

      + GPLv3 or later +

      +
      +

      +

      + Akeeba Live Update (ARS)
      + © Nicholas K. Dionysopoulos | www.akeebabackup.com
      + Licensed under GNU LGPLv3 or later.
      +

      +

      + Timepicker jQuery addon
      + © Trent Richardson | trentrichardson.com
      + Project licensed under the MIT or GPL licenses.
      +

      +

      + TipTip jQuery plugin
      + © Drew Wilson | www.drewwilson.com
      + Dual licensed under the MIT and GPL licenses.
      +

      +

      + Google Maps™
      + © Google Inc. | Google Maps/Google Earth APIs Terms of Service
      + Google™ and Google Maps™ are registered trademarks of Google Inc.
      +

      +

      + and of course... Joomla!
      + www.joomla.org
      +

      + +
      +
      +
      +
      + +
      +
      + + + + + + +
      + + + + + + + +
      + +
      +
      +
      + + +
      +
      +
      +
      +
      +
      + Copyright ©2012- joomlic.com -  +  Joomla! Extensions Directory. +
      +
      +
      + +
      +
      +
      +
      diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/info/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/info/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/info/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/info/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/info/view.html.php new file mode 100644 index 00000000..5b3684cc --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/info/view.html.php @@ -0,0 +1,102 @@ +authorise('core.admin', 'com_icagenda')) +{ + JToolBarHelper::preferences('com_icagenda'); +} + +/** + * View class for a list of iCagenda. + */ +class iCagendaViewinfo extends JViewLegacy +{ + /** + * Display the view + */ + public function display($tpl = null) + { + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::stylesheet('com_icagenda/template.j25.css', false, true); + + JHtml::_('behavior.tooltip'); + } + + JHtml::_('behavior.modal'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + + if (version_compare(JVERSION, '3.0', 'ge')) + { + $this->sidebar = JHtmlSidebar::render(); + } + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @since 1.6 + */ + protected function addToolbar() + { + require_once JPATH_COMPONENT . '/helpers/icagenda.php'; + + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + + $state = $this->get('State'); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title(JText::_('COM_ICAGENDA_TITLE_ICAGENDA_IMAGE')); + } + else + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_INFO') . '', 'info-2'); + } + + $icTitle = JText::_('COM_ICAGENDA_INFO'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/mail/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/mail/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/mail/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/mail/tmpl/edit.php b/deployed/icagenda/administrator/components/com_icagenda/views/mail/tmpl/edit.php new file mode 100644 index 00000000..6eda528a --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/mail/tmpl/edit.php @@ -0,0 +1,143 @@ +get('ic_newsletter', array()); + +$script = "\t" . 'Joomla.submitbutton = function(pressbutton) {' . "\n"; +$script .= "\t\t" . 'var form = document.adminForm;' . "\n"; +$script .= "\t\t" . 'if (pressbutton == \'mail.cancel\') {' . "\n"; +$script .= "\t\t\t" . 'Joomla.submitform(pressbutton);' . "\n"; +$script .= "\t\t\t" . 'return;' . "\n"; +$script .= "\t\t" . '}' . "\n"; +$script .= "\t\t" . '// do field validation' . "\n"; +$script .= "\t\t" . 'if (form.jform_subject.value == ""){' . "\n"; +$script .= "\t\t\t" . 'alert("' . JText::_('COM_ICAGENDA_NEWSLETTER_NO_OBJ_ALERT', true) . '");' . "\n"; +$script .= "\t\t" . '} else if (getSelectedValue(\'adminForm\',\'jform[eventid]\') == ""){' . "\n"; +$script .= "\t\t\t" . 'alert("' . JText::_('COM_ICAGENDA_NEWSLETTER_NO_EVENT_SELECTED', true) . '");' . "\n"; +$script .= "\t\t" . '} else if (getSelectedValue(\'adminForm\',\'jform[date]\') == ""){' . "\n"; +$script .= "\t\t\t" . 'alert("' . JText::_('COM_ICAGENDA_NEWSLETTER_NO_DATE_SELECTED', true) . '");' . "\n"; +//$script .= "\t\t" . '} else if (form.jform_message.value == ""){' . "\n"; +//$script .= "\t\t\t" . 'alert("' . JText::_('COM_ICAGENDA_NEWSLETTER_NO_BODY_ALERT', true) . '");' . "\n"; +$script .= "\t\t" . '} else {' . "\n"; +$script .= "\t\t\t" . 'Joomla.submitform(pressbutton);' . "\n"; +$script .= "\t\t" . '}' . "\n"; +$script .= "\t\t" . '}' . "\n"; + +//JFactory::getDocument()->addScriptDeclaration($script); + +// Access Administration Newsletter check. +if (JFactory::getUser()->authorise('icagenda.access.newsletter', 'com_icagenda')) +{ + ?> + + +
      +
      + +
      +

      +  iCagenda +

      +

      + + +

      +
      + +
       
      + + +

      +
      +
      +
      +
      + form->getLabel('eventid'); ?> +
      + form->getInput('eventid'); ?> +
      +
      +
      +
      +
      + form->getLabel('date'); ?> +
      + form->getInput('date'); ?> +
      +
      +
      +
      +
      +
      +

      +
      +
      +
      + form->getLabel('subject'); ?> +
      + form->getInput('subject'); ?> +
      +
      +
      + form->getLabel('message'); ?> +
      + form->getInput('message'); ?> +
      +
      +
      +
      + + + +
      +
      +
      + enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/mail/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/mail/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/mail/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/mail/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/mail/view.html.php new file mode 100644 index 00000000..10ef0f22 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/mail/view.html.php @@ -0,0 +1,138 @@ +_scripts); + $scriptFound = false; + + for ($i = 0; $i < count($scripts); $i++) + { + if (stripos($scripts[$i], 'jquery.min.js') !== false + || stripos($scripts[$i], 'jquery.js') !== false) + { + $scriptFound = true; + } + } + + // jQuery Library Loader + if (!$scriptFound) + { + // load jQuery, if not loaded before + if (!$app->get('jquery')) + { + $app->set('jquery', true); + + // Add jQuery Library + $document->addScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); + JHtml::script('com_icagenda/jquery.noconflict.js', false, true); + } + } + } + + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + $jinput = $app->input; + + $jinput->set('hidemainmenu', true); + + $user = JFactory::getUser(); + + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title(JText::_('COM_ICAGENDA_TITLE_MAIL'), 'mail.png'); + } + else + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_TITLE_MAIL') . '', 'mail'); + } + + $icTitle = JText::_('COM_ICAGENDA_TITLE_MAIL'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::custom('mail.send', 'forward.png', 'forward.png', 'ICAGENDA_JTOOLBAR_SEND', false); + } + else + { + JToolbarHelper::custom('mail.send', 'envelope.png', 'send_f2.png', 'ICAGENDA_JTOOLBAR_SEND', false); + } + + JToolBarHelper::cancel('mail.cancel', 'JTOOLBAR_CLOSE'); + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/registration/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/registration/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/registration/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/registration/tmpl/edit.php b/deployed/icagenda/administrator/components/com_icagenda/views/registration/tmpl/edit.php new file mode 100644 index 00000000..0b88ae80 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/registration/tmpl/edit.php @@ -0,0 +1,463 @@ +authorise('icagenda.access.registrations', 'com_icagenda')) +{ + $document = JFactory::getDocument(); + $bootstrapType = '1'; + $RegistrationTag = 'Registration'; + $RegistrationTitle = JText::_('COM_ICAGENDA_REGISTRATION_INFORMATION', true); + $DescTag = 'desc'; + $DescTitle = JText::_('COM_ICAGENDA_REGISTRATION_NOTES_DISPLAY_LABEL', true); + $PublishingTag = 'publishing'; + $PublishingTitle = JText::_('JGLOBAL_FIELDSET_PUBLISHING', true); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + jimport( 'joomla.html.html.tabs' ); + + $iCmapDisplay = '3'; + + $icPanRegistration = JText::_('COM_ICAGENDA_TITLE_REGISTRATION'); + $icPanDesc = JText::_('COM_ICAGENDA_REGISTRATION_NOTES_DISPLAY_LABEL'); + $icPanPublishing = JText::_('JGLOBAL_FIELDSET_PUBLISHING'); + $startPane = 'tabs.start'; + $addPanel = 'tabs.panel'; + $endPanel = 'tabs.end'; + $endPane = 'tabs.end'; + $RegistrationTag1 = $RegistrationTag; + $RegistrationTag2 = $RegistrationTitle; + $DescTag1 = $DescTag; + $DescTag2 = $DescTitle; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + + // Joomla 3 + else + { + JHtml::_('formbehavior.chosen', 'select'); + jimport('joomla.html.html.bootstrap'); + + $icPanRegistration = 'icTab'; + $icPanDesc = 'icTab'; + $icPanPublishing = 'icTab'; + + if ($bootstrapType == '1') + { + $iCmapDisplay = '1'; + $startPane = 'bootstrap.startTabSet'; + $addPanel = 'bootstrap.addTab'; + $endPanel = 'bootstrap.endTab'; + $endPane = 'bootstrap.endTabSet'; + $RegistrationTag1 = $RegistrationTag; + $RegistrationTag2 = $RegistrationTitle; + $DescTag1 = $DescTag; + $DescTag2 = $DescTitle; + $PublishingTag1 = $PublishingTag; + $PublishingTag2 = $PublishingTitle; + } + if ($bootstrapType == '2') + { + $iCmapDisplay = '2'; + $startPane = 'bootstrap.startAccordion'; + $addPanel = 'bootstrap.addSlide'; + $endPanel = 'bootstrap.endSlide'; + $endPane = 'bootstrap.endAccordion'; + $RegistrationTag1 = $RegistrationTitle; + $RegistrationTag2 = $RegistrationTag; + $DescTag1 = $DescTitle; + $DescTag2 = $DescTag; + $PublishingTag1 = $PublishingTitle; + $PublishingTag2 = $PublishingTag; + } + } + ?> + + + + +
      +
      + + +
      +

      + item->id) ? JText::_('COM_ICAGENDA_LEGEND_NEW_REGISTRATION') : JText::sprintf('COM_ICAGENDA_LEGEND_EDIT_REGISTRATION', $this->item->id); ?> iCagenda +

      +

      + +

      +
      + +
       
      + + +
      +
      + + + 'Registration')); ?> + + + + +
      +

      + item->id) ? JText::_('COM_ICAGENDA_LEGEND_NEW_REGISTRATION') : JText::sprintf('COM_ICAGENDA_LEGEND_EDIT_REGISTRATION', $this->item->id); ?> +

      +
      +
      +
      +
      +
      + form->getLabel('userid'); ?> +
      +
      + form->getInput('userid'); ?> +
      +
      + +
      +
      + form->getLabel('name'); ?> +
      +
      + form->getInput('name'); ?> +
      +
      +
      +
      + form->getLabel('email'); ?> +
      +
      + form->getInput('email'); ?> +
      +
      +
      +
      + form->getLabel('phone'); ?> +
      +
      + form->getInput('phone'); ?> +
      +
      +

      + item->eventid); +// $customFields = icagendaCustomfields::getCustomFields(1, $customForm); + echo icagendaCustomfields::loader(1, $customForm); + ?> +
      +
      +
      +
      + form->getLabel('eventid'); ?> +
      +
      + form->getInput('eventid'); ?> +
      +
      +
      +
      + form->getLabel('date'); ?> +
      +
      + form->getInput('date'); ?> +
      +
      + item->period) : ?> +
      +
      + form->getLabel('period'); ?> +
      +
      + form->getInput('period'); ?> +
      +
      + +
      +
      + form->getLabel('people'); ?> +
      +
      + form->getInput('people'); ?> +
      +
      + +
      +
      +
      + + + + + + + + +
      +

      +
      +
      +
      + + form->getInput('notes'); ?> +
      +
      +
      + + + + + +
      +

      +
      +
      +
      +
      +
      + form->getLabel('id'); ?> +
      +
      + form->getInput('id'); ?> +
      +
      +
      +
      + form->getLabel('created'); ?> +
      +
      + form->getInput('created'); ?> +
      +
      +
      +
      + form->getLabel('created_by'); ?> +
      +
      + form->getInput('created_by'); ?> +
      +
      +
      +
      + form->getLabel('modified'); ?> +
      +
      + form->getInput('modified'); ?> +
      +
      +
      +
      + form->getLabel('modified_by'); ?> +
      +
      + form->getInput('modified_by'); ?> +
      +
      +
      +
      + form->getLabel('checked_out'); ?> +
      +
      + form->getInput('checked_out'); ?> +
      +
      +
      +
      + form->getLabel('checked_out_time'); ?> +
      +
      + form->getInput('checked_out_time'); ?> +
      +
      +
      +
      +
      + + + + +
      + + +
      +

      +
      +
      +
      + form->getLabel('state'); ?> +
      +
      + form->getInput('state'); ?> +
      +
      +
      + + +
      +
      +
      + + + +
      + +get('autofilluser', 1) == 1) + { + $script[] = ' jQuery(document).ready(function($){'; + $script[] = ' var userid = $("#jform_userid_id").val();'; + $script[] = ' $.ajax({url: "index.php?option=com_icagenda&task=registration.registrationName&userid="+userid,'; + $script[] = ' success: function(output) {'; + $script[] = ' userInfo = output.split(",");'; + + if ( ! $this->item->name && ! $this->item->email) + { + $script[] = ' $("#jform_name").val(userInfo[0]);'; + $script[] = ' $("#jform_email").val(userInfo[1]);'; + } + else + { + $script[] = ' $("#userid_msg").show();'; + $script[] = ' $("#fill_user_info_msg").html("

      ' . JText::_("COM_ICAGENDA_REGISTRATION_UPDATE_NAME_AND_EMAIL_ALERT") . '

      ' . JText::_("JYES") . '
      ' . JText::_("JNO") . '
      ");'; + $script[] = ' $("#update-info").on("click",function(){'; + $script[] = ' $("#jform_name").val(userInfo[0]);'; + $script[] = ' $("#jform_email").val(userInfo[1]);'; + $script[] = ' $("#fill_user_info_msg").html("

      ' . JText::_("COM_ICAGENDA_REGISTRATION_UPDATE_NAME_AND_EMAIL_SUCCESS") . '

      ");'; + $script[] = ' $("#userid_msg").delay(700).fadeOut(300);'; + $script[] = ' });'; + $script[] = ' $("#no-update-info").on("click",function(){'; + $script[] = ' $("#userid_msg").fadeOut(300);'; + $script[] = ' });'; + } + + $script[] = ' },'; + $script[] = ' error: function (xhr, ajaxOptions, thrownError) {'; + $script[] = ' alert(xhr.status + " "+ thrownError);'; + $script[] = ' }'; + $script[] = ' });'; + $script[] = ' });'; + } + else + { + $script[] = ' console.log("iCagenda info: Auto-fill Name and Email disabled");'; + } + + $script[] = ' }'; + + // Add the script to the document head. + JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); + + // Script validation for Registration form (1) + $iCheckForm = icagendaForm::submit(1); + $document->addScriptDeclaration($iCheckForm); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::stylesheet('com_icagenda/template.j25.css', false, true); + JHtml::stylesheet('com_icagenda/icagenda-back.j25.css', false, true); + + // load jQuery, if not loaded before (NEW VERSION IN 1.2.6) + $scripts = array_keys($document->_scripts); + $scriptFound = false; + $scriptuiFound = false; + $mapsgooglescriptFound = false; + for ($i = 0; $i < count($scripts); $i++) + { + if (stripos($scripts[$i], 'jquery.min.js') !== false) + { + $scriptFound = true; + } + // load jQuery, if not loaded before as jquery - added in 1.2.7 + if (stripos($scripts[$i], 'jquery.js') !== false) + { + $scriptFound = true; + } + if (stripos($scripts[$i], 'jquery-ui.min.js') !== false) + { + $scriptuiFound = true; + } + if (stripos($scripts[$i], 'maps.google') !== false) + { + $mapsgooglescriptFound = true; + } + } + + // jQuery Library Loader + if (!$scriptFound) + { + // load jQuery, if not loaded before + if (!JFactory::getApplication()->get('jquery')) + { + JFactory::getApplication()->set('jquery', true); + // add jQuery + $document->addScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/jquery.noconflict.js' ); + } + } + + if (!$scriptuiFound) + { + $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); + } + + $document->addScript( JURI::root( true ) . '/media/com_icagenda/js/template.js' ); + } +} +else +{ + $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/registration/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/registration/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/registration/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/registration/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/registration/view.html.php new file mode 100644 index 00000000..8b439013 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/registration/view.html.php @@ -0,0 +1,122 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + $jinput = $app->input; + + $jinput->set('hidemainmenu', true); + + $user = JFactory::getUser(); + $isNew = ($this->item->id == 0); + + if (isset($this->item->checked_out)) + { + $checkedOut = ! ($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + } + else + { + $checkedOut = false; + } + + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_NEW_REGISTRATION') : 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_EDIT_REGISTRATION'), 'registration.png'); + } + else + { + JToolBarHelper::title($isNew ? 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_NEW_REGISTRATION') . '' : 'iCagenda - ' . JText::_('COM_ICAGENDA_LEGEND_EDIT_REGISTRATION') . '' , $isNew ? 'new' : 'pencil-2'); + } + + $icTitle = $isNew ? JText::_('COM_ICAGENDA_LEGEND_NEW_REGISTRATION') : JText::_('COM_ICAGENDA_LEGEND_EDIT_REGISTRATION'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + // If not checked out, can save the item. + if ( ! $checkedOut && ($canDo->get('core.edit') || $canDo->get('core.edit.own') || $canDo->get('core.create'))) + { + JToolBarHelper::apply('registration.apply', 'JTOOLBAR_APPLY'); + JToolBarHelper::save('registration.save', 'JTOOLBAR_SAVE'); + } + + if ( ! $checkedOut && ($canDo->get('core.create'))) + { + JToolBarHelper::custom('registration.save2new', 'save-new.png', 'save-new_f2.png', 'JTOOLBAR_SAVE_AND_NEW', false); + } + + // If an existing item, can save to a copy. + if ( ! $isNew && $canDo->get('core.create')) + { + JToolBarHelper::custom('registration.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); + } + + if (empty($this->item->id)) + { + JToolBarHelper::cancel('registration.cancel', 'JTOOLBAR_CANCEL'); + } + else + { + JToolBarHelper::cancel('registration.cancel', 'JTOOLBAR_CLOSE'); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/registrations/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/registrations/tmpl/default.php b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/tmpl/default.php new file mode 100644 index 00000000..a9d01463 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/tmpl/default.php @@ -0,0 +1,617 @@ +authorise('icagenda.access.registrations', 'com_icagenda')) +{ + $user = JFactory::getUser(); + $userId = $user->get('id'); + $listOrder = $this->state->get('list.ordering'); + $listDirn = $this->state->get('list.direction'); + $canOrder = $user->authorise('core.edit.state', 'com_icagenda'); + $saveOrder = $listOrder == 'a.ordering'; + $dateFormat = $this->params->get('date_format_global', 'Y - m - d'); + $dateSeparator = $this->params->get('date_separator', ' '); + $timeFormat = ($this->params->get('timeformat', '1') == 1) ? 'H:i' : 'h:i A'; + + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::_('behavior.tooltip'); + } + else + { + // Include the component HTML helpers. + JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + JHtml::_('bootstrap.tooltip'); + JHtml::_('formbehavior.chosen', 'select'); + JHtml::_('dropdown.init'); + +// $archived = $this->state->get('filter.published') == 2 ? true : false; +// $trashed = $this->state->get('filter.published') == -2 ? true : false; + + if ($saveOrder) + { + $saveOrderingUrl = 'index.php?option=com_icagenda&task=registrations.saveOrderAjax&tmpl=component'; + JHtml::_('sortablelist.sortable', 'registrationsList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); + } + } + + ?> + +
      + sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + + +
      + +
      + + + + + + + + + +
      +
      +
      + + + +
      +
      +
      +
      + +
      + + +
      +
      + + pagination->getLimitBox(); ?> +
      +
      +
      + +
      +
      + + + + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_icagenda'); + $canEdit = $user->authorise('core.edit', 'com_icagenda'); + $canCheckin = $user->authorise('core.manage', 'com_icagenda') || $item->checked_out == $userId || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_icagenda') && $canCheckin; + $canEditOwn = $user->authorise('core.edit.own', 'com_icagenda') && $item->userid == $userId; + + // Get participant privacy consents + $user_actions = isset($item->user_action) ? explode(',', $item->user_action) : array(); + + // Get Gravatar consent + if (in_array('consent_gravatar', $user_actions)) + { + $avatar = md5(strtolower(trim($item->email))); + $participant_avatar = '' . $item->name . '
      Gravatar'; + } + else + { + $participant_avatar = '
      '; + } + + // Get Username and name + $data_name = ($item->userid) ? $item->fullname : $item->name; + $data_username = ($item->userid) ? $item->username : false; + + // Load Custom fields DATA + $customfields = icagendaCustomfields::getListNotEmpty($item->id, 1); + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + ' . JText::_( 'JACTION_EDIT' ) . ''; + $savetx = '' . JText::_( 'JSAVE' ) . ''; + + foreach ($this->items as $i => $item) + { + if (($item->asset_id == '0') && ($item->state == '-2')) + { + $ia = $ia+1; + $front_submit = '1'; + } + } + + if ($front_submit == 1 && $ia == 1) + { + $app->enqueueMessage(JText::sprintf( 'COM_ICAGENDA_TRASH_FRONTEND_REGISTRATION_1', $edittx, $savetx ), 'notice'); + } + elseif ($front_submit == 1 && $ia > 1) + { + $app->enqueueMessage(JText::sprintf( 'COM_ICAGENDA_TRASH_FRONTEND_REGISTRATION', $edittx, $savetx ), 'notice'); + } + + foreach ($this->items as $i => $item) + { + if ($item->asset_id == '0' && $item->state == '-2') + { + $editLink = 'index.php?option=com_icagenda&task=registration.edit&id=' . $item->id; + $msg = '- ' . $item->name . ' [' . $item->id . '] : '.JText::_( 'JACTION_EDIT' ).''; + $type = JText::_( 'JGLOBAL_LIST' ).' :'; + } + if ( ! empty($msg)) + { + $app->enqueueMessage($msg, $type); + } + } + } + ?> + + +
      + ', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?> + + + + + + : +  | +  | +  | +  | + +  - +  | +  | + + + +
      + pagination->getListFooter(); ?> +
      + + + + + + + + + + + + evt_state == 1) : ?> + id); ?> + + + + + items[0]->state)) : ?> + state, $i, 'registrations.', $canChange, 'cb'); ?> + + +
      + +
      +
      + checked_out) : ?> + username, $item->checked_out_time, 'registrations.', $canCheckin); ?> + + language == '*'):?> + + + language ? $this->escape($item->language) : JText::_('JUNDEFINED'); ?> + + + + + + +

      + + evt_state == 1) : ?> + + + ' . $this->escape($item->name). ''; ?> + + + ' . $this->escape($item->name). ''; ?> + + + +
      + + : + + +
      + + : + + + + +

      + + ' . $this->escape($data_username) . ''; ?> + [' . $this->escape($data_name) . ']'; ?> + + + + + escape($item->name); ?> + + userid != '0') : ?> +

      + escape($item->userid); ?> +

      + +

      + +

      + + email) OR ($item->phone)) : ?> + +

      + email) : ?> +

      + " . $this->escape($item->email) . ""; ?> +
      + + phone) : ?> +
      + " . $this->escape($item->phone) . ""; ?> +
      + +

      + + + + notes) : ?> +
      + + + +
      +
      + ".JText::_('COM_ICAGENDA_REGISTRATION_NOTES_DISPLAY_LABEL') . ":
      " . nl2br(html_entity_decode($item->notes)); ?> +
      +
      + + + + + + cf_value) ? $customfield->cf_value : JText::_('IC_NOT_SPECIFIED'); ?> +
      + cf_title) . ': ' . JText::_($cf_value) . ''; ?> +
      + + + +

      + + + + + + +

      + + +
      +
      + +
      +
      + evt_state != 1) : ?> +
      +
      + +
      +
      + +
      + +
      +
      + ' . $this->escape($item->event) . ''; ?> +
      +
      + date && $item->period == 0) || ($item->period == 1)) : ?> + + + + + + date && $item->period == 0) : ?> + + startdate)) : ?> + startdate, $dateFormat, $dateSeparator); ?> + displaytime) : ?> + startdate)); ?> + + + startdate; ?> + + enddate) $period.= ' > '; ?> + enddate)) : ?> + enddate, $dateFormat, $dateSeparator); ?> + displaytime) : ?> + enddate)); ?> + + + enddate; ?> + + + date && $item->period == 1) : ?> + + + date)) : ?> + date, $dateFormat, $dateSeparator); ?> + displaytime) : ?> + date)); ?> + + + date; ?> + + + +
      + evt_created_by) : + // Get Author Name + $db = JFactory::getDBO(); + $db->setQuery( + 'SELECT name' . + ' FROM #__users' . + ' WHERE id = '. (int) $item->evt_created_by + ); + $authorname = $db->loadObject()->name; + ?> +
      + ' . $this->escape($authorname) . ''; ?> +
      + +

      +

      + +
      +
      + ' . $item->people . ''; ?> +
      +

      + + 'warning', + '0' => 'important', + '1' => 'default', + '2' => 'info', + '3' => 'success', + ); + $reg_status = array( + '-2' => 'Failed', + '0' => 'Cancelled', + '1' => '...', + '2' => 'Pending', + '3' => 'Completed', + ); + ?> + params); ?> + eventParams); ?> + +
      + +
      +
      + + Registration Status: + + + status]; ?> + +
      +
      + + Payment ID: + + + paymentID; ?> + +
      +
      + + Payment: + + + total . ' ' . $reg_params->currency; ?> + +
      + registration_payment) && $eventParams->registration_payment == 1) + || (isset($eventParams->registration_payment) && $eventParams->registration_payment == '' && JComponentHelper::getParams('com_icagenda')->get('registration_payment', ''))) : ?> +
      + +
      +
      + + Registration Status: + + + status]; ?> + +
      + + +
      +
      + items[0]->id)) : ?> + id; ?> + +
      + + + + JText::_('JTOOLBAR_EXPORT'), + 'url' => JRoute::_('index.php?option=com_icagenda&view=download&tmpl=component'), + 'height' => '900px', + 'width' => '300px', + 'bodyHeight' => '70', + 'modalWidth' => '40', + 'footer' => '' + . JText::_('COM_ICAGENDA_CANCEL') . '' + . '', + ) + ); ?> + + +
      + + + + + +
      +
      + + enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/registrations/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/registrations/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/view.html.php new file mode 100644 index 00000000..08bce582 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/view.html.php @@ -0,0 +1,221 @@ +params = JComponentHelper::getParams('com_icagenda'); + $this->state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->events = $this->get('Events'); + $this->dates = $this->get('Dates'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + + if (version_compare(JVERSION, '3.0', 'ge')) + { + $this->sidebar = JHtmlSidebar::render(); + } + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + require_once JPATH_COMPONENT . '/helpers/icagenda.php'; + + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + + $state = $this->get('State'); + $canDo = iCagendaHelper::getActions(); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_TITLE_REGISTRATION'), 'registration.png'); + } + else + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_TITLE_REGISTRATION') . '', 'users'); + } + + $icTitle = JText::_('COM_ICAGENDA_TITLE_REGISTRATION'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + + //Check if the form exists before showing the add/edit buttons + $formPath = JPATH_COMPONENT_ADMINISTRATOR . '/views/registration'; + + if (file_exists($formPath)) + { + $bar = JToolBar::getInstance('toolbar'); + + // Add Export Button to the ToolBar + if (version_compare(JVERSION, '3.7.0', 'lt')) + { + // Joomla 2.5 + $bar->appendButton('Popup', 'export', 'JTOOLBAR_EXPORT', 'index.php?option=com_icagenda&view=download&tmpl=component', 600, 300); + + JToolBarHelper::divider(); + } + else + { + // Instantiate a new JLayoutFile instance and render the export button + $layout = new JLayoutFile('joomla.toolbar.modal'); + + $dhtml = $layout->render( + array( + 'selector' => 'downloadModal', + 'icon' => 'download', + 'text' => JText::_('JTOOLBAR_EXPORT'), + ) + ); + + $bar->appendButton('Custom', $dhtml, 'download'); + } + + if ($canDo->get('core.create')) + { + JToolBarHelper::addNew('registration.add', 'JTOOLBAR_NEW'); + } + + if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) + { + JToolBarHelper::editList('registration.edit', 'JTOOLBAR_EDIT'); + } + + } + + if ($canDo->get('core.edit.state')) + { + if (isset($this->items[0]->state)) + { +// JToolBarHelper::divider(); + JToolBarHelper::custom('registrations.publish', 'publish.png', 'publish_f2.png','JTOOLBAR_PUBLISH', true); + JToolBarHelper::custom('registrations.unpublish', 'unpublish.png', 'unpublish_f2.png', 'JTOOLBAR_UNPUBLISH', true); + } + else + { + // If this component does not use state then show a direct delete button as we can not trash + JToolBarHelper::deleteList('', 'registrations.delete', 'JTOOLBAR_DELETE'); + } + + if (isset($this->items[0]->state)) + { + JToolBarHelper::divider(); + JToolBarHelper::archiveList('registrations.archive', 'JTOOLBAR_ARCHIVE'); + } + + if (isset($this->items[0]->checked_out)) + { + JToolBarHelper::custom('registrations.checkin', 'checkin.png', 'checkin_f2.png', 'JTOOLBAR_CHECKIN', true); + } + } + + // Show trash and delete for components that uses the state field + if (isset($this->items[0]->state)) + { + if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + JToolBarHelper::deleteList('', 'registrations.delete', 'JTOOLBAR_EMPTY_TRASH'); + JToolBarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + JToolBarHelper::trash('registrations.trash', 'JTOOLBAR_TRASH'); + JToolBarHelper::divider(); + } + } + + if ($canDo->get('core.admin')) + { + JToolBarHelper::preferences('com_icagenda'); + } + + if (version_compare(JVERSION, '3.0', 'ge')) + { + JHtmlSidebar::setAction('index.php?option=com_icagenda&view=registrations'); + + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_REGISTRATIONS_SELECT_STATUS'), + 'filter_published', + JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.state', '1'), true) + ); + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_REGISTRATIONS_SELECT_CATEGORY'), + 'filter_categories', + JHtml::_('select.options', $this->get('Categories'), 'value', 'text', $this->state->get('filter.categories'), true) + ); + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_REGISTRATIONS_SELECT_EVENT'), + 'filter_events', + JHtml::_('select.options', $this->get('Events'), 'value', 'text', $this->state->get('filter.events'), true) + ); + JHtmlSidebar::addFilter( + JText::_('COM_ICAGENDA_REGISTRATIONS_SELECT_DATE'), + 'filter_dates', + JHtml::_('select.options', $this->get('Dates'), 'value', 'text', $this->state->get('filter.dates'), true) + ); + } + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/registrations/view.raw.php b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/view.raw.php new file mode 100644 index 00000000..d40c3462 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/registrations/view.raw.php @@ -0,0 +1,69 @@ +get('BaseName'); + $filetype = $this->get('FileType'); + $mimetype = $this->get('MimeType'); + $content = $this->get('Content'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $document = JFactory::getDocument(); + $document->setMimeEncoding($mimetype); + + // Joomla 3 + if (version_compare(JVERSION, '3.0', 'ge')) + { + JFactory::getApplication() + ->setHeader( + 'Content-disposition', + 'attachment; filename="' . $basename . '.' . $filetype . '"; creation-date="' . JFactory::getDate()->toRFC822() . '"', + true + ); + } + // Joomla 2.5 + else + { + JResponse::setHeader('Content-disposition', 'attachment; filename="' . $basename . '.' . $filetype . '"; creation-date="' . JFactory::getDate()->toRFC822() . '"', true); + } + + echo $content; + } +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/themes/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/themes/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/themes/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/themes/tmpl/default.php b/deployed/icagenda/administrator/components/com_icagenda/views/themes/tmpl/default.php new file mode 100644 index 00000000..2fbeb993 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/themes/tmpl/default.php @@ -0,0 +1,319 @@ +authorise('icagenda.access.themes', 'com_icagenda')) +{ + // Check Theme Packs Compatibility + if (class_exists('icagendaTheme')) icagendaTheme::checkThemePacks(); + + $user = JFactory::getUser(); + $userId = $user->get('id'); + + $params = JComponentHelper::getParams( 'com_icagenda' ); + $version = $params->get('version'); + ?> + +sidebar)) : ?> +
      + sidebar; ?> +
      +
      + +
      + + + +
      +
      +
      +
      +
      + require_ftp)) { + echo iCagendaFileUpload::renderFTPaccess(); + } + ?> +
      + +
      + + +
      +
      + + + + +
      +
      +
      +
      +
      +
      +
      + logo_icagenda +
      +
      +

      + iCagenda +

      +
      +
      +

      + v1 +

      +
      +
      +
      +
      +
      +
      + +
      +

      +
      + load($themeurl); + + $getthemeUpdate = $dom->getElementsByTagName('themeUpdate'); + foreach ($getthemeUpdate AS $themeUpdate) + $themeUpdate = $themeUpdate->firstChild->nodeValue; + $urltheme = $themeUpdate.'/'.$pack.'/update.xml'; + $unknown = JText::_('COM_ICAGENDA_THEME_UNKNOWN'); + + // Test si fichier de mise à jour + $urlex = $urltheme; + + if (url_exists($urlex)) + { + // Récupération données fichier distant de MàJ + $update = new DomDocument; + $update->load($urltheme); + + $getUpdateversion = $update->getElementsByTagName('version'); + $getUpdatedownload = $update->getElementsByTagName('download'); + foreach ($getUpdateversion AS $Updatevers) + foreach ($getUpdatedownload AS $download) + $updateVersion = $Updatevers->firstChild->nodeValue; + $updateDownload = $download->firstChild->nodeValue; + } + else + { + $updateVersion = $unknown; + $updateDownload = '#'; + } + + +// $getUpdatestatus = $dom->getElementsByTagName('status'); + + // Récupération données fichier manifest install + $getthemename = $dom->getElementsByTagName('name'); + $getversion = $dom->getElementsByTagName('version'); + $getcreationDate = $dom->getElementsByTagName('creationDate'); + $getauthor = $dom->getElementsByTagName('author'); + $getauthorEmail = $dom->getElementsByTagName('authorEmail'); + $getauthorWebsite = $dom->getElementsByTagName('authorWebsite'); + $getauthorUrl = $dom->getElementsByTagName('authorUrl'); + $getdescription = $dom->getElementsByTagName('description'); + + // Conversion des données + foreach ($getthemename AS $name) +// foreach ($getUpdatestatus AS $status) + foreach ($getversion AS $version) + foreach ($getcreationDate AS $creationDate) + foreach ($getauthor AS $author) + foreach ($getauthorEmail AS $authorEmail) + foreach ($getauthorWebsite AS $authorWebsite) + foreach ($getauthorUrl AS $authorUrl) + foreach ($getdescription AS $description) + + $authorWebsitetest = $authorWebsite->firstChild->nodeValue; + + // Affichage fiches Themes + echo '
      '; + + // Affichage Titre et Nom + echo '

      ' . $name->firstChild->nodeValue . '
      ' . $pack . ' ]

      '; + + //Image Theme + $urlimg = '../components/com_icagenda/themes/packs'; + $thumb = $urlimg.'/'.$pack.'/images/'.$pack.'_thumbnail.png'; + $preview = $urlimg.'/'.$pack.'/images/'.$pack.'_preview.png'; + if (file_exists($thumb)) + { + $img = ''; + if (file_exists($preview)) + { + $imgtheme = ''; + } + } else { + $imgtheme ='
      '.JText::_('COM_ICAGENDA_THEME_NO_PREVIEW').'
      '; + } + + echo $imgtheme; + + // Affichage Description + echo '

      ' . $description->firstChild->nodeValue . '
      '; + + // Affichage Auteur + echo '
      '.JText::_('COM_ICAGENDA_THEME_AUTHOR').' : ' . $author->firstChild->nodeValue . '
      '; + + // Affichage Site Auteur + $authorWebsite = $authorWebsite->firstChild->nodeValue; + if ($authorWebsite != NULL) { + echo '
      '.JText::_('COM_ICAGENDA_THEME_AUTHOR_WEBSITE').' : ' . $authorWebsite . '
      '; + } + + // Affichage Version installée + echo '
      '.JText::_('COM_ICAGENDA_THEME_INSTALLED_VERSION').' : ' . $version->firstChild->nodeValue . '
      '; + + // Affichage Dernière version publiée + if (($updateVersion > $version->firstChild->nodeValue) && ($updateVersion != $unknown)) { + echo '
      '.JText::_('COM_ICAGENDA_THEME_LATEST_VERSION').' : ' . $updateVersion . '

      '; + } + + echo '

      '; + + if (($updateVersion > $version->firstChild->nodeValue) && ($updateVersion != $unknown)) { + echo '
      '.JText::_('COM_ICAGENDA_THEME_UPDATE').' ' . $updateVersion . ' !
      '; + } elseif ($updateVersion == $unknown) { + echo '
      '.JText::_('COM_ICAGENDA_THEME_AUTHOR_CONTACT').'
      '; + } else { + echo '
      '.JText::_('COM_ICAGENDA_THEME_LATEST').'
      '; + } + + echo '
      '; + echo '
      '; + } // On ferme le if (qui permet de ne pas afficher index.php, etc.) + + } // On termine la boucle + + echo '
      '; + + echo '
       
      '; + + echo '
      ' . JText::_('COM_ICAGENDA_THEME_NB_THEMES_1') . ' ' . $nb_themes . ' ' . JText::_('COM_ICAGENDA_THEME_NB_THEMES_2') .'
      '; + echo '
       
      '; + + closedir($dossier); + + } else { + echo 'ERROR: Folder not opened!'; + } + ?> + +
      + +
      +
      +
      + + +
      +
      +
      +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + Copyright ©2012- joomlic.com -  +  Joomla! Extensions Directory. +
      +
      +
      +
      + JoomliC +
      +  www.joomlic.com +
      +
      +
      + +
      + + enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); + $app->redirect(htmlspecialchars_decode('index.php?option=com_icagenda&view=icagenda')); +} diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/themes/tmpl/index.html b/deployed/icagenda/administrator/components/com_icagenda/views/themes/tmpl/index.html new file mode 100644 index 00000000..42682b47 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/themes/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/administrator/components/com_icagenda/views/themes/view.html.php b/deployed/icagenda/administrator/components/com_icagenda/views/themes/view.html.php new file mode 100644 index 00000000..a12917a4 --- /dev/null +++ b/deployed/icagenda/administrator/components/com_icagenda/views/themes/view.html.php @@ -0,0 +1,88 @@ +authorise('core.admin', 'com_icagenda')) +{ + JToolBarHelper::preferences('com_icagenda'); +} + +/** + * View class Admin - Theme Manager - iCagenda + */ +class iCagendaViewthemes extends JViewLegacy +{ + /** + * Display the view + */ + public function display($tpl = null) + { + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + + if (version_compare(JVERSION, '3.0', 'ge')) + { + $this->sidebar = JHtmlSidebar::render(); + } + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + */ + protected function addToolbar() + { + require_once JPATH_COMPONENT . '/helpers/icagenda.php'; + + $app = JFactory::getApplication(); + $document = JFactory::getDocument(); + + $state = $this->get('State'); + + // Set Title + if (version_compare(JVERSION, '3.0', 'lt')) + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_THEME_MANAGER'), 'themes.png'); + } + else + { + JToolBarHelper::title('iCagenda - ' . JText::_('COM_ICAGENDA_THEME_MANAGER') . '', 'palette'); + } + + $icTitle = JText::_('COM_ICAGENDA_THEME_MANAGER'); + + $sitename = $app->getCfg('sitename'); + $title = $app->getCfg('sitename') . ' - ' . JText::_('JADMINISTRATION') . ' - iCagenda: ' . $icTitle; + + $document->setTitle($title); + } +} diff --git a/deployed/icagenda/components/com_icagenda/add/elements/icevent_vars.php b/deployed/icagenda/components/com_icagenda/add/elements/icevent_vars.php new file mode 100644 index 00000000..da6119aa --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/add/elements/icevent_vars.php @@ -0,0 +1,403 @@ +title); +$EVENT_META_AS_SHORTDESC = iCFilterOutput::fullCleanHTML($item->metadesc); +$EVENT_SHORT_DESCRIPTION = JHtml::_('content.prepare', $item->shortdesc, $this->params, 'com_icagenda.event'); +$EVENT_DESCRIPTION = JHtml::_('content.prepare', $item->desc, $this->params, 'com_icagenda.event'); +$AUTO_SHORT_DESCRIPTION = icagendaEvents::shortDescription($item->desc); // Function to be renamed +$EVENT_SHARING = icagendaAddthis::sharing($item); + +$CUSTOM_FIELDS = icagendaEvent::getCustomFields($item->id); +$EVENT_INFO = icagendaEvent::infoDetails($item, $CUSTOM_FIELDS); +$EVENT_INFOS = $EVENT_INFO; // TODO: changed official Theme Packs (Do not remove for B/C) + +$EVENT_EMAIL_CLOAKING = $item->email ? icagendaRender::emailTag($item->email) : ''; +$EVENT_WEBSITE_LINK = icagendaRender::websiteTag($item->website); +$GOOGLEMAPS_COORDINATES = icagendaGooglemaps::display($item); +$EVENT_MAP = icagendaGooglemaps::map($item); +$EVENT_SINGLE_DATES = icagendaEvent::displayListSingleDates($item); +$EVENT_PERIOD = icagendaEvent::displayPeriodDates($item); +$EVENT_ATTACHEMENTS_TAG = icagendaRender::fileTag($item->file); +$EVENT_IMAGE_TAG = $item->image ? icagendaThumb::sizeLarge($item->image, 'imgTag', true) : ''; + +$EVENT_URL = icagendaEvent::url($item->id, $item->alias); + +// Data from database +$CATEGORY_TITLE = $item->cat_title; +$CATEGORY_COLOR = $item->cat_color; +$EVENT_ATTACHEMENTS = $item->file; +$EVENT_EMAIL = $item->email; +$EVENT_IMAGE = $item->image; // TODO: Check old icmodel function if needed... +$EVENT_NEXT = $item->next; +$EVENT_PHONE = $item->phone; +$EVENT_WEBSITE = $item->website; + + +/** + * Feature Icons + */ +$FEATURES_ICONSIZE_LIST = $this->params->get('features_icon_size_list'); +$FEATURES_ICONSIZE_EVENT = $this->params->get('features_icon_size_event'); +$SHOW_ICON_TITLE = $this->params->get('show_icon_title'); +// Get media path +$params_media = JComponentHelper::getParams('com_media'); +$image_path = $params_media->get('image_path', 'images'); +$FEATURES_ICONROOT_LIST = JUri::root() . $image_path . '/icagenda/feature_icons/' . $FEATURES_ICONSIZE_LIST . '/'; +$FEATURES_ICONROOT_EVENT = JUri::root() . $image_path . '/icagenda/feature_icons/' . $FEATURES_ICONSIZE_EVENT . '/'; +$FEATURES_ICONS = array(); + +if (isset($item->features) && is_array($item->features) + && (!empty($FEATURES_ICONSIZE_LIST) || !empty($FEATURES_ICONSIZE_EVENT))) +{ + foreach ($item->features as $feature) + { + $FEATURES_ICONS[] = array('icon' => $feature->icon, 'icon_alt' => $feature->icon_alt); + } +} + + +/** + * Event Image and Thumbnails + */ +$IMAGE_LARGE_HTML = ($EVENT_IMAGE && icagendaClass::isLoaded('icagendaThumb')) + ? icagendaThumb::sizeLarge($item->image, 'imgTag', true) + : ''; + + +/** + * Description, Meta-description and Intro Text + */ +$EVENT_DESC = ($item->desc || $item->shortdesc) ? true : false; +$EVENT_META = $EVENT_META_AS_SHORTDESC; + +$desc_display_event = $this->params->get('desc_display_event', ''); + +// Full description +if ($desc_display_event == '1') +{ + $EVENT_SHORTDESC = false; + $EVENT_DESCRIPTION = $EVENT_DESCRIPTION ? $EVENT_DESCRIPTION : false; +} + +// Short description +elseif ($desc_display_event == '2') +{ + $EVENT_SHORTDESC = $EVENT_SHORT_DESCRIPTION ? $EVENT_SHORT_DESCRIPTION : false; + $EVENT_DESCRIPTION = false; +} + +// Short and full descriptions +elseif ($desc_display_event == '3') +{ + $EVENT_SHORTDESC = $EVENT_SHORT_DESCRIPTION ? $EVENT_SHORT_DESCRIPTION : false; + $EVENT_DESCRIPTION = $EVENT_DESCRIPTION ? $EVENT_DESCRIPTION : false; +} + +// Hide +elseif ($desc_display_event == '0') +{ + $EVENT_SHORTDESC = false; + $EVENT_DESC = false; + $EVENT_DESCRIPTION = false; +} + +// Auto (First Full Description, if does not exist, will use Short Description if not empty) +else +{ + $EVENT_SHORTDESC = false; + $EVENT_DESCRIPTION = $EVENT_DESCRIPTION ? $EVENT_DESCRIPTION : $EVENT_SHORT_DESCRIPTION; +} + + +/** + * Event Address + */ +$EVENT_VENUE = $this->params->get('venue_display_global') ? $item->place : false; +$EVENT_CITY = $this->params->get('city_display_global') ? $item->city : false; +$EVENT_COUNTRY = $this->params->get('country_display_global') ? $item->country : false; + +if ($item->address) +{ + // Create an array to separate all strings between comma in individual parts + $EVENT_STREET = $item->address; + $ADDRESS_EX = explode(',', $EVENT_STREET); + + $country_to_check = ($EVENT_COUNTRY == 'United States') ? 'USA' : $EVENT_COUNTRY; + $country_removed = false; + $city_removed = false; + + $streetAndCity = $street = ''; + + $i = 0; + $count_ADDRESS_EX = count($ADDRESS_EX); + + for ($i; $i < $count_ADDRESS_EX; $i++) + { + // Remove the country from the full address + if ($EVENT_COUNTRY && ! $country_removed + && strpos($EVENT_STREET, $country_to_check) !== false) + { + $country_removed = true; + + // Remove country + $EVENT_STREET = substr( $EVENT_STREET, 0, strripos( $EVENT_STREET, ',' ) ); + $streetAndCity = $EVENT_STREET; + } + elseif ($EVENT_CITY && ! $city_removed + && strpos($EVENT_STREET, $EVENT_CITY) !== false) + { + $city_removed = true; + + // Remove last value, until city is not found in the string + $EVENT_STREET = substr( $EVENT_STREET, 0, strripos( $EVENT_STREET, ',' ) ); + $street = $EVENT_STREET; + + if (str_replace($street, '', $streetAndCity) != $EVENT_CITY) + { + $EVENT_CITY_POSTALCODE = str_replace($street, '', $streetAndCity); + $EVENT_CITY_POSTALCODE = str_replace(', ', '', $EVENT_CITY_POSTALCODE); + } + } + } + + $EVENT_CITY_POSTALCODE = isset($EVENT_CITY_POSTALCODE) ? $EVENT_CITY_POSTALCODE : $EVENT_CITY; + + + // Generate EVENT_ADDRESS Html tag + $EVENT_ADDRESS = $EVENT_STREET ? $EVENT_STREET . '
      ' : ''; + + if ($EVENT_CITY_POSTALCODE && $EVENT_COUNTRY) + { + $EVENT_ADDRESS.= $EVENT_CITY_POSTALCODE . ', ' . $EVENT_COUNTRY . '
      '; + } + elseif ( ! $EVENT_COUNTRY && $EVENT_CITY_POSTALCODE) + { + $EVENT_ADDRESS.= $EVENT_CITY_POSTALCODE . '
      '; + } + elseif ( ! $EVENT_CITY_POSTALCODE && $EVENT_COUNTRY) + { + $EVENT_ADDRESS.= $EVENT_COUNTRY . '
      '; + } +} +else +{ + $EVENT_ADDRESS = false; +} + + +/** + * Set Date from session + */ +$app = JFactory::getApplication(); +$session = JFactory::getSession(); + +$input = $app->input; +$view = $input->get('view'); + +if ($view == 'event') +{ + $get_date = $input->get('date', ''); + $event_date = $session->get('event_date', ''); + + if ( ! $get_date + && ! $event_date) + { + $get_date = date('Y-m-d-H-i', strtotime(icagendaEvent::getNextDate($item))); + } + elseif ( ! $get_date + && $event_date) + { + $get_date = date('Y-m-d-H-i', strtotime($event_date)); + } + elseif ( ! $get_date + && iCDate::isDate($item->startdate) + && iCDate::isDate($item->enddate) + ) + { + $get_date = date('Y-m-d-H-i', strtotime($item->startdate)); + $session->set('event_date', ''); + } +// elseif ( ! $get_date +// && ! $event_date) +// { +// $get_date = date('Y-m-d-H-i', strtotime($item->next)); +// } +} +else +{ + $session_date = $session->get('session_date', ''); + $get_date = date('Y-m-d-H-i', strtotime($session_date)); +} + +if ($get_date) +{ + $ex = explode('-', $get_date); + + if (count($ex) == 5) + { + $dateday = $ex['0'].'-'.$ex['1'].'-'.$ex['2'].' '.$ex['3'].':'.$ex['4']; + } + else + { + $dateday = ''; + } +} + +$TEXT_FOR_NEXTDATE = icagendaEvent::dateText($item); + +$timeformat = $this->params->get('timeformat'); +$timedisplay = $item->displaytime; + +if ($get_date) +{ +// $item->registered = icagendaRegistration::getRegisteredTotal($item->id, date('Y-m-d H:i:s', strtotime($dateday)), $item->params->get('typeReg', '1')); + $EVENT_NEXTDATE = icagendaEvent::nextDate($dateday, $item); + + $EVENT_THIS_DATE = icagendaRender::dateToFormat($dateday); + + $weekdays_array = $item->weekdays ? explode (',', $item->weekdays) : ''; + $weekdays = $weekdays_array ? count($weekdays_array) : ''; + + $period_array = unserialize($item->period); + $period_array = is_array($period_array) ? $period_array : array(); + + // @TODO: create 'Date' and 'Dates' translation strings. + // Full period (no weekdays selected) + if ( ! $weekdays + && in_array($dateday, $period_array) + ) + { + $EVENT_VIEW_DATE_TEXT = JTEXT::_('COM_ICAGENDA_EVENT_DATE'); // See @TODO + } + + // Single date + else + { + $EVENT_VIEW_DATE_TEXT = JTEXT::_('COM_ICAGENDA_EVENT_DATE'); // See @TODO + } + + $EVENT_VIEW_DATE = $EVENT_NEXTDATE; +} + +// If multiple dates and Display all dates OFF: Use Next date +else +{ + $EVENT_NEXTDATE = icagendaEvent::nextDate($item->next, $item); + + $EVENT_VIEW_DATE_TEXT = $TEXT_FOR_NEXTDATE; + $EVENT_VIEW_DATE = $EVENT_NEXTDATE; + + $item->registered = icagendaRegistration::getRegisteredTotal($item->id, $item->next, $item->params->get('typeReg', '1')); + + $session->set('event_date', $item->next); +} + + +/** + * Registration info + */ +$maxNbTickets = $item->params->get('maxReg', '1000000'); // TODO: check all functions using max nb of tickets, and replace by empty for unlimited +$statutReg = $item->params->get('statutReg', ''); + +// TEST $item->listTicketsAvailable = icagendaRegistration::getListTicketsAvailable($item->id, $item->params->get('typeReg', '1'), $maxNbTickets); + +// Set Registration button + registered people info +if ($input->get('tmpl') != 'component' + && $input->get('print') != 1 + && ! $item->params->get('event_cancelled') + ) +{ + $EVENT_REGISTRATION = icagendaRegistration::reg($item); +} +else +{ + $EVENT_REGISTRATION = ''; +} + +// Set Event information on tickets available/bookable +if ($maxNbTickets != '1000000' + && $statutReg == '1') +{ + $SEATS_AVAILABLE = ($maxNbTickets - $item->registered); + + if ($SEATS_AVAILABLE === 0) + { + $SEATS_AVAILABLE = JText::_('COM_ICAGENDA_REGISTRATION_DATE_NO_TICKETS_LEFT'); + } + + $MAX_NB_OF_SEATS = $maxNbTickets; +} + +// No limit for nb of tickets available +else +{ + $SEATS_AVAILABLE = false; + $MAX_NB_OF_SEATS = false; +} + +// Set Participants list +$PARTICIPANTS_DISPLAY = icagendaRegistrationParticipants::listDisplay($item); +$PARTICIPANTS_HEADER = icagendaRegistrationParticipants::listTitle($item); +$EVENT_PARTICIPANTS = icagendaRegistrationParticipants::registeredUsers($item); + + +// DEPRECATED (old theme packs) +if ( ! in_array($this->template, array('default', 'ic_rounded'))) +{ + $item->coordinate = $GOOGLEMAPS_COORDINATES; + $item->datelistUl = $EVENT_SINGLE_DATES; + $item->dateText = $TEXT_FOR_NEXTDATE; + $item->emailLink = $EVENT_EMAIL_CLOAKING; + $item->fileTag = $EVENT_ATTACHEMENTS_TAG; + $item->imageTag = $EVENT_IMAGE_TAG; + $item->infoDetails = $EVENT_INFO; + $item->loadEventCustomFields = $CUSTOM_FIELDS; + $item->map = $EVENT_MAP; + $item->nextDate = $EVENT_NEXTDATE; + $item->participantList = $PARTICIPANTS_DISPLAY; + $item->participantListTitle = $PARTICIPANTS_HEADER; + $item->periodDates = $EVENT_PERIOD; + $item->reg = $EVENT_REGISTRATION; + $item->registeredUsers = $EVENT_PARTICIPANTS; + $item->share_event = $EVENT_SHARING; + $item->websiteLink = $EVENT_WEBSITE_LINK; + $item->periodDisplay = ($EVENT_SINGLE_DATES || $EVENT_PERIOD) ? true : false; + $item->description = $EVENT_DESCRIPTION; + + // B/C Theme Packs (to be checked, and added if needed) + $item->place_name = $item->place; + $item->startdatetime = $item->startdate; + $item->enddatetime = $item->enddate; + + $item->startDate = icagendaRender::dateToFormat($item->startdate); + $item->endDate = icagendaRender::dateToFormat($item->enddate); + + $item->startTime = icagendaRender::dateToTime($item->startdate); + $item->endTime = icagendaRender::dateToTime($item->enddate); + + $EVENT_INFOS = $EVENT_INFO; // DEPRECATED (Not removed for B/C) +} diff --git a/deployed/icagenda/components/com_icagenda/add/elements/iclist_vars.php b/deployed/icagenda/components/com_icagenda/add/elements/iclist_vars.php new file mode 100644 index 00000000..516255b7 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/add/elements/iclist_vars.php @@ -0,0 +1,245 @@ +titleFormat; +$EVENT_TITLEBAR = $item->titlebar; +$EVENT_META_AS_SHORTDESC = $item->metaAsShortDesc; +$EVENT_SHORT_DESCRIPTION = $item->shortDescription; +$EVENT_DESCRIPTION = $item->description; +$AUTO_SHORT_DESCRIPTION = $item->descShort; +$CATEGORY_FONTCOLOR = $item->fontColor; + +$app = JFactory::getApplication(); +$isSef = $app->getCfg('sef'); + +$datesDisplay = $this->params->get('datesDisplay', 1); + +$eventTimeZone = null; +$weekdays = ($item->weekdays || $item->weekdays == '0') ? true : false; + +$this_date = JHtml::date($evt, 'Y-m-d H:i', $eventTimeZone); +$date_today = JHtml::date('now', 'Y-m-d'); +$period = unserialize($item->period); +$period = is_array($period) ? $period : array(); +$is_in_period = (in_array($this_date, $period)) ? true : false; + +if ($is_in_period + && $item->weekdays == '' + && strtotime($item->startdate) <= strtotime($date_today) + && strtotime($item->enddate) >= strtotime($date_today) + ) +{ + $ongoing = true; +} +else +{ + $ongoing = false; +} + +// Day in Date Box (list of events) +$EVENT_DAY = $this->params->get('day_display_global', 1) + ? icagendaEvents::day($evt, $item) + : false; + +// Month in Date Box (list of events) +$EVENT_MONTH = $this->params->get('month_display_global', 1) + ? icagendaEvents::dateBox($this_date, $this->params->get('event_month_format', 'monthshort'), $ongoing) + : false; + +if ($this->template == 'default' + && $this->params->get('event_month_format') == 'month') +{ + $style = '.ic-month {' + . ' font-size: 12px;' + . '}'; + JFactory::getDocument()->addStyleDeclaration($style); +} + +// @deprecated since 3.6.0 (EVENT_MONTHSHORT kept for B/C) +$EVENT_MONTHSHORT = $this->params->get('month_display_global', 1) ? icagendaEvents::dateBox($this_date, 'monthshort', $ongoing) : false; + +// Year in Date Box (list of events) +$EVENT_YEAR = $this->params->get('year_display_global', 1) + ? icagendaEvents::dateBox($evt, 'year', $ongoing) + : false; + +// Time in Date Box (list of events) +$EVENT_TIME = ($this->params->get('time_display_global', 0) && $item->displaytime == 1) + ? icagendaEvents::dateToTimeFormat($evt) + : false; + +// Load Event Data +$EVENT_DATE = icagendaEvent::nextDate($evt, $item); +$EVENT_SET_DATE = icagendaEvent::urlDateVar($evt); +$READ_MORE = ($this->params->get('shortdesc_display_global', '') == '' && ! $item->shortdesc) + ? icagendaEvent::readMore($item->url, $item->desc, '[...]') + : false; + +// URL to event details view (list of events) +//if ($datesDisplay == 1) +//{ + $date_var = ($isSef == '1') ? '?date=' : '&date='; + $set_url_date = $date_var . $EVENT_SET_DATE; + $date_url = ( ! $weekdays && in_array($this_date, $period)) + ? '' + : $date_var . $EVENT_SET_DATE; + + $EVENT_URL = $item->url . $date_url; +//} +//else +//{ +// $EVENT_URL = $item->url; +//} + +/** + * Event Dates + */ +$EVENT_NEXT = $item->next; + +/** + * Feature Icons + */ +$FEATURES_ICONSIZE_LIST = $this->params->get('features_icon_size_list'); +$FEATURES_ICONSIZE_EVENT = $this->params->get('features_icon_size_event'); +$SHOW_ICON_TITLE = $this->params->get('show_icon_title'); +// Get media path +$params_media = JComponentHelper::getParams('com_media'); +$image_path = $params_media->get('image_path', 'images'); +$FEATURES_ICONROOT_LIST = JUri::root() . $image_path . '/icagenda/feature_icons/' . $FEATURES_ICONSIZE_LIST . '/'; +$FEATURES_ICONROOT_EVENT = JUri::root() . $image_path . '/icagenda/feature_icons/' . $FEATURES_ICONSIZE_EVENT . '/'; +$FEATURES_ICONS = array(); + +if (isset($item->features) && is_array($item->features) + && (!empty($FEATURES_ICONSIZE_LIST) || !empty($FEATURES_ICONSIZE_EVENT))) +{ + foreach ($item->features as $feature) + { + $FEATURES_ICONS[] = array('icon' => $feature->icon, 'icon_alt' => $feature->icon_alt); + } +} + + +/** + * Event Image and Thumbnails + */ +$EVENT_IMAGE = $item->image; + +$IMAGE_MEDIUM = ($EVENT_IMAGE && icagendaClass::isLoaded('icagendaThumb')) + ? icagendaThumb::sizeMedium($item->image) + : ''; + + +/** + * Events List - Intro Text (TO DO: MIGRATE TO UTILITIES) + */ +$EVENT_DESC = ($item->desc || $item->shortdesc) ? true : false; + +$shortdesc_display_global = $this->params->get('shortdesc_display_global', ''); +$Filtering_ShortDesc_Global = JComponentHelper::getParams('com_icagenda')->get('Filtering_ShortDesc_Global', ''); + +if ($shortdesc_display_global == '1') // short desc +{ + $EVENT_DESCSHORT = $item->shortdesc ? $item->shortdesc : false; + + if ($EVENT_DESCSHORT) + { + $EVENT_DESCSHORT = empty($Filtering_ShortDesc_Global) ? '' . $EVENT_DESCSHORT . '' : $EVENT_DESCSHORT; + } +} +elseif ($shortdesc_display_global == '2') // Auto-Introtext +{ + $EVENT_DESCSHORT = $AUTO_SHORT_DESCRIPTION ? $AUTO_SHORT_DESCRIPTION : false; +} +elseif ($shortdesc_display_global == '0') // Hide +{ + $EVENT_DESCSHORT = false; +} +else // Auto (First Short Description, if does not exist, Auto-generated short description from the full description. And if does not exist, will use meta description if not empty) +{ + $shortDescription = $item->shortdesc ? $item->shortdesc : $AUTO_SHORT_DESCRIPTION; + + $metaAsShortDesc = $EVENT_META_AS_SHORTDESC; + + if ($metaAsShortDesc) + { + $metaAsShortDesc = empty($Filtering_ShortDesc_Global) ? '' . $metaAsShortDesc . '' : $metaAsShortDesc; + } + + $EVENT_DESCSHORT = $shortDescription ? $shortDescription : $metaAsShortDesc; +} + +$EVENT_INTRO_TEXT = $EVENT_DESCSHORT; // New var name since 3.4.0 + + + +$EVENT_VENUE = $this->params->get('venue_display_global', 1) ? $item->place : false; +$EVENT_POSTAL_CODE = $this->params->get('city_display_global', 1) ? $item->city : false; +$EVENT_CITY = $this->params->get('city_display_global', 1) ? $item->city : false; +$EVENT_COUNTRY = $this->params->get('country_display_global', 1) ? $item->country : false; + +$CATEGORY_TITLE = $item->cat_title; +$CATEGORY_COLOR = $item->cat_color; + + +/** + * Add Event Info from plugins (if exists) + */ +$onListAddEventInfo = $this->dispatcher->trigger('onListAddEventInfo', array('com_icagenda.list', &$item, &$this->params)); + +$IC_LIST_ADD_EVENT_INFO = ''; + +foreach ($onListAddEventInfo as $added_info) +{ + $IC_LIST_ADD_EVENT_INFO.= '
      ' . $added_info . '
      '; +} + + + +// B/C Theme Packs (to be checked, and added if needed) +if ( ! in_array($this->template, array('default', 'ic_rounded'))) +{ + $item->place_name = $item->place; + $item->startdatetime = $item->startdate; + $item->enddatetime = $item->enddate; + + $item->startDate = icagendaRender::dateToFormat($item->startdate); + $item->endDate = icagendaRender::dateToFormat($item->enddate); + + $item->startTime = icagendaRender::dateToTime($item->startdate); + $item->endTime = icagendaRender::dateToTime($item->enddate); + + $item->day = $EVENT_DAY; + $item->monthShort = $EVENT_MONTHSHORT; + $item->year = $EVENT_YEAR; + $item->evenTime = $EVENT_TIME; + + $this->atlist = ''; + + // To be checked + $CUSTOM_FIELDS = icagendaEventData::loadEventCustomFields($item->id); +} diff --git a/deployed/icagenda/components/com_icagenda/add/elements/index.html b/deployed/icagenda/components/com_icagenda/add/elements/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/add/elements/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/add/index.html b/deployed/icagenda/components/com_icagenda/add/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/add/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/controller.php b/deployed/icagenda/components/com_icagenda/controller.php new file mode 100644 index 00000000..c412e6f7 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/controller.php @@ -0,0 +1,58 @@ +get('enable_cache', 0); + $cachable = false; + + if ($cache == 1) + { + $cachable = true; + } + + $document = JFactory::getDocument(); + + $safeurlparams = array( + 'catid' => 'INT', + 'id' => 'INT', + 'date' => 'STRING', + 'page' => 'INT', + 'year' => 'INT', + 'month' => 'INT', + 'return' => 'BASE64', + 'print' => 'BOOLEAN', + 'lang' => 'CMD', + 'Itemid' => 'INT', + ); + + parent::display($cachable, $safeurlparams); + + return $this; + } +} diff --git a/deployed/icagenda/components/com_icagenda/controllers/index.html b/deployed/icagenda/components/com_icagenda/controllers/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/controllers/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/components/com_icagenda/controllers/registration.php b/deployed/icagenda/components/com_icagenda/controllers/registration.php new file mode 100644 index 00000000..e2f86fa6 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/controllers/registration.php @@ -0,0 +1,342 @@ +evt_id = $data['evt_id']; + $event->date = $data['startDate']; + $event->endDate = $data['endDate']; + $event->zone = $data['zone']; + $event->cntry = $data['country']; + $event->userName = $data['name']; + $event->userEmail = $data['email']; + $event->rerun = $data['rerun']; + $events = new Event($event); + + if ($event->evt_id == '108') + $data['req_url'] = 'https://www.archlinexp.com/update-day-25-november'; + else + $data['req_url'] = 'https://www.archlinexp.com/events'; + + if ($data['g-recaptcha-response'] == '') { + $this->setMessage('

      Please complete the captcha

      ', 'danger'); + $this->setRedirect(JRoute::_($data['req_url'], false)); + return; + } + + if ($data['country'] == '') { + $this->setMessage('

      Please choose a country

      ', 'danger'); + $this->setRedirect(JRoute::_($data['req_url'], false)); + return; + } + + if (!icagendaRegistration::validEmail($data['email'])) { + $this->setMessage(JText::_('COM_ICAGENDA_REGISTRATION_EMAIL_NOT_VALID'), 'danger'); + $this->setRedirect(JRoute::_($data['req_url'], false)); + return; + } + + if ($events->registration()) { + $this->setMessage('Thank you for taking time to register.
      + An email with further details has been sent to the email address you provided.
      + We hope you will enjoy the presentations.'); + } + $this->setRedirect(JRoute::_($data['req_url'], false)); + } + + public function registerToAlLive() + { + require_once(JPATH_BASE . '/common_cadline_libraries/crm_users.class.php'); + + $data = JRequest::get($_POST); + + $event->userName = $data['name']; + $event->userEmail = $data['email']; + $event->cntry = $data['country']; + $events = new Event($event); + + $data['req_url'] = 'https://www.archlinexp.com/win-al-live'; + + if ($data['g-recaptcha-response'] == '') { + $this->setMessage('

      Please complete the captcha

      ', 'danger'); + $this->setRedirect(JRoute::_($data['req_url'], false)); + return; + } + + if ($data['country'] == '') { + $this->setMessage('

      Please choose a country

      ', 'danger'); + $this->setRedirect(JRoute::_($data['req_url'], false)); + return; + } + + if (!icagendaRegistration::validEmail($data['email'])) { + $this->setMessage(JText::_('COM_ICAGENDA_REGISTRATION_EMAIL_NOT_VALID'), 'danger'); + $this->setRedirect(JRoute::_($data['req_url'], false)); + return; + } + + /*if ($events->registerToWinLIVE()) { + $this->setMessage('Thank you for taking time to register.
      + An email with further details has been sent to the email address you provided.
      + We hope you will enjoy the presentations.'); + }*/ + + $this->setMessage('Thank you for taking time to register.
      + An email with further details has been sent to the email address you provided.
      + We hope you will enjoy the presentations.'); + + $this->setRedirect(JRoute::_($data['req_url'], false)); + } + + public function register() + { + // Check for request forgeries. + // JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + // If registration is disabled - Redirect to login page. + // if (JComponentHelper::getParams('com_users')->get('allowUserRegistration') == 0) + // { + // $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false)); + + // return false; + // } + + $app = JFactory::getApplication(); + $jinput = $app->input; + + $id = $jinput->getInt('eventID'); + + $model = $this->getModel('Registration'); + + // Get the user data. + $requestData = $jinput->post->get('jform', array(), 'array'); + + // Validate the posted data. + $form = $model->getForm(); + + if (!$form) { + throw new Exception($model->getError(), 500); + + return false; + } + + $data = $model->validate($form, $requestData); + + // Check for validation errors. + if ($data === false) { + // Get the validation messages. + $errors = $model->getErrors(); + + // Push up to five validation messages out to the user. + for ($i = 0, $n = count($errors); $i < $n && $i < 5; $i++) { + if ($errors[$i] instanceof Exception) { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } else { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState('com_icagenda.registration.data', $requestData); + + // Redirect back to the registration screen. + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=registration&id=' . $id, false)); + + return false; + } + + // Set data to user State + // $app->setUserState('com_icagenda.registration.data', $requestData); + + // Attempt to save the data. + $return = $model->register($data); + + // Check for errors. + if ($return === false) { + // Save the data in the session. + $app->setUserState('com_icagenda.registration.data', $data); + + // Redirect back to the edit screen. + $this->setMessage($model->getError(), 'warning'); + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=registration&id=' . $id, false)); + + return false; + } + + // Flush the data from the session. + $app->setUserState('com_icagenda.registration.data', null); + + // Redirect to the complete layout. + if ($return === 'complete') { + $this->setMessage(JText::_('COM_ICAGENDA_REGISTRATION_COMPLETE_SUCCESS')); + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=registration&layout=complete&id=' . $id, false)); + } + + // Redirect to the actions layout. + elseif ($return) { + // Save the data in the session. + $app->setUserState('com_icagenda.registration.regdata', $data); + $app->setUserState('com_icagenda.registration.actions', $return); + + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=registration&layout=actions&id=' . $id, false)); + } else { + // Save the data in the session. + $app->setUserState('com_icagenda.registration.data', $data); + + // Redirect back to the registration form. + $this->setMessage($model->getError(), 'warning'); + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=registration&id=' . $id, false)); + + return false; + } + + return true; + } + + /** + * Method to complete actions. + * + * @return boolean True on success, false on failure. + * + * @since 3.6.13 + */ + public function actions() + { + $app = JFactory::getApplication(); + $jinput = $app->input; + + $id = $jinput->getInt('eventID'); + $action = $jinput->get('action', ''); + $data = $jinput->get('data', null); + $complete = $jinput->get('complete', ''); + + $regid = $app->getUserState('com_icagenda.registration.regid', ''); + $regData = $app->getUserState('com_icagenda.registration.regdata', null); + + // Get registration ID + $regData['id'] = $regid; + + $app->setUserState('com_icagenda.actions.data', $data); + + $model = $this->getModel('Registration'); + + // Attempt to validate the action. + $return = $model->actions($action, $data, $regData); + + if ($complete && $return) { + $this->setMessage(JText::_('COM_ICAGENDA_REGISTRATION_COMPLETE_SUCCESS')); + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=registration&layout=complete&id=' . $id, false)); + } + + return true; + } + + /** + * Method to cancel one registration. + * + * @return boolean True on success, false on failure. + * + * @since 3.6.13 + */ + public function cancel() + { + $app = JFactory::getApplication(); + $jinput = $app->input; + $user = JFactory::getUser(); + + $dates_cancelled = $jinput->get('dates_cancelled'); + $event_id = $jinput->getInt('eventID'); + $user_id = $user->get('id'); + + if (empty($dates_cancelled)) { + $this->setMessage(JText::_('COM_ICAGENDA_REGISTRATION_CANCEL_SELECT_DATES'), 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=registration&layout=cancel&id=' . $event_id, false)); + } + + $model = $this->getModel('Registration'); + + // Attempt to cancel date(s) registration. + $return = $model->cancel($dates_cancelled, $user_id); + + if ($return === false) { + $this->setMessage(JText::_('JERROR_LAYOUT_PAGE_NOT_FOUND'), 'warning'); + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=event&id=' . $event_id, false)); + + return false; + } elseif ($return && $dates_cancelled && $user_id) { + JArrayHelper::toInteger($dates_cancelled); + $dates_cancelled = implode(',', $dates_cancelled); + $this->setMessage(JText::_('COM_ICAGENDA_REGISTRATION_CANCEL_SUCCESS'), 'message'); + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=registration&layout=cancel&id=' . $event_id . '&dates_cancelled=' . $dates_cancelled, false)); + } else { + $this->setMessage(JText::_('JERROR_LAYOUT_PAGE_NOT_FOUND'), 'warning'); + $this->setRedirect(JRoute::_('index.php?option=com_icagenda&view=event&id=' . $event_id, false)); + + return false; + } + + return true; + } + + /** + * Return Ajax to get total of registered people for one event and one date + * + * @since 3.6.5 + */ + public function ticketsBookable() + { + $jinput = JFactory::getApplication()->input; + + $eventID = $jinput->get('eventID', ''); + + $regDate = $jinput->get('regDate', ''); + $regDate = str_replace('space', ' ', $regDate); + $regDate = str_replace('_', ':', $regDate); + + $typeReg = $jinput->get('typeReg', ''); + $maxReg = $jinput->get('maxReg', ''); + $tickets = $jinput->get('tickets', ''); + + icagendaAjax::getTicketsBookable($eventID, $regDate, $typeReg, $maxReg, $tickets); + } +} diff --git a/deployed/icagenda/components/com_icagenda/helpers/iCicons.class.php b/deployed/icagenda/components/com_icagenda/helpers/iCicons.class.php new file mode 100644 index 00000000..a6dbfd91 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/helpers/iCicons.class.php @@ -0,0 +1,177 @@ +get('iconAddToCal_options', ''); + $iconAddToCal_size = $iC_global->get('iconAddToCal_size', '16'); + + $html = array(); + + switch ( strtolower($type) ) + { + case 'printpreview': + + $html[]= ''; + + // Joomla 3.x / 2.5 SWITCH + if (version_compare(JVERSION, '3.0', 'ge')) + { + $html[]= ''; + } + else + { + $html[]= JHtml::_('image', 'system/printButton.png', JText::_('JGLOBAL_PRINT'), null, true); + } + + $html[]= ''; + + break; + + case 'print': + + $html[]= ''; + + // Joomla 3.x / 2.5 SWITCH + if (version_compare(JVERSION, '3.0', 'ge')) + { + $html[]= ' ' . JText::_('JGLOBAL_PRINT') . ' '; + } + else + { + $html[]= JHtml::_('image', 'system/printButton.png', JText::_('JGLOBAL_PRINT'), null, true).' ' . JText::_('JGLOBAL_PRINT') . ' '; + } + + $html[]= ''; + + break; + + case 'vcal': + + if (is_array($iconAddToCal_options)) + { + $addtocal = ''; + $addtocal.= '
      ' . JText::_('COM_ICAGENDA_ADD_TO_CALL_LABEL') . '
      '; + + // Google Calendar - link + if (in_array('1', $iconAddToCal_options)) + { + $addtocal.= ''; + } + + // iCal Calendar - ics + if (in_array('2', $iconAddToCal_options)) + { + $addtocal.= ''; + } + + // Outlook Calendar - ics + if (in_array('3', $iconAddToCal_options)) + { + $addtocal.= ''; + } + + // Windows Live Calendar - link + if (in_array('4', $iconAddToCal_options)) + { + $addtocal.= ''; + } + + // Yahoo Calendar - link + if (in_array('5', $iconAddToCal_options)) + { + $addtocal.= ''; + } + + $return_atc = htmlspecialchars($addtocal); + + $html[]= ''; // @todo: remove style, and replace by +
      +
      + + + +
      + +
      +
      +
      +
      + +
      + + + + + +
      +
      + +
      +
      + +
      + + + +
      + + +

       

      + + + +
      + + +
      + +
      + + +
      + + + +
      + +
      +
      + + + + +
      +
      +
      +
      + + + + +
      +
      +
      +
      +
      + + + + +
      +
      +
      + + + + +
      +
      +
      +
      + + + + +
      +
      +
      +
      + + + + + + title && $FIELD->value && $FIELD->slug != 'video_url' && $FIELD->slug != 'presenter') : ?> +
      +
      title; ?>
      +
      value; ?>
      +
      + + + + + + +
      +
      +
      +
      + +
      + +
      + + +
      + +
      + + + + +

       

      +
      +


      +
      + +
      +
      + + + + +

       

      +
      +

      + +
      + + + + + + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/ic_rounded_events.php b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/ic_rounded_events.php new file mode 100644 index 00000000..8e8235ef --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/ic_rounded_events.php @@ -0,0 +1,162 @@ + + + + + + + +
      + + + + + + + + + +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + +
      +
      + +
      + + + +
      + + +
      + + +
      +

      + + + +

      +
      + + +
      + +
      + + +
      + + + +
      + +
      + <?php echo $icon['icon_alt'] ?> +
      + +
      + + + + +
      + +
      + + + + +
      + + + + + + + - + , + + + + + , + + +
      + + + + +
      + +
      + + + + + + + + +
      + + + +
      + +
      + +
      + + diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/ic_rounded_registration.php b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/ic_rounded_registration.php new file mode 100644 index 00000000..2f202e0c --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/ic_rounded_registration.php @@ -0,0 +1,50 @@ + + + + + + +
      +
      + +
      +
      + +
      + + +
      + +
      + + +
      + +
      +
      +
      +
      + diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/ic_load.gif b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/ic_load.gif new file mode 100644 index 00000000..97d7e15b Binary files /dev/null and b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/ic_load.gif differ diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/ic_rounded_preview.png b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/ic_rounded_preview.png new file mode 100644 index 00000000..2b7ebd57 Binary files /dev/null and b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/ic_rounded_preview.png differ diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/ic_rounded_thumbnail.png b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/ic_rounded_thumbnail.png new file mode 100644 index 00000000..a2ef8b05 Binary files /dev/null and b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/ic_rounded_thumbnail.png differ diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/index.html b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/info.png b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/info.png new file mode 100644 index 00000000..cb6b2f02 Binary files /dev/null and b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/info.png differ diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/minuslist.png b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/minuslist.png new file mode 100644 index 00000000..7f7e6762 Binary files /dev/null and b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/minuslist.png differ diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/plus.png b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/plus.png new file mode 100644 index 00000000..f95a1d60 Binary files /dev/null and b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/plus.png differ diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/pluslist.png b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/pluslist.png new file mode 100644 index 00000000..b90ad050 Binary files /dev/null and b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/pluslist.png differ diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/regis-baloon.png b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/regis-baloon.png new file mode 100644 index 00000000..f63cbf78 Binary files /dev/null and b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/regis-baloon.png differ diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/selector-arrow.png b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/selector-arrow.png new file mode 100644 index 00000000..80a89468 Binary files /dev/null and b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/images/selector-arrow.png differ diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/index.html b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/themes/packs/ic_rounded/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/themes/packs/index.html b/deployed/icagenda/components/com_icagenda/themes/packs/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/themes/packs/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/views/event/index.html b/deployed/icagenda/components/com_icagenda/views/event/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/event/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/components/com_icagenda/views/event/tmpl/default.php b/deployed/icagenda/components/com_icagenda/views/event/tmpl/default.php new file mode 100644 index 00000000..fa10a547 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/event/tmpl/default.php @@ -0,0 +1,47 @@ +item; +?> + +
      + + + loadTemplate('top'); ?> + + template . " -->"; ?> + + + event->iCagendaOnEventBeforeDisplay; ?> + + + icevent_vars; ?> + + + themeEvent; ?> + + + event->iCagendaOnEventAfterDisplay; ?> +
      + + diff --git a/deployed/icagenda/components/com_icagenda/views/event/tmpl/default_top.php b/deployed/icagenda/components/com_icagenda/views/event/tmpl/default_top.php new file mode 100644 index 00000000..d7176b48 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/event/tmpl/default_top.php @@ -0,0 +1,73 @@ +getCfg('sef'); +$item = $this->item; +$iCicons = new iCicons(); + +$uri = JUri::getInstance()->toString(); +$evt_id = $app->input->getInt('id', 0); +$event_link = JRoute::_('index.php?option=com_icagenda&view=event&id=' . $evt_id); + +$print_url = ($isSef == 1) ? $event_link . '?tmpl=component' : $event_link . '&tmpl=component'; +$ical_url = ($isSef == 1) ? $uri . '?vcal=1' : $uri . '&vcal=1'; +$ical_url = preg_replace('/\?date=[^\?]*/', '', $ical_url); +$ical_url = preg_replace('/&date=[^&]*/', '', $ical_url); +?> + + +
      + +input->get('tmpl') != 'component') : ?> +
      + + + iconPrint_global == 2) : ?> +
      + showIcon('printpreview', $print_url); ?> +
      + + + + iconAddToCal_global == 2) : ?> +
      + showIcon('vcal', $uri, $ical_url, $item->googleCalendar, $item->windowsliveCalendar, $item->yahooCalendar); ?> +
      + + + +
      + managerToolBar; ?> +
      + +
      + + + + +
      + showIcon('print'); ?> +
      + + + +
      +
       
      diff --git a/deployed/icagenda/components/com_icagenda/views/event/tmpl/default_vcal.php b/deployed/icagenda/components/com_icagenda/views/event/tmpl/default_vcal.php new file mode 100644 index 00000000..3312b856 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/event/tmpl/default_vcal.php @@ -0,0 +1,141 @@ +getCfg('sitename'); +$offset = $app->getCfg('offset'); + +// Shortcut for item +$item = $this->item; + +// Get date from the session (current date of the event page) +$session = JFactory::getSession(); +$session_date = $session->get('session_date'); + +if ($session_date) +{ + $eventDateTime = iCDate::isDate($session_date) ? $session_date : ''; +} +else +{ + $url_date = $app->input->get('date', ''); + + if ($url_date) + { + $sd_ex = explode('-', $url_date); + $eventDateTime = $sd_ex['0'] . '-' . $sd_ex['1'] . '-' . $sd_ex['2'] . ' ' . $sd_ex['3'] . ':' . $sd_ex['4'] . ':00'; + } +} + +//$new_date = isset($eventDateTime) ? $eventDateTime : 'now'; +$new_date = isset($eventDateTime) ? $eventDateTime : $item->next; + +// Set Time Offset for date of the event +$dateTimeZone = new DateTimeZone($offset); +$dateTime = new DateTime($new_date, $dateTimeZone); +$timeOffset = $dateTimeZone->getOffset($dateTime); +$timezone = ($timeOffset / 3600); + +$event_date = isset($eventDateTime) + ? date('Y-m-d-H-i', (strtotime($eventDateTime) - $timeOffset)) + : date('Y-m-d-H-i', (strtotime($item->next) - $timeOffset)); + +// Set vCalendar config; +$config = array( "unique_id" => $sitename + // set a (site) unique id + , "TZID" => $offset ); + // opt. "calendar" timezone + +// Create a new calendar instance +$v = new vCalendar($config); +$v->setConfig( 'filename', 'icagenda.ics' ); +$v->prodid = 'iCagenda'; + +//$tz = 'UTC'; +$tz = $offset; +$v->setProperty( 'method', 'PUBLISH' ); +$v->setProperty( 'X-WR-CALDESC', '' ); +$v->setProperty( 'X-WR-TIMEZONE', $tz); +$xprops = array( 'X-LIC-LOCATION' => $tz); + +if (version_compare(PHP_VERSION, '5.3.0') >= 0) +{ + iCalUtilityFunctions::createTimezone($v, $tz, $xprops); +} + +$s_dates = $item->dates; +$single_dates = unserialize($s_dates); + +$ex = explode('-', $event_date); +$this_date = $ex['0'].'-'.$ex['1'].'-'.$ex['2'].' '.$ex['3'].':'.$ex['4']; + +$startdate = date('Y-m-d-H-i', (strtotime($item->startdate) - $timeOffset)); +$enddate = date('Y-m-d-H-i', (strtotime($item->enddate) - $timeOffset)); + +if ( ($event_date >= $startdate) + && ($event_date <= $enddate) + && ( ! in_array($this_date, $single_dates)) ) +{ + $weekdays = ($item->weekdays || $item->weekdays == '0') ? true : false; + + if ($weekdays) + { + $startdate = date('Y-m-d-H-i', strtotime($this_date)); + $enddate = date('Y-m-d', strtotime($this_date)) . '-' . date('H-i', strtotime($item->enddate)-$timeOffset); + } + + $ex_S = explode('-', $startdate); + $ex_E = explode('-', $enddate); + + $start_Datetime = $ex_S['0'] . $ex_S['1'] . $ex_S['2'] . 'T' . $ex_S['3'] . $ex_S['4'] . '00Z'; + $end_Datetime = $ex_E['0'] . $ex_E['1'] . $ex_E['2'] . 'T' . $ex_E['3'] . $ex_E['4'] . '00Z'; +} +else +{ + $start_Datetime = $end_Datetime = $ex['0'] . $ex['1'] . $ex['2'] . 'T' . $ex['3'] . $ex['4'] . '00Z'; +} + +// Not yet used +$urllink = JUri::getInstance()->toString(); +$cleanurl = preg_replace('/&tmpl=[^&]*/', '', $urllink); +$cleanurl = preg_replace('/&vcal=[^&]*/', '', $cleanurl); + +$vevent = &$v->newComponent('vevent'); +$vevent->setProperty('categories', $item->cat_title); +$vevent->setProperty('summary', $item->title); +$vevent->setProperty('description', strip_tags($item->desc)); +$vevent->setProperty('url', $cleanurl); +$vevent->setUID($item->id); + +if ($item->contact_name != '') +{ + $vevent->setOrganizer($item->contact_name, $item->contact_email); +} + +$vevent->setProperty('dtstart', $start_Datetime); +$vevent->setProperty('dtend', $end_Datetime); + +$vevent->setProperty('location',$item->place); + +$v->returnCalendar(); diff --git a/deployed/icagenda/components/com_icagenda/views/event/tmpl/index.html b/deployed/icagenda/components/com_icagenda/views/event/tmpl/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/event/tmpl/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/components/com_icagenda/views/event/view.html.php b/deployed/icagenda/components/com_icagenda/views/event/view.html.php new file mode 100644 index 00000000..ed7acbdf --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/event/view.html.php @@ -0,0 +1,382 @@ +item = $this->get('Item'); + $this->state = $this->get('State'); + $this->params = $this->state->get('params'); + $this->user = $user; + + $this->timeZones = icagendaEventsData::getAllTimeZone(1); + + if (isset($_POST['change_timezone'])) $_SESSION['timezone'] = $_POST['timezone']; + + $offset = substr($_SESSION['timezone'], 0, strpos($_SESSION['timezone'], "_")); + + $this->item->rerun = icagendaEvent::getCustomField($this->item->id, 'rerun'); + + $rerunEnd = new DateTime($this->item->rerun); + $rerunEnd->modify('+45 minutes'); + $rerunEnd = date_format($rerunEnd, 'Y-m-d H:i'); + + $this->item->rerunEnd = $rerunEnd; + + icagendaEventsData::changeDate($offset, $this->item->startdate, $this->item->enddate); + icagendaEventsData::changeDate($offset, $this->item->rerun, $this->item->rerunEnd); + + // Check for errors. + if (count($errors = $this->get('Errors'))) { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + // Shortcuts + $item = $this->item; + $params = $this->params; + + // For Dev. + $time_loading = $params->get('time_loading', ''); + + if ($time_loading) { + $starttime_list = iCLibrary::getMicrotime(); + } + + // Check Access + $userLevels = $user->getAuthorisedViewLevels(); + $userGroups = $user->getAuthorisedGroups(); + + $groupid = JComponentHelper::getParams('com_icagenda')->get('approvalGroups', array("8")); + $groupid = is_array($groupid) ? $groupid : array($groupid); + + $uri = JFactory::getUri(); + $return = base64_encode($uri); // Encode Return URL + $rlink = JRoute::_("index.php?option=com_users&view=login&return=$return", false); + + if ( + !in_array('8', $userGroups) + && (!in_array($item->access, $userLevels) + || ($item->approval == 1 && !array_intersect($userGroups, $groupid))) + ) { + if ($user->id) { + $app->enqueueMessage(JText::_('JERROR_LOGIN_DENIED'), 'warning'); + } else { + $app->enqueueMessage(JText::_('JGLOBAL_YOU_MUST_LOGIN_FIRST'), 'info'); + } + + $app->redirect($rlink); + } + + // Load Theme pack layout for event details view + $this->template = $params->get('template', 'ic_rounded'); + $themeEvent = icagendaTheme::getThemeLayout($this->template, 'event'); + + // Check if errors (file missing) + if ($themeEvent[1]) { + $msg = ($themeEvent[1] !== 'deprecated') + ? 'iCagenda ' . JText::_('PHPMAILER_FILE_OPEN') . ' ' . $this->template . '_event.php' + : JText::_('COM_ICAGENDA_ERROR_THEME_PACK_OUTDATED') . '
      ' . + JText::sprintf('COM_ICAGENDA_ERROR_THEME_PACK_EDIT_OR_CHANGE', '' . $this->template . '_list.php'); + $app->enqueueMessage($msg, 'warning'); + + if ($themeEvent[1] !== 'alert') { + return false; + } + } + + $this->themeEvent = $themeEvent[0]; + + + // Component Options + $this->GoogleMaps = $params->get('GoogleMaps', 1); + $this->iconPrint_global = $params->get('iconPrint_global', 0); + $this->iconAddToCal_global = $params->get('iconAddToCal_global', 0); + $this->iconAddToCal_options = $params->get('iconAddToCal_options', 0); // To be checked + + + // Increment the hit counter of the event. + $model = $this->getModel(); + $model->hit(); + + // Check vcal view (ics file for export to calendar) + $vcal = $app->input->get('vcal'); + + if ($vcal) { + $tpl = 'vcal'; + } else { + icagendaInfo::commentVersion(); + } + + + // Content Object needs a "text" property + $item->text = $item->desc; + + // Process the content plugins. + if (version_compare(JVERSION, '3.0', 'lt')) { + $this->dispatcher = JDispatcher::getInstance(); + } else { + $this->dispatcher = JEventDispatcher::getInstance(); + } + + JPluginHelper::importPlugin('content'); + + // $this->dispatcher->trigger('onContentPrepare', array ('com_icagenda.event', &$item, &$this->params, '0')); + + $this->dispatcher->trigger('onEventPrepare', array('com_icagenda.event', &$item, &$this->params)); // @deprecated. Kept for B/C + $this->dispatcher->trigger('iCagendaOnEventPrepare', array('com_icagenda.event', &$item, &$this->params)); + + $item->event = new stdClass; + + $results = $this->dispatcher->trigger('iCagendaOnEventBeforeDisplay', array('com_icagenda.event', &$item, &$this->params)); + $item->event->iCagendaOnEventBeforeDisplay = trim(implode("\n", $results)); + + $results = $this->dispatcher->trigger('iCagendaOnEventAfterDisplay', array('com_icagenda.event', &$item, &$this->params)); + $item->event->iCagendaOnEventAfterDisplay = trim(implode("\n", $results)); + + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->item->params->get('pageclass_sfx')); + + $this->_prepareDocument(); + + $this->icevent_vars = 'components/com_icagenda/add/elements/icevent_vars.php'; + + parent::display($tpl); + + $this->dispatcher->trigger('onEventAfterDisplay', array('com_icagenda.event', &$item, &$this->params)); // @deprecated. Kept for B/C + + // Loads jQuery Library + if (version_compare(JVERSION, '3.0', 'lt')) { + icagendaThemeJoomla25::loadjQuery(); + } + // Joomla 3 + else { + JHtml::_('bootstrap.framework'); + JHtml::_('jquery.framework'); + } + + // Google Maps api V3 + // @TODO: simplify this loading! + if ( + !empty($item->lng) + && !empty($item->lat) + && $item->lng != '0.0000000000000000' + && $item->lat != '0.0000000000000000' + && $this->GoogleMaps == 1 + ) { + icagendaGooglemaps::loadGMapScripts(); + } + + // Loading Script tipTip used for iCtips + JHtml::script('com_icagenda/jquery.tipTip.js', false, true); + + // Add ic-addtocal tipTip + $iCAddToCal = array(); + $iCAddToCal[] = ' jQuery(document).ready(function(){'; + $iCAddToCal[] = ' jQuery(".ic-addtocal").tipTip({maxWidth: "200px", defaultPosition: "bottom", edgeOffset: 1, activation:"hover", keepAlive: true});'; + $iCAddToCal[] = ' });'; + + // Add the script to the document head. + JFactory::getDocument()->addScriptDeclaration(implode("\n", $iCAddToCal)); + + // Add CSS + $document = Factory::getDocument(); + $document->addStyleSheet('https://www.archlinexp.com/components/com_icagenda/themes/packs/default/css/default_component.css'); + //icagendaTheme::loadComponentCSS($this->template); + icagendaThemeStyle::addMediaCss($this->template, 'component'); + + // For Dev. + if ($time_loading) { + $endtime_list = iCLibrary::getMicrotime(); + + echo '
      Time to create page: ' . round($endtime_list - $starttime_list, 3) . ' seconds
      '; + } + } + + /** + * Prepares the document. + * + * @return void. + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $pathway = $app->getPathway(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } else { + $this->params->def('page_heading', JText::_('IC_EVENT')); + } + + $title = $this->params->get('page_title', ''); + + $id = (int) @$menu->query['id']; + + // If the menu item does not concern this event + if ($menu && ($menu->query['option'] != 'com_icagenda' || $menu->query['view'] != 'event' || $id != $this->item->id)) { + // If this is not a single event menu item, set the page title to the event title + if ($this->item->title) { + $title = $this->item->title; + } + + $pathway->addItem($this->item->title, ''); + } + + // Check for empty title and add site name if param is set + if (empty($title)) { + $title = $app->get('sitename'); + } elseif ($app->get('sitename_pagetitles', 0) == 1) { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } elseif ($app->get('sitename_pagetitles', 0) == 2) { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + if (empty($title)) { + $title = $this->item->title; + } + + $this->document->setTitle($title); + + if ($this->item->metadesc) { + $this->document->setDescription($this->item->metadesc); + } elseif ($this->params->get('menu-meta_description')) { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + // if ($this->item->metakey) + // { + // $this->document->setMetadata('keywords', $this->item->metakey); + // } + // elseif ($this->params->get('menu-meta_keywords')) + // { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + // } + + if ($this->params->get('robots')) { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + + // if ($app->get('MetaAuthor') == '1') + // { + // $author = $this->item->created_by_alias ? $this->item->created_by_alias : $this->item->author; + // $this->document->setMetaData('author', $author); + // } + + // $mdata = $this->item->metadata->toArray(); + + // foreach ($mdata as $k => $v) + // { + // if ($v) + // { + // $this->document->setMetadata($k, $v); + // } + // } + + // If there is a pagebreak heading or title, add it to the page title + if (!empty($this->item->page_title)) { + $this->item->title = $this->item->title . ' - ' . $this->item->page_title; + $this->document->setTitle( + $this->item->page_title . ' - ' . JText::sprintf('PLG_CONTENT_PAGEBREAK_PAGE_NUM', $this->state->get('list.offset') + 1) + ); + } + + if ($this->print) { + $this->document->setMetaData('robots', 'noindex, nofollow'); + } + + // Open Graph Tags + $eventTitle = icagendaEvent::setMetaTitle($this->item); + $eventType = 'article'; + $eventImage = $this->item->image; + $imgLink = filter_var($eventImage, FILTER_VALIDATE_URL); + $eventUrl = JUri::getInstance()->toString(); + $sitename = $app->getCfg('sitename'); + $og_desc = icagendaEvent::setMetaDesc($this->item); + + if ($app->input->get('tmpl') != 'component') { + if ($eventTitle) { + $this->document->setTitle($title); + $this->document->addCustomTag(''); + } + if ($eventType) { + $this->document->addCustomTag(''); + } + if ($eventImage) { + if ($imgLink) { + $this->document->addCustomTag(''); + } else { + $this->document->addCustomTag(''); + } + } + if ($eventUrl) { + $this->document->addCustomTag(''); + } + if ($og_desc) { + $this->document->setDescription($og_desc); + $this->document->addCustomTag(''); + } + if ($sitename) { + $this->document->addCustomTag(''); + } + } + } +} diff --git a/deployed/icagenda/components/com_icagenda/views/index.html b/deployed/icagenda/components/com_icagenda/views/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/views/list/index.html b/deployed/icagenda/components/com_icagenda/views/list/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/list/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/views/list/tmpl/default.php b/deployed/icagenda/components/com_icagenda/views/list/tmpl/default.php new file mode 100644 index 00000000..1fb2c2ca --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/list/tmpl/default.php @@ -0,0 +1,559 @@ +nextItem)) { + $nextItemDate = explode(' ', $this->nextItem->next); + $nextItemEnd = substr($this->nextItem->enddate, -8); + $nextItemEnd = substr($nextItemEnd, 0, -3); + $nextItemStart = substr($nextItemDate[1], 0, 5); + + $presenters = explode(';', $this->nextItem->presenters); +} + +$pos = strpos($actual_link, '-update-day'); +?> + + + + + + + + + + + + + + +
      +
      +
      + +
      +
      + +
      +
      + +
      +
      +
      +
      + + + + + +
      + params->get('show_page_heading', 1)) : ?> + + + + + event->iCagendaOnListBeforeDisplay; ?> + + + + + + getCfg('sef') != 1) : ?> + + + + + + + params->get('search_filters', '0')) : ?> + loadTemplate('filters'); ?> + + + +
      + + + header; ?> + + + loadTemplate('categories'); ?> + +
      + + + + + + params->get('navposition', 1), array('0', '2'))) : ?> +
      + pagination; ?> +
      + + + +
      + template . ' -->'; ?> + +
      +
      + +
      + items as $k => $item) : + $i++; + + $enddate = substr($item->enddate, -8); + $enddate = substr($enddate, 0, 5); + $date = explode(' ', $item->next); + $rerunStart = explode(' ', $item->rerun); + $rerunEnd = explode(' ', $item->rerunEnd); + + if ($date[0] != $prevDate && $prevDate != '') : ?> +
      + + + + +
      +

      + + + + + <?= $item->title ?> + +

      title ?>

      +
      +
      + +
      +

      shortdesc ?>

      + + lang != '') : ?> +
      +
      + +
      +

      lang ?>

      + + + id == '106') : ?> +

      + SIGN UP +

      + +

      + WATCH +

      + +
      + +
      +
      + + See our previous Expo +
      + + + params->get('atlist', 0) && $this->sharing) : ?> + + + + + params->get('navposition', 1), array('1', '2'))) : ?> +
      + pagination; ?> +
      + + + + + + + event->iCagendaOnListAfterDisplay; ?> + +
      + + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/views/list/tmpl/default.xml b/deployed/icagenda/components/com_icagenda/views/list/tmpl/default.xml new file mode 100644 index 00000000..1300e4e2 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/list/tmpl/default.xml @@ -0,0 +1,422 @@ + + + + + COM_ICAGENDA_LIST_VIEW_DEFAULT_DESC + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      +
      diff --git a/deployed/icagenda/components/com_icagenda/views/list/tmpl/default_categories.php b/deployed/icagenda/components/com_icagenda/views/list/tmpl/default_categories.php new file mode 100644 index 00000000..b195cae4 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/list/tmpl/default_categories.php @@ -0,0 +1,72 @@ +items && $this->cat_description && count($this->getAllDates) > 0 + && (in_array('1', $this->cat_options) || in_array('2', $this->cat_options)) + ) +{ + foreach ($this->items AS $cat) + { + $cat_id = $cat->cat_id; + $cat_title = $cat->cat_title; + $cat_color = $cat->cat_color; + $cat_desc = $cat->cat_desc ? $cat->cat_desc : ' '; + $fontColor = (iCColor::getBrightness($cat_color) == 'bright') ? 'fontColor' : ''; + + array_push($catid_array, $cat_id); + + $array = array($cat_title, $cat_color, $cat_desc, $fontColor); + $comma_separated = implode("::", $array); + + if ( ! in_array($comma_separated, $catinfos_array)) + { + array_push($catinfos_array, $comma_separated); + } + } + +// $cat_result = array_unique($catid_array); + + if (count($catinfos_array)) + { + echo '
      '; + + for ($i = 0; $i < count($catinfos_array); $i++) + { + $cat_getinfos = explode('::', $catinfos_array[$i]); + + if (in_array('1', $this->cat_options)) + { + echo '
      ' . $cat_getinfos['0']; + echo '
      '; + } + + if (in_array('2', $this->cat_options)) + { + echo '
      ' . $cat_getinfos['2'] . '
      '; + } + } + + echo '
      '; + } +} diff --git a/deployed/icagenda/components/com_icagenda/views/list/tmpl/default_filters.php b/deployed/icagenda/components/com_icagenda/views/list/tmpl/default_filters.php new file mode 100644 index 00000000..759a4594 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/list/tmpl/default_filters.php @@ -0,0 +1,319 @@ +input; +$menuParams = $app->getMenu()->getActive()->params; +$iCparams = JComponentHelper::getParams('com_icagenda'); + +JFormHelper::addFieldPath(JPATH_COMPONENT . '/models/fields'); + +// Get Category options +$categories = JFormHelper::loadFieldType('Categories', false); +$categoryOptions = $categories->getOptions(); + +// Get Month options +$month = JFormHelper::loadFieldType('Month', false); +$monthOptions = $month->getOptions(); + +// Get Year options +$year = JFormHelper::loadFieldType('Year', false); +$yearOptions = $year->getOptions(); + +// Params +$menuOptions = ($menuParams->get('search_filters') == 1); +$menuSuffix = $menuOptions ? '_menu' : ''; + +$icfilterDisplay = $menuOptions + ? $this->params->get('filters_display', '2') + : $iCparams->get('filters_display', '2'); + +// Display option (responsive grid or full width) +$icDisplayClass = ($icfilterDisplay == '1') ? ' ic-col-full' : ''; + +// Label "Search" +$icfilterLabel = $menuOptions + ? $this->params->get('filters_label', '1') + : $iCparams->get('filters_label', '1'); + +if ($icfilterLabel) +{ + $icfilterLabel = ($icfilterDisplay == '1') ? '12' : '4'; // 4=columns, 12=full width +} + +// Get config ordering for filters +$default_ordering = 'filter_search,filter_from,filter_to,filter_category,filter_month,filter_year'; +$filter_ordering = $menuOptions + ? $this->params->get('filter_ordering', $default_ordering) + : $iCparams->get('filter_ordering', $default_ordering); +$icfilterList = explode(',', $filter_ordering); + +// Get Filters +$filter_search = $menuOptions + ? ($this->params->get('filter_search', 2) * 6) + : ($iCparams->get('filter_search', 2) * 6); +$filter_from = $menuOptions + ? ($this->params->get('filter_from', 1) * 6) + : ($iCparams->get('filter_from', 1) * 6); +$filter_to = $menuOptions + ? ($this->params->get('filter_to', 1) * 6) + : ($iCparams->get('filter_to', 1) * 6); +$filter_category = $menuOptions + ? ($this->params->get('filter_category', 1) * 6) + : ($iCparams->get('filter_category', 1) * 6); +$filter_month = $menuOptions + ? ($this->params->get('filter_month', 1) * 6) + : ($iCparams->get('filter_month', 1) * 6); +$filter_year = $menuOptions + ? ($this->params->get('filter_year', 1) * 6) + : ($iCparams->get('filter_year', 1) * 6); + +$button_more = 6; + +$filters = $fields = $total = $option1 = $lastMain = '0'; + +foreach ($icfilterList as $filter) +{ + // Filter is disabled + if ( ! ${$filter}) + { + $key = array_search($filter, $icfilterList); + unset($icfilterList[$key]); + } + + // Filter is enabled + else + { + $total = $total + (${$filter} / 6); + + if ($total <= 6) + { + $filters = $filters + 1; + $fields = $fields + (${$filter} / 6); + } + } +} + +$adjustTotal = ($total > 6) ? ($fields - $filters) : '0'; +$countMainFilters = $filters - $adjustTotal; + +$mainFilters = array_slice($icfilterList, 0, $countMainFilters); + +if ($total > 6) +{ + $mainFilters[] = 'button_more'; +} + +$optionsFilters = array_slice($icfilterList, $countMainFilters); + + +// Full Width +if ($icfilterDisplay == 1) +{ + $colList = '12'; + $rowLabel = '1'; + $rowSubmit = '2'; + $rowReset = '1'; + + $colFilters = '12'; + $colMore = '12'; + $colControls = '12'; + $colSubmit = '6'; + $colReset = '6'; +} + +// Responsive Extendable Grid of 12 +else +{ + $colList = $icfilterLabel ? '8' : '12'; + $rows = round($total/2, 0, PHP_ROUND_HALF_UP); + $rowLabel = ($rows <= 3) ? $rows : '3'; + $rowSubmit = ($total > 4) ? '2' : '1'; + $rowReset = '1'; + + $colFilters = '9'; + $colMore = '16'; + $colControls = '3'; + $colSubmit = ($total <= 2) ? '8' : '12'; + $colReset = ($total <= 2) ? '4' : '12'; +} + +$script = array(); + +// Add script declaration +$script[] = ' jQuery(document).ready(function($){'; +$script[] = ' $("#ic-toggle-filters").click(function(){'; +$script[] = ' $("#ic-more-filters").toggle("500",'; +$script[] = ' function(){'; +$script[] = ' if ($(this).is(":visible")) {'; +$script[] = ' $(".ic-filter-more-btn").removeClass("ic-inactive").addClass("ic-active");'; +$script[] = ' $(".ic-filter-more-btn > span").removeClass("iCicon-arrow-down").addClass("iCicon-arrow-up");'; +$script[] = ' } else {'; +$script[] = ' $(".ic-filter-more-btn").removeClass("ic-active").addClass("ic-inactive");'; +$script[] = ' $(".ic-filter-more-btn > span").removeClass("iCicon-arrow-up").addClass("iCicon-arrow-down");'; +$script[] = ' }'; +$script[] = ' }'; +$script[] = ' );'; +$script[] = ' });'; + +foreach ($optionsFilters as $filter) +{ + $script[] = ' if($("#' . $filter . '").val() !== ""){'; + $script[] = ' $("#ic-more-filters").css("display", "block");'; + $script[] = ' $(".ic-filter-more-btn > span").removeClass("iCicon-arrow-down").addClass("iCicon-arrow-up");'; + $script[] = ' $(".ic-filter-more-btn").removeClass("ic-inactive").addClass("ic-active");'; + $script[] = ' }'; +} + +$script[] = ' });'; + + +$script[] = 'jQuery(document).ready(function($){'; + +$script[] = ' $("#icagenda-list").submit(function() {'; +$script[] = ' $(this).find(":input:not([type=hidden])").filter(function(){ return !this.value; }).attr("disabled", "disabled");'; +$script[] = ' return true;'; +$script[] = ' });'; + +$script[] = ' $("#icagenda-list").find(":input:not([type=hidden])").attr("disabled", false);'; + +$script[] = ' $(".ic-filter-reset-btn").click(function(){'; +$script[] = ' $("#icagenda-list").find(":input:not([type=hidden])").val("");'; +$script[] = ' $("#icagenda-list").submit();'; +$script[] = ' });'; + +$script[] = '});'; + + +$document->addScriptDeclaration(implode("\n", $script)); + + +// Filters HTML rendering +$html_filter_search = ''; + +$html_filter_from = $filter_from + ? JHtml::_('calendar', $jinput->get('filter_from'), 'filter_from', 'filter_from', '%Y-%m-%d', + array('placeholder' => JText::_('COM_ICAGENDA_FILTERS_PERIOD_FROM'), 'class' => '')) + : ''; + +$html_filter_to = $filter_to + ? JHtml::_('calendar', $jinput->get('filter_to'), 'filter_to', 'filter_to', '%Y-%m-%d', + array('placeholder' => JText::_('COM_ICAGENDA_FILTERS_PERIOD_TO'), 'class' => '')) + : ''; + +$html_filter_category = ''; + +$html_filter_month = ''; + +$html_filter_year = ''; + +$html_button_more = '
      ' + . JText::_('COM_ICAGENDA_FILTERS_MORE_OPTIONS') + . '
      '; +?> + +
      +
      + + + +
      +
      +
      +
      +
      + + + +
      + + +
      +
      +
      + +
      +
      +
      + + +
      + + + = 6) : ?> + + + +
      +
      + + +
      +
      + +
      +
      +
      +
      + +
      +
      + +
      +
      diff --git a/deployed/icagenda/components/com_icagenda/views/list/tmpl/index.html b/deployed/icagenda/components/com_icagenda/views/list/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/list/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/views/list/view.feed.php b/deployed/icagenda/components/com_icagenda/views/list/view.feed.php new file mode 100644 index 00000000..7fb0636a --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/list/view.feed.php @@ -0,0 +1,118 @@ +getParams(); + $Itemid = $app->input->getInt('Itemid'); + $items = $this->get('Items'); + + $mcatid = $params->get('mcatid', ''); + $filter_category = ! is_array($mcatid) ? array($mcatid) : $mcatid; + + // Set events for the current page + $getAllDates = icagendaEventsData::getAllDates(); + $new_items = array(); + $evt = array(); + + if (count($getAllDates) > 0) + { + $number = JFactory::getConfig()->get('feed_limit', $params->get('number', 5)); + + // Set number of events to be displayed per page + $currentPageDates = array_slice($getAllDates, '0', $number, true); + + foreach ($currentPageDates as $date_id) + { + // Get id and date for each event to be displayed + $ex_date_id = explode('_', $date_id); + $evt[] = $ex_date_id['0']; + $evt_id = $ex_date_id['1']; + + foreach ($items as $item) + { + if ($evt_id == $item->id) + { + $new_items[] = $item; + } + } + } + } + + $items = $new_items; + + foreach ($items as $k => $item) + { + if ( ! in_array('', $filter_category) && ! in_array('0', $filter_category) + && in_array($item->catid, $filter_category) + || in_array('', $filter_category) + || in_array('0', $filter_category) + ) + { + $EVENT_TIME = ($item->displaytime == 1) + ? ' ' . icagendaEvents::dateToTimeFormat($evt[$k]) + : ''; + + // Load individual item creator class. + $feeditem = new JFeedItem; + $feeditem->title = $item->title . ' (' . $item->cat_title . ')'; + $feeditem->link = JROUTE::_('index.php?option=com_icagenda&view=event&Itemid=' + . (int) $Itemid . '&id=' . (int) $item->id . ':' . $item->alias); + $feeditem->image = icagendaThumb::sizeMedium($item->image); + $feeditem->description = icagendaRender::dateToFormat($evt[$k]) . $EVENT_TIME . '
      ' . $item->description; + + // Set date + $timezone = self::getTimeZone(); + $date = new JDate($evt[$k], $timezone); + $date = $date->format('Y-m-d H:i:s', false, false); + + $feeditem->date = $date; + $feeditem->category = $item->cat_title; + + // Loads item information into RSS array + $document->addItem($feeditem); + } + } + } + + /** + * Returns the userTime zone if the user has set one, or the global config one + * @return mixed + */ + public function getTimeZone() + { + $userTz = JFactory::getUser()->get('timezone'); + $timeZone = JFactory::getConfig()->get('offset'); + + if ($userTz) + { + $timeZone = $userTz; + } + + return new DateTimeZone($timeZone); + } +} diff --git a/deployed/icagenda/components/com_icagenda/views/list/view.html.php b/deployed/icagenda/components/com_icagenda/views/list/view.html.php new file mode 100644 index 00000000..d10a3c92 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/list/view.html.php @@ -0,0 +1,305 @@ +input; + + // Loading data + $items = $this->getModel()->getItems(); + $this->state = $this->get('State'); + $this->params = $this->state->get('params'); + $this->getAllDates = icagendaEventsData::getAllDates(); + //$this->nextItem = $this->getModel()->getNextItem(); + $this->timeZones = icagendaEventsData::getAllTimeZone(2); + + if (isset($_GET['success']) && $_GET['success'] == 'success') { + JFactory::getApplication()->enqueueMessage('Thank you for taking time to register.
      + An email with further details has been sent to the email address you provided.
      + We hope you will enjoy the presentations.'); + } + + if (isset($_POST['change_timezone'])) $_SESSION['timezone'] = $_POST['timezone']; + + $offset = substr($_SESSION['timezone'], 0, strpos($_SESSION['timezone'], "_")); + + // icagendaEventsData::changeDate($offset, $this->nextItem->next, $this->nextItem->enddate); + + // Check for errors. + if (count($errors = $this->get('Errors'))) { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + // Shortcut for params + $params = $this->params; + + // For Dev. + $time_loading = $params->get('time_loading', ''); + + if ($time_loading) { + $starttime_list = iCLibrary::getMicrotime(); + } + + $getAllDates = $this->getAllDates; + $number = $params->get('number', 5); + + // Process the content plugins. + if (version_compare(JVERSION, '3.0', 'lt')) { + $this->dispatcher = JDispatcher::getInstance(); + } else { + $this->dispatcher = JEventDispatcher::getInstance(); + } + + JPluginHelper::importPlugin('content'); + + $this->dispatcher->trigger('iCagendaOnListPrepare', array('com_icagenda.list', &$items, &$params, &$getAllDates)); + + // Set events for the current page + $new_items = array(); + $evt = array(); + + if (count($getAllDates) > 0) { + $limit = $jinput->get('limit', ''); + $getpage = $jinput->get('page', 1); + + if ($limit != '' && $limit >= 0) { + $number = ($limit == 0) ? count($getAllDates) : (int) $limit; + } + + // Set number of events to be displayed per page + $index = $number * ($getpage - 1); + $currentPageDates = array_slice($getAllDates, $index, $number, true); + + foreach ($currentPageDates as $date_id) { + // Get id and date for each event to be displayed + $ex_date_id = explode('_', $date_id); + $evt[] = $ex_date_id['0']; + $evt_id = $ex_date_id['1']; + + foreach ($items as $item) { + if ($evt_id == $item->id) { + $new_items[] = $item; + } + } + } + } + + $this->items = $new_items; + $this->evt = $evt; + + foreach ($this->items as $item) { + icagendaEventsData::changeDate($offset, $item->next, $item->enddate); + icagendaEventsData::changeDate($offset, $item->rerun, $item->rerunEnd); + } + + // Load Theme pack layout for list + $this->template = $params->get('template', 'default'); + $themeList = icagendaTheme::getThemeLayout($this->template, 'list'); + + // Check if errors (file missing) + if ($themeList[1]) { + $msg = ($themeList[1] !== 'deprecated') + ? 'iCagenda ' . JText::_('PHPMAILER_FILE_OPEN') . ' ' . $this->template . '_list.php' + : JText::_('COM_ICAGENDA_ERROR_THEME_PACK_OUTDATED') . '
      ' + . JText::sprintf('COM_ICAGENDA_ERROR_THEME_PACK_EDIT_OR_CHANGE', '' + . $this->template . '_list.php'); + + $app->enqueueMessage($msg, 'warning'); + + if ($themeList[1] !== 'alert') { + return false; + } + } + + $this->themeList = $themeList[0]; + + // Component Options + $this->cat_description = ($params->get('displayCatDesc_menu', 'global') == 'global') + ? $params->get('CatDesc_global', '0') + : $params->get('displayCatDesc_menu', ''); + + $cat_options = ($params->get('displayCatDesc_menu', 'global') == 'global') + ? $params->get('CatDesc_checkbox', '') + : $params->get('displayCatDesc_checkbox', ''); + + $this->cat_options = is_array($cat_options) ? $cat_options : array(); + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + + // Set Header and pagination + $countAll = count($getAllDates); + $arrowText = $params->get('arrowtext', 1); + $pagination = $params->get('pagination', 1); + $filters_active = $jinput->get('filter_search') + || $jinput->get('filter_from') + || $jinput->get('filter_to') + || $jinput->get('filter_category') + || $jinput->get('filter_month') + || $jinput->get('filter_year') + ? true + : false; + + $this->header = icagendaList::header($countAll, $number, $filters_active); + $this->pagination = icagendaList::pagination($countAll, $arrowText, $number, $pagination); + $this->sharing = icagendaAddthis::share(); + + + // Define plugin events. + $this->event = new stdClass; + + $results = $this->dispatcher->trigger('iCagendaOnListBeforeDisplay', array('com_icagenda.list', &$this->items, &$this->params)); + $this->event->iCagendaOnListBeforeDisplay = trim(implode("\n", $results)); + + $results = $this->dispatcher->trigger('iCagendaOnListAfterDisplay', array('com_icagenda.list', &$this->items, &$this->params)); + $this->event->iCagendaOnListAfterDisplay = trim(implode("\n", $results)); + + icagendaInfo::commentVersion(); + + $this->_prepareDocument(); + + $this->iclist_vars = 'components/com_icagenda/add/elements/iclist_vars.php'; // icagendaEvent::setVar($evt, $item); + + parent::display($tpl); + + $this->dispatcher->trigger('onListAfterDisplay', array('com_icagenda.list', &$this->items, &$this->params)); // @deprecated. Kept for B/C + + // Loads jQuery Library + if (version_compare(JVERSION, '3.0', 'lt')) { + icagendaThemeJoomla25::loadjQuery(); + } + // Joomla 3 + else { + JHtml::_('bootstrap.framework'); + JHtml::_('jquery.framework'); + } + + // Add CSS + icagendaTheme::loadComponentCSS($this->template); + icagendaThemeStyle::addMediaCss($this->template, 'component'); + + // Loading Script tipTip used for iCtips + JHtml::script('com_icagenda/jquery.tipTip.js', false, true); + + // Add RSS Feeds + $menu = $app->getMenu()->getActive()->id; + + $feed = 'index.php?option=com_icagenda&view=list&Itemid=' . (int) $menu . '&format=feed'; + $rss = array( + 'type' => 'application/rss+xml', + 'title' => 'RSS 2.0', + ); + + $document->addHeadLink(JRoute::_($feed . '&type=rss'), 'alternate', 'rel', $rss); + + // For Dev. + if ($time_loading) { + $endtime_list = iCLibrary::getMicrotime(); + + echo '
      Time to create page: ' . round($endtime_list - $starttime_list, 3) . ' seconds
      '; + } + } + + /** + * Prepares the document + * + * @since 3.6.0 + */ + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $pathway = $app->getPathway(); + $title = null; + $menu = $menus->getActive(); + + if ($menu) { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } else { + $this->params->def('page_heading', JText::_('JGLOBAL_ARTICLES')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) { + $title = $app->getCfg('sitename'); + } elseif ($app->getCfg('sitename_pagetitles', 0) == 1) { + $title = JText::sprintf('JPAGETITLE', $app->getCfg('sitename'), $title); + } elseif ($app->getCfg('sitename_pagetitles', 0) == 2) { + $title = JText::sprintf('JPAGETITLE', $title, $app->getCfg('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description', '')) { + $this->document->setDescription($this->params->get('menu-meta_description', '')); + } + + if ($this->params->get('menu-meta_keywords', '')) { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords', '')); + } + + if ( + $app->getCfg('MetaTitle') == '1' + && $this->params->get('menupage_title', '') + ) { + $this->document->setMetaData('title', $this->params->get('page_title', '')); + } + } +} diff --git a/deployed/icagenda/components/com_icagenda/views/registration/index.html b/deployed/icagenda/components/com_icagenda/views/registration/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/registration/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/components/com_icagenda/views/registration/tmpl/actions.php b/deployed/icagenda/components/com_icagenda/views/registration/tmpl/actions.php new file mode 100644 index 00000000..481d259a --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/registration/tmpl/actions.php @@ -0,0 +1,54 @@ +getUserState('com_icagenda.registration.actions', ''); + +if ($actions) +{ + $layout = new JLayoutFile($actions, $basePath = JPATH_PLUGINS . '/icagenda/' . $actions . '/layouts'); + $displayData = array('item' => $this->item, 'actions' => $this->actions, 'params' => $this->params); + $actionsHTML = $layout->render($displayData); +} +else +{ + $actionsHTML = 'No Action'; +} + +?> +
      + + +
      +
      +input; + +$date_time_separator = ' - '; // @todo: create custom/globalized option +$start_end_separator = ' ➜ '; // @todo: create custom/globalized option + +$iCclass_btn_info = 'ic-btn ic-btn-info button'; + +$eventURL = icagendaEvent::eventURL($this->item); +$listURL = JRoute::_('index.php?option=com_icagenda&view=list&id=' . $input->getInt('id') . '&Itemid=' . $input->getInt('Itemid')); +?> +
      + + + + get('dates_cancelled') && ! $this->participantEventRegistrations) : ?> + +
      + item->title); ?> +
      +
      +
      + +   + +   + +   + +   + +   + +
      +
      + + get('dates_cancelled') && $this->participantEventRegistrations) : ?> +
      +

      + item->title); ?> +

      +
      +
      +
      + + + + + + + + + + + +
      +
      + + + participantEventRegistrations) : ?> + + +
      +
      + +
      + + +
      +
      +

      + item->title); ?> +

      + + + + + + + + +
      +
      + +
      + + cancelled)) : ?> + +
      + item->title); ?> +
      +
      + +
      + + + +
      +

      +
      + + + + +
      +getCfg('sef'); +$eventId = $app->input->getInt('id'); +$menu = $app->getMenu(); + +$lang = JFactory::getLanguage(); + +// Look for the home menu +if (JLanguageMultilang::isEnabled()) +{ + $home = $menu->getDefault($lang->getTag()); +} +else +{ + $home = $menu->getDefault(); +} + +//$regid = $app->input->get('reg'); + +$startDate = icagendaRender::dateToFormat($this->item->startdate); +$startTime = icagendaRender::dateToTime($this->item->startdate); +$endDate = icagendaRender::dateToFormat($this->item->enddate); +$endTime = icagendaRender::dateToTime($this->item->enddate); + +if ( ! $this->registration) +{ + $app->redirect(JRoute::_('index.php?option=com_icagenda&view=event&id=' . $app->input->getInt('id'), false)); +} + +$regDateTime = icagendaRender::dateToFormat($this->registration->date) + . ' - ' . icagendaRender::dateToTime($this->registration->date); + + +$period_set = substr($this->item->startdate, 0, 4); + +$urlDateVar = ''; + +// Registration Type is 'all dates of the event' (single dates + period) +if ($this->registration->period == 1) +{ + $registrationDates = ''; +} + +// Registration Type is 'select list of dates' +// Is a Period (no date, and period = 0) +elseif ($this->registration->date == '' && ! $this->registration->period) +{ + $registrationDates = (iCDate::isDate($this->item->startdate) && iCDate::isDate($this->item->enddate)) +// ? JText::sprintf( 'COM_ICAGENDA_REGISTERED_EVENT_PERIOD', $startDate, $startTime, $endDate, $endTime ) + ? '
      ' . JText::_('COM_ICAGENDA_REGISTRATION_DATES') . ':
      ' + . '
      ' . JText::_('COM_ICAGENDA_PERIOD_FROM') . ' ' . $startDate . ' ' . $startTime + . ' ' . JText::_('COM_ICAGENDA_PERIOD_TO') . ' ' . $endDate . ' ' . $endTime . '
      ' + : ''; +} + +// Registration Type is 'select list of dates' (single dates + period) +// Is a Single date +else +{ +// $registrationDates = JText::sprintf( 'COM_ICAGENDA_REGISTERED_EVENT_DATE', $regDateTime, '' ); + $registrationDates = '
      ' . JText::_('COM_ICAGENDA_REGISTRATION_DATE') . '
      ' + . '
      ' . $regDateTime . '
      '; + + $date_var = ($isSef == '1') ? '?date=' : '&date='; + $urlDateVar = $date_var . icagendaEvent::urlDateVar($this->registration->date); +} + +$eventURL = JRoute::_('index.php?option=com_icagenda&view=event&id=' . $eventId) . $urlDateVar; + +// Complete Page Content +$content = '

      ' . JText::_('COM_ICAGENDA_REGISTRATION_TY') . ' ' . $this->registration->name . ',

      '; // @TODO: name used in sprintf %s +$content.= '

      ' . JText::sprintf('COM_ICAGENDA_REGISTRATION_COMPLETE_CONFIRMED', $this->item->title) . '

      '; + +$content.= '
      '; + +// Currently, only 'Simple Registration' system (in roadmap: 'Paiement' and 'Attend/Not Attend' systems) +$simpleRegSystem = JText::_('COM_ICAGENDA_REGISTRATION_SUMMARY_REGISTRATION'); + +$content.= '' . JText::sprintf('COM_ICAGENDA_REGISTRATION_SUMMARY_LEGEND', $simpleRegSystem) . ''; + + +// Event +$content.= '
      '; +$content.= '
      ' . JText::_('IC_EVENT') . '
      ' + . '
      ' . $this->item->title . '
      '; +$content.= '
      '; + +// Date(s) booked +$content.= '
      '; +$content.= $registrationDates; +$content.= '
      '; + +// Number of tickets booked +$content.= '
      '; +$content.= '
      ' . JText::_('ICAGENDA_REGISTRATION_FORM_PEOPLE') . '
      ' + . '
      ' . $this->registration->people . '
      '; +$content.= '
      '; + +$content.= $this->iCagendaOnRegistrationCompleteDataDisplay; + +$content.= '
      '; + +?> +
      +

      + escape(JText::_('COM_ICAGENDA_REGISTRATION_TITLE')); ?> +

      +
      + +
      +
      + +
      +
      +item; + +// Form Validation (Only Server side validation (1), or Client & Server validation (default)) +$form_validate = ($this->reg_form_validation == 1) ? '' : ' form-validate'; +$novalidate = ($this->reg_form_validation == 1) ? ' novalidate' : ''; + +// Load custom fields +$customFields = icagendaCustomfields::getCustomFields(1, $item->params->get('custom_form', '')); +$listSlugs = icagendaCustomfields::listSlugs($customFields); + +// Terms +$terms = $this->params->get('terms', 0); +$session = JFactory::getSession(); +$ic_submit_tos = $session->get('ic_submit_tos', ''); +?> + +
      + + template . " -->"; ?> + + + icevent_vars; ?> + + + event->iCagendaOnRegistrationBeforeDisplay; ?> + + + themeRegistration; ?> + + + + +
      +

      +
      + + +
      + +
      + + +
      + > + + + +
      + + + form->getFieldset('default'); ?> + + + + name); ?> + + coreFields[$name]) && $this->coreFields[$name] && ! in_array('core_' . $name, $listSlugs)) : ?> + + readonly) : ?> + + description = ''; ?> + form->setFieldAttribute($name, 'description', ''); ?> + + description) : ?> + + ' . JText::_($field->title) . '
      ' . JText::_($field->description)); ?> + '; ?> + form->setFieldAttribute($name, 'description', ''); ?> + + + + + hidden || ($name == 'people' && $item->tickets == 1)) : ?> + form->getInput($name); ?> + +
      +
      + form->getLabel($name); ?> +
      +
      + form->getInput($name); ?> + +
      +
      + + + + + + + + + + params->get('custom_form', ''), $customFields); ?> + + + + description) : ?> + + ' . JText::_($field->title) . '
      ' . JText::_($field->description)); ?> + '; ?> + form->setFieldAttribute($field->slug, 'description', ''); ?> + + + type == 'hidden') : ?> + form->getInput($field->slug); ?> + +
      +
      + form->getLabel($field->slug); ?> +
      +
      + form->getInput($field->slug); ?> + +
      +
      + + slug == 'email' && $this->params->get('emailConfirm', 1)) : ?> +
      +
      + form->getLabel('email2'); ?> +
      +
      + form->getInput('email2'); ?> + +
      +
      + + + + + + + + form->getFieldset('temporary'); ?> + + + + name); ?> + extraFields[$name]) && $this->extraFields[$name]) : ?> + + hidden) : ?> + form->getInput($name); ?> + + renderField(); ?> + + + + + +
      + + + + params->get('participant_name_visibility', ''); ?> + params->get('participant_name_consent', ''); // '0' means Force Name Consent (no consent request in form) ?> + params->get('participant_gravatar_consent', ''); ?> + params->get('participantDisplay') != '3' || $gravatar_consent == '1') + ? $gravatar_consent + : '0'; ?> + + params->get('participantList', 0) && (($name_visibility && $name_consent != '0') || $gravatar_checkbox != '0')) + || $this->params->get('privacy_organiser', 0) + || ($name_visibility && $name_consent == '1') + || $gravatar_checkbox == '1'): ?> + + +
      + + + + + form->renderField('consent_name' . $consent_access, 'consent'); ?> + + + + params->get('participantList', 0))) : ?> + form->renderField('consent_gravatar', 'consent'); ?> + + + + params->get('privacy_organiser', 0)) : ?> + form->renderField('consent_organiser', 'consent'); ?> + + +
      + + + + + params->get('terms', 1)) : ?> + form->renderField('consent_terms', 'consent'); ?> + + + + + form->getFieldset('extra'); ?> + +
      + + + name); ?> + extraFields[$name]) && $this->extraFields[$name]) : ?> + + hidden) : ?> + form->getInput($name); ?> + + renderField(); ?> + + + +
      + + + + + input->getInt('id'); ?> + input->getInt('Itemid'); ?> + form->getFieldset('hidden'); ?> + +
      + + + name); ?> + hidden) : ?> + form->getInput($name, null, ${$name}); ?> + + +
      + + + + + + + +actions + && $item->params->get('registration_actions', 0)) +{ + $registerButton = JText::_('JNEXT'); +} +else +{ + $registerButton = JText::_('COM_ICAGENDA_REGISTRATION_REGISTER_BTN'); + $registerButton = ($registerButton == 'Register') ? JText::_('JREGISTER') : $registerButton; // B/C before 3.6.13 +} +?> + + +
      +
      + + + + + + + + +
      +
      +
      + + + event->iCagendaOnRegistrationAfterDisplay; ?> +
      + +addScriptDeclaration(' + jQuery(document).ready(function(){ + jQuery(".iCFormTip").tipTip({maxWidth: "250px", defaultPosition: "right", edgeOffset: 10}); + }); +'); + +// Disable submit button after first click (TODO : check and simplify) +$document->addScriptDeclaration(' + jQuery(function($) { + $("#icagenda-registration").one("submit", function() { + $(this).find(\'button[type="submit"]\') + .attr("disabled","disabled") + .css({ + "background-color": "transparent", + "color": "grey" + }); + $("#submit").addClass("ic-loader"); + $(".buttonx").css("display", "none"); + }); + }); +'); diff --git a/deployed/icagenda/components/com_icagenda/views/registration/tmpl/index.html b/deployed/icagenda/components/com_icagenda/views/registration/tmpl/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/registration/tmpl/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/components/com_icagenda/views/registration/view.html.php b/deployed/icagenda/components/com_icagenda/views/registration/view.html.php new file mode 100644 index 00000000..08e3cdda --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/registration/view.html.php @@ -0,0 +1,405 @@ +data = $this->get('Data'); + $this->form = $this->get('Form'); + $this->state = $this->get('State'); + $this->item = $this->get('Item'); + $this->registration = $this->get('Registration'); + + $this->participantEventRegistrations = $this->get('ParticipantEventRegistrations'); + + $this->params = $this->state->get('params'); + + $this->coreFields = array( + 'uid' => true, + 'name' => true, + 'email' => true, + 'email2' => true, + 'phone' => $this->params->get('phoneDisplay', 1) ? true : false, + 'date' => true, + 'people' => true, + ); + + $this->extraFields = array( + 'notes' => $this->params->get('notesDisplay', 0) ? true : false, + 'terms' => $this->params->get('terms', 0) ? true : false, + 'captcha' => $this->params->get('reg_captcha', 0) ? true : false, + ); + + // Shortcuts + $params = $this->params; + $item = $this->item; + + // For Dev. + $time_loading = $params->get('time_loading', ''); + + if ($time_loading) + { + $starttime_reg = iCLibrary::getMicrotime(); + } + + // Get Options + $this->reg_captcha = $params->get('reg_captcha', 0); + $this->reg_form_validation = $params->get('reg_form_validation', ''); + + // Check Access + $userLevels = $user->getAuthorisedViewLevels(); + $userGroups = $user->getAuthorisedGroups(); + + $groupid = JComponentHelper::getParams('com_icagenda')->get('approvalGroups', array("8")); + $groupid = is_array($groupid) ? $groupid : array($groupid); + + $uri = JFactory::getUri(); + $return = base64_encode($uri); // Encode Return URL + $rlink = JRoute::_("index.php?option=com_users&view=login&return=$return", false); + + $eventURL = icagendaEvent::eventURL($this->item); + + if ($item == NULL + || $item->state != 1 + || $item->approval == 1 + || $item->params->get('event_cancelled') == 1 + ) + { + $app->enqueueMessage(JTEXT::_('JERROR_LAYOUT_PAGE_NOT_FOUND'), 'error'); + + return false; + } + + // Warning 'Registration closed' if no ticket available for the current form + // @TODO: set this as a content message, replacing the form, and keeping the event info header. + elseif ($app->input->get('layout', 'default') == 'default' + && ( + $item->ticketsBookable <= 0 + || ! icagendaRegistration::upcomingDatesBooking($item) + ) + ) + { + $app->enqueueMessage(JTEXT::_('COM_ICAGENDA_REGISTRATION_CLOSED'), 'warning'); + + $app->redirect($eventURL); + + return false; + } + + // Layout Cancel: not for "actions" plugin yet. // @todo: action cancel request system + elseif ($this->item->params->get('registration_actions') + && $app->input->get('layout', 'default') == 'cancel' + ) + { + $app->enqueueMessage(JTEXT::_('JERROR_LAYOUT_PAGE_NOT_FOUND'), 'error'); + + return false; + } + + // Layout Cancel: logged-in user access only + elseif ( ! $user->id + && $app->input->get('layout', 'default') == 'cancel' + ) + { + $msg = ''; + + // Redirect to login page if user not logged-in to be able to cancel registration. + $msg.= '

      ' . JText::_('IC_AUTH_REQUIRED') . '

      '; + $msg.= '

      ' . JText::_('COM_ICAGENDA_LOGIN_TO_ACCESS_REGISTRATION_CANCELLATION') . '

      '; + + $app->enqueueMessage($msg, ''); + + $app->redirect($rlink); + } + + elseif ( ! in_array('8', $userGroups) + && ! in_array(icagendaRegistration::accessReg($item), $userLevels) + ) + { + if ($user->id) + { + $app->enqueueMessage(JText::_( 'JERROR_LOGIN_DENIED' ), 'warning'); + } + else + { +// $app->enqueueMessage(JText::_( 'JGLOBAL_YOU_MUST_LOGIN_FIRST' ), 'info'); + + // Redirect to login page if no access to registration form. + $msg = '
      '; + $msg.= '

      '; + $msg.= JText::_('IC_AUTH_REQUIRED'); + $msg.= '

      '; + $msg.= '
      '; + $msg.= JText::_("COM_ICAGENDA_LOGIN_TO_ACCESS_REGISTRATION_FORM"); + $msg.= '
      '; + $msg.= '
      '; + $msg.= ''; + $msg.= '
      '; + + // if not login, and registration form not "public". + $app->enqueueMessage($msg); + } + + $app->redirect($rlink); + } + + + // Load Theme Pack layout for event details view. + $this->template = $params->get('template', 'default'); + $themeRegistration = icagendaTheme::getThemeLayout($this->template, 'registration'); + + // Check for Theme Pack errors (layout file missing). + if ($themeRegistration[1]) + { + $msg = ($themeRegistration[1] !== 'deprecated') + ? 'iCagenda ' . JText::_('PHPMAILER_FILE_OPEN') . ' ' . $this->template . '_registration.php' + : JText::_('COM_ICAGENDA_ERROR_THEME_PACK_OUTDATED') . '
      ' . + JText::sprintf('COM_ICAGENDA_ERROR_THEME_PACK_EDIT_OR_CHANGE', '' . $this->template . '_registration.php'); + $app->enqueueMessage($msg, 'warning'); + + if ($themeRegistration[1] !== 'alert') + { + return false; + } + } + + $this->themeRegistration = $themeRegistration[0]; + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + // Check for layout override + $active = JFactory::getApplication()->getMenu()->getActive(); + + if (isset($active->query['layout'])) + { + $this->setLayout($active->query['layout']); + } + + // Process the content plugins. + if (version_compare(JVERSION, '3.0', 'lt')) + { + $this->dispatcher = JDispatcher::getInstance(); + } + else + { + $this->dispatcher = JEventDispatcher::getInstance(); + } + + //JPluginHelper::importPlugin('content'); + JPluginHelper::importPlugin('icagenda'); + + $this->actions = $this->dispatcher->trigger('iCagendaOnRegistrationActions', array('com_icagenda.actions', &$item, &$this->params)); + + $this->dispatcher->trigger('iCagendaOnRegistrationPrepare', array('com_icagenda.registration', &$item, &$this->params)); + + $item->event = new stdClass; + + $results = $this->dispatcher->trigger('iCagendaOnRegistrationBeforeDisplay', array('com_icagenda.registration', &$item, &$this->params)); + $item->event->iCagendaOnRegistrationBeforeDisplay = trim(implode("\n", $results)); + + $results = $this->dispatcher->trigger('iCagendaOnRegistrationAfterDisplay', array('com_icagenda.registration', &$item, &$this->params)); + $item->event->iCagendaOnRegistrationAfterDisplay = trim(implode("\n", $results)); + + $results = $this->dispatcher->trigger('iCagendaOnRegistrationCompleteDataDisplay', array('com_icagenda.registration', &$item, &$this->params)); + $this->iCagendaOnRegistrationCompleteDataDisplay = trim(implode("\n", $results)); + + + // Escape strings for HTML output + $this->pageclass_sfx = htmlspecialchars($this->params->get('pageclass_sfx')); + + icagendaInfo::commentVersion(); + + $this->icevent_vars = 'components/com_icagenda/add/elements/icevent_vars.php'; + + // Common fields + JFormHelper::addFieldPath(JPATH_ADMINISTRATOR . '/components/com_icagenda/utilities/form/field'); + + $this->prepareDocument(); + + parent::display($tpl); + + + // Loads Scripts and CSS + $document = JFactory::getDocument(); + + // Loads jQuery Library + if (version_compare(JVERSION, '3.0', 'lt')) + { + icagendaThemeJoomla25::loadjQuery(); + } + // Joomla 3 + else + { + JHtml::_('bootstrap.framework'); + JHtml::_('jquery.framework'); + } + + // iCagenda scripts (radio buttons...) + JHtml::script('com_icagenda/icagenda.js', false, true); + + // Loading tipTip Library used for iCtips + JHtml::script('com_icagenda/jquery.tipTip.js', false, true); + + // iCagenda Script validation for Registration form (1) +// if ( ! $this->reg_form_validation) +// { +// $iCheckForm = icagendaForm::submit(1); +// $document->addScriptDeclaration($iCheckForm); +// } + + // Add custom handler to check both the emails (Email and Confirm Email) are same +// $document->addScriptDeclaration('jQuery(document).ready(function(){ +// document.formvalidator.setHandler("emailverify", function (value) { +// var email = document.getElementById("reg_email"); +// var email2 = document.getElementById("reg_email2"); +// return (email.value === email2.value); +// }); +// });'); + + // Add CSS + icagendaTheme::loadComponentCSS($this->template); + icagendaThemeStyle::addMediaCss($this->template, 'component'); + + // For Dev. + if ($time_loading) + { + $endtime_reg = iCLibrary::getMicrotime(); + + echo '
      Time to create page: ' . round($endtime_reg-$starttime_reg, 3) . ' seconds
      '; + } + } + + /** + * Prepares the document. + * + * @return void + * + * @since 3.6.0 + */ + protected function prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $pathway = $app->getPathway(); + $title = null; + + // Because the application sets a default page title, + // we need to get it from the menu item itself + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('COM_ICAGENDA_REGISTRATION_TITLE')); + } + + $title = $this->params->get('page_title', ''); + + $id = (int) @$menu->query['id']; + + // If the menu item does not concern this event + if ($menu && ($menu->query['option'] != 'com_icagenda' || $menu->query['view'] != 'registration' || $id != $this->item->id)) + { + // If this is not a single event menu item, set the page title to the event title + if ($this->item->title) + { + $title = $this->item->title; + } + + $pathway->addItem($this->item->title . ' (' . JText::_('COM_ICAGENDA_REGISTRATION_TITLE') . ')', ''); + } + + if (empty($title)) + { + $title = $app->get('sitename'); + } + elseif ($app->get('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title); + } + elseif ($app->get('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename')); + } + + $this->document->setTitle($title . ' - ' . JText::_('COM_ICAGENDA_REGISTRATION_TITLE')); + + if ($this->params->get('menu-meta_description')) + { + $this->document->setDescription($this->params->get('menu-meta_description')); + } + + if ($this->params->get('menu-meta_keywords')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords')); + } + + if ($this->params->get('robots')) + { + $this->document->setMetadata('robots', $this->params->get('robots')); + } + } +} diff --git a/deployed/icagenda/components/com_icagenda/views/submit/index.html b/deployed/icagenda/components/com_icagenda/views/submit/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/submit/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/views/submit/tmpl/default.php b/deployed/icagenda/components/com_icagenda/views/submit/tmpl/default.php new file mode 100644 index 00000000..2bd311ee --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/submit/tmpl/default.php @@ -0,0 +1,1372 @@ +getParams(); +$maps_service = $iCparams->get('maps_service', ''); + +// Get User Info (Access Levels, id, email) +$userLevels = $user->getAuthorisedViewLevels(); +$u_id = $user->get('id'); +$u_mail = $user->get('email'); + +// Get Access Levels to the form +$accessDefault = array('2'); +$submitAccess = $iCparams->get('submitAccess', $accessDefault); + +// Get Content of the page for not logged-in users +$NotLoginDefault = JText::_( 'COM_ICAGENDA_EVENT_SUBMISSION_ACCESS' ).'
      '; +$submitNotLogin = $iCparams->get('submitNotLogin', ''); + +if ($submitNotLogin == 2) +{ + $submitNotLogin_Content = $iCparams->get('submitNotLogin_Content', $NotLoginDefault); +} +else +{ + $submitNotLogin_Content = $NotLoginDefault; +} + +// Get Content of the page for not authorised logged-in users +$NoRightsDefault = JText::_( 'COM_ICAGENDA_EVENT_SUBMISSION_NO_RIGHTS' ).'
      '; +$submitNoRights = $iCparams->get('submitNoRights', ''); +if ($submitNoRights == 2) +{ + $submitNoRights_Content = $iCparams->get('submitNoRights_Content', $NoRightsDefault); +} +else +{ + $submitNoRights_Content = $NoRightsDefault; +} + +// Control: if access level, set true to display form +$AccessForm = false; + +foreach ($submitAccess AS $ac) +{ + if ( in_array($ac, $userLevels )) + { + $AccessForm = true; + } +} + +// Set Return Page +$uri = JFactory::getURI(); +$return = base64_encode($uri); // Encode Return URL +$rlink = JRoute::_("index.php?option=com_users&view=login&return=$return", false); + +// Loading Submission Page +if ( !$u_id && !in_array('1', $submitAccess )) +{ + // if not login, and submission form not "public" + $app->enqueueMessage($submitNotLogin_Content, 'info'); + $app->redirect($rlink); + +} +elseif (!$AccessForm) +{ + // if No Access Permissions + $app->enqueueMessage($submitNoRights_Content, 'info'); + $app->redirect($rlink); + +} +else +{ + // Display Form + + // Set name or username for logged-in user + $nameJoomlaUser = $iCparams->get('nameJoomlaUser', 1); + if ($nameJoomlaUser == 1) + { + $u_name=$user->get('name'); + } + else + { + $u_name=$user->get('username'); + } + + // Autofill name and email if registered user log in + $autofilluser = $iCparams->get('autofilluser', 1); + if ($autofilluser != 1) + { + $u_name=''; + $u_mail=''; + } + + $theme = $this->template; +// $infoimg = JURI::root().'components/com_icagenda/themes/packs/default/images/info.png'; + + JText::script('COM_ICAGENDA_TERMS_OF_SERVICE_NOT_CHECKED_SUBMIT_EVENT'); + JText::script('COM_ICAGENDA_FORM_NO_DATES_ALERT'); + + $period_display = $this->submit_periodDisplay; + $weekdays_display = $this->submit_weekdaysDisplay; + $dates_display = $this->submit_datesDisplay; + $displaytime_display = $this->submit_displaytimeDisplay; + $displaytime_default = $iCparams->get('displaytime', '1'); + + $tos = $iCparams->get('tos', 1); + + // Set Tooltips + $icTip_name = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_SUBMIT_FORM_USER_NAME' ) . '
      ' . JText::_( 'COM_ICAGENDA_SUBMIT_FORM_USER_NAME_DESC' ) . ''); + $icTip_Uemail = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_SUBMIT_FORM_USER_EMAIL' ) . '
      ' . JText::_( 'COM_ICAGENDA_SUBMIT_FORM_USER_EMAIL_DESC' ) . ''); + $icTip_title = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENT_TITLE' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENT_TITLE' ) . ''); + $icTip_category = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENT_CATID' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENT_CATID' ) . ''); + $icTip_image = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENT_IMAGE' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENT_IMAGE' ) . ''); + $icTip_startD = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENTPERIOD_START' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENTPERIOD_START' ) . ''); + $icTip_endD = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENTPERIOD_END' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENTPERIOD_END' ) . ''); + $icTip_weekDays = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_WEEK_DAYS_INFO_TITLE' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_WEEK_DAYS_INFO_DESC' ) . ''); + $icTip_displayTime = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_DISPLAY_TIME_LABEL' ) . '
      ' . JText::_( 'COM_ICAGENDA_DISPLAY_TIME_DESC' ) . ''); + $icTip_venue = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENT_VENUE' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENT_VENUE' ) . ''); + $icTip_email = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENT_EMAIL' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENT_EMAIL' ) . ''); + $icTip_phone = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENT_PHONE' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENT_PHONE' ) . ''); + $icTip_website = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENT_WEBSITE' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENT_WEBSITE' ) . ''); + $icTip_file = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_FORM_LBL_EVENT_FILE' ) . '
      ' . JText::_( 'COM_ICAGENDA_FORM_DESC_EVENT_FILE' ) . ''); + $icTip_reg = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_REGISTRATION_LABEL' ) . '
      ' . JText::_( 'COM_ICAGENDA_REGISTRATION_DESC' ) . ''); + $icTip_tickets = htmlspecialchars('' . JText::_( 'COM_ICAGENDA_MAX_REGISTRATIONS_LABEL' ) . '
      ' . JText::_( 'COM_ICAGENDA_MAX_REGISTRATIONS_DESC' ) . ''); + + $session = JFactory::getSession(); + $address_session = $session->get('ic_submit_address', ''); + $ic_submit_tos = $session->get('ic_submit_tos', ''); + $post = $session->get('ic_submit', ''); + + $post_username = $post ? $post->username : ''; + $post_created_by_email = $post ? $post->created_by_email : ''; + $post_title = $post ? $post->title : ''; + $post_image = $post ? $post->image : ''; + $post_startdate = $post ? $post->startdate : '0000-00-00 00:00:00'; + $post_enddate = $post ? $post->enddate : '0000-00-00 00:00:00'; + $post_weekdays = $post ? explode(',', $post->weekdays) : array(); + $post_displaytime = $post ? $post->displaytime : '1'; + $post_desc = $post ? $post->desc : ''; + $post_venue = $post ? $post->place : ''; + $post_email = $post ? $post->email : ''; + $post_phone = $post ? $post->phone : ''; + $post_website = $post ? $post->website : ''; + $post_file = $post ? $post->file : ''; + $post_address = $post ? $post->address : ''; + $post_lat = $post ? $post->lat : '0'; + $post_lng = $post ? $post->lng : '0'; + $post_params = $post ? $post->params : ''; + + if ($post_params) + { +// foreach ($post_image as $key => $value) +// { +// $post_img[$key] = $value; +// } + + $post_params = json_decode( $post_params, true ); + + foreach ($post_params as $key => $value) + { + $post_param[$key] = $value; + } + } + + $params = $this->form->getFieldsets('params'); + + + // Set default values for Google Maps + // ZOOM + $zoom = '16'; + // HYBRID, ROADMAP, SATELLITE, TERRAIN + $mapTypeId = 'ROADMAP'; + + $coords = $post_lat . ', ' . $post_lng; + $lat = '0'; + $lng = '0'; + $zoom = $post ? '16' : '1'; + + // Form Validation + $novalidate = ($this->submit_form_validation == 1) ? ' novalidate' : ''; + $form_validate = ($this->submit_form_validation == 1) ? '' : ' form-validate'; + $iCheckForm = ($this->submit_form_validation == 1) ? '' : ' onsubmit="return iCheckForm();"'; + ?> + + + + +
      + params->get('show_page_heading', 1)) : ?> +

      + escape($this->params->get('page_heading')); ?> +

      + + + + pluginEvent->iCagendaOnSubmitBeforeDisplay; ?> + +
      > +
      + +
      +
      +
      + +
      +
      + escape($u_name).'" size="40" class="input-large required" aria-required="true" readonly="true" />'; + } + else + { + echo ''; + } + ?> + '; ?> +
      +
      +
      +
      + +
      +
      + escape($u_mail) . '" size="40" class="input-large required" aria-required="true" readonly="true" />'; + } + else + { + echo ''; + } + ?> + '; ?> +
      +
      +
      +
       
      + + + +
      +
      +
      + +
      +
      + + '; ?> +
      +
      +
      +
      + +
      +
      + form->getInput('catid'); ?> + '; ?> +
      +
      + submit_imageDisplay) : ?> +
      +
      + +
      +
      + + form->getInput('image'); ?> + '; ?> + + '; ?> + '; ?> + +
      +
      +
      + +
      +
       
      + + + +
      + +

      +
      +
      + +
      +
      + getTag() == 'fa-IR') : ?> + + + + + '; ?> +
      +
      +
      +
      + +
      +
      + getTag() == 'fa-IR') : ?> + + + + + '; ?> +
      +
      + +
      +
      + form->getLabel('weekdays'); ?> +
      +
      + + form->getInput('weekdays'); ?> + + + + '; ?> +
      +
      + + + + +

      +
      + form->getInput('dates'); ?> +
      + + + +

      + +
      +
      + '; ?> + ' . JText::_('JHIDE') . ''; ?> + '; ?> + ' . JText::_('JSHOW') . ''; ?> +
      + '; ?> +
      + + '; ?> + + + form->getInput('next'); ?> +
      +
       
      + + + submit_descDisplay + || $this->submit_shortdescDisplay + || $this->submit_metadescDisplay) : ?> + +
      + + + submit_shortdescDisplay) : ?> +
      +

      '; ?>

      + form->getInput('shortdesc'); ?> +
      + + + + submit_descDisplay) : ?> +
      +

      '; ?>

      +
      + '; + echo $editor->display("desc", $post_desc, "100%", "300", "300", "20", 1, null, null, null, array('mode' => 'advanced')); + echo '
      '; + } + else + { + echo $this->form->getInput('desc'); + } + ?> +
      +
       
      +
      + + + + submit_metadescDisplay) : ?> +
      +

      '; ?>

      + form->getInput('metadesc'); ?> +
      + + + +
      +
       
      + + + + submit_venueDisplay + OR $this->submit_emailDisplay + OR $this->submit_phoneDisplay + OR $this->submit_websiteDisplay + OR $this->submit_fileDisplay + OR $this->submit_customfieldsDisplay) : ?> + +
      + + + submit_venueDisplay) : ?> +

      +
      +
      + +
      +
      + '; + } + else + { + echo $this->form->getInput('place'); + } + ?> + '; ?> +
      +
      + + + + submit_emailDisplay + OR $this->submit_phoneDisplay + OR $this->submit_websiteDisplay) : ?> +

      + + + submit_emailDisplay) : ?> +
      +
      + +
      +
      + '; + } + else + { + echo $this->form->getInput('email'); + } + ?> + '; ?> +
      +
      + + + + submit_phoneDisplay) : ?> +
      +
      + +
      +
      + '; + } + else + { + echo $this->form->getInput('phone'); + } + ?> + '; ?> +
      +
      + + + + submit_websiteDisplay) : ?> +
      +
      + +
      +
      + '; + } + else + { + echo $this->form->getInput('website'); + } + ?> + '; ?> +
      +
      + + + + + + submit_customfieldsDisplay) : ?> + + + + + + + +

      + + +
      + + + + description) : ?> + + ' . JText::_($field->title) . '
      ' . JText::_($field->description)); ?> + '; ?> + form->setFieldAttribute($field->slug, 'description', ''); ?> + + + type == 'hidden') : ?> + input;?> + +
      +
      + form->getLabel($field->slug); ?> +
      +
      + form->getInput($field->slug);?> + +
      +
      + + +
      + + + + + submit_fileDisplay) : ?> +

      +
      +
      + +
      +
      + + '; ?> + + + form->getInput('file'); ?> + '; ?> + +
      +
      + +
      +
       
      + + + + submit_gmapDisplay) : ?> + +
      +
      +
      + +
      +
      +
      +
      + form->getLabel('address'); ?> +
      +
      + '; + } + ?> + form->getInput('address'); ?> +
      +
      +
      + + +
      + + +
      +
      +
      +
      + form->getLabel('address'); ?> +
      +
      + '; + } + ?> +
      + form->getInput('address'); ?> + +
      +
      +
      +
      +
      + + get('googlemaps_embed_key', '') . '&q=' . urlencode(strip_tags($address_session)) . '" allowfullscreen>'; ?> + +
      + +
      + + +
      +

      +
      + +
      + +
      +
      +
      +
      +
      + '; + } + ?> +
      + form->getLabel('address'); ?> +
      + form->getInput('address'); ?> +
      +
      + form->getInput('city'); ?> +
      +
      + form->getInput('country'); ?> +
      +
      + form->getInput('lat'); ?> +
      +
      + form->getInput('lng'); ?> +
      +
      +
      +
      +
      +

      Map

      + +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
       
      + + + + submit_regoptionsDisplay) : ?> + +
      + + get('statutReg', '0'); + $checked_0 = ($statutReg == '0') ? ' checked="checked"' : ''; + $checked_1 = ($statutReg == '1') ? ' checked="checked"' : '';; + $maxReg = ''; + } + ?> + + +
      +
      + +
      +
      +
      + '; ?> + ' . JText::_('JOFF') . ''; ?> + '; ?> + ' . JText::_('JON') . ''; ?> +
      + '; ?> +
      +
      + + +
      +
      + +
      +
      + '; ?> + '; ?> +
      +
      + + $fieldSet) : ?> + name == 'registrations') : ?> + description) && trim($fieldSet->description)) : ?> +

      escape(JText::_($fieldSet->description));?>

      + + + + + form->getFieldset($name) as $field) : ?> + name); ?> + + form->setValue($nameshort, 'params', $post_params[$nameshort]); ?> + + + + + form->getFieldset($name) as $field) : ?> + name); ?> +
      +
      + label; ?> +
      +
      + value = $post_param[$nameshort]; + } + ?> + input; ?> +
      +
      + + + +
      +
       
      + + + +
      + form->getInput('alias'); ?> + form->getInput('id'); ?> + form->getInput('created_by'); ?> + form->getInput('created_by_alias'); ?> + form->getInput('created'); ?> + form->getInput('checked_out'); ?> + form->getInput('checked_out_time'); ?> + toString(); + $menu = JFactory::getApplication()->getMenu(); + $current_menu = $menu->getActive(); + ?> + + + + + +
      + + +
      + + + submit_captcha != '0') : ?> +
      +
      + +
      +
      + form->getInput('captcha'); ?> +
      +
      +
      + + + + + + + + + + +
      + get('sitename'); + } else { + $sitename = $config->getValue('config.sitename'); + } + + // Tos Type + $iCparams = JComponentHelper::getParams('com_icagenda'); + $tos_Type = $iCparams->get('tos_Type', ''); + $tosArticle = $iCparams->get('tosArticle', ''); + $tosContent = $iCparams->get('tosContent', ''); + + $tosDEFAULT = JText::sprintf( 'COM_ICAGENDA_TOS', $sitename, $sitename); + $tosARTICLE = 'index.php?option=com_content&view=article&id=' . $tosArticle . '&tmpl=component'; + $tosCUSTOM = $tosContent; + + ?> +
      +
      + +
      + '; + } + elseif ($tos_Type == 2) + { + echo '
      '; + echo $tosCUSTOM; + echo '
      '; + } + else + { + echo '
      '; + echo $tosDEFAULT; + echo '
      '; + } + ?> + +
      +

      + + * +

      +
      + + + submit_captcha != '0') : ?> +
      +
      + +
      +
      + form->getInput('captcha'); ?> +
      +
      +
      + + +
      + + + + + +
      + +
      + +
      +
      + + + + pluginEvent->iCagendaOnSubmitAfterDisplay; ?> +
      + + + get('timeformat', 1) == 2) ? 'true' : ''; + $firstDay = $iCparams->get('firstday_week_global', 1); + ?> + + + submit_imageMaxSize; + + // Script to test Text Counter limit on mouse move and on scroll + $ic_max_com_shortdesc = JComponentHelper::getParams('com_icagenda')->get('char_limit_short_description', '100'); + $ic_max_shortdesc = $this->params->get('char_limit_short_description', '100'); + $ic_max_shortdesc = ($ic_max_com_shortdesc >= $ic_max_shortdesc) ? $ic_max_shortdesc : $ic_max_com_shortdesc; + + $ic_max_com_metadesc = JComponentHelper::getParams('com_icagenda')->get('char_limit_meta_description', '320'); + $ic_max_metadesc = $this->params->get('char_limit_meta_description', '320'); + $ic_max_metadesc = ($ic_max_com_metadesc >= $ic_max_metadesc) ? $ic_max_metadesc : $ic_max_com_metadesc; + + $script = ''; + + echo $script; + ?> + + + + submit_gmapDisplay && $maps_service == '3') : ?> + + + + clear('ic_submit'); + $session->clear('custom_fields'); + $session->clear('ic_submit_dates'); + $session->clear('ic_submit_catid'); + $session->clear('ic_submit_shortdesc'); + $session->clear('ic_submit_metadesc'); + $session->clear('ic_submit_city'); + $session->clear('ic_submit_country'); + $session->clear('ic_submit_lat'); + $session->clear('ic_submit_lat'); + $session->clear('ic_submit_address'); + $session->clear('ic_submit_tos'); + $session->clear('email2'); + + // Script validation for Submit Event form (2) + if (!$this->submit_form_validation) + { + $iCheckForm = icagendaForm::submit(2); + JFactory::getDocument()->addScriptDeclaration($iCheckForm); + } + + // RTL css if site language is RTL + $lang = JFactory::getLanguage(); + + if ( $lang->isRTL() + && file_exists( JPATH_SITE . $css_com_rtl) ) + { + $document->addStyleSheet( JURI::base( true ) . $css_com_rtl ); + } + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::stylesheet( 'com_icagenda/icagenda-front.j25.css', false, true ); + + JHtml::_('behavior.framework'); + + // load jQuery, if not loaded before (NEW VERSION IN 1.2.6) + $scripts = array_keys($document->_scripts); + $scriptFound = false; + $scriptuiFound = false; + $mapsgooglescriptFound = false; + + for ($i = 0; $i < count($scripts); $i++) + { + if (stripos($scripts[$i], 'jquery.min.js') !== false) + { + $scriptFound = true; + } + // load jQuery, if not loaded before as jquery - added in 1.2.7 + if (stripos($scripts[$i], 'jquery.js') !== false) + { + $scriptFound = true; + } + if (stripos($scripts[$i], 'jquery-ui.min.js') !== false) + { + $scriptuiFound = true; + } + if (stripos($scripts[$i], 'maps.google') !== false) + { + $mapsgooglescriptFound = true; + } + } + + // jQuery Library Loader + if (!$scriptFound) + { + // load jQuery, if not loaded before + if (!JFactory::getApplication()->get('jquery')) + { + JFactory::getApplication()->set('jquery', true); + // add jQuery + $document->addScript('https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); + JHtml::script('com_icagenda/jquery.noconflict.js', false, true); + } + } + + if (!$scriptuiFound) + { + $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); + } + } + // Joomla 3 + else + { + JHtml::_('bootstrap.framework'); + JHtml::_('jquery.framework'); + + /** + * Change jQuery UI version from 1.9.2 to 1.8.23 (joomla version, but not complete) + * to prevent a conflict in tooltip that appeared since Joomla 3.1.4 + */ +// $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); + $document->addScript( 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js' ); + } + + // Google Maps api V3 + if ($this->submit_gmapDisplay && $maps_service == '3') + { + icagendaGooglemaps::loadGMapScripts('edit'); + } + + /** + * Script files which could be overridden into your site template. + * (eg. /templates/my_template/js/com_icagenda/FILE_NAME.js) + */ + JHtml::script( 'com_icagenda/timepicker.js', false, true ); + JHtml::script( 'com_icagenda/icdates.js', false, true ); + JHtml::script( 'com_icagenda/jquery.tipTip.js', false, true ); + JHtml::script( 'com_icagenda/icagenda.js', false, true ); + JHtml::script( 'com_icagenda/icform.js', false, true ); + + $iCtip = array(); + $iCtip[] = ' jQuery(document).ready(function(){'; + $iCtip[] = ' jQuery(".iCFormTip").tipTip({maxWidth: "280px", defaultPosition: "right", edgeOffset: 5});'; + $iCtip[] = ' });'; + + // Add the script to the document head. + JFactory::getDocument()->addScriptDeclaration(implode("\n", $iCtip)); +} diff --git a/deployed/icagenda/components/com_icagenda/views/submit/tmpl/default.xml b/deployed/icagenda/components/com_icagenda/views/submit/tmpl/default.xml new file mode 100644 index 00000000..661bd780 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/submit/tmpl/default.xml @@ -0,0 +1,326 @@ + + + + COM_ICAGENDA_SUBMIT_VIEW_DEFAULT_DESC + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + +
      diff --git a/deployed/icagenda/components/com_icagenda/views/submit/tmpl/index.html b/deployed/icagenda/components/com_icagenda/views/submit/tmpl/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/submit/tmpl/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/components/com_icagenda/views/submit/tmpl/send.php b/deployed/icagenda/components/com_icagenda/views/submit/tmpl/send.php new file mode 100644 index 00000000..5136a4d4 --- /dev/null +++ b/deployed/icagenda/components/com_icagenda/views/submit/tmpl/send.php @@ -0,0 +1,113 @@ +getMenu(); + +$lang = JFactory::getLanguage(); + +// Look for the home menu +if (JLanguageMultilang::isEnabled()) +{ + $home = $menu->getDefault($lang->getTag()); +} +else +{ + $home = $menu->getDefault(); +} + +// Get the site name +$sitename = $app->getCfg('sitename'); + +// Get Component Global Options +$iCparams = JComponentHelper::getParams('com_icagenda'); + +// Get Authorized user groups (approval managers) +$approvalGroups = $iCparams->get('approvalGroups', array("8")); + +// Get User +$user = JFactory::getUser(); +$u_id = $user->get('id'); + +// Control: if Manager +jimport( 'joomla.access.access' ); +$adminUsersArray = array(); + +foreach ($approvalGroups AS $ag) +{ + $adminUsers = JAccess::getUsersByGroup($ag, False); + $adminUsersArray = array_merge($adminUsersArray, $adminUsers); +} + +$isManager = in_array($u_id, $adminUsersArray) ? true : false; + +//$urllink = JURI::getInstance()->toString(); +//$urllink = preg_replace('/&view=[^&]*/', '', $urllink); +//$urlNewEvent = preg_replace('/&layout=[^&]*/', '', $urllink); +$urlNewEvent = str_replace('&', '&', JRoute::_('index.php?option=com_icagenda&view=submit')); + +// clear the data so we don't process it again +$session = JFactory::getSession(); +$session->clear('ic_submit'); +$session->clear('custom_fields'); +$session->clear('ic_submit_dates'); +$session->clear('ic_submit_catid'); +$session->clear('ic_submit_shortdesc'); +$session->clear('ic_submit_metadesc'); +$session->clear('ic_submit_city'); +$session->clear('ic_submit_country'); +$session->clear('ic_submit_lat'); +$session->clear('ic_submit_lat'); +$session->clear('ic_submit_address'); +$session->clear('ic_submit_tos'); +$session->clear('email2'); +?> + +
      + +
      +
      +
      + +
      + +
      +
      +input; + + // Initialiase variables. + $this->state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + if (version_compare(JVERSION, '3.2', 'lt')) + { + if (JRequest::get('POST')) $this->get('data'); + } + else + { + if ($jinput->post->getArray()) $this->get('data'); + } + + // loading params + $params = $app->getParams(); + + // Shortcuts + $item = $this->item; + + $this->template = $params->get('template'); + $this->title = $params->get('title'); + $this->format = $params->get('format'); + $this->copy = $params->get('copy'); + + $this->submit_imageDisplay = $params->get('submit_imageDisplay', 1); + $this->submit_periodDisplay = $params->get('submit_periodDisplay', 1); + $this->submit_weekdaysDisplay = $params->get('submit_weekdaysDisplay', 1); + $this->submit_datesDisplay = $params->get('submit_datesDisplay', 1); + $this->submit_displaytimeDisplay = $params->get('submit_displaytimeDisplay', 0); + $this->submit_shortdescDisplay = $params->get('submit_shortdescDisplay', 1); + $this->submit_descDisplay = $params->get('submit_descDisplay', 1); + $this->submit_metadescDisplay = $params->get('submit_metadescDisplay', 0); + $this->submit_venueDisplay = $params->get('submit_venueDisplay', 1); + $this->submit_emailDisplay = $params->get('submit_emailDisplay', 1); + $this->submit_phoneDisplay = $params->get('submit_phoneDisplay', 1); + $this->submit_websiteDisplay = $params->get('submit_websiteDisplay', 1); + $this->submit_customfieldsDisplay = $params->get('submit_customfieldsDisplay', 1); + $this->submit_fileDisplay = $params->get('submit_fileDisplay', 1); + $this->submit_gmapDisplay = $params->get('submit_gmapDisplay', 1); + $this->submit_regoptionsDisplay = $params->get('submit_regoptionsDisplay', 1); + $this->statutReg = $params->get('statutReg', 0); + $this->ShortDescLimit = $params->get('ShortDescLimit', '160'); + $this->submit_imageMaxSize = $params->get('submit_imageMaxSize', '800'); + $this->submit_captcha = $params->get('submit_captcha', 0); + $this->submit_form_validation = $params->get('submit_form_validation', ''); + + $this->params = $this->state->get('params'); + $this->iCparams = $this->params; + + // Process the content plugins. + if (version_compare(JVERSION, '3.0', 'lt')) + { + $this->dispatcher = JDispatcher::getInstance(); + } + else + { + $this->dispatcher = JEventDispatcher::getInstance(); + } + + JPluginHelper::importPlugin('content'); + $this->dispatcher->trigger('iCagendaOnSubmitPrepare', array ('com_icagenda.submit', &$item, &$this->params)); + + $this->pluginEvent = new stdClass; + + $results = $this->dispatcher->trigger('iCagendaOnSubmitBeforeDisplay', array('com_icagenda.submit', &$item, &$this->params)); + $this->pluginEvent->iCagendaOnSubmitBeforeDisplay = trim(implode("\n", $results)); + + $results = $this->dispatcher->trigger('iCagendaOnSubmitAfterDisplay', array('com_icagenda.submit', &$item, &$this->params)); + $this->pluginEvent->iCagendaOnSubmitAfterDisplay = trim(implode("\n", $results)); + + + $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx')); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + + return false; + } + + $this->_prepareDocument(); + + icagendaInfo::commentVersion(); + + parent::display($tpl); + + // Add CSS + icagendaTheme::loadComponentCSS($this->template); + icagendaThemeStyle::addMediaCss($this->template, 'component'); + + icagendaForm::loadDateTimePickerJSLanguage(); + + $jlayout = $jinput->get('layout', ''); + $layouts_array = array('event', 'registration'); + $layout = in_array($jlayout, $layouts_array) ? $jlayout : ''; + + if ( ! $layout || $layout == 'submit') + { + JHtml::stylesheet('com_icagenda/icagenda.css', false, true); + JHtml::stylesheet('com_icagenda/jquery-ui-1.8.17.custom.css', false, true); + } + } + + + protected function _prepareDocument() + { + $app = JFactory::getApplication(); + $menus = $app->getMenu(); + $pathway = $app->getPathway(); + + $title = null; + $menu = $menus->getActive(); + + if ($menu) + { + $this->params->def('page_heading', $this->params->get('page_title', $menu->title)); + } + else + { + $this->params->def('page_heading', JText::_('JGLOBAL_ARTICLES')); + } + + $title = $this->params->get('page_title', ''); + + if (empty($title)) + { + $title = $app->getCfg('sitename'); + } + elseif ($app->getCfg('sitename_pagetitles', 0) == 1) + { + $title = JText::sprintf('JPAGETITLE', $app->getCfg('sitename'), $title); + } + elseif ($app->getCfg('sitename_pagetitles', 0) == 2) + { + $title = JText::sprintf('JPAGETITLE', $title, $app->getCfg('sitename')); + } + + $this->document->setTitle($title); + + if ($this->params->get('menu-meta_description', '')) + { + $this->document->setDescription($this->params->get('menu-meta_description', '')); + } + + if ($this->params->get('menu-meta_keywords', '')) + { + $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords', '')); + } + + if ($app->getCfg('MetaTitle') == '1' + && $this->params->get('menupage_title', '')) + { + $this->document->setMetaData('title', $this->params->get('page_title', '')); + } + } +} diff --git a/deployed/icagenda/libraries/ic_library/LICENSE.txt b/deployed/icagenda/libraries/ic_library/LICENSE.txt new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/deployed/icagenda/libraries/ic_library/color/color.php b/deployed/icagenda/libraries/ic_library/color/color.php new file mode 100644 index 00000000..315e943b --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/color/color.php @@ -0,0 +1,122 @@ + '125') ? 'bright' : 'dark'; + } + else + { + return false; + } + } +} diff --git a/deployed/icagenda/libraries/ic_library/color/index.html b/deployed/icagenda/libraries/ic_library/color/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/color/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/libraries/ic_library/date/date.php b/deployed/icagenda/libraries/ic_library/date/date.php new file mode 100644 index 00000000..753b5698 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/date/date.php @@ -0,0 +1,133 @@ + 19930430143300) + * @return alias + * + * @since 1.1.0 + */ + static public function dateToNumeric($date) + { + $date = preg_replace("/[^0-9]/","", $date); + + return $date; + } + + /** + * Function to convert datetime to alias + * + * @access public static + * @param $date: date to convert (1993-04-30 14:33:00 -> 1993-04-30-14-33-00) + * $format: format of the date before convertion (eg. Y-m-d if only date) + * default format: use parent format + * @return alias + * + * @since 1.0.3 + */ + static public function dateToAlias($date, $format = null) + { + if ($format) + { + $date = date($format, strtotime($date)); + } + + if (self::isDate($date)) + { + $replace = array(' ', ':'); + $date = str_replace($replace, '-', $date); + + return $date; + } + + return false; + } + + /** + * Format Month Short Core - From Joomla language file xx-XX.ini (eg. Apr) + * + * @access public static + * @param $date: date to convert (1993-04-30 14:33:00 -> Apr) + * @return translation string for MONTH_SHORT + * + * @since 1.2.0 + */ + static public function monthShortJoomla($date) + { + $month = date('F', strtotime($date)); + $monthShortJoomla = JText::_($month . '_SHORT'); + + return $monthShortJoomla; + } + + /** + * Format Month Core - From Joomla language file xx-XX.ini (eg. April) + * + * @access public static + * @param $date: date to convert (1993-04-30 14:33:00 -> April) + * @return translation string for MONTH + * + * @since 1.4.0 + */ + static public function monthJoomla($date) + { + $month = date('F', strtotime($date)); + $monthJoomla = JText::_($month); + + return $monthJoomla; + } +} diff --git a/deployed/icagenda/libraries/ic_library/date/index.html b/deployed/icagenda/libraries/ic_library/date/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/date/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/libraries/ic_library/date/period.php b/deployed/icagenda/libraries/ic_library/date/period.php new file mode 100644 index 00000000..98048375 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/date/period.php @@ -0,0 +1,156 @@ +format('Y-m-d H:i') + ); + } + } + else + { + // TO BE REMOVED : when Joomla 2.5 and php 5.2 support will end + // Create array with all dates of the period - PHP 5.2 + $nodate = '0000-00-00 00:00:00'; + + if (($startdate != $nodate) && ($enddate != $nodate)) + { + $start = new DateTime($startdate); + + if ($timeenddate <= $timestartdate) + { + $end = new DateTime("$enddate +1 days"); + } + else + { + $end = new DateTime($enddate); + } + + while($start < $end) + { + $out[] = $start->format('Y-m-d H:i'); + $start->modify('+1 day'); + } + } + } + + return $out; + } + else + { + return array(); + } + } + + /** + * Return weekdays data to array of days of the week selected + * + * @access public static + * @param $weekdays : weekdays saved in database (x,x,x) + * @return array of all weekdays of the period + * + * @since 1.2.0 + */ + static public function weekdaysToArray($i_weekdays) + { + $allWeekDays = array(0,1,2,3,4,5,6); + + $weekdays = isset($i_weekdays) ? $i_weekdays : array(); + $weekdays = explode (',', $weekdays); + + $weekdaysarray = array(); + + foreach ($weekdays as $day) + { + array_push($weekdaysarray, $day); + } + + if (in_array('', $weekdaysarray)) // Joomla 2.5 multiple select + { + $arrayWeekDays = $allWeekDays; + } + elseif ($i_weekdays) + { + $arrayWeekDays = $weekdaysarray; + } + elseif (in_array('0', $weekdaysarray)) // Sunday only selected + { + $arrayWeekDays = $weekdaysarray; + } + else + { + $arrayWeekDays = $allWeekDays; + } + + return $arrayWeekDays; + } +} diff --git a/deployed/icagenda/libraries/ic_library/file/file.php b/deployed/icagenda/libraries/ic_library/file/file.php new file mode 100644 index 00000000..cc53e21e --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/file/file.php @@ -0,0 +1,47 @@ + diff --git a/deployed/icagenda/libraries/ic_library/filter/index.html b/deployed/icagenda/libraries/ic_library/filter/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/filter/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/libraries/ic_library/filter/output.php b/deployed/icagenda/libraries/ic_library/filter/output.php new file mode 100644 index 00000000..8f85828b --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/filter/output.php @@ -0,0 +1,125 @@ +transliterate($str); + + // Trim white spaces at beginning and end of translation string and make uppercase + $str = trim(JString::strtoupper($str)); + + // Remove any duplicate whitespace, and ensure all characters are alphanumeric + $str = preg_replace('/(\s|[^A-Za-z0-9\-])+/', '_', $str); + + // Trim underscores at beginning and end of translation string + $str = trim($str, '_'); + + return $str; + } + + /** + * Process a string in slug format. + * This method processes a string and replaces all accented UTF-8 characters by unaccented + * ASCII-7 "equivalents" and the string is lowercase. Spaces replaced by underscore. + * + * @param string $string String to process + * string(1) $concatenater Concatener (default underscore - data slug) + * + * @return string Processed string + * + * @since 1.0.0 + */ + public static function stringToSlug($string, $concatenater = '_') + { + // Remove any '$concatenater' from the string since they will be used as concatenaters + $concatenater = (strlen($concatenater) == 1) ? $concatenater : '_'; + $str = str_replace($concatenater, ' ', $string); + + // Replaces all accented UTF-8 characters by unaccented ASCII-7 "equivalents" + $lang = JFactory::getLanguage(); + $str = $lang->transliterate($str); + + // Trim white spaces at beginning and end of translation string and make lowercase + $str = trim(JString::strtolower($str)); + + // Remove any duplicate whitespace, and ensure all characters are alphanumeric + $str = preg_replace('/(\s|[^A-Za-z0-9])+/', $concatenater, $str); + + // Trim '$concatenater' at beginning and end of translation string + $str = trim($str, $concatenater); + + return $str; + } + + /** + * Convert a HTML string in a text single line. + * This method processes a string, cleans all HTML tags and converts special characters to HTML entities. + * The string is lowercase. Spaces replaced by underscore. + * + * @param string $string String to process + * + * @return string Processed string + * + * @since 1.0.0 + */ + static public function fullCleanHTML($string) + { + // Clean text of all formatting and scripting code + $str = preg_replace("']*>.*?'si", '', $string); + $str = preg_replace('/]*>([^<]+)<\/a>/is', '\2 (\1)', $str); + $str = preg_replace('//', '', $str); + $str = preg_replace('/{.+?}/', '', $str); + + // Strip HTML and PHP tags + $str = strip_tags($str); + + // Replace all sequences of two or more spaces, tabs, and/or line breaks with a single space + $str = preg_replace('/[\p{Z}\s]{2,}/u', ' ', $str); + + // Convert special characters to HTML entities + $str = htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); + + // Trim spaces at beginning and end of translation string + $str = trim($str); + + return $str; + } +} diff --git a/deployed/icagenda/libraries/ic_library/form/field/index.html b/deployed/icagenda/libraries/ic_library/form/field/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/form/field/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/libraries/ic_library/form/field/sortablefields.php b/deployed/icagenda/libraries/ic_library/form/field/sortablefields.php new file mode 100644 index 00000000..aadf744c --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/form/field/sortablefields.php @@ -0,0 +1,348 @@ +input->get('option') == 'com_menus'); + $menuParams = $isMenu ? 'params_' : ''; + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + $level = E_ALL & ~E_NOTICE & ~E_DEPRECATED; + + // Remove not-error message (only needed for Joomla 2.5) : + // Strict Standards: Only variables should be assigned by reference in .../libraries/joomla/form/form.php + if (version_compare(PHP_VERSION, '5.4.0-dev', '>=')) + { + if ( ! defined('E_STRICT')) + { + define('E_STRICT', 2048); + } + + $level &= ~E_STRICT; + } + + error_reporting($level); + + if ($isMenu) + { + return false; + } + } + + if (empty($this->element['label']) && empty($this->element['description'])) + { + return ''; + } + + $title = $this->element['label'] + ? (string) $this->element['label'] + : ($this->element['title'] ? (string) $this->element['title'] : ''); + $heading = $this->element['heading'] ? (string) $this->element['heading'] : 'h4'; + $description = (string) $this->element['description']; + $class = ! empty($this->class) + ? ' class="' . $this->class . '"' + : ' class="alert alert-info input-xxlarge" style="display:block;clear:both;"'; + $close = (string) $this->element['close']; + + $html = array(); + + if ($close) + { + $close = $close == 'true' ? 'alert' : $close; + $html[] = ''; + } + + $html[] = '
      '; + $html[] = ''; +// $html[] = !empty($title) ? '<' . $heading . '>' . JText::_($title) . '' : ''; + $html[] = ! empty($description) ? JText::_($description) : ''; + $html[] = '
      '; + + $html[] = '
      '; + + $fieldnames = isset($this->value) ? $this->value : (string) $this->element['default']; + $fieldnames = explode(',', $fieldnames); + + $group = $isMenu ? 'params' : ''; + + foreach ($fieldnames AS $k => $fieldname) + { + $fieldname = trim($fieldname); + $field = $this->form->getField($fieldname, $group); + + // Make sure the selected field is hidden + if ( ! isset($field->element['type']) || $field->element['type'] !== 'hidden') + { + $this->form->setFieldAttribute($fieldname, 'type', 'hidden'); + } + + // Settings attributes + $name = isset($field->element['name']) ? $field->element['name'] : false; + + if ($name) + { + $rendertype = isset($field->element['rendertype']) ? $field->element['rendertype'] : 'text'; + $label = isset($field->element['label']) ? $field->element['label'] : ''; + $description = isset($field->element['description']) ? $field->element['description'] : ''; + $class = isset($field->element['class']) ? $field->element['class'] : ''; + $labelclass = isset($field->element['labelclass']) ? $field->element['labelclass'] : ''; + $default = isset($field->element['default']) ? $field->element['default'] : ''; + + // Add new field to the sortable list + $type_field = new SimpleXMLElement(''); + $type_field->addAttribute('name', $fieldname); + $type_field->addAttribute('type', $rendertype); + $type_field->addAttribute('label', $label); + $type_field->addAttribute('description', $description); + $type_field->addAttribute('class', $class); + $type_field->addAttribute('labelclass', $labelclass); + $type_field->addAttribute('default', $default); +// $type_field->addAttribute('fieldset', 'list'); + + if (isset($field->element->option)) + { + $values = (array) $field->element->xpath('option'); + $options = (array) $field->element->option; + unset($values['@attributes']); + unset($options['@attributes']); + + + // Add 'Use Global' with value + if ($field->element['useglobal']) + { + $tmp = new stdClass; + $tmp->value = ''; + $tmp->text = JText::_('JGLOBAL_USE_GLOBAL'); + $component = JFactory::getApplication()->input->getCmd('option'); + + // Get correct component for menu items + if ($component == 'com_menus') + { + $link = $this->form->getData()->get('link'); + $uri = new JUri($link); + $component = $uri->getVar('option', 'com_menus'); + } + + $params = JComponentHelper::getParams($component); + $value = $params->get($fieldname); + + // Try with global configuration + if (is_null($value)) + { + $value = JFactory::getConfig()->get($fieldname); + } + + // Try with menu configuration + if (is_null($value) && JFactory::getApplication()->input->getCmd('option') == 'com_menus') + { + $value = JComponentHelper::getParams('com_menus')->get($fieldname); + } + + if (!is_null($value)) + { + $value = (string) $value; + + foreach ($values as $key => $option) + { + if ((string) $values[$key]['value'] === $value) + { + $value = JText::_($option); + + break; + } + } + + $tmp->text = (version_compare(JVERSION, '3.7', 'lt')) + ? JText::_('JGLOBAL_USE_GLOBAL') . ' (' . $value . ')' + : JText::sprintf('JGLOBAL_USE_GLOBAL_VALUE', $value); + } + + $child = $type_field->addChild('option', $tmp->text); + $child->addAttribute('value', $tmp->value); + } + + + // Add Options + foreach ($values as $key => $option) + { + $child = $type_field->addChild('option', $option); + $child->addAttribute('value', $values[$key]['value']); + } + } + + $this->form->setField($type_field, $group); + + $label = $this->form->getLabel($fieldname, $group); + $input = $this->form->getInput($fieldname, $group); + + $html[] = '
      '; + + // Switch Joomla 2.5 / 3 + if (version_compare(JVERSION, '3.0', 'lt')) + { + $html[] = ' ' . $label . $input . ''; + } + else + { + $html[] = ' '; + $html[] = JLayoutHelper::render('joomla.form.renderfield', + array('input' => $input, 'label' => $label, 'options' => array('rel' => ''))); // 'rel' kept for older J3 version (3.2.5...) + } + + $html[] = '
      '; + + $label_suffix = ''; + + if ($fieldname == 'filter_search') + { + $label_suffix = Jtext::_('IC_FIELD_TYPE_TEXT'); + } + elseif (in_array($fieldname, array('filter_from', 'filter_to'))) + { + $label_suffix = Jtext::_('IC_FIELD_TYPE_CALENDAR'); + } + elseif (in_array($fieldname, array('filter_category', 'filter_month', 'filter_year'))) + { + $label_suffix = Jtext::_('IC_FIELD_TYPE_LIST'); + } + + $document->addScriptDeclaration(' + jQuery(document).ready(function($) { + var label = $("#jform_' . $menuParams . $fieldname . '-lbl").text(); + $("#jform_' . $menuParams . $fieldname . '-lbl").html(""+label+" (' . $label_suffix . ')"); + }); + '); + } + } + + $html[] = '
      '; + + $document->addScriptDeclaration(' + jQuery(document).ready(function($) { + $( "#ic-sortable" ).sortable({ + placeholder: "ui-state-highlight", + cursor: "crosshair", + update: function(event, ui) { + var order = $("#ic-sortable").sortable("toArray"); + $("#' . $this->id . '").val(order.join(",")); + } + }); + $( "#ic-sortable" ).disableSelection(); + + // Will hide control-group field, if input type is hidden +// $("input[type=hidden]").parents(".control-group").css("margin-bottom", "0"); + }); + '); + + $document->addStyleDeclaration(' + .ui-state-default { + background: #f7f7f9; + border: 1px solid #e1e1e8; + padding: 3px 5px; + margin-bottom: 3px; + } + .ui-sortable-helper{ + /* + background: #449d44; + background: rgba(68, 157, 68, 0.5); + */ + /* @brand-info BT3 */ + background; #5bc0de; + background: rgba(91, 192, 222, 0.5); + + border: none; + color: #fff; + padding: 3px 5px; + margin-bottom: 3px; + } + .ui-state-default .control-group { + margin-bottom: 5px; + } + .icon-move:hover, + .ui-state-default:hover { + cursor: move; + } + .ui-state-default .control-label:hover { + cursor: move; + } + .ui-state-highlight { + /* + background: #449d44; + background: rgba(68, 157, 68, 0.7); + border: 1px dotted #398439; + */ + /* @brand-info BT3 */ + background; #5bc0de; + background: rgba(91, 192, 222, 0.5); + border: 1px dotted #2aa8ce; + + height: 44px; + margin-bottom: 3px; + } + '); +// JHtml::_('bootstrap.framework'); +// JHtml::_('jquery.framework'); + + // Change jQuery UI version from 1.9.2 to 1.8.23 to prevent a conflict in tooltip that appeared since Joomla 3.1.4 +// $document->addScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js'); +// JHtml::stylesheet( 'com_icagenda/jquery-ui-1.8.17.custom.css', false, true ); + + // Joomla 2.5 + if (version_compare(JVERSION, '3.0', 'lt')) + { + JHtml::stylesheet( 'com_icagenda/jquery-ui-1.8.17.custom.css', false, true ); + $document->addScript('//code.jquery.com/ui/1.11.4/jquery-ui.js'); + } + else + { + JHtml::_('jquery.ui', array('core', 'sortable')); + } + + return '
    ' . implode('', $html); + } + + public function getInput() + { +// return ''; + return ''; + } +} diff --git a/deployed/icagenda/libraries/ic_library/form/index.html b/deployed/icagenda/libraries/ic_library/form/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/form/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/libraries/ic_library/form/rule/positiveinteger.php b/deployed/icagenda/libraries/ic_library/form/rule/positiveinteger.php new file mode 100644 index 00000000..17ee5a28 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/form/rule/positiveinteger.php @@ -0,0 +1,43 @@ +` 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]". + * @param Registry $input An optional Registry object with the entire data set to validate against the entire form. + * @param JForm $form The form object for which the field is being tested. + * + * @return boolean True if the value is valid, false otherwise. + * + * @since 11.1 + */ + public function test(SimpleXMLElement $element, $value, $group = null, Registry $input = null, JForm $form = null) + { + // If the field is empty and not required, the field is valid. + $required = ((string) $element['required'] == 'true' || (string) $element['required'] == 'required'); + + if (!$required && empty($value)) + { + return true; + } + + /* + * @see http://www.nanpa.com/ + * @see http://tools.ietf.org/html/rfc4933 + * @see http://www.itu.int/rec/T-REC-E.164/en + * + * Regex by Steve Levithan + * @see http://blog.stevenlevithan.com/archives/validate-phone-number + * @note that valid ITU-T and EPP must begin with +. + */ + $regexarray = array( + 'NANP' => '/^(?:\+?1[-. ]?)?\(?([2-9][0-8][0-9])\)?[-. ]?([2-9][0-9]{2})[-. ]?([0-9]{4})$/', + 'ITU-T' => '/^\+(?:[0-9] ?){6,14}[0-9]$/', + 'EPP' => '/^\+[0-9]{1,3}\.[0-9]{4,14}(?:x.+)?$/', + ); + + if (isset($element['plan'])) + { + $plan = (string) $element['plan']; + + if ($plan == 'northamerica' || $plan == 'us') + { + $plan = 'NANP'; + } + elseif ($plan == 'International' || $plan == 'int' || $plan == 'missdn' || !$plan) + { + $plan = 'ITU-T'; + } + elseif ($plan == 'IETF') + { + $plan = 'EPP'; + } + + $regex = $regexarray[$plan]; + + // Test the value against the regular expression. + if (preg_match($regex, $value) == false) + { + return false; + } + } + else + { + /* + * If the rule is set but no plan is selected just check that there are between + * 7 and 15 digits inclusive and no illegal characters (but common number separators + * are allowed). + */ + $cleanvalue = preg_replace('/[+. \-(\)]/', '', $value); + $regex = '/^[0-9]{6,15}?$/'; + + if (preg_match($regex, $cleanvalue) == true) + { + return true; + } + else + { + return false; + } + } + + return true; + } +} diff --git a/deployed/icagenda/libraries/ic_library/globalize/convert.php b/deployed/icagenda/libraries/ic_library/globalize/convert.php new file mode 100644 index 00000000..74ab9043 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/globalize/convert.php @@ -0,0 +1,183 @@ +1 && (($gy%4==0 && $gy%100!=0) || ($gy%400==0))) + /* leap and after Feb */ + $g_day_no++; + $g_day_no += $gd; + + $j_day_no = $g_day_no-79; + + $j_np = self::div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */ + $j_day_no = $j_day_no % 12053; + + $jy = 979+33*$j_np+4*self::div($j_day_no,1461); /* 1461 = 365*4 + 4/4 */ + + $j_day_no %= 1461; + + if ($j_day_no >= 366) + { + $jy += self::div($j_day_no-1, 365); + $j_day_no = ($j_day_no-1)%365; + } + + for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i) + $j_day_no -= $j_days_in_month[$i]; + $jm = $i+1; + $jd = $j_day_no+1; + + if ($str) + { + return $jy . '-' . $jm . '-' . $jd; + } + + return array($jy, $jm, $jd); + } + + /** + * Jalali to Gregorian Conversion + * Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi + * + * @since 1.3.2 + */ + static public function jalaliToGregorian($j_y, $j_m, $j_d, $str) + { + $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); + $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29); + + $jy = (int)($j_y)-979; + $jm = (int)($j_m)-1; + $jd = (int)($j_d)-1; + + $j_day_no = 365*$jy + self::div($jy, 33)*8 + self::div($jy%33+3, 4); + + for ($i=0; $i < $jm; ++$i) + $j_day_no += $j_days_in_month[$i]; + + $j_day_no += $jd; + + $g_day_no = $j_day_no+79; + + $gy = 1600 + 400*self::div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */ + $g_day_no = $g_day_no % 146097; + + $leap = true; + + if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */ + { + $g_day_no--; + $gy += 100*self::div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */ + $g_day_no = $g_day_no % 36524; + + if ($g_day_no >= 365) + $g_day_no++; + else + $leap = false; + } + + $gy += 4*self::div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */ + $g_day_no %= 1461; + + if ($g_day_no >= 366) + { + $leap = false; + + $g_day_no--; + $gy += self::div($g_day_no, 365); + $g_day_no = $g_day_no % 365; + } + + for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++) + $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap); + $gm = $i+1; + $gd = $g_day_no+1; + + if ($str) + { + return $gy . '-' . $gm . '-' . $gd; + } + + return array($gy, $gm, $gd); + } + + + function comparedate($_date_mix_jalaly, $_date_mix_gregorian) + { + $_date_arr_jalaly = explode('/', $_date_mix_jalaly); + $_date_arr_gregorian = explode('/', $_date_mix_gregorian); + + $arr_jtg = self::jalali_to_gregorian($_date_arr_jalaly[0],$_date_arr_jalaly[1],$_date_arr_jalaly[2]); + + if ($_date_arr_gregorian[0]> $arr_jtg[0]) + { + return false; + } + elseif ($_date_arr_gregorian[0]== $arr_jtg[0] && $_date_arr_gregorian[1]>$arr_jtg[1]) + { + return false; + } + elseif ($_date_arr_gregorian[0]== $arr_jtg[0] && $_date_arr_gregorian[1]==$arr_jtg[1] && $_date_arr_gregorian[2]>$arr_jtg[2]) + { + return false; + } + + return true ; + } +} diff --git a/deployed/icagenda/libraries/ic_library/globalize/culture/cs-CZ.php b/deployed/icagenda/libraries/ic_library/globalize/culture/cs-CZ.php new file mode 100644 index 00000000..0519dcb6 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/globalize/culture/cs-CZ.php @@ -0,0 +1,64 @@ + \ No newline at end of file diff --git a/deployed/icagenda/libraries/ic_library/globalize/culture/iso.php b/deployed/icagenda/libraries/ic_library/globalize/culture/iso.php new file mode 100644 index 00000000..4bd3c66c --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/globalize/culture/iso.php @@ -0,0 +1,51 @@ +getTag(); + $langName = $lang->getName(); + + if ( ! file_exists(JPATH_LIBRARIES . '/ic_library/globalize/culture/' . $langTag . '.php')) + { + $langTag = 'en-GB'; + } + + $globalize = JPATH_LIBRARIES . '/ic_library/globalize/culture/' . $langTag . '.php'; + $iso = JPATH_LIBRARIES . '/ic_library/globalize/culture/iso.php'; + + // Languages with English ordinal suffix for the day of the month, 2 characters + $en_langs = array('en-GB', 'en-US'); + + // Set iso format if format is equal to zero (Y-m-d) + $option = ($option == '0') ? 'Y - m - d' : $option; + + if (is_numeric($option)) + { + require $globalize; + + // Format with "th" only for english languages + if ( ! in_array($langTag, $en_langs)) + { + if ($option == '5') $option = '4'; + if ($option == '9') $option = '7'; + if ($option == '10') $option = '8'; + } + + // No Short month for Persian language + elseif ($langTag == 'fa-IR') + { + if ($option == '3') $option = '2'; + if ($option == '11') $option = '7'; + if ($option == '12') $option = '8'; + } + + $format = ${"dateformat_" . $option}; + } + else + { + require $iso; + + $format = $option; + } + + // Load Globalization Date Format if selected + + // Explode components of the date + $exformat = explode (' ', $format); + + // Set datetime format + $thisDate = date('Y-m-d H:i:s', strtotime($date)); +// $month_n = JHtml::date($thisDate, 'n', $eventTimeZone); // 1 through 12 +// $day_w = JHtml::date($thisDate, 'w', $eventTimeZone); // 0 (for Sunday) through 6 (for Saturday) + + // Strings of translation for convertion +// $array_days = array( +// 'SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY' +// ); + +// $array_days_short = array( +// 'SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT' +// ); + +// $array_months = array( +// 'JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', +// 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER' +// ); + + $dateFormatted = ''; + + // Creates date formatted + foreach ($exformat as $k => $val) + { + switch($val) + { + // Day + case 'd': + $val = JHtml::date($thisDate, 'd', $eventTimeZone); + break; + + case 'j': + $val = JHtml::date($thisDate, 'j', $eventTimeZone); + break; + + case 'D': + // A textual representation of day of the week, three letters (use Joomla Translation string) +// $val = JText::_($array_days_short[$day_w]); + $val = JHtml::date($thisDate, 'D', $eventTimeZone); + break; + + case 'l': + // A full textual representation of the day of the week (use Joomla Translation string) +// $val = JText::_($array_days[$day_w]); + $val = JHtml::date($thisDate, 'l', $eventTimeZone); + break; + + case 'S': + $val = '' . JHtml::date($thisDate, 'S', $eventTimeZone) . ''; + break; + + case 'jS': + $val = JHtml::date($thisDate, 'j', $eventTimeZone) . '' . JHtml::date($thisDate, 'S', $eventTimeZone) . ''; + break; + + // Month + case 'm': + $val = JHtml::date($thisDate, 'm', $eventTimeZone); + break; + + case 'F': + // A full textual representation of a month (use Joomla Translation string) +// $val = JText::_($array_months[($month_n-1)]); + $val = JHtml::date($thisDate, 'F', $eventTimeZone); + break; + + case 'M': + // A short textual representation of a month (use Joomla Translation string) +// $val = JText::_($array_months[($month_n-1)] . '_SHORT'); + $val = JHtml::date($thisDate, 'M', $eventTimeZone); + break; + + case 'n': + $val = JHtml::date($thisDate, 'n', $eventTimeZone); + break; + + // year (v3) + case 'Y': + $val = JHtml::date($thisDate, 'Y', $eventTimeZone); + break; + + case 'y': + $val = JHtml::date($thisDate, 'y', $eventTimeZone); + break; + + // Separator of the components + case '*': + $val = $separator; + break; + case '_': + $val = ' '; +// $val = ' '; + break; + + // day + case 'N': + $val = strftime("%u", strtotime("$thisDate")); + break; + case 'w': + $val = strftime("%w", strtotime("$thisDate")); + break; + case 'z': + $val = strftime("%j", strtotime("$thisDate")); + break; + + // week + case 'W': + $val = JHtml::date($thisDate, 'W', $eventTimeZone); + break; + + // Default + default: + $val; + break; + } + + $dateFormatted.= ($k !== 0) ? '' . $val : $val; + } + + return $dateFormatted; + } +} diff --git a/deployed/icagenda/libraries/ic_library/globalize/index.html b/deployed/icagenda/libraries/ic_library/globalize/index.html new file mode 100644 index 00000000..2efb97f3 --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/globalize/index.html @@ -0,0 +1 @@ + diff --git a/deployed/icagenda/libraries/ic_library/iCalcreator/iCalcreator.class.php b/deployed/icagenda/libraries/ic_library/iCalcreator/iCalcreator.class.php new file mode 100644 index 00000000..1d20abeb --- /dev/null +++ b/deployed/icagenda/libraries/ic_library/iCalcreator/iCalcreator.class.php @@ -0,0 +1,10569 @@ + + * @since 2.9.6 - 2011-05-14 + */ +class vcalendar { + // calendar property variables + var $calscale; + var $method; + var $prodid; + var $version; + var $xprop; + // container for calendar components + var $components; + // component config variables + var $allowEmpty; + var $unique_id; + var $language; + var $directory; + var $filename; + var $url; + var $delimiter; + var $nl; + var $format; + var $dtzid; + // component internal variables + var $attributeDelimiter; + var $valueInit; + // component xCal declaration container + var $xcaldecl; +/** + * constructor for calendar object + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.9.6 - 2011-05-14 + * @param array $config + * @return void + */ + function __construct ( $config = array()) { + $this->_makeVersion(); + $this->calscale = null; + $this->method = null; + $this->_makeUnique_id(); + $this->prodid = null; + $this->xprop = array(); + $this->language = null; + $this->directory = null; + $this->filename = null; + $this->url = null; + $this->dtzid = null; +/** + * language = + */ + if( defined( 'ICAL_LANG' ) && !isset( $config['language'] )) + $config['language'] = ICAL_LANG; + if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE; + if( !isset( $config['nl'] )) $config['nl'] = "\r\n"; + if( !isset( $config['format'] )) $config['format'] = 'iCal'; + if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR; + $this->setConfig( $config ); + + $this->xcaldecl = array(); + $this->components = array(); + } +/*********************************************************************************/ +/** + * Property Name: CALSCALE + */ +/** + * creates formatted output for calendar property calscale + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.16 - 2011-10-28 + * @return string + */ + function createCalscale() { + if( empty( $this->calscale )) return FALSE; + switch( $this->format ) { + case 'xcal': + return $this->nl.' calscale="'.$this->calscale.'"'; + break; + default: + return 'CALSCALE:'.$this->calscale.$this->nl; + break; + } + } +/** + * set calendar property calscale + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @param string $value + * @return void + */ + function setCalscale( $value ) { + if( empty( $value )) return FALSE; + $this->calscale = $value; + } +/*********************************************************************************/ +/** + * Property Name: METHOD + */ +/** + * creates formatted output for calendar property method + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.16 - 2011-10-28 + * @return string + */ + function createMethod() { + if( empty( $this->method )) return FALSE; + switch( $this->format ) { + case 'xcal': + return $this->nl.' method="'.$this->method.'"'; + break; + default: + return 'METHOD:'.$this->method.$this->nl; + break; + } + } +/** + * set calendar property method + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-20-23 + * @param string $value + * @return bool + */ + function setMethod( $value ) { + if( empty( $value )) return FALSE; + $this->method = $value; + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: PRODID + * + * The identifier is RECOMMENDED to be the identical syntax to the + * [RFC 822] addr-spec. A good method to assure uniqueness is to put the + * domain name or a domain literal IP address of the host on which.. . + */ +/** + * creates formatted output for calendar property prodid + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.12.11 - 2012-05-13 + * @return string + */ + function createProdid() { + if( !isset( $this->prodid )) + $this->_makeProdid(); + switch( $this->format ) { + case 'xcal': + return $this->nl.' prodid="'.$this->prodid.'"'; + break; + default: + $toolbox = new calendarComponent(); + $toolbox->setConfig( $this->getConfig()); + return $toolbox->_createElement( 'PRODID', '', $this->prodid ); + break; + } + } +/** + * make default value for calendar prodid + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.6.8 - 2009-12-30 + * @return void + */ + function _makeProdid() { + $this->prodid = '-//'.$this->unique_id.'//NONSGML kigkonsult.se '.ICALCREATOR_VERSION.'//'.strtoupper( $this->language ); + } +/** + * Conformance: The property MUST be specified once in an iCalendar object. + * Description: The vendor of the implementation SHOULD assure that this + * is a globally unique identifier; using some technique such as an FPI + * value, as defined in [ISO 9070]. + */ +/** + * make default unique_id for calendar prodid + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 0.3.0 - 2006-08-10 + * @return void + */ + function _makeUnique_id() { + $this->unique_id = ( isset( $_SERVER['SERVER_NAME'] )) ? gethostbyname( $_SERVER['SERVER_NAME'] ) : 'localhost'; + } +/*********************************************************************************/ +/** + * Property Name: VERSION + * + * Description: A value of "2.0" corresponds to this memo. + */ +/** + * creates formatted output for calendar property version + + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.16 - 2011-10-28 + * @return string + */ + function createVersion() { + if( empty( $this->version )) + $this->_makeVersion(); + switch( $this->format ) { + case 'xcal': + return $this->nl.' version="'.$this->version.'"'; + break; + default: + return 'VERSION:'.$this->version.$this->nl; + break; + } + } +/** + * set default calendar version + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 0.3.0 - 2006-08-10 + * @return void + */ + function _makeVersion() { + $this->version = '2.0'; + } +/** + * set calendar version + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-23 + * @param string $value + * @return void + */ + function setVersion( $value ) { + if( empty( $value )) return FALSE; + $this->version = $value; + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: x-prop + */ +/** + * creates formatted output for calendar property x-prop, iCal format only + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-05-25 + * @return string + */ + function createXprop() { + if( empty( $this->xprop ) || !is_array( $this->xprop )) return FALSE; + $output = null; + $toolbox = new calendarComponent(); + $toolbox->setConfig( $this->getConfig()); + foreach( $this->xprop as $label => $xpropPart ) { + if( !isset($xpropPart['value']) || ( empty( $xpropPart['value'] ) && !is_numeric( $xpropPart['value'] ))) { + if( $this->getConfig( 'allowEmpty' )) + $output .= $toolbox->_createElement( $label ); + continue; + } + $attributes = $toolbox->_createParams( $xpropPart['params'], array( 'LANGUAGE' )); + if( is_array( $xpropPart['value'] )) { + foreach( $xpropPart['value'] as $pix => $theXpart ) + $xpropPart['value'][$pix] = iCalUtilityFunctions::_strrep( $theXpart, $this->format, $this->nl ); + $xpropPart['value'] = implode( ',', $xpropPart['value'] ); + } + else + $xpropPart['value'] = iCalUtilityFunctions::_strrep( $xpropPart['value'], $this->format, $this->nl ); + $output .= $toolbox->_createElement( $label, $attributes, $xpropPart['value'] ); + if( is_array( $toolbox->xcaldecl ) && ( 0 < count( $toolbox->xcaldecl ))) { + foreach( $toolbox->xcaldecl as $localxcaldecl ) + $this->xcaldecl[] = $localxcaldecl; + } + } + return $output; + } +/** + * set calendar property x-prop + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $label + * @param string $value + * @param array $params optional + * @return bool + */ + function setXprop( $label, $value, $params=FALSE ) { + if( empty( $label )) + return FALSE; + if( 'X-' != strtoupper( substr( $label, 0, 2 ))) + return FALSE; + if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $xprop = array( 'value' => $value ); + $xprop['params'] = iCalUtilityFunctions::_setParams( $params ); + if( !is_array( $this->xprop )) $this->xprop = array(); + $this->xprop[strtoupper( $label )] = $xprop; + return TRUE; + } +/*********************************************************************************/ +/** + * delete calendar property value + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.8 - 2011-03-15 + * @param mixed $propName, bool FALSE => X-property + * @param int $propix, optional, if specific property is wanted in case of multiply occurences + * @return bool, if successfull delete + */ + function deleteProperty( $propName=FALSE, $propix=FALSE ) { + $propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; + if( !$propix ) + $propix = ( isset( $this->propdelix[$propName] ) && ( 'X-PROP' != $propName )) ? $this->propdelix[$propName] + 2 : 1; + $this->propdelix[$propName] = --$propix; + $return = FALSE; + switch( $propName ) { + case 'CALSCALE': + if( isset( $this->calscale )) { + $this->calscale = null; + $return = TRUE; + } + break; + case 'METHOD': + if( isset( $this->method )) { + $this->method = null; + $return = TRUE; + } + break; + default: + $reduced = array(); + if( $propName != 'X-PROP' ) { + if( !isset( $this->xprop[$propName] )) { unset( $this->propdelix[$propName] ); return FALSE; } + foreach( $this->xprop as $k => $a ) { + if(( $k != $propName ) && !empty( $a )) + $reduced[$k] = $a; + } + } + else { + if( count( $this->xprop ) <= $propix ) return FALSE; + $xpropno = 0; + foreach( $this->xprop as $xpropkey => $xpropvalue ) { + if( $propix != $xpropno ) + $reduced[$xpropkey] = $xpropvalue; + $xpropno++; + } + } + $this->xprop = $reduced; + if( empty( $this->xprop )) { + unset( $this->propdelix[$propName] ); + return FALSE; + } + return TRUE; + } + return $return; + } +/** + * get calendar property value/params + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.13.4 - 2012-08-08 + * @param string $propName, optional + * @param int $propix, optional, if specific property is wanted in case of multiply occurences + * @param bool $inclParam=FALSE + * @return mixed + */ + function getProperty( $propName=FALSE, $propix=FALSE, $inclParam=FALSE ) { + $propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; + if( 'X-PROP' == $propName ) { + if( !$propix ) + $propix = ( isset( $this->propix[$propName] )) ? $this->propix[$propName] + 2 : 1; + $this->propix[$propName] = --$propix; + } + else + $mProps = array( 'ATTENDEE', 'CATEGORIES', 'CONTACT', 'RELATED-TO', 'RESOURCES' ); + switch( $propName ) { + case 'ATTENDEE': + case 'CATEGORIES': + case 'CONTACT': + case 'DTSTART': + case 'GEOLOCATION': + case 'LOCATION': + case 'ORGANIZER': + case 'PRIORITY': + case 'RESOURCES': + case 'STATUS': + case 'SUMMARY': + case 'RECURRENCE-ID-UID': + case 'RELATED-TO': + case 'R-UID': + case 'UID': + case 'URL': + $output = array(); + foreach ( $this->components as $cix => $component) { + if( !in_array( $component->objName, array('vevent', 'vtodo', 'vjournal', 'vfreebusy' ))) + continue; + if( in_array( strtoupper( $propName ), $mProps )) { + $component->_getProperties( $propName, $output ); + continue; + } + elseif(( 3 < strlen( $propName )) && ( 'UID' == substr( $propName, -3 ))) { + if( FALSE !== ( $content = $component->getProperty( 'RECURRENCE-ID' ))) + $content = $component->getProperty( 'UID' ); + } + elseif( 'GEOLOCATION' == $propName ) { + $content = $component->getProperty( 'LOCATION' ); + $content = ( !empty( $content )) ? $content.' ' : ''; + if(( FALSE === ( $geo = $component->getProperty( 'GEO' ))) || empty( $geo )) + continue; + if( 0.0 < $geo['latitude'] ) + $sign = '+'; + else + $sign = ( 0.0 > $geo['latitude'] ) ? '-' : ''; + $content .= ' '.$sign.sprintf( "%09.6f", abs( $geo['latitude'] )); + $content = rtrim( rtrim( $content, '0' ), '.' ); + if( 0.0 < $geo['longitude'] ) + $sign = '+'; + else + $sign = ( 0.0 > $geo['longitude'] ) ? '-' : ''; + $content .= $sign.sprintf( '%8.6f', abs( $geo['longitude'] )).'/'; + } + elseif( FALSE === ( $content = $component->getProperty( $propName ))) + continue; + if(( FALSE === $content ) || empty( $content )) + continue; + elseif( is_array( $content )) { + if( isset( $content['year'] )) { + $key = sprintf( '%04d%02d%02d', $content['year'], $content['month'], $content['day'] ); + if( !isset( $output[$key] )) + $output[$key] = 1; + else + $output[$key] += 1; + } + else { + foreach( $content as $partValue => $partCount ) { + if( !isset( $output[$partValue] )) + $output[$partValue] = $partCount; + else + $output[$partValue] += $partCount; + } + } + } // end elseif( is_array( $content )) { + elseif( !isset( $output[$content] )) + $output[$content] = 1; + else + $output[$content] += 1; + } // end foreach ( $this->components as $cix => $component) + if( !empty( $output )) + ksort( $output ); + return $output; + break; + case 'CALSCALE': + return ( !empty( $this->calscale )) ? $this->calscale : FALSE; + break; + case 'METHOD': + return ( !empty( $this->method )) ? $this->method : FALSE; + break; + case 'PRODID': + if( empty( $this->prodid )) + $this->_makeProdid(); + return $this->prodid; + break; + case 'VERSION': + return ( !empty( $this->version )) ? $this->version : FALSE; + break; + default: + if( $propName != 'X-PROP' ) { + if( !isset( $this->xprop[$propName] )) return FALSE; + return ( $inclParam ) ? array( $propName, $this->xprop[$propName] ) + : array( $propName, $this->xprop[$propName]['value'] ); + } + else { + if( empty( $this->xprop )) return FALSE; + $xpropno = 0; + foreach( $this->xprop as $xpropkey => $xpropvalue ) { + if( $propix == $xpropno ) + return ( $inclParam ) ? array( $xpropkey, $this->xprop[$xpropkey] ) + : array( $xpropkey, $this->xprop[$xpropkey]['value'] ); + else + $xpropno++; + } + unset( $this->propix[$propName] ); + return FALSE; // not found ?? + } + } + return FALSE; + } +/** + * general vcalendar property setting + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.2.13 - 2007-11-04 + * @param mixed $args variable number of function arguments, + * first argument is ALWAYS component name, + * second ALWAYS component value! + * @return bool + */ + function setProperty () { + $numargs = func_num_args(); + if( 1 > $numargs ) + return FALSE; + $arglist = func_get_args(); + $arglist[0] = strtoupper( $arglist[0] ); + switch( $arglist[0] ) { + case 'CALSCALE': + return $this->setCalscale( $arglist[1] ); + case 'METHOD': + return $this->setMethod( $arglist[1] ); + case 'VERSION': + return $this->setVersion( $arglist[1] ); + default: + if( !isset( $arglist[1] )) $arglist[1] = null; + if( !isset( $arglist[2] )) $arglist[2] = null; + return $this->setXprop( $arglist[0], $arglist[1], $arglist[2] ); + } + return FALSE; + } +/*********************************************************************************/ +/** + * get vcalendar config values or * calendar components + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.11.7 - 2012-01-12 + * @param mixed $config + * @return value + */ + function getConfig( $config = FALSE ) { + if( !$config ) { + $return = array(); + $return['ALLOWEMPTY'] = $this->getConfig( 'ALLOWEMPTY' ); + $return['DELIMITER'] = $this->getConfig( 'DELIMITER' ); + $return['DIRECTORY'] = $this->getConfig( 'DIRECTORY' ); + $return['FILENAME'] = $this->getConfig( 'FILENAME' ); + $return['DIRFILE'] = $this->getConfig( 'DIRFILE' ); + $return['FILESIZE'] = $this->getConfig( 'FILESIZE' ); + $return['FORMAT'] = $this->getConfig( 'FORMAT' ); + if( FALSE !== ( $lang = $this->getConfig( 'LANGUAGE' ))) + $return['LANGUAGE'] = $lang; + $return['NEWLINECHAR'] = $this->getConfig( 'NEWLINECHAR' ); + $return['UNIQUE_ID'] = $this->getConfig( 'UNIQUE_ID' ); + if( FALSE !== ( $url = $this->getConfig( 'URL' ))) + $return['URL'] = $url; + $return['TZID'] = $this->getConfig( 'TZID' ); + return $return; + } + switch( strtoupper( $config )) { + case 'ALLOWEMPTY': + return $this->allowEmpty; + break; + case 'COMPSINFO': + unset( $this->compix ); + $info = array(); + foreach( $this->components as $cix => $component ) { + if( empty( $component )) continue; + $info[$cix]['ordno'] = $cix + 1; + $info[$cix]['type'] = $component->objName; + $info[$cix]['uid'] = $component->getProperty( 'uid' ); + $info[$cix]['props'] = $component->getConfig( 'propinfo' ); + $info[$cix]['sub'] = $component->getConfig( 'compsinfo' ); + } + return $info; + break; + case 'DELIMITER': + return $this->delimiter; + break; + case 'DIRECTORY': + if( empty( $this->directory ) && ( '0' != $this->directory )) + $this->directory = '.'; + return $this->directory; + break; + case 'DIRFILE': + return $this->getConfig( 'directory' ).$this->getConfig( 'delimiter' ).$this->getConfig( 'filename' ); + break; + case 'FILEINFO': + return array( $this->getConfig( 'directory' ) + , $this->getConfig( 'filename' ) + , $this->getConfig( 'filesize' )); + break; + case 'FILENAME': + if( empty( $this->filename ) && ( '0' != $this->filename )) { + if( 'xcal' == $this->format ) + $this->filename = date( 'YmdHis' ).'.xml'; // recommended xcs.. . + else + $this->filename = date( 'YmdHis' ).'.ics'; + } + return $this->filename; + break; + case 'FILESIZE': + $size = 0; + if( empty( $this->url )) { + $dirfile = $this->getConfig( 'dirfile' ); + if( !is_file( $dirfile ) || ( FALSE === ( $size = filesize( $dirfile )))) + $size = 0; + clearstatcache(); + } + return $size; + break; + case 'FORMAT': + return ( $this->format == 'xcal' ) ? 'xCal' : 'iCal'; + break; + case 'LANGUAGE': + /* get language for calendar component as defined in [RFC 1766] */ + return $this->language; + break; + case 'NL': + case 'NEWLINECHAR': + return $this->nl; + break; + case 'TZID': + return $this->dtzid; + break; + case 'UNIQUE_ID': + return $this->unique_id; + break; + case 'URL': + if( !empty( $this->url )) + return $this->url; + else + return FALSE; + break; + } + } +/** + * general vcalendar config setting + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.7 - 2013-01-11 + * @param mixed $config + * @param string $value + * @return void + */ + function setConfig( $config, $value = FALSE) { + if( is_array( $config )) { + $ak = array_keys( $config ); + foreach( $ak as $k ) { + if( 'DIRECTORY' == strtoupper( $k )) { + if( FALSE === $this->setConfig( 'DIRECTORY', $config[$k] )) + return FALSE; + unset( $config[$k] ); + } + elseif( 'NEWLINECHAR' == strtoupper( $k )) { + if( FALSE === $this->setConfig( 'NEWLINECHAR', $config[$k] )) + return FALSE; + unset( $config[$k] ); + } + } + foreach( $config as $cKey => $cValue ) { + if( FALSE === $this->setConfig( $cKey, $cValue )) + return FALSE; + } + return TRUE; + } + $res = FALSE; + switch( strtoupper( $config )) { + case 'ALLOWEMPTY': + $this->allowEmpty = $value; + $subcfg = array( 'ALLOWEMPTY' => $value ); + $res = TRUE; + break; + case 'DELIMITER': + $this->delimiter = $value; + return TRUE; + break; + case 'DIRECTORY': + $value = trim( $value ); + $del = $this->getConfig('delimiter'); + if( $del == substr( $value, ( 0 - strlen( $del )))) + $value = substr( $value, 0, ( strlen( $value ) - strlen( $del ))); + if( is_dir( $value )) { + /* local directory */ + clearstatcache(); + $this->directory = $value; + $this->url = null; + return TRUE; + } + else + return FALSE; + break; + case 'FILENAME': + $value = trim( $value ); + if( !empty( $this->url )) { + /* remote directory+file -> URL */ + $this->filename = $value; + return TRUE; + } + $dirfile = $this->getConfig( 'directory' ).$this->getConfig( 'delimiter' ).$value; + if( file_exists( $dirfile )) { + /* local file exists */ + if( is_readable( $dirfile ) || is_writable( $dirfile )) { + clearstatcache(); + $this->filename = $value; + return TRUE; + } + else + return FALSE; + } + elseif( is_readable($this->getConfig( 'directory' ) ) || is_writable( $this->getConfig( 'directory' ) )) { + /* read- or writable directory */ + $this->filename = $value; + return TRUE; + } + else + return FALSE; + break; + case 'FORMAT': + $value = trim( strtolower( $value )); + if( 'xcal' == $value ) { + $this->format = 'xcal'; + $this->attributeDelimiter = $this->nl; + $this->valueInit = null; + } + else { + $this->format = null; + $this->attributeDelimiter = ';'; + $this->valueInit = ':'; + } + $subcfg = array( 'FORMAT' => $value ); + $res = TRUE; + break; + case 'LANGUAGE': // set language for calendar component as defined in [RFC 1766] + $value = trim( $value ); + $this->language = $value; + $this->_makeProdid(); + $subcfg = array( 'LANGUAGE' => $value ); + $res = TRUE; + break; + case 'NL': + case 'NEWLINECHAR': + $this->nl = $value; + if( 'xcal' == $value ) { + $this->attributeDelimiter = $this->nl; + $this->valueInit = null; + } + else { + $this->attributeDelimiter = ';'; + $this->valueInit = ':'; + } + $subcfg = array( 'NL' => $value ); + $res = TRUE; + break; + case 'TZID': + $this->dtzid = $value; + $subcfg = array( 'TZID' => $value ); + $res = TRUE; + break; + case 'UNIQUE_ID': + $value = trim( $value ); + $this->unique_id = $value; + $this->_makeProdid(); + $subcfg = array( 'UNIQUE_ID' => $value ); + $res = TRUE; + break; + case 'URL': + /* remote file - URL */ + $value = str_replace( array( 'HTTP://', 'WEBCAL://', 'webcal://' ), 'http://', trim( $value )); + if( 'http://' != substr( $value, 0, 7 )) + return FALSE; + $s1 = $this->url; + $this->url = $value; + $s2 = $this->directory; + $this->directory = null; + $parts = pathinfo( $value ); + if( FALSE === $this->setConfig( 'filename', $parts['basename'] )) { + $this->url = $s1; + $this->directory = $s2; + return FALSE; + } + else + return TRUE; + break; + default: // any unvalid config key.. . + return TRUE; + } + if( !$res ) return FALSE; + if( isset( $subcfg ) && !empty( $this->components )) { + foreach( $subcfg as $cfgkey => $cfgvalue ) { + foreach( $this->components as $cix => $component ) { + $res = $component->setConfig( $cfgkey, $cfgvalue, TRUE ); + if( !$res ) + break 2; + $this->components[$cix] = $component->copy(); // PHP4 compliant + } + } + } + return $res; + } +/*********************************************************************************/ +/** + * add calendar component to container + * + * alias to setComponent + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 1.x.x - 2007-04-24 + * @param object $component calendar component + * @return void + */ + function addComponent( $component ) { + $this->setComponent( $component ); + } +/** + * delete calendar component from container + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.8 - 2011-03-15 + * @param mixed $arg1 ordno / component type / component uid + * @param mixed $arg2 optional, ordno if arg1 = component type + * @return void + */ + function deleteComponent( $arg1, $arg2=FALSE ) { + $argType = $index = null; + if ( ctype_digit( (string) $arg1 )) { + $argType = 'INDEX'; + $index = (int) $arg1 - 1; + } + elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { + $argType = strtolower( $arg1 ); + $index = ( !empty( $arg2 ) && ctype_digit( (string) $arg2 )) ? (( int ) $arg2 - 1 ) : 0; + } + $cix1dC = 0; + foreach ( $this->components as $cix => $component) { + if( empty( $component )) continue; + if(( 'INDEX' == $argType ) && ( $index == $cix )) { + unset( $this->components[$cix] ); + return TRUE; + } + elseif( $argType == $component->objName ) { + if( $index == $cix1dC ) { + unset( $this->components[$cix] ); + return TRUE; + } + $cix1dC++; + } + elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { + unset( $this->components[$cix] ); + return TRUE; + } + } + return FALSE; + } +/** + * get calendar component from container + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.15 - 2013-04-25 + * @param mixed $arg1 optional, ordno/component type/ component uid + * @param mixed $arg2 optional, ordno if arg1 = component type + * @return object + */ + function getComponent( $arg1=FALSE, $arg2=FALSE ) { + $index = $argType = null; + if ( !$arg1 ) { // first or next in component chain + $argType = 'INDEX'; + $index = $this->compix['INDEX'] = ( isset( $this->compix['INDEX'] )) ? $this->compix['INDEX'] + 1 : 1; + } + elseif( is_array( $arg1 )) { // array( *[propertyName => propertyValue] ) + $arg2 = implode( '-', array_keys( $arg1 )); + $index = $this->compix[$arg2] = ( isset( $this->compix[$arg2] )) ? $this->compix[$arg2] + 1 : 1; + $dateProps = array( 'DTSTART', 'DTEND', 'DUE', 'CREATED', 'COMPLETED', 'DTSTAMP', 'LAST-MODIFIED', 'RECURRENCE-ID' ); + $otherProps = array( 'ATTENDEE', 'CATEGORIES', 'CONTACT', 'LOCATION', 'ORGANIZER', 'PRIORITY', 'RELATED-TO', 'RESOURCES', 'STATUS', 'SUMMARY', 'UID', 'URL' ); + $mProps = array( 'ATTENDEE', 'CATEGORIES', 'CONTACT', 'RELATED-TO', 'RESOURCES' ); + } + elseif ( ctype_digit( (string) $arg1 )) { // specific component in chain + $argType = 'INDEX'; + $index = (int) $arg1; + unset( $this->compix ); + } + elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { // object class name + unset( $this->compix['INDEX'] ); + $argType = strtolower( $arg1 ); + if( !$arg2 ) + $index = $this->compix[$argType] = ( isset( $this->compix[$argType] )) ? $this->compix[$argType] + 1 : 1; + elseif( isset( $arg2 ) && ctype_digit( (string) $arg2 )) + $index = (int) $arg2; + } + elseif(( strlen( $arg1 ) > strlen( 'vfreebusy' )) && ( FALSE !== strpos( $arg1, '@' ))) { // UID as 1st argument + if( !$arg2 ) + $index = $this->compix[$arg1] = ( isset( $this->compix[$arg1] )) ? $this->compix[$arg1] + 1 : 1; + elseif( isset( $arg2 ) && ctype_digit( (string) $arg2 )) + $index = (int) $arg2; + } + if( isset( $index )) + $index -= 1; + $ckeys = array_keys( $this->components ); + if( !empty( $index) && ( $index > end( $ckeys ))) + return FALSE; + $cix1gC = 0; + foreach ( $this->components as $cix => $component) { + if( empty( $component )) continue; + if(( 'INDEX' == $argType ) && ( $index == $cix )) + return $component->copy(); + elseif( $argType == $component->objName ) { + if( $index == $cix1gC ) + return $component->copy(); + $cix1gC++; + } + elseif( is_array( $arg1 )) { // array( *[propertyName => propertyValue] ) + $hit = array(); + foreach( $arg1 as $pName => $pValue ) { + $pName = strtoupper( $pName ); + if( !in_array( $pName, $dateProps ) && !in_array( $pName, $otherProps )) + continue; + if( in_array( $pName, $mProps )) { // multiple occurrence + $propValues = array(); + $component->_getProperties( $pName, $propValues ); + $propValues = array_keys( $propValues ); + $hit[] = ( in_array( $pValue, $propValues )) ? TRUE : FALSE; + continue; + } // end if(.. .// multiple occurrence + if( FALSE === ( $value = $component->getProperty( $pName ))) { // single occurrence + $hit[] = FALSE; // missing property + continue; + } + if( 'SUMMARY' == $pName ) { // exists within (any case) + $hit[] = ( FALSE !== stripos( $value, $pValue )) ? TRUE : FALSE; + continue; + } + if( in_array( strtoupper( $pName ), $dateProps )) { + $valuedate = sprintf( '%04d%02d%02d', $value['year'], $value['month'], $value['day'] ); + if( 8 < strlen( $pValue )) { + if( isset( $value['hour'] )) { + if( 'T' == substr( $pValue, 8, 1 )) + $pValue = str_replace( 'T', '', $pValue ); + $valuedate .= sprintf( '%02d%02d%02d', $value['hour'], $value['min'], $value['sec'] ); + } + else + $pValue = substr( $pValue, 0, 8 ); + } + $hit[] = ( $pValue == $valuedate ) ? TRUE : FALSE; + continue; + } + elseif( !is_array( $value )) + $value = array( $value ); + foreach( $value as $part ) { + $part = ( FALSE !== strpos( $part, ',' )) ? explode( ',', $part ) : array( $part ); + foreach( $part as $subPart ) { + if( $pValue == $subPart ) { + $hit[] = TRUE; + continue 3; + } + } + } // end foreach( $value as $part ) + $hit[] = FALSE; // no hit in property + } // end foreach( $arg1 as $pName => $pValue ) + if( in_array( TRUE, $hit )) { + if( $index == $cix1gC ) + return $component->copy(); + $cix1gC++; + } + } // end elseif( is_array( $arg1 )) { // array( *[propertyName => propertyValue] ) + elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { // UID + if( $index == $cix1gC ) + return $component->copy(); + $cix1gC++; + } + } // end foreach ( $this->components.. . + /* not found.. . */ + unset( $this->compix ); + return FALSE; + } +/** + * create new calendar component, already included within calendar + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.6.33 - 2011-01-03 + * @param string $compType component type + * @return object (reference) + */ + function & newComponent( $compType ) { + $config = $this->getConfig(); + $keys = array_keys( $this->components ); + $ix = end( $keys) + 1; + switch( strtoupper( $compType )) { + case 'EVENT': + case 'VEVENT': + $this->components[$ix] = new vevent( $config ); + break; + case 'TODO': + case 'VTODO': + $this->components[$ix] = new vtodo( $config ); + break; + case 'JOURNAL': + case 'VJOURNAL': + $this->components[$ix] = new vjournal( $config ); + break; + case 'FREEBUSY': + case 'VFREEBUSY': + $this->components[$ix] = new vfreebusy( $config ); + break; + case 'TIMEZONE': + case 'VTIMEZONE': + array_unshift( $this->components, new vtimezone( $config )); + $ix = 0; + break; + default: + return FALSE; + } + return $this->components[$ix]; + } +/** + * select components from calendar on date or selectOption basis + * + * Ensure DTSTART is set for every component. + * No date controls occurs. + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.13 - 2013-03-16 + * @param mixed $startY optional, start Year, default current Year ALT. array selecOptions ( *[ => ] ) + * @param int $startM optional, start Month, default current Month + * @param int $startD optional, start Day, default current Day + * @param int $endY optional, end Year, default $startY + * @param int $endY optional, end Month, default $startM + * @param int $endY optional, end Day, default $startD + * @param mixed $cType optional, calendar component type(-s), default FALSE=all else string/array type(-s) + * @param bool $flat optional, FALSE (default) => output : array[Year][Month][Day][] + * TRUE => output : array[] (ignores split) + * @param bool $any optional, TRUE (default) - select component(-s) that occurs within period + * FALSE - only component(-s) that starts within period + * @param bool $split optional, TRUE (default) - one component copy every DAY it occurs during the + * period (implies flat=FALSE) + * FALSE - one occurance of component only in output array + * @return array or FALSE + */ + function selectComponents( $startY=FALSE, $startM=FALSE, $startD=FALSE, $endY=FALSE, $endM=FALSE, $endD=FALSE, $cType=FALSE, $flat=FALSE, $any=TRUE, $split=TRUE ) { + /* check if empty calendar */ + if( 0 >= count( $this->components )) return FALSE; + if( is_array( $startY )) + return $this->selectComponents2( $startY ); + /* check default dates */ + if( !$startY ) $startY = date( 'Y' ); + if( !$startM ) $startM = date( 'm' ); + if( !$startD ) $startD = date( 'd' ); + $startDate = mktime( 0, 0, 0, $startM, $startD, $startY ); + if( !$endY ) $endY = $startY; + if( !$endM ) $endM = $startM; + if( !$endD ) $endD = $startD; + $endDate = mktime( 23, 59, 59, $endM, $endD, $endY ); +// echo 'selectComp arg='.date( 'Y-m-d H:i:s', $startDate).' -- '.date( 'Y-m-d H:i:s', $endDate)."
    \n"; $tcnt = 0;// test ### + /* check component types */ + $validTypes = array('vevent', 'vtodo', 'vjournal', 'vfreebusy' ); + if( is_array( $cType )) { + foreach( $cType as $cix => $theType ) { + $cType[$cix] = $theType = strtolower( $theType ); + if( !in_array( $theType, $validTypes )) + $cType[$cix] = 'vevent'; + } + $cType = array_unique( $cType ); + } + elseif( !empty( $cType )) { + $cType = strtolower( $cType ); + if( !in_array( $cType, $validTypes )) + $cType = array( 'vevent' ); + else + $cType = array( $cType ); + } + else + $cType = $validTypes; + if( 0 >= count( $cType )) + $cType = $validTypes; + if(( FALSE === $flat ) && ( FALSE === $any )) // invalid combination + $split = FALSE; + if(( TRUE === $flat ) && ( TRUE === $split )) // invalid combination + $split = FALSE; + /* iterate components */ + $result = array(); + $this->sort( 'UID' ); + $compUIDcmp = null; + $recurridList = array(); + foreach ( $this->components as $cix => $component ) { + if( empty( $component )) continue; + unset( $start ); + /* deselect unvalid type components */ + if( !in_array( $component->objName, $cType )) + continue; + $start = $component->getProperty( 'dtstart' ); + /* select due when dtstart is missing */ + if( empty( $start ) && ( $component->objName == 'vtodo' ) && ( FALSE === ( $start = $component->getProperty( 'due' )))) + continue; + if( empty( $start )) + continue; + $compUID = $component->getProperty( 'UID' ); + if( $compUIDcmp != $compUID ) { + $compUIDcmp = $compUID; + unset( $exdatelist, $recurridList ); + } + $dtendExist = $dueExist = $durationExist = $endAllDayEvent = $recurrid = FALSE; + unset( $end, $startWdate, $endWdate, $rdurWsecs, $rdur, $workstart, $workend, $endDateFormat ); // clean up + $startWdate = iCalUtilityFunctions::_date2timestamp( $start ); + $startDateFormat = ( isset( $start['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d'; + /* get end date from dtend/due/duration properties */ + $end = $component->getProperty( 'dtend' ); + if( !empty( $end )) { + $dtendExist = TRUE; + $endDateFormat = ( isset( $end['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d'; + } + if( empty( $end ) && ( $component->objName == 'vtodo' )) { + $end = $component->getProperty( 'due' ); + if( !empty( $end )) { + $dueExist = TRUE; + $endDateFormat = ( isset( $end['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d'; + } + } + if( !empty( $end ) && !isset( $end['hour'] )) { + /* a DTEND without time part regards an event that ends the day before, + for an all-day event DTSTART=20071201 DTEND=20071202 (taking place 20071201!!! */ + $endAllDayEvent = TRUE; + $endWdate = mktime( 23, 59, 59, $end['month'], ($end['day'] - 1), $end['year'] ); + $end['year'] = date( 'Y', $endWdate ); + $end['month'] = date( 'm', $endWdate ); + $end['day'] = date( 'd', $endWdate ); + $end['hour'] = 23; + $end['min'] = $end['sec'] = 59; + } + if( empty( $end )) { + $end = $component->getProperty( 'duration', FALSE, FALSE, TRUE );// in dtend (array) format + if( !empty( $end )) + $durationExist = TRUE; + $endDateFormat = ( isset( $start['hour'] )) ? 'Y-m-d H:i:s' : 'Y-m-d'; +// if( !empty($end)) echo 'selectComp 4 start='.implode('-',$start).' end='.implode('-',$end)."
    \n"; // test ### + } + if( empty( $end )) { // assume one day duration if missing end date + $end = array( 'year' => $start['year'], 'month' => $start['month'], 'day' => $start['day'], 'hour' => 23, 'min' => 59, 'sec' => 59 ); + } +// if( isset($end)) echo 'selectComp 5 start='.implode('-',$start).' end='.implode('-',$end)."
    \n"; // test ### + $endWdate = iCalUtilityFunctions::_date2timestamp( $end ); + if( $endWdate < $startWdate ) { // MUST be after start date!! + $end = array( 'year' => $start['year'], 'month' => $start['month'], 'day' => $start['day'], 'hour' => 23, 'min' => 59, 'sec' => 59 ); + $endWdate = iCalUtilityFunctions::_date2timestamp( $end ); + } + $rdurWsecs = $endWdate - $startWdate; // compute event (component) duration in seconds + /* make a list of optional exclude dates for component occurence from exrule and exdate */ + $exdatelist = array(); + $workstart = iCalUtilityFunctions::_timestamp2date(( $startDate - $rdurWsecs ), 6); + $workend = iCalUtilityFunctions::_timestamp2date(( $endDate + $rdurWsecs ), 6); + while( FALSE !== ( $exrule = $component->getProperty( 'exrule' ))) // check exrule + iCalUtilityFunctions::_recur2date( $exdatelist, $exrule, $start, $workstart, $workend ); + while( FALSE !== ( $exdate = $component->getProperty( 'exdate' ))) { // check exdate + foreach( $exdate as $theExdate ) { + $exWdate = iCalUtilityFunctions::_date2timestamp( $theExdate ); + $exWdate = mktime( 0, 0, 0, date( 'm', $exWdate ), date( 'd', $exWdate ), date( 'Y', $exWdate )); // on a day-basis !!! + if((( $startDate - $rdurWsecs ) <= $exWdate ) && ( $endDate >= $exWdate )) + $exdatelist[$exWdate] = TRUE; + } // end - foreach( $exdate as $theExdate ) + } // end - check exdate + /* check recurrence-id (note, a missing sequence is the same as sequence=0 so don't test for sequence), remove hit with reccurr-id date */ + if( FALSE !== ( $t = $recurrid = $component->getProperty( 'recurrence-id' ))) { + $recurrid = iCalUtilityFunctions::_date2timestamp( $recurrid ); + $recurrid = mktime( 0, 0, 0, date( 'm', $recurrid ), date( 'd', $recurrid ), date( 'Y', $recurrid )); // on a day-basis !!! + $recurridList[$recurrid] = TRUE; // no recurring to start this day +// echo "adding comp no:$cix with date=".implode($start)." and recurrid=".implode($t)." to recurridList id=$recurrid
    \n"; // test ### + } // end recurrence-id/sequence test + /* select only components with.. . */ + if(( !$any && ( $startWdate >= $startDate ) && ( $startWdate <= $endDate )) || // (dt)start within the period + ( $any && ( $startWdate < $endDate ) && ( $endWdate >= $startDate ))) { // occurs within the period + /* add the selected component (WITHIN valid dates) to output array */ + if( $flat ) { // any=true/false, ignores split + if( !$recurrid ) + $result[$compUID] = $component->copy(); // copy original to output (but not anyone with recurrence-id) + } + elseif( $split ) { // split the original component + if( $endWdate > $endDate ) + $endWdate = $endDate; // use period end date + $rstart = $startWdate; + if( $rstart < $startDate ) + $rstart = $startDate; // use period start date + $startYMD = $rstartYMD = date( 'Ymd', $rstart ); + $endYMD = date( 'Ymd', $endWdate ); + $checkDate = mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!! +// echo "going to test comp no:$cix with rstartYMD=$rstartYMD, endYMD=$endYMD and checkDate($checkDate) with recurridList=".implode(',',array_keys($recurridList))."
    \n"; // test ### + if( !isset( $exdatelist[$checkDate] )) { // exclude any recurrence START date, found in exdatelist + while( $rstartYMD <= $endYMD ) { // iterate + if( isset( $exdatelist[$checkDate] ) || // exclude any recurrence date, found in the exdatelist + ( isset( $recurridList[$checkDate] ) && !$recurrid )) { // or in the recurridList, but not itself +// echo "skipping comp no:$cix with datestart=$rstartYMD and checkdate=$checkDate
    \n"; // test ### + $rstart = mktime( date( 'H', $rstart ), date( 'i', $rstart ), date( 's', $rstart ), date( 'm', $rstart ), date( 'd', $rstart ) + 1, date( 'Y', $rstart ) ); // step one day + $rstartYMD = date( 'Ymd', $rstart ); + continue; + } + if( $rstartYMD > $startYMD ) // date after dtstart + $datestring = date( $startDateFormat, $checkDate ); // mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ))); + else + $datestring = date( $startDateFormat, $rstart ); + if( isset( $start['tz'] )) + $datestring .= ' '.$start['tz']; +// echo "split org comp no:$cix rstartYMD=$rstartYMD (datestring=$datestring)
    \n"; // test ### + $component->setProperty( 'X-CURRENT-DTSTART', $datestring ); + if( $dtendExist || $dueExist || $durationExist ) { + if( $rstartYMD < $endYMD ) // not the last day + $tend = mktime( 23, 59, 59, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart )); + else + $tend = mktime( date( 'H', $endWdate ), date( 'i', $endWdate ), date( 's', $endWdate ), date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!! + if( $endAllDayEvent && $dtendExist ) + $tend += ( 24 * 3600 ); // alldaysevents has an end date 'day after' meaning this day + $datestring = date( $endDateFormat, $tend ); + if( isset( $end['tz'] )) + $datestring .= ' '.$end['tz']; + $propName = ( !$dueExist ) ? 'X-CURRENT-DTEND' : 'X-CURRENT-DUE'; + $component->setProperty( $propName, $datestring ); + } // end if( $dtendExist || $dueExist || $durationExist ) + $wd = getdate( $rstart ); + $result[$wd['year']][$wd['mon']][$wd['mday']][$compUID] = $component->copy(); // copy to output + $rstart = mktime( date( 'H', $rstart ), date( 'i', $rstart ), date( 's', $rstart ), date( 'm', $rstart ), date( 'd', $rstart ) + 1, date( 'Y', $rstart ) ); // step one day + $rstartYMD = date( 'Ymd', $rstart ); + $checkDate = mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!! + } // end while( $rstart <= $endWdate ) + } // end if( !isset( $exdatelist[$checkDate] )) + } // end elseif( $split ) - else use component date + elseif( $recurrid && !$flat && !$any && !$split ) + $continue = TRUE; + else { // !$flat && !$split, i.e. no flat array and DTSTART within period + $checkDate = mktime( 0, 0, 0, date( 'm', $startWdate ), date( 'd', $startWdate ), date( 'Y', $startWdate ) ); // on a day-basis !!! +// echo "going to test comp no:$cix with checkDate=$checkDate with recurridList=".implode(',',array_keys($recurridList)); // test ### + if(( !$any || !isset( $exdatelist[$checkDate] )) && // exclude any recurrence date, found in exdatelist + ( !isset( $recurridList[$checkDate] ) || $recurrid )) { // or in the recurridList, but not itself +// echo " and copied to output
    \n"; // test ### + $wd = getdate( $startWdate ); + $result[$wd['year']][$wd['mon']][$wd['mday']][$compUID] = $component->copy(); // copy to output + } + } + } // end if(( $startWdate >= $startDate ) && ( $startWdate <= $endDate )) + /* if 'any' components, check components with reccurrence rules, removing all excluding dates */ + if( TRUE === $any ) { + /* make a list of optional repeating dates for component occurence, rrule, rdate */ + $recurlist = array(); + while( FALSE !== ( $rrule = $component->getProperty( 'rrule' ))) // check rrule + iCalUtilityFunctions::_recur2date( $recurlist, $rrule, $start, $workstart, $workend ); + foreach( $recurlist as $recurkey => $recurvalue ) // key=match date as timestamp + $recurlist[$recurkey] = $rdurWsecs; // add duration in seconds + while( FALSE !== ( $rdate = $component->getProperty( 'rdate' ))) { // check rdate + foreach( $rdate as $theRdate ) { + if( is_array( $theRdate ) && ( 2 == count( $theRdate )) && // all days within PERIOD + array_key_exists( '0', $theRdate ) && array_key_exists( '1', $theRdate )) { + $rstart = iCalUtilityFunctions::_date2timestamp( $theRdate[0] ); + if(( $rstart < ( $startDate - $rdurWsecs )) || ( $rstart > $endDate )) + continue; + if( isset( $theRdate[1]['year'] )) // date-date period + $rend = iCalUtilityFunctions::_date2timestamp( $theRdate[1] ); + else { // date-duration period + $rend = iCalUtilityFunctions::_duration2date( $theRdate[0], $theRdate[1] ); + $rend = iCalUtilityFunctions::_date2timestamp( $rend ); + } + while( $rstart < $rend ) { + $recurlist[$rstart] = $rdurWsecs; // set start date for recurrence instance + rdate duration in seconds + $rstart = mktime( date( 'H', $rstart ), date( 'i', $rstart ), date( 's', $rstart ), date( 'm', $rstart ), date( 'd', $rstart ) + 1, date( 'Y', $rstart ) ); // step one day + } + } // PERIOD end + else { // single date + $theRdate = iCalUtilityFunctions::_date2timestamp( $theRdate ); + if((( $startDate - $rdurWsecs ) <= $theRdate ) && ( $endDate >= $theRdate )) + $recurlist[$theRdate] = $rdurWsecs; // set start date for recurrence instance + event duration in seconds + } + } + } // end - check rdate + foreach( $recurlist as $recurkey => $durvalue ) { // remove all recurrence START dates found in the exdatelist + $checkDate = mktime( 0, 0, 0, date( 'm', $recurkey ), date( 'd', $recurkey ), date( 'Y', $recurkey ) ); // on a day-basis !!! + if( isset( $exdatelist[$checkDate] )) // no recurring to start this day + unset( $recurlist[$recurkey] ); + } + if( 0 < count( $recurlist )) { + ksort( $recurlist ); + $xRecurrence = 1; + $component2 = $component->copy(); + $compUID = $component2->getProperty( 'UID' ); + foreach( $recurlist as $recurkey => $durvalue ) { +// echo "recurKey=".date( 'Y-m-d H:i:s', $recurkey ).' dur='.iCalUtilityFunctions::offsetSec2His( $durvalue )."
    \n"; // test ###; + if((( $startDate - $rdurWsecs ) > $recurkey ) || ( $endDate < $recurkey )) // not within period + continue; + $checkDate = mktime( 0, 0, 0, date( 'm', $recurkey ), date( 'd', $recurkey ), date( 'Y', $recurkey ) ); // on a day-basis !!! + if( isset( $recurridList[$checkDate] )) // no recurring to start this day + continue; + if( isset( $exdatelist[$checkDate] )) // check excluded dates + continue; + if( $startWdate >= $recurkey ) // exclude component start date + continue; + $rstart = $recurkey; + $rend = $recurkey + $durvalue; + /* add repeating components within valid dates to output array, only start date set */ + if( $flat ) { + if( !isset( $result[$compUID] )) // only one comp + $result[$compUID] = $component2->copy(); // copy to output + } + /* add repeating components within valid dates to output array, one each day */ + elseif( $split ) { + $xRecurrence += 1; + if( $rend > $endDate ) + $rend = $endDate; + $startYMD = $rstartYMD = date( 'Ymd', $rstart ); + $endYMD = date( 'Ymd', $rend ); +// echo "splitStart=".date( 'Y-m-d H:i:s', $rstart ).' end='.date( 'Y-m-d H:i:s', $rend )."
    \n"; // test ###; + while( $rstart <= $rend ) { // iterate.. . + $checkDate = mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!! + if( isset( $recurridList[$checkDate] )) // no recurring to start this day + break; + if( isset( $exdatelist[$checkDate] )) // exclude any recurrence START date, found in exdatelist + break; +// echo "checking date after startdate=".date( 'Y-m-d H:i:s', $rstart ).' mot '.date( 'Y-m-d H:i:s', $startDate )."
    "; // test ###; + if( $rstart >= $startDate ) { // date after dtstart + if( $rstartYMD > $startYMD ) // date after dtstart + $datestring = date( $startDateFormat, $checkDate ); + else + $datestring = date( $startDateFormat, $rstart ); + if( isset( $start['tz'] )) + $datestring .= ' '.$start['tz']; +// echo "spliting = $datestring
    \n"; // test ### + $component2->setProperty( 'X-CURRENT-DTSTART', $datestring ); + if( $dtendExist || $dueExist || $durationExist ) { + if( $rstartYMD < $endYMD ) // not the last day + $tend = mktime( 23, 59, 59, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart )); + else + $tend = mktime( date( 'H', $endWdate ), date( 'i', $endWdate ), date( 's', $endWdate ), date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!! + if( $endAllDayEvent && $dtendExist ) + $tend += ( 24 * 3600 ); // alldaysevents has an end date 'day after' meaning this day + $datestring = date( $endDateFormat, $tend ); + if( isset( $end['tz'] )) + $datestring .= ' '.$end['tz']; + $propName = ( !$dueExist ) ? 'X-CURRENT-DTEND' : 'X-CURRENT-DUE'; + $component2->setProperty( $propName, $datestring ); + } // end if( $dtendExist || $dueExist || $durationExist ) + $component2->setProperty( 'X-RECURRENCE', $xRecurrence ); + $wd = getdate( $rstart ); + $result[$wd['year']][$wd['mon']][$wd['mday']][$compUID] = $component2->copy(); // copy to output + } // end if( $checkDate > $startYMD ) { // date after dtstart + $rstart = mktime( date( 'H', $rstart ), date( 'i', $rstart ), date( 's', $rstart ), date( 'm', $rstart ), date( 'd', $rstart ) + 1, date( 'Y', $rstart ) ); // step one day + $rstartYMD = date( 'Ymd', $rstart ); + } // end while( $rstart <= $rend ) + } // end elseif( $split ) + elseif( $rstart >= $startDate ) { // date within period //* flat=FALSE && split=FALSE => one comp every recur startdate *// + $xRecurrence += 1; + $checkDate = mktime( 0, 0, 0, date( 'm', $rstart ), date( 'd', $rstart ), date( 'Y', $rstart ) ); // on a day-basis !!! + if( !isset( $exdatelist[$checkDate] )) { // exclude any recurrence START date, found in exdatelist + $datestring = date( $startDateFormat, $rstart ); + if( isset( $start['tz'] )) + $datestring .= ' '.$start['tz']; +//echo "X-CURRENT-DTSTART 2 = $datestring xRecurrence=$xRecurrence tcnt =".++$tcnt."
    ";$component2->setProperty( 'X-CNT', $tcnt ); // test ### + $component2->setProperty( 'X-CURRENT-DTSTART', $datestring ); + if( $dtendExist || $dueExist || $durationExist ) { + $tend = $rstart + $rdurWsecs; + if( date( 'Ymd', $tend ) < date( 'Ymd', $endWdate )) + $tend = mktime( 23, 59, 59, date( 'm', $tend ), date( 'd', $tend ), date( 'Y', $tend )); + else + $tend = mktime( date( 'H', $endWdate ), date( 'i', $endWdate ), date( 's', $endWdate ), date( 'm', $tend ), date( 'd', $tend ), date( 'Y', $tend ) ); // on a day-basis !!! + if( $endAllDayEvent && $dtendExist ) + $tend += ( 24 * 3600 ); // alldaysevents has an end date 'day after' meaning this day + $datestring = date( $endDateFormat, $tend ); + if( isset( $end['tz'] )) + $datestring .= ' '.$end['tz']; + $propName = ( !$dueExist ) ? 'X-CURRENT-DTEND' : 'X-CURRENT-DUE'; + $component2->setProperty( $propName, $datestring ); + } // end if( $dtendExist || $dueExist || $durationExist ) + $component2->setProperty( 'X-RECURRENCE', $xRecurrence ); + $wd = getdate( $rstart ); + $result[$wd['year']][$wd['mon']][$wd['mday']][$compUID] = $component2->copy(); // copy to output + } // end if( !isset( $exdatelist[$checkDate] )) + } // end elseif( $rstart >= $startDate ) + } // end foreach( $recurlist as $recurkey => $durvalue ) + unset( $component2 ); + } // end if( 0 < count( $recurlist )) + /* deselect components with startdate/enddate not within period */ + if(( $endWdate < $startDate ) || ( $startWdate > $endDate )) + continue; + } // end if( TRUE === $any ) + } // end foreach ( $this->components as $cix => $component ) + unset( $dtendExist, $dueExist, $durationExist, $endAllDayEvent, $recurrid, $recurridList, + $end, $startWdate, $endWdate, $rdurWsecs, $rdur, $exdatelist, $recurlist, $workstart, $workend, $endDateFormat ); // clean up + if( 0 >= count( $result )) return FALSE; + elseif( !$flat ) { + foreach( $result as $y => $yeararr ) { + foreach( $yeararr as $m => $montharr ) { + foreach( $montharr as $d => $dayarr ) { + if( empty( $result[$y][$m][$d] )) + unset( $result[$y][$m][$d] ); + else + $result[$y][$m][$d] = array_values( $dayarr ); // skip tricky UID-index, hoping they are in hour order.. . + } + if( empty( $result[$y][$m] )) + unset( $result[$y][$m] ); + else + ksort( $result[$y][$m] ); + } + if( empty( $result[$y] )) + unset( $result[$y] ); + else + ksort( $result[$y] ); + } + if( empty( $result )) + unset( $result ); + else + ksort( $result ); + } // end elseif( !$flat ) + if( 0 >= count( $result )) + return FALSE; + return $result; + } +/** + * select components from calendar on based on specific property value(-s) + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.6 - 2012-12-26 + * @param array $selectOptions, (string) key => (mixed) value, (key=propertyName) + * @return array + */ + function selectComponents2( $selectOptions ) { + $output = array(); + $allowedComps = array('vevent', 'vtodo', 'vjournal', 'vfreebusy' ); + $allowedProperties = array( 'ATTENDEE', 'CATEGORIES', 'CONTACT', 'LOCATION', 'ORGANIZER', 'PRIORITY', 'RELATED-TO', 'RESOURCES', 'STATUS', 'SUMMARY', 'UID', 'URL' ); + foreach( $this->components as $cix => $component3 ) { + if( !in_array( $component3->objName, $allowedComps )) + continue; + $uid = $component3->getProperty( 'UID' ); + foreach( $selectOptions as $propName => $pvalue ) { + $propName = strtoupper( $propName ); + if( !in_array( $propName, $allowedProperties )) + continue; + if( !is_array( $pvalue )) + $pvalue = array( $pvalue ); + if(( 'UID' == $propName ) && in_array( $uid, $pvalue )) { + $output[$uid][] = $component3->copy(); + continue; + } + elseif(( 'ATTENDEE' == $propName ) || ( 'CATEGORIES' == $propName ) || ( 'CONTACT' == $propName ) || ( 'RELATED-TO' == $propName ) || ( 'RESOURCES' == $propName )) { // multiple occurrence? + $propValues = array(); + $component3->_getProperties( $propName, $propValues ); + $propValues = array_keys( $propValues ); + foreach( $pvalue as $theValue ) { + if( in_array( $theValue, $propValues )) { // && !isset( $output[$uid] )) { + $output[$uid][] = $component3->copy(); + break; + } + } + continue; + } // end elseif( // multiple occurrence? + elseif( FALSE === ( $d = $component3->getProperty( $propName ))) // single occurrence + continue; + if( is_array( $d )) { + foreach( $d as $part ) { + if( in_array( $part, $pvalue ) && !isset( $output[$uid] )) + $output[$uid][] = $component3->copy(); + } + } + elseif(( 'SUMMARY' == $propName ) && !isset( $output[$uid] )) { + foreach( $pvalue as $pval ) { + if( FALSE !== stripos( $d, $pval )) { + $output[$uid][] = $component3->copy(); + break; + } + } + } + elseif( in_array( $d, $pvalue ) && !isset( $output[$uid] )) + $output[$uid][] = $component3->copy(); + } // end foreach( $selectOptions as $propName => $pvalue ) { + } // end foreach( $this->components as $cix => $component3 ) { + if( !empty( $output )) { + ksort( $output ); // uid order + $output2 = array(); + foreach( $output as $uid => $components ) { + foreach( $components as $component ) + $output2[] = $component; + } + $output = $output2; + } + return $output; + } +/** + * add calendar component to container + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.8 - 2011-03-15 + * @param object $component calendar component + * @param mixed $arg1 optional, ordno/component type/ component uid + * @param mixed $arg2 optional, ordno if arg1 = component type + * @return void + */ + function setComponent( $component, $arg1=FALSE, $arg2=FALSE ) { + $component->setConfig( $this->getConfig(), FALSE, TRUE ); + if( !in_array( $component->objName, array( 'valarm', 'vtimezone' ))) { + /* make sure dtstamp and uid is set */ + $dummy1 = $component->getProperty( 'dtstamp' ); + $dummy2 = $component->getProperty( 'uid' ); + } + if( !$arg1 ) { // plain insert, last in chain + $this->components[] = $component->copy(); + return TRUE; + } + $argType = $index = null; + if ( ctype_digit( (string) $arg1 )) { // index insert/replace + $argType = 'INDEX'; + $index = (int) $arg1 - 1; + } + elseif( in_array( strtolower( $arg1 ), array( 'vevent', 'vtodo', 'vjournal', 'vfreebusy', 'valarm', 'vtimezone' ))) { + $argType = strtolower( $arg1 ); + $index = ( ctype_digit( (string) $arg2 )) ? ((int) $arg2) - 1 : 0; + } + // else if arg1 is set, arg1 must be an UID + $cix1sC = 0; + foreach ( $this->components as $cix => $component2) { + if( empty( $component2 )) continue; + if(( 'INDEX' == $argType ) && ( $index == $cix )) { // index insert/replace + $this->components[$cix] = $component->copy(); + return TRUE; + } + elseif( $argType == $component2->objName ) { // component Type index insert/replace + if( $index == $cix1sC ) { + $this->components[$cix] = $component->copy(); + return TRUE; + } + $cix1sC++; + } + elseif( !$argType && ( $arg1 == $component2->getProperty( 'uid' ))) { // UID insert/replace + $this->components[$cix] = $component->copy(); + return TRUE; + } + } + /* arg1=index and not found.. . insert at index .. .*/ + if( 'INDEX' == $argType ) { + $this->components[$index] = $component->copy(); + ksort( $this->components, SORT_NUMERIC ); + } + else /* not found.. . insert last in chain anyway .. .*/ + $this->components[] = $component->copy(); + return TRUE; + } +/** + * sort iCal compoments + * + * ascending sort on properties (if exist) x-current-dtstart, dtstart, + * x-current-dtend, dtend, x-current-due, due, duration, created, dtstamp, uid if called without arguments, + * otherwise sorting on specific (argument) property values + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.4 - 2012-12-17 + * @param string $sortArg, optional + * @return void + * + */ + function sort( $sortArg=FALSE ) { + if( ! is_array( $this->components ) || ( 2 > count( $this->components ))) + return; + if( $sortArg ) { + $sortArg = strtoupper( $sortArg ); + if( !in_array( $sortArg, array( 'ATTENDEE', 'CATEGORIES', 'CONTACT', 'DTSTAMP', 'LOCATION', 'ORGANIZER', 'PRIORITY', 'RELATED-TO', 'RESOURCES', 'STATUS', 'SUMMARY', 'UID', 'URL' ))) + $sortArg = FALSE; + } + /* set sort parameters for each component */ + foreach( $this->components as $cix => & $c ) { + $c->srtk = array( '0', '0', '0', '0' ); + if( 'vtimezone' == $c->objName ) { + if( FALSE === ( $c->srtk[0] = $c->getProperty( 'tzid' ))) + $c->srtk[0] = 0; + continue; + } + elseif( $sortArg ) { + if(( 'ATTENDEE' == $sortArg ) || ( 'CATEGORIES' == $sortArg ) || ( 'CONTACT' == $sortArg ) || ( 'RELATED-TO' == $sortArg ) || ( 'RESOURCES' == $sortArg )) { + $propValues = array(); + $c->_getProperties( $sortArg, $propValues ); + if( !empty( $propValues )) { + $sk = array_keys( $propValues ); + $c->srtk[0] = $sk[0]; + if( 'RELATED-TO' == $sortArg ) + $c->srtk[0] .= $c->getProperty( 'uid' ); + } + elseif( 'RELATED-TO' == $sortArg ) + $c->srtk[0] = $c->getProperty( 'uid' ); + } + elseif( FALSE !== ( $d = $c->getProperty( $sortArg ))) { + $c->srtk[0] = $d; + if( 'UID' == $sortArg ) { + if( FALSE !== ( $d = $c->getProperty( 'recurrence-id' ))) { + $c->srtk[1] = iCalUtilityFunctions::_date2strdate( $d ); + if( FALSE === ( $c->srtk[2] = $c->getProperty( 'sequence' ))) + $c->srtk[2] = PHP_INT_MAX; + } + else + $c->srtk[1] = $c->srtk[2] = PHP_INT_MAX; + } + } + continue; + } // end elseif( $sortArg ) + if( FALSE !== ( $d = $c->getProperty( 'X-CURRENT-DTSTART' ))) { + $c->srtk[0] = iCalUtilityFunctions::_strdate2date( $d[1] ); + unset( $c->srtk[0]['unparsedtext'] ); + } + elseif( FALSE === ( $c->srtk[0] = $c->getProperty( 'dtstart' ))) + $c->srtk[0] = 0; // sortkey 0 : dtstart + + if( FALSE !== ( $d = $c->getProperty( 'X-CURRENT-DTEND' ))) { + $c->srtk[1] = iCalUtilityFunctions::_strdate2date( $d[1] ); // sortkey 1 : dtend/due(/duration) + unset( $c->srtk[1]['unparsedtext'] ); + } + elseif( FALSE === ( $c->srtk[1] = $c->getProperty( 'dtend' ))) { + if( FALSE !== ( $d = $c->getProperty( 'X-CURRENT-DUE' ))) { + $c->srtk[1] = iCalUtilityFunctions::_strdate2date( $d[1] ); + unset( $c->srtk[1]['unparsedtext'] ); + } + elseif( FALSE === ( $c->srtk[1] = $c->getProperty( 'due' ))) + if( FALSE === ( $c->srtk[1] = $c->getProperty( 'duration', FALSE, FALSE, TRUE ))) + $c->srtk[1] = 0; + } + + if( FALSE === ( $c->srtk[2] = $c->getProperty( 'created' ))) // sortkey 2 : created/dtstamp + if( FALSE === ( $c->srtk[2] = $c->getProperty( 'dtstamp' ))) + $c->srtk[2] = 0; + + if( FALSE === ( $c->srtk[3] = $c->getProperty( 'uid' ))) // sortkey 3 : uid + $c->srtk[3] = 0; + } // end foreach( $this->components as & $c + /* sort */ + usort( $this->components, array( 'iCalUtilityFunctions', '_cmpfcn' )); + } +/** + * parse iCal text/file into vcalendar, components, properties and parameters + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @param mixed $unparsedtext, optional, strict rfc2445 formatted, single property string or array of property strings + * @return bool FALSE if error occurs during parsing + * + */ + function parse( $unparsedtext=FALSE ) { + $nl = $this->getConfig( 'nl' ); + if(( FALSE === $unparsedtext ) || empty( $unparsedtext )) { + /* directory+filename is set previously via setConfig directory+filename or url */ + if( FALSE === ( $filename = $this->getConfig( 'url' ))) + $filename = $this->getConfig( 'dirfile' ); + /* READ FILE */ + if( FALSE === ( $rows = file_get_contents( $filename ))) + return FALSE; /* err 1 */ + } + elseif( is_array( $unparsedtext )) + $rows = implode( '\n'.$nl, $unparsedtext ); + else + $rows = & $unparsedtext; + /* fix line folding */ + $rows = explode( $nl, iCalUtilityFunctions::convEolChar( $rows, $nl )); + /* skip leading (empty/invalid) lines */ + foreach( $rows as $lix => $line ) { + if( FALSE !== stripos( $line, 'BEGIN:VCALENDAR' )) + break; + unset( $rows[$lix] ); + } + $rcnt = count( $rows ); + if( 3 > $rcnt ) /* err 10 */ + return FALSE; + /* skip trailing empty lines and ensure an end row */ + $lix = array_keys( $rows ); + $lix = end( $lix ); + while( 3 < $lix ) { + $tst = trim( $rows[$lix] ); + if(( '\n' == $tst ) || empty( $tst )) { + unset( $rows[$lix] ); + $lix--; + continue; + } + if( FALSE === stripos( $rows[$lix], 'END:VCALENDAR' )) + $rows[] = 'END:VCALENDAR'; + break; + } + $comp = & $this; + $calsync = $compsync = 0; + /* identify components and update unparsed data within component */ + $config = $this->getConfig(); + $endtxt = array( 'END:VE', 'END:VF', 'END:VJ', 'END:VT' ); + foreach( $rows as $lix => $line ) { + if( 'BEGIN:VCALENDAR' == strtoupper( substr( $line, 0, 15 ))) { + $calsync++; + continue; + } + elseif( 'END:VCALENDAR' == strtoupper( substr( $line, 0, 13 ))) { + if( 0 < $compsync ) + $this->components[] = $comp->copy(); + $compsync--; + $calsync--; + break; + } + elseif( 1 != $calsync ) + return FALSE; /* err 20 */ + elseif( in_array( strtoupper( substr( $line, 0, 6 )), $endtxt )) { + $this->components[] = $comp->copy(); + $compsync--; + continue; + } + if( 'BEGIN:VEVENT' == strtoupper( substr( $line, 0, 12 ))) { + $comp = new vevent( $config ); + $compsync++; + } + elseif( 'BEGIN:VFREEBUSY' == strtoupper( substr( $line, 0, 15 ))) { + $comp = new vfreebusy( $config ); + $compsync++; + } + elseif( 'BEGIN:VJOURNAL' == strtoupper( substr( $line, 0, 14 ))) { + $comp = new vjournal( $config ); + $compsync++; + } + elseif( 'BEGIN:VTODO' == strtoupper( substr( $line, 0, 11 ))) { + $comp = new vtodo( $config ); + $compsync++; + } + elseif( 'BEGIN:VTIMEZONE' == strtoupper( substr( $line, 0, 15 ))) { + $comp = new vtimezone( $config ); + $compsync++; + } + else { /* update component with unparsed data */ + $comp->unparsed[] = $line; + } + } // end foreach( $rows as $line ) + unset( $config, $endtxt ); + /* parse data for calendar (this) object */ + if( isset( $this->unparsed ) && is_array( $this->unparsed ) && ( 0 < count( $this->unparsed ))) { + /* concatenate property values spread over several lines */ + $propnames = array( 'calscale','method','prodid','version','x-' ); + $proprows = array(); + for( $i = 0; $i < count( $this->unparsed ); $i++ ) { // concatenate lines + $line = rtrim( $this->unparsed[$i], $nl ); + while( isset( $this->unparsed[$i+1] ) && !empty( $this->unparsed[$i+1] ) && ( ' ' == $this->unparsed[$i+1]{0} )) + $line .= rtrim( substr( $this->unparsed[++$i], 1 ), $nl ); + $proprows[] = $line; + } + $paramMStz = array( 'utc-', 'utc+', 'gmt-', 'gmt+' ); + $paramProto3 = array( 'fax:', 'cid:', 'sms:', 'tel:', 'urn:' ); + $paramProto4 = array( 'crid:', 'news:', 'pres:' ); + foreach( $proprows as $line ) { + if( '\n' == substr( $line, -2 )) + $line = substr( $line, 0, -2 ); + /* get property name */ + $propname = ''; + $cix = 0; + while( FALSE !== ( $char = substr( $line, $cix, 1 ))) { + if( in_array( $char, array( ':', ';' ))) + break; + else + $propname .= $char; + $cix++; + } + /* skip non standard property names */ + if(( 'x-' != strtolower( substr( $propname, 0, 2 ))) && !in_array( strtolower( $propname ), $propnames )) + continue; + /* ignore version/prodid properties */ + if( in_array( strtolower( $propname ), array( 'version', 'prodid' ))) + continue; + /* rest of the line is opt.params and value */ + $line = substr( $line, $cix); + /* separate attributes from value */ + $attr = array(); + $attrix = -1; + $strlen = strlen( $line ); + $WithinQuotes = FALSE; + $cix = 0; + while( FALSE !== substr( $line, $cix, 1 )) { + if( ( ':' == $line[$cix] ) && + ( substr( $line,$cix, 3 ) != '://' ) && + ( !in_array( strtolower( substr( $line,$cix - 6, 4 )), $paramMStz )) && + ( !in_array( strtolower( substr( $line,$cix - 3, 4 )), $paramProto3 )) && + ( !in_array( strtolower( substr( $line,$cix - 4, 5 )), $paramProto4 )) && + ( strtolower( substr( $line,$cix - 6, 7 )) != 'mailto:' ) && + !$WithinQuotes ) { + $attrEnd = TRUE; + if(( $cix < ( $strlen - 4 )) && + ctype_digit( substr( $line, $cix+1, 4 ))) { // an URI with a (4pos) portnr?? + for( $c2ix = $cix; 3 < $c2ix; $c2ix-- ) { + if( '://' == substr( $line, $c2ix - 2, 3 )) { + $attrEnd = FALSE; + break; // an URI with a portnr!! + } + } + } + if( $attrEnd) { + $line = substr( $line, ( $cix + 1 )); + break; + } + } + if( '"' == $line[$cix] ) + $WithinQuotes = ( FALSE === $WithinQuotes ) ? TRUE : FALSE; + if( ';' == $line[$cix] ) + $attr[++$attrix] = null; + else + $attr[$attrix] .= $line[$cix]; + $cix++; + } + /* make attributes in array format */ + $propattr = array(); + foreach( $attr as $attribute ) { + $attrsplit = explode( '=', $attribute, 2 ); + if( 1 < count( $attrsplit )) + $propattr[$attrsplit[0]] = $attrsplit[1]; + else + $propattr[] = $attribute; + } + /* update Property */ + if( FALSE !== strpos( $line, ',' )) { + $content = array( 0 => '' ); + $cix = $lix = 0; + while( FALSE !== substr( $line, $lix, 1 )) { + if(( 0 < $lix ) && ( ',' == $line[$lix] ) && ( "\\" != $line[( $lix - 1 )])) { + $cix++; + $content[$cix] = ''; + } + else + $content[$cix] .= $line[$lix]; + $lix++; + } + if( 1 < count( $content )) { + foreach( $content as $cix => $contentPart ) + $content[$cix] = iCalUtilityFunctions::_strunrep( $contentPart ); + $this->setProperty( $propname, $content, $propattr ); + continue; + } + else + $line = reset( $content ); + $line = iCalUtilityFunctions::_strunrep( $line ); + } + $this->setProperty( $propname, rtrim( $line, "\x00..\x1F" ), $propattr ); + } // end - foreach( $this->unparsed.. . + } // end - if( is_array( $this->unparsed.. . + unset( $unparsedtext, $rows, $this->unparsed, $proprows ); + /* parse Components */ + if( is_array( $this->components ) && ( 0 < count( $this->components ))) { + $ckeys = array_keys( $this->components ); + foreach( $ckeys as $ckey ) { + if( !empty( $this->components[$ckey] ) && !empty( $this->components[$ckey]->unparsed )) { + $this->components[$ckey]->parse(); + } + } + } + else + return FALSE; /* err 91 or something.. . */ + return TRUE; + } +/*********************************************************************************/ +/** + * creates formatted output for calendar object instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.16 - 2011-10-28 + * @return string + */ + function createCalendar() { + $calendarInit = $calendarxCaldecl = $calendarStart = $calendar = ''; + switch( $this->format ) { + case 'xcal': + $calendarInit = ''.$this->nl. + 'nl. + '"http://www.ietf.org/internet-drafts/draft-ietf-calsch-many-xcal-01.txt"'; + $calendarStart = '>'.$this->nl.'nl; + break; + } + $calendarStart .= $this->createVersion(); + $calendarStart .= $this->createProdid(); + $calendarStart .= $this->createCalscale(); + $calendarStart .= $this->createMethod(); + if( 'xcal' == $this->format ) + $calendarStart .= '>'.$this->nl; + $calendar .= $this->createXprop(); + + foreach( $this->components as $component ) { + if( empty( $component )) continue; + $component->setConfig( $this->getConfig(), FALSE, TRUE ); + $calendar .= $component->createComponent( $this->xcaldecl ); + } + if(( 'xcal' == $this->format ) && ( 0 < count( $this->xcaldecl ))) { // xCal only + $calendarInit .= ' ['; + $old_xcaldecl = array(); + foreach( $this->xcaldecl as $declix => $declPart ) { + if(( 0 < count( $old_xcaldecl)) && + isset( $declPart['uri'] ) && isset( $declPart['external'] ) && + isset( $old_xcaldecl['uri'] ) && isset( $old_xcaldecl['external'] ) && + ( in_array( $declPart['uri'], $old_xcaldecl['uri'] )) && + ( in_array( $declPart['external'], $old_xcaldecl['external'] ))) + continue; // no duplicate uri and ext. references + if(( 0 < count( $old_xcaldecl)) && + !isset( $declPart['uri'] ) && !isset( $declPart['uri'] ) && + isset( $declPart['ref'] ) && isset( $old_xcaldecl['ref'] ) && + ( in_array( $declPart['ref'], $old_xcaldecl['ref'] ))) + continue; // no duplicate element declarations + $calendarxCaldecl .= $this->nl.' $declValue ) { + switch( $declKey ) { // index + case 'xmldecl': // no 1 + $calendarxCaldecl .= $declValue.' '; + break; + case 'uri': // no 2 + $calendarxCaldecl .= $declValue.' '; + $old_xcaldecl['uri'][] = $declValue; + break; + case 'ref': // no 3 + $calendarxCaldecl .= $declValue.' '; + $old_xcaldecl['ref'][] = $declValue; + break; + case 'external': // no 4 + $calendarxCaldecl .= '"'.$declValue.'" '; + $old_xcaldecl['external'][] = $declValue; + break; + case 'type': // no 5 + $calendarxCaldecl .= $declValue.' '; + break; + case 'type2': // no 6 + $calendarxCaldecl .= $declValue; + break; + } + } + $calendarxCaldecl .= '>'; + } + $calendarxCaldecl .= $this->nl.']'; + } + switch( $this->format ) { + case 'xcal': + $calendar .= ''.$this->nl; + break; + default: + $calendar .= 'END:VCALENDAR'.$this->nl; + break; + } + return $calendarInit.$calendarxCaldecl.$calendarStart.$calendar; + } +/** + * a HTTP redirect header is sent with created, updated and/or parsed calendar + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.24 - 2011-12-23 + * @param bool $utf8Encode + * @param bool $gzip + * @return redirect + */ + function returnCalendar( $utf8Encode=FALSE, $gzip=FALSE ) { + $filename = $this->getConfig( 'filename' ); + $output = $this->createCalendar(); + if( $utf8Encode ) + $output = utf8_encode( $output ); + if( $gzip ) { + $output = gzencode( $output, 9 ); + header( 'Content-Encoding: gzip' ); + header( 'Vary: *' ); + header( 'Content-Length: '.strlen( $output )); + } + if( 'xcal' == $this->format ) + header( 'Content-Type: application/calendar+xml; charset=utf-8' ); + else + header( 'Content-Type: text/calendar; charset=utf-8' ); + header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); + header( 'Cache-Control: max-age=10' ); + die( $output ); + } +/** + * save content in a file + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.2.12 - 2007-12-30 + * @param string $directory optional + * @param string $filename optional + * @param string $delimiter optional + * @return bool + */ + function saveCalendar( $directory=FALSE, $filename=FALSE, $delimiter=FALSE ) { + if( $directory ) + $this->setConfig( 'directory', $directory ); + if( $filename ) + $this->setConfig( 'filename', $filename ); + if( $delimiter && ($delimiter != DIRECTORY_SEPARATOR )) + $this->setConfig( 'delimiter', $delimiter ); + if( FALSE === ( $dirfile = $this->getConfig( 'url' ))) + $dirfile = $this->getConfig( 'dirfile' ); + $iCalFile = @fopen( $dirfile, 'w' ); + if( $iCalFile ) { + if( FALSE === fwrite( $iCalFile, $this->createCalendar() )) + return FALSE; + fclose( $iCalFile ); + return TRUE; + } + else + return FALSE; + } +/** + * if recent version of calendar file exists (default one hour), an HTTP redirect header is sent + * else FALSE is returned + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.2.12 - 2007-10-28 + * @param string $directory optional alt. int timeout + * @param string $filename optional + * @param string $delimiter optional + * @param int timeout optional, default 3600 sec + * @return redirect/FALSE + */ + function useCachedCalendar( $directory=FALSE, $filename=FALSE, $delimiter=FALSE, $timeout=3600) { + if ( $directory && ctype_digit( (string) $directory ) && !$filename ) { + $timeout = (int) $directory; + $directory = FALSE; + } + if( $directory ) + $this->setConfig( 'directory', $directory ); + if( $filename ) + $this->setConfig( 'filename', $filename ); + if( $delimiter && ( $delimiter != DIRECTORY_SEPARATOR )) + $this->setConfig( 'delimiter', $delimiter ); + $filesize = $this->getConfig( 'filesize' ); + if( 0 >= $filesize ) + return FALSE; + $dirfile = $this->getConfig( 'dirfile' ); + if( time() - filemtime( $dirfile ) < $timeout) { + clearstatcache(); + $dirfile = $this->getConfig( 'dirfile' ); + $filename = $this->getConfig( 'filename' ); +// if( headers_sent( $filename, $linenum )) +// die( "Headers already sent in $filename on line $linenum\n" ); + if( 'xcal' == $this->format ) + header( 'Content-Type: application/calendar+xml; charset=utf-8' ); + else + header( 'Content-Type: text/calendar; charset=utf-8' ); + header( 'Content-Length: '.$filesize ); + header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); + header( 'Cache-Control: max-age=10' ); + $fp = @fopen( $dirfile, 'r' ); + if( $fp ) { + fpassthru( $fp ); + fclose( $fp ); + } + die(); + } + else + return FALSE; + } +} +/*********************************************************************************/ +/*********************************************************************************/ +/** + * abstract class for calendar components + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.9.6 - 2011-05-14 + */ +class calendarComponent { + // component property variables + var $uid; + var $dtstamp; + + // component config variables + var $allowEmpty; + var $language; + var $nl; + var $unique_id; + var $format; + var $objName; // created automatically at instance creation + var $dtzid; // default (local) timezone + // component internal variables + var $componentStart1; + var $componentStart2; + var $componentEnd1; + var $componentEnd2; + var $elementStart1; + var $elementStart2; + var $elementEnd1; + var $elementEnd2; + var $intAttrDelimiter; + var $attributeDelimiter; + var $valueInit; + // component xCal declaration container + var $xcaldecl; +/** + * constructor for calendar component object + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.9.6 - 2011-05-17 + */ + function __construct() { + $this->objName = ( isset( $this->timezonetype )) ? + strtolower( $this->timezonetype ) : get_class ( $this ); + $this->uid = array(); + $this->dtstamp = array(); + + $this->language = null; + $this->nl = null; + $this->unique_id = null; + $this->format = null; + $this->dtzid = null; + $this->allowEmpty = TRUE; + $this->xcaldecl = array(); + + $this->_createFormat(); + $this->_makeDtstamp(); + } +/*********************************************************************************/ +/** + * Property Name: ACTION + */ +/** + * creates formatted output for calendar component property action + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-22 + * @return string + */ + function createAction() { + if( empty( $this->action )) return FALSE; + if( empty( $this->action['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'ACTION' ) : FALSE; + $attributes = $this->_createParams( $this->action['params'] ); + return $this->_createElement( 'ACTION', $attributes, $this->action['value'] ); + } +/** + * set calendar component property action + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE" + * @param mixed $params + * @return bool + */ + function setAction( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->action = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: ATTACH + */ +/** + * creates formatted output for calendar component property attach + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.11.16 - 2012-02-04 + * @return string + */ + function createAttach() { + if( empty( $this->attach )) return FALSE; + $output = null; + foreach( $this->attach as $attachPart ) { + if( !empty( $attachPart['value'] )) { + $attributes = $this->_createParams( $attachPart['params'] ); + if(( 'xcal' != $this->format ) && isset( $attachPart['params']['VALUE'] ) && ( 'BINARY' == $attachPart['params']['VALUE'] )) { + $attributes = str_replace( $this->intAttrDelimiter, $this->attributeDelimiter, $attributes ); + $str = 'ATTACH'.$attributes.$this->valueInit.$attachPart['value']; + $output = substr( $str, 0, 75 ).$this->nl; + $str = substr( $str, 75 ); + $output .= ' '.chunk_split( $str, 74, $this->nl.' ' ); + if( ' ' == substr( $output, -1 )) + $output = rtrim( $output ); + if( $this->nl != substr( $output, ( 0 - strlen( $this->nl )))) + $output .= $this->nl; + return $output; + } + $output .= $this->_createElement( 'ATTACH', $attributes, $attachPart['value'] ); + } + elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'ATTACH' ); + } + return $output; + } +/** + * set calendar component property attach + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setAttach( $value, $params=FALSE, $index=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + iCalUtilityFunctions::_setMval( $this->attach, $value, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: ATTENDEE + */ +/** + * creates formatted output for calendar component property attendee + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.11.12 - 2012-01-31 + * @return string + */ + function createAttendee() { + if( empty( $this->attendee )) return FALSE; + $output = null; + foreach( $this->attendee as $attendeePart ) { // start foreach 1 + if( empty( $attendeePart['value'] )) { + if( $this->getConfig( 'allowEmpty' )) + $output .= $this->_createElement( 'ATTENDEE' ); + continue; + } + $attendee1 = $attendee2 = null; + foreach( $attendeePart as $paramlabel => $paramvalue ) { // start foreach 2 + if( 'value' == $paramlabel ) + $attendee2 .= $paramvalue; + elseif(( 'params' == $paramlabel ) && ( is_array( $paramvalue ))) { // start elseif + $mParams = array( 'MEMBER', 'DELEGATED-TO', 'DELEGATED-FROM' ); + foreach( $paramvalue as $pKey => $pValue ) { // fix (opt) quotes + if( is_array( $pValue ) || in_array( $pKey, $mParams )) + continue; + if(( FALSE !== strpos( $pValue, ':' )) || + ( FALSE !== strpos( $pValue, ';' )) || + ( FALSE !== strpos( $pValue, ',' ))) + $paramvalue[$pKey] = '"'.$pValue.'"'; + } + // set attenddee parameters in rfc2445 order + if( isset( $paramvalue['CUTYPE'] )) + $attendee1 .= $this->intAttrDelimiter.'CUTYPE='.$paramvalue['CUTYPE']; + if( isset( $paramvalue['MEMBER'] )) { + $attendee1 .= $this->intAttrDelimiter.'MEMBER='; + foreach( $paramvalue['MEMBER'] as $cix => $opv ) + $attendee1 .= ( $cix ) ? ',"'.$opv.'"' : '"'.$opv.'"' ; + } + if( isset( $paramvalue['ROLE'] )) + $attendee1 .= $this->intAttrDelimiter.'ROLE='.$paramvalue['ROLE']; + if( isset( $paramvalue['PARTSTAT'] )) + $attendee1 .= $this->intAttrDelimiter.'PARTSTAT='.$paramvalue['PARTSTAT']; + if( isset( $paramvalue['RSVP'] )) + $attendee1 .= $this->intAttrDelimiter.'RSVP='.$paramvalue['RSVP']; + if( isset( $paramvalue['DELEGATED-TO'] )) { + $attendee1 .= $this->intAttrDelimiter.'DELEGATED-TO='; + foreach( $paramvalue['DELEGATED-TO'] as $cix => $opv ) + $attendee1 .= ( $cix ) ? ',"'.$opv.'"' : '"'.$opv.'"' ; + } + if( isset( $paramvalue['DELEGATED-FROM'] )) { + $attendee1 .= $this->intAttrDelimiter.'DELEGATED-FROM='; + foreach( $paramvalue['DELEGATED-FROM'] as $cix => $opv ) + $attendee1 .= ( $cix ) ? ',"'.$opv.'"' : '"'.$opv.'"' ; + } + if( isset( $paramvalue['SENT-BY'] )) + $attendee1 .= $this->intAttrDelimiter.'SENT-BY='.$paramvalue['SENT-BY']; + if( isset( $paramvalue['CN'] )) + $attendee1 .= $this->intAttrDelimiter.'CN='.$paramvalue['CN']; + if( isset( $paramvalue['DIR'] )) { + $delim = ( FALSE === strpos( $paramvalue['DIR'], '"' )) ? '"' : ''; + $attendee1 .= $this->intAttrDelimiter.'DIR='.$delim.$paramvalue['DIR'].$delim; + } + if( isset( $paramvalue['LANGUAGE'] )) + $attendee1 .= $this->intAttrDelimiter.'LANGUAGE='.$paramvalue['LANGUAGE']; + $xparams = array(); + foreach( $paramvalue as $optparamlabel => $optparamvalue ) { // start foreach 3 + if( ctype_digit( (string) $optparamlabel )) { + $xparams[] = $optparamvalue; + continue; + } + if( !in_array( $optparamlabel, array( 'CUTYPE', 'MEMBER', 'ROLE', 'PARTSTAT', 'RSVP', 'DELEGATED-TO', 'DELEGATED-FROM', 'SENT-BY', 'CN', 'DIR', 'LANGUAGE' ))) + $xparams[$optparamlabel] = $optparamvalue; + } // end foreach 3 + ksort( $xparams, SORT_STRING ); + foreach( $xparams as $paramKey => $paramValue ) { + if( ctype_digit( (string) $paramKey )) + $attendee1 .= $this->intAttrDelimiter.$paramValue; + else + $attendee1 .= $this->intAttrDelimiter."$paramKey=$paramValue"; + } // end foreach 3 + } // end elseif(( 'params' == $paramlabel ) && ( is_array( $paramvalue ))) + } // end foreach 2 + $output .= $this->_createElement( 'ATTENDEE', $attendee1, $attendee2 ); + } // end foreach 1 + return $output; + } +/** + * set calendar component property attach + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setAttendee( $value, $params=FALSE, $index=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + // ftp://, http://, mailto:, file://, gopher://, news:, nntp://, telnet://, wais://, prospero:// may exist.. . also in params + if( !empty( $value )) { + if( FALSE === ( $pos = strpos( substr( $value, 0, 9 ), ':' ))) + $value = 'MAILTO:'.$value; + elseif( !empty( $value )) + $value = strtolower( substr( $value, 0, $pos )).substr( $value, $pos ); + $value = str_replace( 'mailto:', 'MAILTO:', $value ); + } + $params2 = array(); + if( is_array($params )) { + $optarrays = array(); + foreach( $params as $optparamlabel => $optparamvalue ) { + $optparamlabel = strtoupper( $optparamlabel ); + switch( $optparamlabel ) { + case 'MEMBER': + case 'DELEGATED-TO': + case 'DELEGATED-FROM': + if( !is_array( $optparamvalue )) + $optparamvalue = array( $optparamvalue ); + foreach( $optparamvalue as $part ) { + $part = trim( $part ); + if(( '"' == substr( $part, 0, 1 )) && + ( '"' == substr( $part, -1 ))) + $part = substr( $part, 1, ( strlen( $part ) - 2 )); + if( 'mailto:' != strtolower( substr( $part, 0, 7 ))) + $part = "MAILTO:$part"; + else + $part = 'MAILTO:'.substr( $part, 7 ); + $optarrays[$optparamlabel][] = $part; + } + break; + default: + if(( '"' == substr( $optparamvalue, 0, 1 )) && + ( '"' == substr( $optparamvalue, -1 ))) + $optparamvalue = substr( $optparamvalue, 1, ( strlen( $optparamvalue ) - 2 )); + if( 'SENT-BY' == $optparamlabel ) { + if( 'mailto:' != strtolower( substr( $optparamvalue, 0, 7 ))) + $optparamvalue = "MAILTO:$optparamvalue"; + else + $optparamvalue = 'MAILTO:'.substr( $optparamvalue, 7 ); + } + $params2[$optparamlabel] = $optparamvalue; + break; + } // end switch( $optparamlabel.. . + } // end foreach( $optparam.. . + foreach( $optarrays as $optparamlabel => $optparams ) + $params2[$optparamlabel] = $optparams; + } + // remove defaults + iCalUtilityFunctions::_existRem( $params2, 'CUTYPE', 'INDIVIDUAL' ); + iCalUtilityFunctions::_existRem( $params2, 'PARTSTAT', 'NEEDS-ACTION' ); + iCalUtilityFunctions::_existRem( $params2, 'ROLE', 'REQ-PARTICIPANT' ); + iCalUtilityFunctions::_existRem( $params2, 'RSVP', 'FALSE' ); + // check language setting + if( isset( $params2['CN' ] )) { + $lang = $this->getConfig( 'language' ); + if( !isset( $params2['LANGUAGE' ] ) && !empty( $lang )) + $params2['LANGUAGE' ] = $lang; + } + iCalUtilityFunctions::_setMval( $this->attendee, $value, $params2, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: CATEGORIES + */ +/** + * creates formatted output for calendar component property categories + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createCategories() { + if( empty( $this->categories )) return FALSE; + $output = null; + foreach( $this->categories as $category ) { + if( empty( $category['value'] )) { + if ( $this->getConfig( 'allowEmpty' )) + $output .= $this->_createElement( 'CATEGORIES' ); + continue; + } + $attributes = $this->_createParams( $category['params'], array( 'LANGUAGE' )); + if( is_array( $category['value'] )) { + foreach( $category['value'] as $cix => $categoryPart ) + $category['value'][$cix] = iCalUtilityFunctions::_strrep( $categoryPart, $this->format, $this->nl ); + $content = implode( ',', $category['value'] ); + } + else + $content = iCalUtilityFunctions::_strrep( $category['value'], $this->format, $this->nl ); + $output .= $this->_createElement( 'CATEGORIES', $attributes, $content ); + } + return $output; + } +/** + * set calendar component property categories + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param mixed $value + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setCategories( $value, $params=FALSE, $index=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + iCalUtilityFunctions::_setMval( $this->categories, $value, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: CLASS + */ +/** + * creates formatted output for calendar component property class + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 0.9.7 - 2006-11-20 + * @return string + */ + function createClass() { + if( empty( $this->class )) return FALSE; + if( empty( $this->class['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'CLASS' ) : FALSE; + $attributes = $this->_createParams( $this->class['params'] ); + return $this->_createElement( 'CLASS', $attributes, $this->class['value'] ); + } +/** + * set calendar component property class + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token / x-name + * @param array $params optional + * @return bool + */ + function setClass( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->class = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: COMMENT + */ +/** + * creates formatted output for calendar component property comment + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createComment() { + if( empty( $this->comment )) return FALSE; + $output = null; + foreach( $this->comment as $commentPart ) { + if( empty( $commentPart['value'] )) { + if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'COMMENT' ); + continue; + } + $attributes = $this->_createParams( $commentPart['params'], array( 'ALTREP', 'LANGUAGE' )); + $content = iCalUtilityFunctions::_strrep( $commentPart['value'], $this->format, $this->nl ); + $output .= $this->_createElement( 'COMMENT', $attributes, $content ); + } + return $output; + } +/** + * set calendar component property comment + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setComment( $value, $params=FALSE, $index=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + iCalUtilityFunctions::_setMval( $this->comment, $value, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: COMPLETED + */ +/** + * creates formatted output for calendar component property completed + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-22 + * @return string + */ + function createCompleted( ) { + if( empty( $this->completed )) return FALSE; + if( !isset( $this->completed['value']['year'] ) && + !isset( $this->completed['value']['month'] ) && + !isset( $this->completed['value']['day'] ) && + !isset( $this->completed['value']['hour'] ) && + !isset( $this->completed['value']['min'] ) && + !isset( $this->completed['value']['sec'] )) + if( $this->getConfig( 'allowEmpty' )) + return $this->_createElement( 'COMPLETED' ); + else return FALSE; + $formatted = iCalUtilityFunctions::_date2strdate( $this->completed['value'], 7 ); + $attributes = $this->_createParams( $this->completed['params'] ); + return $this->_createElement( 'COMPLETED', $attributes, $formatted ); + } +/** + * set calendar component property completed + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param mixed $year + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param array $params optional + * @return bool + */ + function setCompleted( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { + if( empty( $year )) { + if( $this->getConfig( 'allowEmpty' )) { + $this->completed = array( 'value' => '', 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } + else + return FALSE; + } + $this->completed = iCalUtilityFunctions::_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: CONTACT + */ +/** + * creates formatted output for calendar component property contact + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createContact() { + if( empty( $this->contact )) return FALSE; + $output = null; + foreach( $this->contact as $contact ) { + if( !empty( $contact['value'] )) { + $attributes = $this->_createParams( $contact['params'], array( 'ALTREP', 'LANGUAGE' )); + $content = iCalUtilityFunctions::_strrep( $contact['value'], $this->format, $this->nl ); + $output .= $this->_createElement( 'CONTACT', $attributes, $content ); + } + elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'CONTACT' ); + } + return $output; + } +/** + * set calendar component property contact + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setContact( $value, $params=FALSE, $index=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + iCalUtilityFunctions::_setMval( $this->contact, $value, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: CREATED + */ +/** + * creates formatted output for calendar component property created + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @return string + */ + function createCreated() { + if( empty( $this->created )) return FALSE; + $formatted = iCalUtilityFunctions::_date2strdate( $this->created['value'], 7 ); + $attributes = $this->_createParams( $this->created['params'] ); + return $this->_createElement( 'CREATED', $attributes, $formatted ); + } +/** + * set calendar component property created + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-23 + * @param mixed $year optional + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param mixed $params optional + * @return bool + */ + function setCreated( $year=FALSE, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { + if( !isset( $year )) { + $year = date('Ymd\THis', mktime( date( 'H' ), date( 'i' ), date( 's' ) - date( 'Z'), date( 'm' ), date( 'd' ), date( 'Y' ))); + } + $this->created = iCalUtilityFunctions::_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: DESCRIPTION + */ +/** + * creates formatted output for calendar component property description + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createDescription() { + if( empty( $this->description )) return FALSE; + $output = null; + foreach( $this->description as $description ) { + if( !empty( $description['value'] )) { + $attributes = $this->_createParams( $description['params'], array( 'ALTREP', 'LANGUAGE' )); + $content = iCalUtilityFunctions::_strrep( $description['value'], $this->format, $this->nl ); + $output .= $this->_createElement( 'DESCRIPTION', $attributes, $content ); + } + elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'DESCRIPTION' ); + } + return $output; + } +/** + * set calendar component property description + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setDescription( $value, $params=FALSE, $index=FALSE ) { + if( empty( $value )) { if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; } + if( 'vjournal' != $this->objName ) + $index = 1; + iCalUtilityFunctions::_setMval( $this->description, $value, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: DTEND + */ +/** + * creates formatted output for calendar component property dtend + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.4 - 2012-09-26 + * @return string + */ + function createDtend() { + if( empty( $this->dtend )) return FALSE; + if( !isset( $this->dtend['value']['year'] ) && + !isset( $this->dtend['value']['month'] ) && + !isset( $this->dtend['value']['day'] ) && + !isset( $this->dtend['value']['hour'] ) && + !isset( $this->dtend['value']['min'] ) && + !isset( $this->dtend['value']['sec'] )) + if( $this->getConfig( 'allowEmpty' )) + return $this->_createElement( 'DTEND' ); + else return FALSE; + $parno = ( isset( $this->dtend['params']['VALUE'] ) && ( 'DATE' == $this->dtend['params']['VALUE'] )) ? 3 : null; + $formatted = iCalUtilityFunctions::_date2strdate( $this->dtend['value'], $parno ); + $attributes = $this->_createParams( $this->dtend['params'] ); + return $this->_createElement( 'DTEND', $attributes, $formatted ); + } +/** + * set calendar component property dtend + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param mixed $year + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param string $tz optional + * @param array params optional + * @return bool + */ + function setDtend( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { + if( empty( $year )) { + if( $this->getConfig( 'allowEmpty' )) { + $this->dtend = array( 'value' => '', 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } + else + return FALSE; + } + $this->dtend = iCalUtilityFunctions::_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params, null, null, $this->getConfig( 'TZID' )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: DTSTAMP + */ +/** + * creates formatted output for calendar component property dtstamp + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.4 - 2008-03-07 + * @return string + */ + function createDtstamp() { + if( !isset( $this->dtstamp['value']['year'] ) && + !isset( $this->dtstamp['value']['month'] ) && + !isset( $this->dtstamp['value']['day'] ) && + !isset( $this->dtstamp['value']['hour'] ) && + !isset( $this->dtstamp['value']['min'] ) && + !isset( $this->dtstamp['value']['sec'] )) + $this->_makeDtstamp(); + $formatted = iCalUtilityFunctions::_date2strdate( $this->dtstamp['value'], 7 ); + $attributes = $this->_createParams( $this->dtstamp['params'] ); + return $this->_createElement( 'DTSTAMP', $attributes, $formatted ); + } +/** + * computes datestamp for calendar component object instance dtstamp + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.1 - 2012-09-29 + * @return void + */ + function _makeDtstamp() { + $d = date( 'Y-m-d-H-i-s', mktime( date('H'), date('i'), (date('s') - date( 'Z' )), date('m'), date('d'), date('Y'))); + $date = explode( '-', $d ); + $this->dtstamp['value'] = array( 'year' => $date[0], 'month' => $date[1], 'day' => $date[2], 'hour' => $date[3], 'min' => $date[4], 'sec' => $date[5], 'tz' => 'Z' ); + $this->dtstamp['params'] = null; + } +/** + * set calendar component property dtstamp + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-23 + * @param mixed $year + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param array $params optional + * @return TRUE + */ + function setDtstamp( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { + if( empty( $year )) + $this->_makeDtstamp(); + else + $this->dtstamp = iCalUtilityFunctions::_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: DTSTART + */ +/** + * creates formatted output for calendar component property dtstart + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.4 - 2012-09-26 + * @return string + */ + function createDtstart() { + if( empty( $this->dtstart )) return FALSE; + if( !isset( $this->dtstart['value']['year'] ) && + !isset( $this->dtstart['value']['month'] ) && + !isset( $this->dtstart['value']['day'] ) && + !isset( $this->dtstart['value']['hour'] ) && + !isset( $this->dtstart['value']['min'] ) && + !isset( $this->dtstart['value']['sec'] )) { + if( $this->getConfig( 'allowEmpty' )) + return $this->_createElement( 'DTSTART' ); + else return FALSE; + } + if( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) + unset( $this->dtstart['value']['tz'], $this->dtstart['params']['TZID'] ); + $parno = ( isset( $this->dtstart['params']['VALUE'] ) && ( 'DATE' == $this->dtstart['params']['VALUE'] )) ? 3 : null; + $formatted = iCalUtilityFunctions::_date2strdate( $this->dtstart['value'], $parno ); + $attributes = $this->_createParams( $this->dtstart['params'] ); + return $this->_createElement( 'DTSTART', $attributes, $formatted ); + } +/** + * set calendar component property dtstart + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param mixed $year + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param string $tz optional + * @param array $params optional + * @return bool + */ + function setDtstart( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { + if( empty( $year )) { + if( $this->getConfig( 'allowEmpty' )) { + $this->dtstart = array( 'value' => '', 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } + else + return FALSE; + } + $this->dtstart = iCalUtilityFunctions::_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params, 'dtstart', $this->objName, $this->getConfig( 'TZID' )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: DUE + */ +/** + * creates formatted output for calendar component property due + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.4 - 2012-09-26 + * @return string + */ + function createDue() { + if( empty( $this->due )) return FALSE; + if( !isset( $this->due['value']['year'] ) && + !isset( $this->due['value']['month'] ) && + !isset( $this->due['value']['day'] ) && + !isset( $this->due['value']['hour'] ) && + !isset( $this->due['value']['min'] ) && + !isset( $this->due['value']['sec'] )) { + if( $this->getConfig( 'allowEmpty' )) + return $this->_createElement( 'DUE' ); + else + return FALSE; + } + $parno = ( isset( $this->due['params']['VALUE'] ) && ( 'DATE' == $this->due['params']['VALUE'] )) ? 3 : null; + $formatted = iCalUtilityFunctions::_date2strdate( $this->due['value'], $parno ); + $attributes = $this->_createParams( $this->due['params'] ); + return $this->_createElement( 'DUE', $attributes, $formatted ); + } +/** + * set calendar component property due + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param mixed $year + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param array $params optional + * @return bool + */ + function setDue( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { + if( empty( $year )) { + if( $this->getConfig( 'allowEmpty' )) { + $this->due = array( 'value' => '', 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } + else + return FALSE; + } + $this->due = iCalUtilityFunctions::_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params, null, null, $this->getConfig( 'TZID' )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: DURATION + */ +/** + * creates formatted output for calendar component property duration + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-05-25 + * @return string + */ + function createDuration() { + if( empty( $this->duration )) return FALSE; + if( !isset( $this->duration['value']['week'] ) && + !isset( $this->duration['value']['day'] ) && + !isset( $this->duration['value']['hour'] ) && + !isset( $this->duration['value']['min'] ) && + !isset( $this->duration['value']['sec'] )) + if( $this->getConfig( 'allowEmpty' )) + return $this->_createElement( 'DURATION' ); + else return FALSE; + $attributes = $this->_createParams( $this->duration['params'] ); + return $this->_createElement( 'DURATION', $attributes, iCalUtilityFunctions::_duration2str( $this->duration['value'] )); + } +/** + * set calendar component property duration + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-05-25 + * @param mixed $week + * @param mixed $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param array $params optional + * @return bool + */ + function setDuration( $week, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { + if( empty( $week ) && empty( $day ) && empty( $hour ) && empty( $min ) && empty( $sec )) { + if( $this->getConfig( 'allowEmpty' )) + $week = $day = null; + else + return FALSE; + } + if( is_array( $week ) && ( 1 <= count( $week ))) + $this->duration = array( 'value' => iCalUtilityFunctions::_duration2arr( $week ), 'params' => iCalUtilityFunctions::_setParams( $day )); + elseif( is_string( $week ) && ( 3 <= strlen( trim( $week )))) { + $week = trim( $week ); + if( in_array( substr( $week, 0, 1 ), array( '+', '-' ))) + $week = substr( $week, 1 ); + $this->duration = array( 'value' => iCalUtilityFunctions::_durationStr2arr( $week ), 'params' => iCalUtilityFunctions::_setParams( $day )); + } + else + $this->duration = array( 'value' => iCalUtilityFunctions::_duration2arr( array( 'week' => $week, 'day' => $day, 'hour' => $hour, 'min' => $min, 'sec' => $sec )) + , 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: EXDATE + */ +/** + * creates formatted output for calendar component property exdate + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.5 - 2012-12-28 + * @return string + */ + function createExdate() { + if( empty( $this->exdate )) return FALSE; + $output = null; + $exdates = array(); + foreach( $this->exdate as $theExdate ) { + if( empty( $theExdate['value'] )) { + if( $this->getConfig( 'allowEmpty' )) + $output .= $this->_createElement( 'EXDATE' ); + continue; + } + if( 1 < count( $theExdate['value'] )) + usort( $theExdate['value'], array( 'iCalUtilityFunctions', '_sortExdate1' )); + $exdates[] = $theExdate; + } + if( 1 < count( $exdates )) + usort( $exdates, array( 'iCalUtilityFunctions', '_sortExdate2' )); + foreach( $exdates as $theExdate ) { + $content = $attributes = null; + foreach( $theExdate['value'] as $eix => $exdatePart ) { + $parno = count( $exdatePart ); + $formatted = iCalUtilityFunctions::_date2strdate( $exdatePart, $parno ); + if( isset( $theExdate['params']['TZID'] )) + $formatted = str_replace( 'Z', '', $formatted); + if( 0 < $eix ) { + if( isset( $theExdate['value'][0]['tz'] )) { + if( ctype_digit( substr( $theExdate['value'][0]['tz'], -4 )) || + ( 'Z' == $theExdate['value'][0]['tz'] )) { + if( 'Z' != substr( $formatted, -1 )) + $formatted .= 'Z'; + } + else + $formatted = str_replace( 'Z', '', $formatted ); + } + else + $formatted = str_replace( 'Z', '', $formatted ); + } // end if( 0 < $eix ) + $content .= ( 0 < $eix ) ? ','.$formatted : $formatted; + } // end foreach( $theExdate['value'] as $eix => $exdatePart ) + $attributes .= $this->_createParams( $theExdate['params'] ); + $output .= $this->_createElement( 'EXDATE', $attributes, $content ); + } // end foreach( $exdates as $theExdate ) + return $output; + } +/** + * set calendar component property exdate + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param array exdates + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setExdate( $exdates, $params=FALSE, $index=FALSE ) { + if( empty( $exdates )) { + if( $this->getConfig( 'allowEmpty' )) { + iCalUtilityFunctions::_setMval( $this->exdate, '', $params, FALSE, $index ); + return TRUE; + } + else + return FALSE; + } + $input = array( 'params' => iCalUtilityFunctions::_setParams( $params, array( 'VALUE' => 'DATE-TIME' ))); + $toZ = ( isset( $input['params']['TZID'] ) && in_array( strtoupper( $input['params']['TZID'] ), array( 'GMT', 'UTC', 'Z' ))) ? TRUE : FALSE; + /* ev. check 1:st date and save ev. timezone **/ + iCalUtilityFunctions::_chkdatecfg( reset( $exdates ), $parno, $input['params'] ); + iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME' ); // remove default parameter + foreach( $exdates as $eix => $theExdate ) { + iCalUtilityFunctions::_strDate2arr( $theExdate ); + if( iCalUtilityFunctions::_isArrayTimestampDate( $theExdate )) { + if( isset( $theExdate['tz'] ) && !iCalUtilityFunctions::_isOffset( $theExdate['tz'] )) { + if( isset( $input['params']['TZID'] )) + $theExdate['tz'] = $input['params']['TZID']; + else + $input['params']['TZID'] = $theExdate['tz']; + } + $exdatea = iCalUtilityFunctions::_timestamp2date( $theExdate, $parno ); + } + elseif( is_array( $theExdate )) { + $d = iCalUtilityFunctions::_chkDateArr( $theExdate, $parno ); + if( isset( $d['tz'] ) && ( 'Z' != $d['tz'] ) && iCalUtilityFunctions::_isOffset( $d['tz'] )) { + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $d['tz'] ); + $exdatea = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $exdatea['unparsedtext'] ); + } + else + $exdatea = $d; + } + elseif( 8 <= strlen( trim( $theExdate ))) { // ex. 2006-08-03 10:12:18 + $exdatea = iCalUtilityFunctions::_strdate2date( $theExdate, $parno ); + unset( $exdatea['unparsedtext'] ); + } + if( 3 == $parno ) + unset( $exdatea['hour'], $exdatea['min'], $exdatea['sec'], $exdatea['tz'] ); + elseif( isset( $exdatea['tz'] )) + $exdatea['tz'] = (string) $exdatea['tz']; + if( isset( $input['params']['TZID'] ) || + ( isset( $exdatea['tz'] ) && !iCalUtilityFunctions::_isOffset( $exdatea['tz'] )) || + ( isset( $input['value'][0] ) && ( !isset( $input['value'][0]['tz'] ))) || + ( isset( $input['value'][0]['tz'] ) && !iCalUtilityFunctions::_isOffset( $input['value'][0]['tz'] ))) + unset( $exdatea['tz'] ); + if( $toZ ) // time zone Z + $exdatea['tz'] = 'Z'; + $input['value'][] = $exdatea; + } + if( 0 >= count( $input['value'] )) + return FALSE; + if( 3 == $parno ) { + $input['params']['VALUE'] = 'DATE'; + unset( $input['params']['TZID'] ); + } + if( $toZ ) // time zone Z + unset( $input['params']['TZID'] ); + iCalUtilityFunctions::_setMval( $this->exdate, $input['value'], $input['params'], FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: EXRULE + */ +/** + * creates formatted output for calendar component property exrule + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-22 + * @return string + */ + function createExrule() { + if( empty( $this->exrule )) return FALSE; + return $this->_format_recur( 'EXRULE', $this->exrule ); + } +/** + * set calendar component property exdate + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param array $exruleset + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setExrule( $exruleset, $params=FALSE, $index=FALSE ) { + if( empty( $exruleset )) if( $this->getConfig( 'allowEmpty' )) $exruleset = ''; else return FALSE; + iCalUtilityFunctions::_setMval( $this->exrule, iCalUtilityFunctions::_setRexrule( $exruleset ), $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: FREEBUSY + */ +/** + * creates formatted output for calendar component property freebusy + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.27 - 2013-07-05 + * @return string + */ + function createFreebusy() { + if( empty( $this->freebusy )) return FALSE; + $output = null; + foreach( $this->freebusy as $freebusyPart ) { + if( empty( $freebusyPart['value'] ) || (( 1 == count( $freebusyPart['value'] )) && isset( $freebusyPart['value']['fbtype'] ))) { + if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'FREEBUSY' ); + continue; + } + $attributes = $content = null; + if( isset( $freebusyPart['value']['fbtype'] )) { + $attributes .= $this->intAttrDelimiter.'FBTYPE='.$freebusyPart['value']['fbtype']; + unset( $freebusyPart['value']['fbtype'] ); + $freebusyPart['value'] = array_values( $freebusyPart['value'] ); + } + else + $attributes .= $this->intAttrDelimiter.'FBTYPE=BUSY'; + $attributes .= $this->_createParams( $freebusyPart['params'] ); + $fno = 1; + $cnt = count( $freebusyPart['value']); + if( 1 < $cnt ) + usort( $freebusyPart['value'], array( 'iCalUtilityFunctions', '_sortRdate1' )); + foreach( $freebusyPart['value'] as $periodix => $freebusyPeriod ) { + $formatted = iCalUtilityFunctions::_date2strdate( $freebusyPeriod[0] ); + $content .= $formatted; + $content .= '/'; + $cnt2 = count( $freebusyPeriod[1]); + if( array_key_exists( 'year', $freebusyPeriod[1] )) // date-time + $cnt2 = 7; + elseif( array_key_exists( 'week', $freebusyPeriod[1] )) // duration + $cnt2 = 5; + if(( 7 == $cnt2 ) && // period= -> date-time + isset( $freebusyPeriod[1]['year'] ) && + isset( $freebusyPeriod[1]['month'] ) && + isset( $freebusyPeriod[1]['day'] )) { + $content .= iCalUtilityFunctions::_date2strdate( $freebusyPeriod[1] ); + } + else { // period= -> dur-time + $content .= iCalUtilityFunctions::_duration2str( $freebusyPeriod[1] ); + } + if( $fno < $cnt ) + $content .= ','; + $fno++; + } + $output .= $this->_createElement( 'FREEBUSY', $attributes, $content ); + } + return $output; + } +/** + * set calendar component property freebusy + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $fbType + * @param array $fbValues + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setFreebusy( $fbType, $fbValues, $params=FALSE, $index=FALSE ) { + if( empty( $fbValues )) { + if( $this->getConfig( 'allowEmpty' )) { + iCalUtilityFunctions::_setMval( $this->freebusy, '', $params, FALSE, $index ); + return TRUE; + } + else + return FALSE; + } + $fbType = strtoupper( $fbType ); + if(( !in_array( $fbType, array( 'FREE', 'BUSY', 'BUSY-UNAVAILABLE', 'BUSY-TENTATIVE' ))) && + ( 'X-' != substr( $fbType, 0, 2 ))) + $fbType = 'BUSY'; + $input = array( 'fbtype' => $fbType ); + foreach( $fbValues as $fbPeriod ) { // periods => period + if( empty( $fbPeriod )) + continue; + $freebusyPeriod = array(); + foreach( $fbPeriod as $fbMember ) { // pairs => singlepart + $freebusyPairMember = array(); + if( is_array( $fbMember )) { + if( iCalUtilityFunctions::_isArrayDate( $fbMember )) { // date-time value + $freebusyPairMember = iCalUtilityFunctions::_chkDateArr( $fbMember, 7 ); + $freebusyPairMember['tz'] = 'Z'; + } + elseif( iCalUtilityFunctions::_isArrayTimestampDate( $fbMember )) { // timestamp value + $freebusyPairMember = iCalUtilityFunctions::_timestamp2date( $fbMember['timestamp'], 7 ); + $freebusyPairMember['tz'] = 'Z'; + } + else { // array format duration + $freebusyPairMember = iCalUtilityFunctions::_duration2arr( $fbMember ); + } + } + elseif(( 3 <= strlen( trim( $fbMember ))) && // string format duration + ( in_array( $fbMember{0}, array( 'P', '+', '-' )))) { + if( 'P' != $fbMember{0} ) + $fbmember = substr( $fbMember, 1 ); + $freebusyPairMember = iCalUtilityFunctions::_durationStr2arr( $fbMember ); + } + elseif( 8 <= strlen( trim( $fbMember ))) { // text date ex. 2006-08-03 10:12:18 + $freebusyPairMember = iCalUtilityFunctions::_strdate2date( $fbMember, 7 ); + unset( $freebusyPairMember['unparsedtext'] ); + $freebusyPairMember['tz'] = 'Z'; + } + $freebusyPeriod[] = $freebusyPairMember; + } + $input[] = $freebusyPeriod; + } + iCalUtilityFunctions::_setMval( $this->freebusy, $input, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: GEO + */ +/** + * creates formatted output for calendar component property geo + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.12.6 - 2012-04-21 + * @return string + */ + function createGeo() { + if( empty( $this->geo )) return FALSE; + if( empty( $this->geo['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'GEO' ) : FALSE; + $attributes = $this->_createParams( $this->geo['params'] ); + if( 0.0 < $this->geo['value']['latitude'] ) + $sign = '+'; + else + $sign = ( 0.0 > $this->geo['value']['latitude'] ) ? '-' : ''; + $content = $sign.sprintf( "%09.6f", abs( $this->geo['value']['latitude'] )); // sprintf && lpad && float && sign !"#¤%&/( + $content = rtrim( rtrim( $content, '0' ), '.' ); + if( 0.0 < $this->geo['value']['longitude'] ) + $sign = '+'; + else + $sign = ( 0.0 > $this->geo['value']['longitude'] ) ? '-' : ''; + $content .= ';'.$sign.sprintf( '%8.6f', abs( $this->geo['value']['longitude'] )); // sprintf && lpad && float && sign !"#¤%&/( + $content = rtrim( rtrim( $content, '0' ), '.' ); + return $this->_createElement( 'GEO', $attributes, $content ); + } +/** + * set calendar component property geo + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param float $latitude + * @param float $longitude + * @param array $params optional + * @return bool + */ + function setGeo( $latitude, $longitude, $params=FALSE ) { + if( isset( $latitude ) && isset( $longitude )) { + if( !is_array( $this->geo )) $this->geo = array(); + $this->geo['value']['latitude'] = (float) $latitude; + $this->geo['value']['longitude'] = (float) $longitude; + $this->geo['params'] = iCalUtilityFunctions::_setParams( $params ); + } + elseif( $this->getConfig( 'allowEmpty' )) + $this->geo = array( 'value' => '', 'params' => iCalUtilityFunctions::_setParams( $params ) ); + else + return FALSE; + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: LAST-MODIFIED + */ +/** + * creates formatted output for calendar component property last-modified + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @return string + */ + function createLastModified() { + if( empty( $this->lastmodified )) return FALSE; + $attributes = $this->_createParams( $this->lastmodified['params'] ); + $formatted = iCalUtilityFunctions::_date2strdate( $this->lastmodified['value'], 7 ); + return $this->_createElement( 'LAST-MODIFIED', $attributes, $formatted ); + } +/** + * set calendar component property completed + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-23 + * @param mixed $year optional + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param array $params optional + * @return boll + */ + function setLastModified( $year=FALSE, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { + if( empty( $year )) + $year = date('Ymd\THis', mktime( date( 'H' ), date( 'i' ), date( 's' ) - date( 'Z'), date( 'm' ), date( 'd' ), date( 'Y' ))); + $this->lastmodified = iCalUtilityFunctions::_setDate2( $year, $month, $day, $hour, $min, $sec, $params ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: LOCATION + */ +/** + * creates formatted output for calendar component property location + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createLocation() { + if( empty( $this->location )) return FALSE; + if( empty( $this->location['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'LOCATION' ) : FALSE; + $attributes = $this->_createParams( $this->location['params'], array( 'ALTREP', 'LANGUAGE' )); + $content = iCalUtilityFunctions::_strrep( $this->location['value'], $this->format, $this->nl ); + return $this->_createElement( 'LOCATION', $attributes, $content ); + } +/** + * set calendar component property location + ' + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array params optional + * @return bool + */ + function setLocation( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->location = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: ORGANIZER + */ +/** + * creates formatted output for calendar component property organizer + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.6.33 - 2010-12-17 + * @return string + */ + function createOrganizer() { + if( empty( $this->organizer )) return FALSE; + if( empty( $this->organizer['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'ORGANIZER' ) : FALSE; + $attributes = $this->_createParams( $this->organizer['params'] + , array( 'CN', 'DIR', 'SENT-BY', 'LANGUAGE' )); + return $this->_createElement( 'ORGANIZER', $attributes, $this->organizer['value'] ); + } +/** + * set calendar component property organizer + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array params optional + * @return bool + */ + function setOrganizer( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + if( !empty( $value )) { + if( FALSE === ( $pos = strpos( substr( $value, 0, 9 ), ':' ))) + $value = 'MAILTO:'.$value; + elseif( !empty( $value )) + $value = strtolower( substr( $value, 0, $pos )).substr( $value, $pos ); + $value = str_replace( 'mailto:', 'MAILTO:', $value ); + } + $this->organizer = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + if( isset( $this->organizer['params']['SENT-BY'] )){ + if( 'mailto:' !== strtolower( substr( $this->organizer['params']['SENT-BY'], 0, 7 ))) + $this->organizer['params']['SENT-BY'] = 'MAILTO:'.$this->organizer['params']['SENT-BY']; + else + $this->organizer['params']['SENT-BY'] = 'MAILTO:'.substr( $this->organizer['params']['SENT-BY'], 7 ); + } + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: PERCENT-COMPLETE + */ +/** + * creates formatted output for calendar component property percent-complete + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.9.3 - 2011-05-14 + * @return string + */ + function createPercentComplete() { + if( !isset($this->percentcomplete) || ( empty( $this->percentcomplete ) && !is_numeric( $this->percentcomplete ))) return FALSE; + if( !isset( $this->percentcomplete['value'] ) || ( empty( $this->percentcomplete['value'] ) && !is_numeric( $this->percentcomplete['value'] ))) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'PERCENT-COMPLETE' ) : FALSE; + $attributes = $this->_createParams( $this->percentcomplete['params'] ); + return $this->_createElement( 'PERCENT-COMPLETE', $attributes, $this->percentcomplete['value'] ); + } +/** + * set calendar component property percent-complete + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param int $value + * @param array $params optional + * @return bool + */ + function setPercentComplete( $value, $params=FALSE ) { + if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->percentcomplete = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: PRIORITY + */ +/** + * creates formatted output for calendar component property priority + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.9.3 - 2011-05-14 + * @return string + */ + function createPriority() { + if( !isset($this->priority) || ( empty( $this->priority ) && !is_numeric( $this->priority ))) return FALSE; + if( !isset( $this->priority['value'] ) || ( empty( $this->priority['value'] ) && !is_numeric( $this->priority['value'] ))) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'PRIORITY' ) : FALSE; + $attributes = $this->_createParams( $this->priority['params'] ); + return $this->_createElement( 'PRIORITY', $attributes, $this->priority['value'] ); + } +/** + * set calendar component property priority + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param int $value + * @param array $params optional + * @return bool + */ + function setPriority( $value, $params=FALSE ) { + if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->priority = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: RDATE + */ +/** + * creates formatted output for calendar component property rdate + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.9 - 2013-01-09 + * @return string + */ + function createRdate() { + if( empty( $this->rdate )) return FALSE; + $utctime = ( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) ? TRUE : FALSE; + $output = null; + $rdates = array(); + foreach( $this->rdate as $rpix => $theRdate ) { + if( empty( $theRdate['value'] )) { + if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'RDATE' ); + continue; + } + if( $utctime ) + unset( $theRdate['params']['TZID'] ); + if( 1 < count( $theRdate['value'] )) + usort( $theRdate['value'], array( 'iCalUtilityFunctions', '_sortRdate1' )); + $rdates[] = $theRdate; + } + if( 1 < count( $rdates )) + usort( $rdates, array( 'iCalUtilityFunctions', '_sortRdate2' )); + foreach( $rdates as $rpix => $theRdate ) { + $attributes = $this->_createParams( $theRdate['params'] ); + $cnt = count( $theRdate['value'] ); + $content = null; + $rno = 1; + foreach( $theRdate['value'] as $rix => $rdatePart ) { + $contentPart = null; + if( is_array( $rdatePart ) && + isset( $theRdate['params']['VALUE'] ) && ( 'PERIOD' == $theRdate['params']['VALUE'] )) { // PERIOD + if( $utctime ) + unset( $rdatePart[0]['tz'] ); + $formatted = iCalUtilityFunctions::_date2strdate( $rdatePart[0] ); // PERIOD part 1 + if( $utctime || !empty( $theRdate['params']['TZID'] )) + $formatted = str_replace( 'Z', '', $formatted); + $contentPart .= $formatted; + $contentPart .= '/'; + $cnt2 = count( $rdatePart[1]); + if( array_key_exists( 'year', $rdatePart[1] )) { + if( array_key_exists( 'hour', $rdatePart[1] )) + $cnt2 = 7; // date-time + else + $cnt2 = 3; // date + } + elseif( array_key_exists( 'week', $rdatePart[1] )) // duration + $cnt2 = 5; + if(( 7 == $cnt2 ) && // period= -> date-time + isset( $rdatePart[1]['year'] ) && + isset( $rdatePart[1]['month'] ) && + isset( $rdatePart[1]['day'] )) { + if( $utctime ) + unset( $rdatePart[1]['tz'] ); + $formatted = iCalUtilityFunctions::_date2strdate( $rdatePart[1] ); // PERIOD part 2 + if( $utctime || !empty( $theRdate['params']['TZID'] )) + $formatted = str_replace( 'Z', '', $formatted ); + $contentPart .= $formatted; + } + else { // period= -> dur-time + $contentPart .= iCalUtilityFunctions::_duration2str( $rdatePart[1] ); + } + } // PERIOD end + else { // SINGLE date start + if( $utctime ) + unset( $rdatePart['tz'] ); + $parno = ( isset( $theRdate['params']['VALUE'] ) && ( 'DATE' == isset( $theRdate['params']['VALUE'] ))) ? 3 : null; + $formatted = iCalUtilityFunctions::_date2strdate( $rdatePart, $parno ); + if( $utctime || !empty( $theRdate['params']['TZID'] )) + $formatted = str_replace( 'Z', '', $formatted); + $contentPart .= $formatted; + } + $content .= $contentPart; + if( $rno < $cnt ) + $content .= ','; + $rno++; + } + $output .= $this->_createElement( 'RDATE', $attributes, $content ); + } + return $output; + } +/** + * set calendar component property rdate + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param array $rdates + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setRdate( $rdates, $params=FALSE, $index=FALSE ) { + if( empty( $rdates )) { + if( $this->getConfig( 'allowEmpty' )) { + iCalUtilityFunctions::_setMval( $this->rdate, '', $params, FALSE, $index ); + return TRUE; + } + else + return FALSE; + } + $input = array( 'params' => iCalUtilityFunctions::_setParams( $params, array( 'VALUE' => 'DATE-TIME' ))); + if( in_array( $this->objName, array( 'vtimezone', 'standard', 'daylight' ))) { + unset( $input['params']['TZID'] ); + $input['params']['VALUE'] = 'DATE-TIME'; + } + $zArr = array( 'GMT', 'UTC', 'Z' ); + $toZ = ( isset( $params['TZID'] ) && in_array( strtoupper( $params['TZID'] ), $zArr )) ? TRUE : FALSE; + /* check if PERIOD, if not set */ + if((!isset( $input['params']['VALUE'] ) || !in_array( $input['params']['VALUE'], array( 'DATE', 'PERIOD' ))) && + isset( $rdates[0] ) && is_array( $rdates[0] ) && ( 2 == count( $rdates[0] )) && + isset( $rdates[0][0] ) && isset( $rdates[0][1] ) && !isset( $rdates[0]['timestamp'] ) && + (( is_array( $rdates[0][0] ) && ( isset( $rdates[0][0]['timestamp'] ) || + iCalUtilityFunctions::_isArrayDate( $rdates[0][0] ))) || + ( is_string( $rdates[0][0] ) && ( 8 <= strlen( trim( $rdates[0][0] ))))) && + ( is_array( $rdates[0][1] ) || ( is_string( $rdates[0][1] ) && ( 3 <= strlen( trim( $rdates[0][1] )))))) + $input['params']['VALUE'] = 'PERIOD'; + /* check 1:st date, upd. $parno (opt) and save ev. timezone **/ + $date = reset( $rdates ); + if( isset( $input['params']['VALUE'] ) && ( 'PERIOD' == $input['params']['VALUE'] )) // PERIOD + $date = reset( $date ); + iCalUtilityFunctions::_chkdatecfg( $date, $parno, $input['params'] ); + iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME' ); // remove default + foreach( $rdates as $rpix => $theRdate ) { + $inputa = null; + iCalUtilityFunctions::_strDate2arr( $theRdate ); + if( is_array( $theRdate )) { + if( isset( $input['params']['VALUE'] ) && ( 'PERIOD' == $input['params']['VALUE'] )) { // PERIOD + foreach( $theRdate as $rix => $rPeriod ) { + iCalUtilityFunctions::_strDate2arr( $theRdate ); + if( is_array( $rPeriod )) { + if( iCalUtilityFunctions::_isArrayTimestampDate( $rPeriod )) { // timestamp + if( isset( $rPeriod['tz'] ) && !iCalUtilityFunctions::_isOffset( $rPeriod['tz'] )) { + if( isset( $input['params']['TZID'] )) + $rPeriod['tz'] = $input['params']['TZID']; + else + $input['params']['TZID'] = $rPeriod['tz']; + } + $inputab = iCalUtilityFunctions::_timestamp2date( $rPeriod, $parno ); + } + elseif( iCalUtilityFunctions::_isArrayDate( $rPeriod )) { + $d = ( 3 < count ( $rPeriod )) ? iCalUtilityFunctions::_chkDateArr( $rPeriod, $parno ) : iCalUtilityFunctions::_chkDateArr( $rPeriod, 6 ); + if( isset( $d['tz'] ) && ( 'Z' != $d['tz'] ) && iCalUtilityFunctions::_isOffset( $d['tz'] )) { + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $d['tz'] ); + $inputab = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $inputab['unparsedtext'] ); + } + else + $inputab = $d; + } + elseif (( 1 == count( $rPeriod )) && ( 8 <= strlen( reset( $rPeriod )))) { // text-date + $inputab = iCalUtilityFunctions::_strdate2date( reset( $rPeriod ), $parno ); + unset( $inputab['unparsedtext'] ); + } + else // array format duration + $inputab = iCalUtilityFunctions::_duration2arr( $rPeriod ); + } + elseif(( 3 <= strlen( trim( $rPeriod ))) && // string format duration + ( in_array( $rPeriod[0], array( 'P', '+', '-' )))) { + if( 'P' != $rPeriod[0] ) + $rPeriod = substr( $rPeriod, 1 ); + $inputab = iCalUtilityFunctions::_durationStr2arr( $rPeriod ); + } + elseif( 8 <= strlen( trim( $rPeriod ))) { // text date ex. 2006-08-03 10:12:18 + $inputab = iCalUtilityFunctions::_strdate2date( $rPeriod, $parno ); + unset( $inputab['unparsedtext'] ); + } + if(( 0 == $rpix ) && ( 0 == $rix )) { + if( isset( $inputab['tz'] ) && in_array( strtoupper( $inputab['tz'] ), $zArr )) { + $inputab['tz'] = 'Z'; + $toZ = TRUE; + } + } + else { + if( isset( $inputa[0]['tz'] ) && ( 'Z' == $inputa[0]['tz'] ) && isset( $inputab['year'] )) + $inputab['tz'] = 'Z'; + else + unset( $inputab['tz'] ); + } + if( $toZ && isset( $inputab['year'] ) ) + $inputab['tz'] = 'Z'; + $inputa[] = $inputab; + } + } // PERIOD end + elseif ( iCalUtilityFunctions::_isArrayTimestampDate( $theRdate )) { // timestamp + if( isset( $theRdate['tz'] ) && !iCalUtilityFunctions::_isOffset( $theRdate['tz'] )) { + if( isset( $input['params']['TZID'] )) + $theRdate['tz'] = $input['params']['TZID']; + else + $input['params']['TZID'] = $theRdate['tz']; + } + $inputa = iCalUtilityFunctions::_timestamp2date( $theRdate, $parno ); + } + else { // date[-time] + $inputa = iCalUtilityFunctions::_chkDateArr( $theRdate, $parno ); + if( isset( $inputa['tz'] ) && ( 'Z' != $inputa['tz'] ) && iCalUtilityFunctions::_isOffset( $inputa['tz'] )) { + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $inputa['year'], $inputa['month'], $inputa['day'], $inputa['hour'], $inputa['min'], $inputa['sec'], $inputa['tz'] ); + $inputa = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $inputa['unparsedtext'] ); + } + } + } + elseif( 8 <= strlen( trim( $theRdate ))) { // text date ex. 2006-08-03 10:12:18 + $inputa = iCalUtilityFunctions::_strdate2date( $theRdate, $parno ); + unset( $inputa['unparsedtext'] ); + if( $toZ ) + $inputa['tz'] = 'Z'; + } + if( !isset( $input['params']['VALUE'] ) || ( 'PERIOD' != $input['params']['VALUE'] )) { // no PERIOD + if(( 0 == $rpix ) && !$toZ ) + $toZ = ( isset( $inputa['tz'] ) && in_array( strtoupper( $inputa['tz'] ), $zArr )) ? TRUE : FALSE; + if( $toZ ) + $inputa['tz'] = 'Z'; + if( 3 == $parno ) + unset( $inputa['hour'], $inputa['min'], $inputa['sec'], $inputa['tz'] ); + elseif( isset( $inputa['tz'] )) + $inputa['tz'] = (string) $inputa['tz']; + if( isset( $input['params']['TZID'] ) || ( isset( $input['value'][0] ) && ( !isset( $input['value'][0]['tz'] )))) + if( !$toZ ) + unset( $inputa['tz'] ); + } + $input['value'][] = $inputa; + } + if( 3 == $parno ) { + $input['params']['VALUE'] = 'DATE'; + unset( $input['params']['TZID'] ); + } + if( $toZ ) + unset( $input['params']['TZID'] ); + iCalUtilityFunctions::_setMval( $this->rdate, $input['value'], $input['params'], FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: RECURRENCE-ID + */ +/** + * creates formatted output for calendar component property recurrence-id + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.4 - 2012-09-26 + * @return string + */ + function createRecurrenceid() { + if( empty( $this->recurrenceid )) return FALSE; + if( empty( $this->recurrenceid['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'RECURRENCE-ID' ) : FALSE; + $parno = ( isset( $this->recurrenceid['params']['VALUE'] ) && ( 'DATE' == $this->recurrenceid['params']['VALUE'] )) ? 3 : null; + $formatted = iCalUtilityFunctions::_date2strdate( $this->recurrenceid['value'], $parno ); + $attributes = $this->_createParams( $this->recurrenceid['params'] ); + return $this->_createElement( 'RECURRENCE-ID', $attributes, $formatted ); + } +/** + * set calendar component property recurrence-id + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param mixed $year + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param array $params optional + * @return bool + */ + function setRecurrenceid( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE ) { + if( empty( $year )) { + if( $this->getConfig( 'allowEmpty' )) { + $this->recurrenceid = array( 'value' => '', 'params' => null ); + return TRUE; + } + else + return FALSE; + } + $this->recurrenceid = iCalUtilityFunctions::_setDate( $year, $month, $day, $hour, $min, $sec, $tz, $params, null, null, $this->getConfig( 'TZID' )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: RELATED-TO + */ +/** + * creates formatted output for calendar component property related-to + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-05-25 + * @return string + */ + function createRelatedTo() { + if( empty( $this->relatedto )) return FALSE; + $output = null; + foreach( $this->relatedto as $relation ) { + if( !empty( $relation['value'] )) + $output .= $this->_createElement( 'RELATED-TO', $this->_createParams( $relation['params'] ), iCalUtilityFunctions::_strrep( $relation['value'], $this->format, $this->nl )); + elseif( $this->getConfig( 'allowEmpty' )) + $output .= $this->_createElement( 'RELATED-TO' ); + } + return $output; + } +/** + * set calendar component property related-to + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param float $relid + * @param array $params, optional + * @param index $index, optional + * @return bool + */ + function setRelatedTo( $value, $params=FALSE, $index=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + iCalUtilityFunctions::_existRem( $params, 'RELTYPE', 'PARENT', TRUE ); // remove default + iCalUtilityFunctions::_setMval( $this->relatedto, $value, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: REPEAT + */ +/** + * creates formatted output for calendar component property repeat + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.9.3 - 2011-05-14 + * @return string + */ + function createRepeat() { + if( !isset( $this->repeat ) || ( empty( $this->repeat ) && !is_numeric( $this->repeat ))) return FALSE; + if( !isset( $this->repeat['value']) || ( empty( $this->repeat['value'] ) && !is_numeric( $this->repeat['value'] ))) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'REPEAT' ) : FALSE; + $attributes = $this->_createParams( $this->repeat['params'] ); + return $this->_createElement( 'REPEAT', $attributes, $this->repeat['value'] ); + } +/** + * set calendar component property repeat + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array $params optional + * @return void + */ + function setRepeat( $value, $params=FALSE ) { + if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->repeat = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: REQUEST-STATUS + */ +/** + * creates formatted output for calendar component property request-status + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createRequestStatus() { + if( empty( $this->requeststatus )) return FALSE; + $output = null; + foreach( $this->requeststatus as $rstat ) { + if( empty( $rstat['value']['statcode'] )) { + if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'REQUEST-STATUS' ); + continue; + } + $attributes = $this->_createParams( $rstat['params'], array( 'LANGUAGE' )); + $content = number_format( (float) $rstat['value']['statcode'], 2, '.', ''); + $content .= ';'.iCalUtilityFunctions::_strrep( $rstat['value']['text'], $this->format, $this->nl ); + if( isset( $rstat['value']['extdata'] )) + $content .= ';'.iCalUtilityFunctions::_strrep( $rstat['value']['extdata'], $this->format, $this->nl ); + $output .= $this->_createElement( 'REQUEST-STATUS', $attributes, $content ); + } + return $output; + } +/** + * set calendar component property request-status + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param float $statcode + * @param string $text + * @param string $extdata, optional + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setRequestStatus( $statcode, $text, $extdata=FALSE, $params=FALSE, $index=FALSE ) { + if( empty( $statcode ) || empty( $text )) if( $this->getConfig( 'allowEmpty' )) $statcode = $text = ''; else return FALSE; + $input = array( 'statcode' => $statcode, 'text' => $text ); + if( $extdata ) + $input['extdata'] = $extdata; + iCalUtilityFunctions::_setMval( $this->requeststatus, $input, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: RESOURCES + */ +/** + * creates formatted output for calendar component property resources + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createResources() { + if( empty( $this->resources )) return FALSE; + $output = null; + foreach( $this->resources as $resource ) { + if( empty( $resource['value'] )) { + if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'RESOURCES' ); + continue; + } + $attributes = $this->_createParams( $resource['params'], array( 'ALTREP', 'LANGUAGE' )); + if( is_array( $resource['value'] )) { + foreach( $resource['value'] as $rix => $resourcePart ) + $resource['value'][$rix] = iCalUtilityFunctions::_strrep( $resourcePart, $this->format, $this->nl ); + $content = implode( ',', $resource['value'] ); + } + else + $content = iCalUtilityFunctions::_strrep( $resource['value'], $this->format, $this->nl ); + $output .= $this->_createElement( 'RESOURCES', $attributes, $content ); + } + return $output; + } +/** + * set calendar component property recources + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param mixed $value + * @param array $params, optional + * @param integer $index, optional + * @return bool + */ + function setResources( $value, $params=FALSE, $index=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + iCalUtilityFunctions::_setMval( $this->resources, $value, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: RRULE + */ +/** + * creates formatted output for calendar component property rrule + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @return string + */ + function createRrule() { + if( empty( $this->rrule )) return FALSE; + return $this->_format_recur( 'RRULE', $this->rrule ); + } +/** + * set calendar component property rrule + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param array $rruleset + * @param array $params, optional + * @param integer $index, optional + * @return void + */ + function setRrule( $rruleset, $params=FALSE, $index=FALSE ) { + if( empty( $rruleset )) if( $this->getConfig( 'allowEmpty' )) $rruleset = ''; else return FALSE; + iCalUtilityFunctions::_setMval( $this->rrule, iCalUtilityFunctions::_setRexrule( $rruleset ), $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: SEQUENCE + */ +/** + * creates formatted output for calendar component property sequence + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.9.3 - 2011-05-14 + * @return string + */ + function createSequence() { + if( !isset( $this->sequence ) || ( empty( $this->sequence ) && !is_numeric( $this->sequence ))) return FALSE; + if(( !isset($this->sequence['value'] ) || ( empty( $this->sequence['value'] ) && !is_numeric( $this->sequence['value'] ))) && + ( '0' != $this->sequence['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'SEQUENCE' ) : FALSE; + $attributes = $this->_createParams( $this->sequence['params'] ); + return $this->_createElement( 'SEQUENCE', $attributes, $this->sequence['value'] ); + } +/** + * set calendar component property sequence + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.8 - 2011-09-19 + * @param int $value optional + * @param array $params optional + * @return bool + */ + function setSequence( $value=FALSE, $params=FALSE ) { + if(( empty( $value ) && !is_numeric( $value )) && ( '0' != $value )) + $value = ( isset( $this->sequence['value'] ) && ( -1 < $this->sequence['value'] )) ? $this->sequence['value'] + 1 : '0'; + $this->sequence = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: STATUS + */ +/** + * creates formatted output for calendar component property status + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @return string + */ + function createStatus() { + if( empty( $this->status )) return FALSE; + if( empty( $this->status['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'STATUS' ) : FALSE; + $attributes = $this->_createParams( $this->status['params'] ); + return $this->_createElement( 'STATUS', $attributes, $this->status['value'] ); + } +/** + * set calendar component property status + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array $params optional + * @return bool + */ + function setStatus( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->status = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: SUMMARY + */ +/** + * creates formatted output for calendar component property summary + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createSummary() { + if( empty( $this->summary )) return FALSE; + if( empty( $this->summary['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'SUMMARY' ) : FALSE; + $attributes = $this->_createParams( $this->summary['params'], array( 'ALTREP', 'LANGUAGE' )); + $content = iCalUtilityFunctions::_strrep( $this->summary['value'], $this->format, $this->nl ); + return $this->_createElement( 'SUMMARY', $attributes, $content ); + } +/** + * set calendar component property summary + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param string $params optional + * @return bool + */ + function setSummary( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->summary = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: TRANSP + */ +/** + * creates formatted output for calendar component property transp + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @return string + */ + function createTransp() { + if( empty( $this->transp )) return FALSE; + if( empty( $this->transp['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TRANSP' ) : FALSE; + $attributes = $this->_createParams( $this->transp['params'] ); + return $this->_createElement( 'TRANSP', $attributes, $this->transp['value'] ); + } +/** + * set calendar component property transp + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param string $params optional + * @return bool + */ + function setTransp( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->transp = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: TRIGGER + */ +/** + * creates formatted output for calendar component property trigger + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.16 - 2008-10-21 + * @return string + */ + function createTrigger() { + if( empty( $this->trigger )) return FALSE; + if( empty( $this->trigger['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TRIGGER' ) : FALSE; + $content = $attributes = null; + if( isset( $this->trigger['value']['year'] ) && + isset( $this->trigger['value']['month'] ) && + isset( $this->trigger['value']['day'] )) + $content .= iCalUtilityFunctions::_date2strdate( $this->trigger['value'] ); + else { + if( TRUE !== $this->trigger['value']['relatedStart'] ) + $attributes .= $this->intAttrDelimiter.'RELATED=END'; + if( $this->trigger['value']['before'] ) + $content .= '-'; + $content .= iCalUtilityFunctions::_duration2str( $this->trigger['value'] ); + } + $attributes .= $this->_createParams( $this->trigger['params'] ); + return $this->_createElement( 'TRIGGER', $attributes, $content ); + } +/** + * set calendar component property trigger + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param mixed $year + * @param mixed $month optional + * @param int $day optional + * @param int $week optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param bool $relatedStart optional + * @param bool $before optional + * @param array $params optional + * @return bool + */ + function setTrigger( $year, $month=null, $day=null, $week=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $relatedStart=TRUE, $before=TRUE, $params=FALSE ) { + if( empty( $year ) && ( empty( $month ) || is_array( $month )) && empty( $day ) && empty( $week ) && empty( $hour ) && empty( $min ) && empty( $sec )) + if( $this->getConfig( 'allowEmpty' )) { + $this->trigger = array( 'value' => '', 'params' => iCalUtilityFunctions::_setParams( $month ) ); + return TRUE; + } + else + return FALSE; + if( iCalUtilityFunctions::_isArrayTimestampDate( $year )) { // timestamp UTC + $params = iCalUtilityFunctions::_setParams( $month ); + $date = iCalUtilityFunctions::_timestamp2date( $year, 7 ); + foreach( $date as $k => $v ) + $$k = $v; + } + elseif( is_array( $year ) && ( is_array( $month ) || empty( $month ))) { + $params = iCalUtilityFunctions::_setParams( $month ); + if(!(array_key_exists( 'year', $year ) && // exclude date-time + array_key_exists( 'month', $year ) && + array_key_exists( 'day', $year ))) { // when this must be a duration + if( isset( $params['RELATED'] ) && ( 'END' == strtoupper( $params['RELATED'] ))) + $relatedStart = FALSE; + else + $relatedStart = ( array_key_exists( 'relatedStart', $year ) && ( TRUE !== $year['relatedStart'] )) ? FALSE : TRUE; + $before = ( array_key_exists( 'before', $year ) && ( TRUE !== $year['before'] )) ? FALSE : TRUE; + } + $SSYY = ( array_key_exists( 'year', $year )) ? $year['year'] : null; + $month = ( array_key_exists( 'month', $year )) ? $year['month'] : null; + $day = ( array_key_exists( 'day', $year )) ? $year['day'] : null; + $week = ( array_key_exists( 'week', $year )) ? $year['week'] : null; + $hour = ( array_key_exists( 'hour', $year )) ? $year['hour'] : 0; //null; + $min = ( array_key_exists( 'min', $year )) ? $year['min'] : 0; //null; + $sec = ( array_key_exists( 'sec', $year )) ? $year['sec'] : 0; //null; + $year = $SSYY; + } + elseif(is_string( $year ) && ( is_array( $month ) || empty( $month ))) { // duration or date in a string + $params = iCalUtilityFunctions::_setParams( $month ); + if( in_array( $year{0}, array( 'P', '+', '-' ))) { // duration + $relatedStart = ( isset( $params['RELATED'] ) && ( 'END' == strtoupper( $params['RELATED'] ))) ? FALSE : TRUE; + $before = ( '-' == $year[0] ) ? TRUE : FALSE; + if( 'P' != $year[0] ) + $year = substr( $year, 1 ); + $date = iCalUtilityFunctions::_durationStr2arr( $year); + } + else // date + $date = iCalUtilityFunctions::_strdate2date( $year, 7 ); + unset( $year, $month, $day, $date['unparsedtext'] ); + if( empty( $date )) + $sec = 0; + else + foreach( $date as $k => $v ) + $$k = $v; + } + else // single values in function input parameters + $params = iCalUtilityFunctions::_setParams( $params ); + if( !empty( $year ) && !empty( $month ) && !empty( $day )) { // date + $params['VALUE'] = 'DATE-TIME'; + $hour = ( $hour ) ? $hour : 0; + $min = ( $min ) ? $min : 0; + $sec = ( $sec ) ? $sec : 0; + $this->trigger = array( 'params' => $params ); + $this->trigger['value'] = array( 'year' => $year + , 'month' => $month + , 'day' => $day + , 'hour' => $hour + , 'min' => $min + , 'sec' => $sec + , 'tz' => 'Z' ); + return TRUE; + } + elseif(( empty( $year ) && empty( $month )) && // duration + (( !empty( $week ) || ( 0 == $week )) || + ( !empty( $day ) || ( 0 == $day )) || + ( !empty( $hour ) || ( 0 == $hour )) || + ( !empty( $min ) || ( 0 == $min )) || + ( !empty( $sec ) || ( 0 == $sec )))) { + unset( $params['RELATED'] ); // set at output creation (END only) + unset( $params['VALUE'] ); // 'DURATION' default + $this->trigger = array( 'params' => $params ); + $this->trigger['value'] = array(); + if( !empty( $week )) $this->trigger['value']['week'] = $week; + if( !empty( $day )) $this->trigger['value']['day'] = $day; + if( !empty( $hour )) $this->trigger['value']['hour'] = $hour; + if( !empty( $min )) $this->trigger['value']['min'] = $min; + if( !empty( $sec )) $this->trigger['value']['sec'] = $sec; + if( empty( $this->trigger['value'] )) { + $this->trigger['value']['sec'] = 0; + $before = FALSE; + } + else + $this->trigger['value'] = iCalUtilityFunctions::_duration2arr( $this->trigger['value'] ); + $relatedStart = ( FALSE !== $relatedStart ) ? TRUE : FALSE; + $before = ( FALSE !== $before ) ? TRUE : FALSE; + $this->trigger['value']['relatedStart'] = $relatedStart; + $this->trigger['value']['before'] = $before; + return TRUE; + } + return FALSE; + } +/*********************************************************************************/ +/** + * Property Name: TZID + */ +/** + * creates formatted output for calendar component property tzid + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createTzid() { + if( empty( $this->tzid )) return FALSE; + if( empty( $this->tzid['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZID' ) : FALSE; + $attributes = $this->_createParams( $this->tzid['params'] ); + return $this->_createElement( 'TZID', $attributes, iCalUtilityFunctions::_strrep( $this->tzid['value'], $this->format, $this->nl )); + } +/** + * set calendar component property tzid + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param array $params optional + * @return bool + */ + function setTzid( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->tzid = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * .. . + * Property Name: TZNAME + */ +/** + * creates formatted output for calendar component property tzname + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createTzname() { + if( empty( $this->tzname )) return FALSE; + $output = null; + foreach( $this->tzname as $theName ) { + if( !empty( $theName['value'] )) { + $attributes = $this->_createParams( $theName['params'], array( 'LANGUAGE' )); + $output .= $this->_createElement( 'TZNAME', $attributes, iCalUtilityFunctions::_strrep( $theName['value'], $this->format, $this->nl )); + } + elseif( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( 'TZNAME' ); + } + return $output; + } +/** + * set calendar component property tzname + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param string $params, optional + * @param integer $index, optional + * @return bool + */ + function setTzname( $value, $params=FALSE, $index=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + iCalUtilityFunctions::_setMval( $this->tzname, $value, $params, FALSE, $index ); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: TZOFFSETFROM + */ +/** + * creates formatted output for calendar component property tzoffsetfrom + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @return string + */ + function createTzoffsetfrom() { + if( empty( $this->tzoffsetfrom )) return FALSE; + if( empty( $this->tzoffsetfrom['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZOFFSETFROM' ) : FALSE; + $attributes = $this->_createParams( $this->tzoffsetfrom['params'] ); + return $this->_createElement( 'TZOFFSETFROM', $attributes, $this->tzoffsetfrom['value'] ); + } +/** + * set calendar component property tzoffsetfrom + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param string $params optional + * @return bool + */ + function setTzoffsetfrom( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->tzoffsetfrom = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: TZOFFSETTO + */ +/** + * creates formatted output for calendar component property tzoffsetto + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @return string + */ + function createTzoffsetto() { + if( empty( $this->tzoffsetto )) return FALSE; + if( empty( $this->tzoffsetto['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZOFFSETTO' ) : FALSE; + $attributes = $this->_createParams( $this->tzoffsetto['params'] ); + return $this->_createElement( 'TZOFFSETTO', $attributes, $this->tzoffsetto['value'] ); + } +/** + * set calendar component property tzoffsetto + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param string $params optional + * @return bool + */ + function setTzoffsetto( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->tzoffsetto = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: TZURL + */ +/** + * creates formatted output for calendar component property tzurl + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @return string + */ + function createTzurl() { + if( empty( $this->tzurl )) return FALSE; + if( empty( $this->tzurl['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'TZURL' ) : FALSE; + $attributes = $this->_createParams( $this->tzurl['params'] ); + return $this->_createElement( 'TZURL', $attributes, $this->tzurl['value'] ); + } +/** + * set calendar component property tzurl + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param string $params optional + * @return boll + */ + function setTzurl( $value, $params=FALSE ) { + if( empty( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $this->tzurl = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: UID + */ +/** + * creates formatted output for calendar component property uid + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 0.9.7 - 2006-11-20 + * @return string + */ + function createUid() { + if( 0 >= count( $this->uid )) + $this->_makeuid(); + $attributes = $this->_createParams( $this->uid['params'] ); + return $this->_createElement( 'UID', $attributes, $this->uid['value'] ); + } +/** + * create an unique id for this calendar component object instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.2.7 - 2007-09-04 + * @return void + */ + function _makeUid() { + $date = date('Ymd\THisT'); + $unique = substr(microtime(), 2, 4); + $base = 'aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPrRsStTuUvVxXuUvVwWzZ1234567890'; + $start = 0; + $end = strlen( $base ) - 1; + $length = 6; + $str = null; + for( $p = 0; $p < $length; $p++ ) + $unique .= $base{mt_rand( $start, $end )}; + $this->uid = array( 'params' => null ); + $this->uid['value'] = $date.'-'.$unique.'@'.$this->getConfig( 'unique_id' ); + } +/** + * set calendar component property uid + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-11-04 + * @param string $value + * @param string $params optional + * @return bool + */ + function setUid( $value, $params=FALSE ) { + if( empty( $value )) return FALSE; // no allowEmpty check here !!!! + $this->uid = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: URL + */ +/** + * creates formatted output for calendar component property url + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.8 - 2008-10-21 + * @return string + */ + function createUrl() { + if( empty( $this->url )) return FALSE; + if( empty( $this->url['value'] )) + return ( $this->getConfig( 'allowEmpty' )) ? $this->_createElement( 'URL' ) : FALSE; + $attributes = $this->_createParams( $this->url['params'] ); + return $this->_createElement( 'URL', $attributes, $this->url['value'] ); + } +/** + * set calendar component property url + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $value + * @param string $params optional + * @return bool + */ + function setUrl( $value, $params=FALSE ) { + if( !empty( $value )) { + if( !filter_var( $value, FILTER_VALIDATE_URL ) && ( 'urn' != strtolower( substr( $value, 0, 3 )))) + return FALSE; + } + elseif( $this->getConfig( 'allowEmpty' )) + $value = ''; + else + return FALSE; + $this->url = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params )); + return TRUE; + } +/*********************************************************************************/ +/** + * Property Name: x-prop + */ +/** + * creates formatted output for calendar component property x-prop + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @return string + */ + function createXprop() { + if( empty( $this->xprop )) return FALSE; + $output = null; + foreach( $this->xprop as $label => $xpropPart ) { + if( !isset($xpropPart['value']) || ( empty( $xpropPart['value'] ) && !is_numeric( $xpropPart['value'] ))) { + if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( $label ); + continue; + } + $attributes = $this->_createParams( $xpropPart['params'], array( 'LANGUAGE' )); + if( is_array( $xpropPart['value'] )) { + foreach( $xpropPart['value'] as $pix => $theXpart ) + $xpropPart['value'][$pix] = iCalUtilityFunctions::_strrep( $theXpart, $this->format, $this->format ); + $xpropPart['value'] = implode( ',', $xpropPart['value'] ); + } + else + $xpropPart['value'] = iCalUtilityFunctions::_strrep( $xpropPart['value'], $this->format, $this->nl ); + $output .= $this->_createElement( $label, $attributes, $xpropPart['value'] ); + } + return $output; + } +/** + * set calendar component property x-prop + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $label + * @param mixed $value + * @param array $params optional + * @return bool + */ + function setXprop( $label, $value, $params=FALSE ) { + if( empty( $label )) + return FALSE; + if( 'X-' != strtoupper( substr( $label, 0, 2 ))) + return FALSE; + if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE; + $xprop = array( 'value' => $value ); + $xprop['params'] = iCalUtilityFunctions::_setParams( $params ); + if( !is_array( $this->xprop )) $this->xprop = array(); + $this->xprop[strtoupper( $label )] = $xprop; + return TRUE; + } +/*********************************************************************************/ +/*********************************************************************************/ +/** + * create element format parts + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.0.6 - 2006-06-20 + * @return string + */ + function _createFormat() { + $objectname = null; + switch( $this->format ) { + case 'xcal': + $objectname = ( isset( $this->timezonetype )) ? + strtolower( $this->timezonetype ) : strtolower( $this->objName ); + $this->componentStart1 = $this->elementStart1 = '<'; + $this->componentStart2 = $this->elementStart2 = '>'; + $this->componentEnd1 = $this->elementEnd1 = 'componentEnd2 = $this->elementEnd2 = '>'.$this->nl; + $this->intAttrDelimiter = ''; + $this->attributeDelimiter = $this->nl; + $this->valueInit = null; + break; + default: + $objectname = ( isset( $this->timezonetype )) ? + strtoupper( $this->timezonetype ) : strtoupper( $this->objName ); + $this->componentStart1 = 'BEGIN:'; + $this->componentStart2 = null; + $this->componentEnd1 = 'END:'; + $this->componentEnd2 = $this->nl; + $this->elementStart1 = null; + $this->elementStart2 = null; + $this->elementEnd1 = null; + $this->elementEnd2 = $this->nl; + $this->intAttrDelimiter = ''; + $this->attributeDelimiter = ';'; + $this->valueInit = ':'; + break; + } + return $objectname; + } +/** + * creates formatted output for calendar component property + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @param string $label property name + * @param string $attributes property attributes + * @param string $content property content (optional) + * @return string + */ + function _createElement( $label, $attributes=null, $content=FALSE ) { + switch( $this->format ) { + case 'xcal': + $label = strtolower( $label ); + break; + default: + $label = strtoupper( $label ); + break; + } + $output = $this->elementStart1.$label; + $categoriesAttrLang = null; + $attachInlineBinary = FALSE; + $attachfmttype = null; + if (( 'xcal' == $this->format) && ( 'x-' == substr( $label, 0, 2 ))) { + $this->xcaldecl[] = array( 'xmldecl' => 'ELEMENT' + , 'ref' => $label + , 'type2' => '(#PCDATA)' ); + } + if( !empty( $attributes )) { + $attributes = trim( $attributes ); + if ( 'xcal' == $this->format ) { + $attributes2 = explode( $this->intAttrDelimiter, $attributes ); + $attributes = null; + foreach( $attributes2 as $aix => $attribute ) { + $attrKVarr = explode( '=', $attribute ); + if( empty( $attrKVarr[0] )) + continue; + if( !isset( $attrKVarr[1] )) { + $attrValue = $attrKVarr[0]; + $attrKey = $aix; + } + elseif( 2 == count( $attrKVarr)) { + $attrKey = strtolower( $attrKVarr[0] ); + $attrValue = $attrKVarr[1]; + } + else { + $attrKey = strtolower( $attrKVarr[0] ); + unset( $attrKVarr[0] ); + $attrValue = implode( '=', $attrKVarr ); + } + if(( 'attach' == $label ) && ( in_array( $attrKey, array( 'fmttype', 'encoding', 'value' )))) { + $attachInlineBinary = TRUE; + if( 'fmttype' == $attrKey ) + $attachfmttype = $attrKey.'='.$attrValue; + continue; + } + elseif(( 'categories' == $label ) && ( 'language' == $attrKey )) + $categoriesAttrLang = $attrKey.'='.$attrValue; + else { + $attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' '; + $attributes .= ( !empty( $attrKey )) ? $attrKey.'=' : null; + if(( '"' == substr( $attrValue, 0, 1 )) && ( '"' == substr( $attrValue, -1 ))) { + $attrValue = substr( $attrValue, 1, ( strlen( $attrValue ) - 2 )); + $attrValue = str_replace( '"', '', $attrValue ); + } + $attributes .= '"'.htmlspecialchars( $attrValue ).'"'; + } + } + } + else { + $attributes = str_replace( $this->intAttrDelimiter, $this->attributeDelimiter, $attributes ); + } + } + if(( 'xcal' == $this->format) && + ((( 'attach' == $label ) && !$attachInlineBinary ) || ( in_array( $label, array( 'tzurl', 'url' ))))) { + $pos = strrpos($content, "/"); + $docname = ( $pos !== false) ? substr( $content, (1 - strlen( $content ) + $pos )) : $content; + $this->xcaldecl[] = array( 'xmldecl' => 'ENTITY' + , 'uri' => $docname + , 'ref' => 'SYSTEM' + , 'external' => $content + , 'type' => 'NDATA' + , 'type2' => 'BINERY' ); + $attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' '; + $attributes .= 'uri="'.$docname.'"'; + $content = null; + if( 'attach' == $label ) { + $attributes = str_replace( $this->attributeDelimiter, $this->intAttrDelimiter, $attributes ); + $content = $this->nl.$this->_createElement( 'extref', $attributes, null ); + $attributes = null; + } + } + elseif(( 'xcal' == $this->format) && ( 'attach' == $label ) && $attachInlineBinary ) { + $content = $this->nl.$this->_createElement( 'b64bin', $attachfmttype, $content ); // max one attribute + } + $output .= $attributes; + if( !$content && ( '0' != $content )) { + switch( $this->format ) { + case 'xcal': + $output .= ' /'; + $output .= $this->elementStart2.$this->nl; + return $output; + break; + default: + $output .= $this->elementStart2.$this->valueInit; + return iCalUtilityFunctions::_size75( $output, $this->nl ); + break; + } + } + $output .= $this->elementStart2; + $output .= $this->valueInit.$content; + switch( $this->format ) { + case 'xcal': + return $output.$this->elementEnd1.$label.$this->elementEnd2; + break; + default: + return iCalUtilityFunctions::_size75( $output, $this->nl ); + break; + } + } +/** + * creates formatted output for calendar component property parameters + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.27 - 2012-01-16 + * @param array $params optional + * @param array $ctrKeys optional + * @return string + */ + function _createParams( $params=array(), $ctrKeys=array() ) { + if( !is_array( $params ) || empty( $params )) + $params = array(); + $attrLANG = $attr1 = $attr2 = $lang = null; + $CNattrKey = ( in_array( 'CN', $ctrKeys )) ? TRUE : FALSE ; + $LANGattrKey = ( in_array( 'LANGUAGE', $ctrKeys )) ? TRUE : FALSE ; + $CNattrExist = $LANGattrExist = FALSE; + $xparams = array(); + foreach( $params as $paramKey => $paramValue ) { + if(( FALSE !== strpos( $paramValue, ':' )) || + ( FALSE !== strpos( $paramValue, ';' )) || + ( FALSE !== strpos( $paramValue, ',' ))) + $paramValue = '"'.$paramValue.'"'; + if( ctype_digit( (string) $paramKey )) { + $xparams[] = $paramValue; + continue; + } + $paramKey = strtoupper( $paramKey ); + if( !in_array( $paramKey, array( 'ALTREP', 'CN', 'DIR', 'ENCODING', 'FMTTYPE', 'LANGUAGE', 'RANGE', 'RELTYPE', 'SENT-BY', 'TZID', 'VALUE' ))) + $xparams[$paramKey] = $paramValue; + else + $params[$paramKey] = $paramValue; + } + ksort( $xparams, SORT_STRING ); + foreach( $xparams as $paramKey => $paramValue ) { + if( ctype_digit( (string) $paramKey )) + $attr2 .= $this->intAttrDelimiter.$paramValue; + else + $attr2 .= $this->intAttrDelimiter."$paramKey=$paramValue"; + } + if( isset( $params['FMTTYPE'] ) && !in_array( 'FMTTYPE', $ctrKeys )) { + $attr1 .= $this->intAttrDelimiter.'FMTTYPE='.$params['FMTTYPE'].$attr2; + $attr2 = null; + } + if( isset( $params['ENCODING'] ) && !in_array( 'ENCODING', $ctrKeys )) { + if( !empty( $attr2 )) { + $attr1 .= $attr2; + $attr2 = null; + } + $attr1 .= $this->intAttrDelimiter.'ENCODING='.$params['ENCODING']; + } + if( isset( $params['VALUE'] ) && !in_array( 'VALUE', $ctrKeys )) + $attr1 .= $this->intAttrDelimiter.'VALUE='.$params['VALUE']; + if( isset( $params['TZID'] ) && !in_array( 'TZID', $ctrKeys )) { + $attr1 .= $this->intAttrDelimiter.'TZID='.$params['TZID']; + } + if( isset( $params['RANGE'] ) && !in_array( 'RANGE', $ctrKeys )) + $attr1 .= $this->intAttrDelimiter.'RANGE='.$params['RANGE']; + if( isset( $params['RELTYPE'] ) && !in_array( 'RELTYPE', $ctrKeys )) + $attr1 .= $this->intAttrDelimiter.'RELTYPE='.$params['RELTYPE']; + if( isset( $params['CN'] ) && $CNattrKey ) { + $attr1 = $this->intAttrDelimiter.'CN='.$params['CN']; + $CNattrExist = TRUE; + } + if( isset( $params['DIR'] ) && in_array( 'DIR', $ctrKeys )) { + $delim = ( FALSE !== strpos( $params['DIR'], '"' )) ? '' : '"'; + $attr1 .= $this->intAttrDelimiter.'DIR='.$delim.$params['DIR'].$delim; + } + if( isset( $params['SENT-BY'] ) && in_array( 'SENT-BY', $ctrKeys )) + $attr1 .= $this->intAttrDelimiter.'SENT-BY='.$params['SENT-BY']; + if( isset( $params['ALTREP'] ) && in_array( 'ALTREP', $ctrKeys )) { + $delim = ( FALSE !== strpos( $params['ALTREP'], '"' )) ? '' : '"'; + $attr1 .= $this->intAttrDelimiter.'ALTREP='.$delim.$params['ALTREP'].$delim; + } + if( isset( $params['LANGUAGE'] ) && $LANGattrKey ) { + $attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$params['LANGUAGE']; + $LANGattrExist = TRUE; + } + if( !$LANGattrExist ) { + $lang = $this->getConfig( 'language' ); + if(( $CNattrExist || $LANGattrKey ) && $lang ) + $attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$lang; + } + return $attr1.$attrLANG.$attr2; + } +/** + * creates formatted output for calendar component property data value type recur + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.25 - 2013-06-30 + * @param array $recurlabel + * @param array $recurdata + * @return string + */ + function _format_recur( $recurlabel, $recurdata ) { + $output = null; + foreach( $recurdata as $therule ) { + if( empty( $therule['value'] )) { + if( $this->getConfig( 'allowEmpty' )) $output .= $this->_createElement( $recurlabel ); + continue; + } + $attributes = ( isset( $therule['params'] )) ? $this->_createParams( $therule['params'] ) : null; + $content1 = $content2 = null; + foreach( $therule['value'] as $rulelabel => $rulevalue ) { + switch( strtoupper( $rulelabel )) { + case 'FREQ': { + $content1 .= "FREQ=$rulevalue"; + break; + } + case 'UNTIL': { + $parno = ( isset( $rulevalue['hour'] )) ? 7 : 3; + $content2 .= ';UNTIL='.iCalUtilityFunctions::_date2strdate( $rulevalue, $parno ); + break; + } + case 'COUNT': + case 'INTERVAL': + case 'WKST': { + $content2 .= ";$rulelabel=$rulevalue"; + break; + } + case 'BYSECOND': + case 'BYMINUTE': + case 'BYHOUR': + case 'BYMONTHDAY': + case 'BYYEARDAY': + case 'BYWEEKNO': + case 'BYMONTH': + case 'BYSETPOS': { + $content2 .= ";$rulelabel="; + if( is_array( $rulevalue )) { + foreach( $rulevalue as $vix => $valuePart ) { + $content2 .= ( $vix ) ? ',' : null; + $content2 .= $valuePart; + } + } + else + $content2 .= $rulevalue; + break; + } + case 'BYDAY': { + $byday = array( '' ); + $bx = 0; + foreach( $rulevalue as $bix => $bydayPart ) { + if( ! empty( $byday[$bx] ) && ! ctype_digit( substr( $byday[$bx], -1 ))) // new day + $byday[++$bx] = ''; + if( ! is_array( $bydayPart )) // day without order number + $byday[$bx] .= (string) $bydayPart; + else { // day with order number + foreach( $bydayPart as $bix2 => $bydayPart2 ) + $byday[$bx] .= (string) $bydayPart2; + } + } // end foreach( $rulevalue as $bix => $bydayPart ) + if( 1 < count( $byday )) + usort( $byday, array( 'iCalUtilityFunctions', '_recurBydaySort' )); + $content2 .= ';BYDAY='.implode( ',', $byday ); + break; + } + default: { + $content2 .= ";$rulelabel=$rulevalue"; + break; + } + } + } + $output .= $this->_createElement( $recurlabel, $attributes, $content1.$content2 ); + } + return $output; + } +/** + * check if property not exists within component + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-15 + * @param string $propName + * @return bool + */ + function _notExistProp( $propName ) { + if( empty( $propName )) return FALSE; // when deleting x-prop, an empty propName may be used=allowed + $propName = strtolower( $propName ); + if( 'last-modified' == $propName ) { if( !isset( $this->lastmodified )) return TRUE; } + elseif( 'percent-complete' == $propName ) { if( !isset( $this->percentcomplete )) return TRUE; } + elseif( 'recurrence-id' == $propName ) { if( !isset( $this->recurrenceid )) return TRUE; } + elseif( 'related-to' == $propName ) { if( !isset( $this->relatedto )) return TRUE; } + elseif( 'request-status' == $propName ) { if( !isset( $this->requeststatus )) return TRUE; } + elseif(( 'x-' != substr($propName,0,2)) && !isset( $this->$propName )) return TRUE; + return FALSE; + } +/*********************************************************************************/ +/*********************************************************************************/ +/** + * get general component config variables or info about subcomponents + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.9.6 - 2011-05-14 + * @param mixed $config + * @return value + */ + function getConfig( $config = FALSE) { + if( !$config ) { + $return = array(); + $return['ALLOWEMPTY'] = $this->getConfig( 'ALLOWEMPTY' ); + $return['FORMAT'] = $this->getConfig( 'FORMAT' ); + if( FALSE !== ( $lang = $this->getConfig( 'LANGUAGE' ))) + $return['LANGUAGE'] = $lang; + $return['NEWLINECHAR'] = $this->getConfig( 'NEWLINECHAR' ); + $return['TZTD'] = $this->getConfig( 'TZID' ); + $return['UNIQUE_ID'] = $this->getConfig( 'UNIQUE_ID' ); + return $return; + } + switch( strtoupper( $config )) { + case 'ALLOWEMPTY': + return $this->allowEmpty; + break; + case 'COMPSINFO': + unset( $this->compix ); + $info = array(); + if( isset( $this->components )) { + foreach( $this->components as $cix => $component ) { + if( empty( $component )) continue; + $info[$cix]['ordno'] = $cix + 1; + $info[$cix]['type'] = $component->objName; + $info[$cix]['uid'] = $component->getProperty( 'uid' ); + $info[$cix]['props'] = $component->getConfig( 'propinfo' ); + $info[$cix]['sub'] = $component->getConfig( 'compsinfo' ); + } + } + return $info; + break; + case 'FORMAT': + return $this->format; + break; + case 'LANGUAGE': + // get language for calendar component as defined in [RFC 1766] + return $this->language; + break; + case 'NL': + case 'NEWLINECHAR': + return $this->nl; + break; + case 'PROPINFO': + $output = array(); + if( !in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) { + if( empty( $this->uid['value'] )) $this->_makeuid(); + $output['UID'] = 1; + if( empty( $this->dtstamp )) $this->_makeDtstamp(); + $output['DTSTAMP'] = 1; + } + if( !empty( $this->summary )) $output['SUMMARY'] = 1; + if( !empty( $this->description )) $output['DESCRIPTION'] = count( $this->description ); + if( !empty( $this->dtstart )) $output['DTSTART'] = 1; + if( !empty( $this->dtend )) $output['DTEND'] = 1; + if( !empty( $this->due )) $output['DUE'] = 1; + if( !empty( $this->duration )) $output['DURATION'] = 1; + if( !empty( $this->rrule )) $output['RRULE'] = count( $this->rrule ); + if( !empty( $this->rdate )) $output['RDATE'] = count( $this->rdate ); + if( !empty( $this->exdate )) $output['EXDATE'] = count( $this->exdate ); + if( !empty( $this->exrule )) $output['EXRULE'] = count( $this->exrule ); + if( !empty( $this->action )) $output['ACTION'] = 1; + if( !empty( $this->attach )) $output['ATTACH'] = count( $this->attach ); + if( !empty( $this->attendee )) $output['ATTENDEE'] = count( $this->attendee ); + if( !empty( $this->categories )) $output['CATEGORIES'] = count( $this->categories ); + if( !empty( $this->class )) $output['CLASS'] = 1; + if( !empty( $this->comment )) $output['COMMENT'] = count( $this->comment ); + if( !empty( $this->completed )) $output['COMPLETED'] = 1; + if( !empty( $this->contact )) $output['CONTACT'] = count( $this->contact ); + if( !empty( $this->created )) $output['CREATED'] = 1; + if( !empty( $this->freebusy )) $output['FREEBUSY'] = count( $this->freebusy ); + if( !empty( $this->geo )) $output['GEO'] = 1; + if( !empty( $this->lastmodified )) $output['LAST-MODIFIED'] = 1; + if( !empty( $this->location )) $output['LOCATION'] = 1; + if( !empty( $this->organizer )) $output['ORGANIZER'] = 1; + if( !empty( $this->percentcomplete )) $output['PERCENT-COMPLETE'] = 1; + if( !empty( $this->priority )) $output['PRIORITY'] = 1; + if( !empty( $this->recurrenceid )) $output['RECURRENCE-ID'] = 1; + if( !empty( $this->relatedto )) $output['RELATED-TO'] = count( $this->relatedto ); + if( !empty( $this->repeat )) $output['REPEAT'] = 1; + if( !empty( $this->requeststatus )) $output['REQUEST-STATUS'] = count( $this->requeststatus ); + if( !empty( $this->resources )) $output['RESOURCES'] = count( $this->resources ); + if( !empty( $this->sequence )) $output['SEQUENCE'] = 1; + if( !empty( $this->sequence )) $output['SEQUENCE'] = 1; + if( !empty( $this->status )) $output['STATUS'] = 1; + if( !empty( $this->transp )) $output['TRANSP'] = 1; + if( !empty( $this->trigger )) $output['TRIGGER'] = 1; + if( !empty( $this->tzid )) $output['TZID'] = 1; + if( !empty( $this->tzname )) $output['TZNAME'] = count( $this->tzname ); + if( !empty( $this->tzoffsetfrom )) $output['TZOFFSETFROM'] = 1; + if( !empty( $this->tzoffsetto )) $output['TZOFFSETTO'] = 1; + if( !empty( $this->tzurl )) $output['TZURL'] = 1; + if( !empty( $this->url )) $output['URL'] = 1; + if( !empty( $this->xprop )) $output['X-PROP'] = count( $this->xprop ); + return $output; + break; + case 'SETPROPERTYNAMES': + return array_keys( $this->getConfig( 'propinfo' )); + break; + case 'TZID': + return $this->dtzid; + break; + case 'UNIQUE_ID': + if( empty( $this->unique_id )) + $this->unique_id = ( isset( $_SERVER['SERVER_NAME'] )) ? gethostbyname( $_SERVER['SERVER_NAME'] ) : 'localhost'; + return $this->unique_id; + break; + } + } +/** + * general component config setting + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.18 - 2011-10-28 + * @param mixed $config + * @param string $value + * @param bool $softUpdate + * @return void + */ + function setConfig( $config, $value = FALSE, $softUpdate = FALSE ) { + if( is_array( $config )) { + $ak = array_keys( $config ); + foreach( $ak as $k ) { + if( 'NEWLINECHAR' == strtoupper( $k )) { + if( FALSE === $this->setConfig( 'NEWLINECHAR', $config[$k] )) + return FALSE; + unset( $config[$k] ); + break; + } + } + foreach( $config as $cKey => $cValue ) { + if( FALSE === $this->setConfig( $cKey, $cValue, $softUpdate )) + return FALSE; + } + return TRUE; + } + $res = FALSE; + switch( strtoupper( $config )) { + case 'ALLOWEMPTY': + $this->allowEmpty = $value; + $subcfg = array( 'ALLOWEMPTY' => $value ); + $res = TRUE; + break; + case 'FORMAT': + $value = trim( strtolower( $value )); + $this->format = $value; + $this->_createFormat(); + $subcfg = array( 'FORMAT' => $value ); + $res = TRUE; + break; + case 'LANGUAGE': + // set language for calendar component as defined in [RFC 1766] + $value = trim( $value ); + if( empty( $this->language ) || !$softUpdate ) + $this->language = $value; + $subcfg = array( 'LANGUAGE' => $value ); + $res = TRUE; + break; + case 'NL': + case 'NEWLINECHAR': + $this->nl = $value; + $this->_createFormat(); + $subcfg = array( 'NL' => $value ); + $res = TRUE; + break; + case 'TZID': + $this->dtzid = $value; + $subcfg = array( 'TZID' => $value ); + $res = TRUE; + break; + case 'UNIQUE_ID': + $value = trim( $value ); + $this->unique_id = $value; + $subcfg = array( 'UNIQUE_ID' => $value ); + $res = TRUE; + break; + default: // any unvalid config key.. . + return TRUE; + } + if( !$res ) return FALSE; + if( isset( $subcfg ) && !empty( $this->components )) { + foreach( $subcfg as $cfgkey => $cfgvalue ) { + foreach( $this->components as $cix => $component ) { + $res = $component->setConfig( $cfgkey, $cfgvalue, $softUpdate ); + if( !$res ) + break 2; + $this->components[$cix] = $component->copy(); // PHP4 compliant + } + } + } + return $res; + } +/*********************************************************************************/ +/** + * delete component property value + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.8 - 2011-03-15 + * @param mixed $propName, bool FALSE => X-property + * @param int $propix, optional, if specific property is wanted in case of multiply occurences + * @return bool, if successfull delete TRUE + */ + function deleteProperty( $propName=FALSE, $propix=FALSE ) { + if( $this->_notExistProp( $propName )) return FALSE; + $propName = strtoupper( $propName ); + if( in_array( $propName, array( 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'DESCRIPTION', 'EXDATE', 'EXRULE', + 'FREEBUSY', 'RDATE', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'TZNAME', 'X-PROP' ))) { + if( !$propix ) + $propix = ( isset( $this->propdelix[$propName] ) && ( 'X-PROP' != $propName )) ? $this->propdelix[$propName] + 2 : 1; + $this->propdelix[$propName] = --$propix; + } + $return = FALSE; + switch( $propName ) { + case 'ACTION': + if( !empty( $this->action )) { + $this->action = ''; + $return = TRUE; + } + break; + case 'ATTACH': + return $this->deletePropertyM( $this->attach, $this->propdelix[$propName] ); + break; + case 'ATTENDEE': + return $this->deletePropertyM( $this->attendee, $this->propdelix[$propName] ); + break; + case 'CATEGORIES': + return $this->deletePropertyM( $this->categories, $this->propdelix[$propName] ); + break; + case 'CLASS': + if( !empty( $this->class )) { + $this->class = ''; + $return = TRUE; + } + break; + case 'COMMENT': + return $this->deletePropertyM( $this->comment, $this->propdelix[$propName] ); + break; + case 'COMPLETED': + if( !empty( $this->completed )) { + $this->completed = ''; + $return = TRUE; + } + break; + case 'CONTACT': + return $this->deletePropertyM( $this->contact, $this->propdelix[$propName] ); + break; + case 'CREATED': + if( !empty( $this->created )) { + $this->created = ''; + $return = TRUE; + } + break; + case 'DESCRIPTION': + return $this->deletePropertyM( $this->description, $this->propdelix[$propName] ); + break; + case 'DTEND': + if( !empty( $this->dtend )) { + $this->dtend = ''; + $return = TRUE; + } + break; + case 'DTSTAMP': + if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) + return FALSE; + if( !empty( $this->dtstamp )) { + $this->dtstamp = ''; + $return = TRUE; + } + break; + case 'DTSTART': + if( !empty( $this->dtstart )) { + $this->dtstart = ''; + $return = TRUE; + } + break; + case 'DUE': + if( !empty( $this->due )) { + $this->due = ''; + $return = TRUE; + } + break; + case 'DURATION': + if( !empty( $this->duration )) { + $this->duration = ''; + $return = TRUE; + } + break; + case 'EXDATE': + return $this->deletePropertyM( $this->exdate, $this->propdelix[$propName] ); + break; + case 'EXRULE': + return $this->deletePropertyM( $this->exrule, $this->propdelix[$propName] ); + break; + case 'FREEBUSY': + return $this->deletePropertyM( $this->freebusy, $this->propdelix[$propName] ); + break; + case 'GEO': + if( !empty( $this->geo )) { + $this->geo = ''; + $return = TRUE; + } + break; + case 'LAST-MODIFIED': + if( !empty( $this->lastmodified )) { + $this->lastmodified = ''; + $return = TRUE; + } + break; + case 'LOCATION': + if( !empty( $this->location )) { + $this->location = ''; + $return = TRUE; + } + break; + case 'ORGANIZER': + if( !empty( $this->organizer )) { + $this->organizer = ''; + $return = TRUE; + } + break; + case 'PERCENT-COMPLETE': + if( !empty( $this->percentcomplete )) { + $this->percentcomplete = ''; + $return = TRUE; + } + break; + case 'PRIORITY': + if( !empty( $this->priority )) { + $this->priority = ''; + $return = TRUE; + } + break; + case 'RDATE': + return $this->deletePropertyM( $this->rdate, $this->propdelix[$propName] ); + break; + case 'RECURRENCE-ID': + if( !empty( $this->recurrenceid )) { + $this->recurrenceid = ''; + $return = TRUE; + } + break; + case 'RELATED-TO': + return $this->deletePropertyM( $this->relatedto, $this->propdelix[$propName] ); + break; + case 'REPEAT': + if( !empty( $this->repeat )) { + $this->repeat = ''; + $return = TRUE; + } + break; + case 'REQUEST-STATUS': + return $this->deletePropertyM( $this->requeststatus, $this->propdelix[$propName] ); + break; + case 'RESOURCES': + return $this->deletePropertyM( $this->resources, $this->propdelix[$propName] ); + break; + case 'RRULE': + return $this->deletePropertyM( $this->rrule, $this->propdelix[$propName] ); + break; + case 'SEQUENCE': + if( !empty( $this->sequence )) { + $this->sequence = ''; + $return = TRUE; + } + break; + case 'STATUS': + if( !empty( $this->status )) { + $this->status = ''; + $return = TRUE; + } + break; + case 'SUMMARY': + if( !empty( $this->summary )) { + $this->summary = ''; + $return = TRUE; + } + break; + case 'TRANSP': + if( !empty( $this->transp )) { + $this->transp = ''; + $return = TRUE; + } + break; + case 'TRIGGER': + if( !empty( $this->trigger )) { + $this->trigger = ''; + $return = TRUE; + } + break; + case 'TZID': + if( !empty( $this->tzid )) { + $this->tzid = ''; + $return = TRUE; + } + break; + case 'TZNAME': + return $this->deletePropertyM( $this->tzname, $this->propdelix[$propName] ); + break; + case 'TZOFFSETFROM': + if( !empty( $this->tzoffsetfrom )) { + $this->tzoffsetfrom = ''; + $return = TRUE; + } + break; + case 'TZOFFSETTO': + if( !empty( $this->tzoffsetto )) { + $this->tzoffsetto = ''; + $return = TRUE; + } + break; + case 'TZURL': + if( !empty( $this->tzurl )) { + $this->tzurl = ''; + $return = TRUE; + } + break; + case 'UID': + if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) + return FALSE; + if( !empty( $this->uid )) { + $this->uid = ''; + $return = TRUE; + } + break; + case 'URL': + if( !empty( $this->url )) { + $this->url = ''; + $return = TRUE; + } + break; + default: + $reduced = ''; + if( $propName != 'X-PROP' ) { + if( !isset( $this->xprop[$propName] )) return FALSE; + foreach( $this->xprop as $k => $a ) { + if(( $k != $propName ) && !empty( $a )) + $reduced[$k] = $a; + } + } + else { + if( count( $this->xprop ) <= $propix ) { unset( $this->propdelix[$propName] ); return FALSE; } + $xpropno = 0; + foreach( $this->xprop as $xpropkey => $xpropvalue ) { + if( $propix != $xpropno ) + $reduced[$xpropkey] = $xpropvalue; + $xpropno++; + } + } + $this->xprop = $reduced; + if( empty( $this->xprop )) { + unset( $this->propdelix[$propName] ); + return FALSE; + } + return TRUE; + } + return $return; + } +/*********************************************************************************/ +/** + * delete component property value, fixing components with multiple occurencies + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.8 - 2011-03-15 + * @param array $multiprop, reference to a component property + * @param int $propix, reference to removal counter + * @return bool TRUE + */ + function deletePropertyM( & $multiprop, & $propix ) { + if( isset( $multiprop[$propix] )) + unset( $multiprop[$propix] ); + if( empty( $multiprop )) { + $multiprop = ''; + unset( $propix ); + return FALSE; + } + else + return TRUE; + } +/** + * get component property value/params + * + * if property has multiply values, consequtive function calls are needed + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param string $propName, optional + * @param int @propix, optional, if specific property is wanted in case of multiply occurences + * @param bool $inclParam=FALSE + * @param bool $specform=FALSE + * @return mixed + */ + function getProperty( $propName=FALSE, $propix=FALSE, $inclParam=FALSE, $specform=FALSE ) { + if( 'GEOLOCATION' == strtoupper( $propName )) { + $content = $this->getProperty( 'LOCATION' ); + $content = ( !empty( $content )) ? $content.' ' : ''; + if(( FALSE === ( $geo = $this->getProperty( 'GEO' ))) || empty( $geo )) + return FALSE; + if( 0.0 < $geo['latitude'] ) + $sign = '+'; + else + $sign = ( 0.0 > $geo['latitude'] ) ? '-' : ''; + $content .= $sign.sprintf( "%09.6f", abs( $geo['latitude'] )); // sprintf && lpad && float && sign !"#¤%&/( + $content = rtrim( rtrim( $content, '0' ), '.' ); + if( 0.0 < $geo['longitude'] ) + $sign = '+'; + else + $sign = ( 0.0 > $geo['longitude'] ) ? '-' : ''; + return $content.$sign.sprintf( '%8.6f', abs( $geo['longitude'] )).'/'; // sprintf && lpad && float && sign !"#¤%&/( + } + if( $this->_notExistProp( $propName )) return FALSE; + $propName = ( $propName ) ? strtoupper( $propName ) : 'X-PROP'; + if( in_array( $propName, array( 'ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'DESCRIPTION', 'EXDATE', 'EXRULE', + 'FREEBUSY', 'RDATE', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'TZNAME', 'X-PROP' ))) { + if( !$propix ) + $propix = ( isset( $this->propix[$propName] )) ? $this->propix[$propName] + 2 : 1; + $this->propix[$propName] = --$propix; + } + switch( $propName ) { + case 'ACTION': + if( isset( $this->action['value'] )) return ( $inclParam ) ? $this->action : $this->action['value']; + break; + case 'ATTACH': + $ak = ( is_array( $this->attach )) ? array_keys( $this->attach ) : array(); + while( is_array( $this->attach ) && !isset( $this->attach[$propix] ) && ( 0 < count( $this->attach )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->attach[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->attach[$propix] : $this->attach[$propix]['value']; + break; + case 'ATTENDEE': + $ak = ( is_array( $this->attendee )) ? array_keys( $this->attendee ) : array(); + while( is_array( $this->attendee ) && !isset( $this->attendee[$propix] ) && ( 0 < count( $this->attendee )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->attendee[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->attendee[$propix] : $this->attendee[$propix]['value']; + break; + case 'CATEGORIES': + $ak = ( is_array( $this->categories )) ? array_keys( $this->categories ) : array(); + while( is_array( $this->categories ) && !isset( $this->categories[$propix] ) && ( 0 < count( $this->categories )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->categories[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->categories[$propix] : $this->categories[$propix]['value']; + break; + case 'CLASS': + if( isset( $this->class['value'] )) return ( $inclParam ) ? $this->class : $this->class['value']; + break; + case 'COMMENT': + $ak = ( is_array( $this->comment )) ? array_keys( $this->comment ) : array(); + while( is_array( $this->comment ) && !isset( $this->comment[$propix] ) && ( 0 < count( $this->comment )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->comment[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->comment[$propix] : $this->comment[$propix]['value']; + break; + case 'COMPLETED': + if( isset( $this->completed['value'] )) return ( $inclParam ) ? $this->completed : $this->completed['value']; + break; + case 'CONTACT': + $ak = ( is_array( $this->contact )) ? array_keys( $this->contact ) : array(); + while( is_array( $this->contact ) && !isset( $this->contact[$propix] ) && ( 0 < count( $this->contact )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->contact[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->contact[$propix] : $this->contact[$propix]['value']; + break; + case 'CREATED': + if( isset( $this->created['value'] )) return ( $inclParam ) ? $this->created : $this->created['value']; + break; + case 'DESCRIPTION': + $ak = ( is_array( $this->description )) ? array_keys( $this->description ) : array(); + while( is_array( $this->description ) && !isset( $this->description[$propix] ) && ( 0 < count( $this->description )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->description[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->description[$propix] : $this->description[$propix]['value']; + break; + case 'DTEND': + if( isset( $this->dtend['value'] )) return ( $inclParam ) ? $this->dtend : $this->dtend['value']; + break; + case 'DTSTAMP': + if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) + return; + if( !isset( $this->dtstamp['value'] )) + $this->_makeDtstamp(); + return ( $inclParam ) ? $this->dtstamp : $this->dtstamp['value']; + break; + case 'DTSTART': + if( isset( $this->dtstart['value'] )) return ( $inclParam ) ? $this->dtstart : $this->dtstart['value']; + break; + case 'DUE': + if( isset( $this->due['value'] )) return ( $inclParam ) ? $this->due : $this->due['value']; + break; + case 'DURATION': + if( ! isset( $this->duration['value'] )) return FALSE; + $value = ( $specform && isset( $this->dtstart['value'] ) && isset( $this->duration['value'] )) ? iCalUtilityFunctions::_duration2date( $this->dtstart['value'], $this->duration['value'] ) : $this->duration['value']; + return ( $inclParam ) ? array( 'value' => $value, 'params' => $this->duration['params'] ) : $value; + break; + case 'EXDATE': + $ak = ( is_array( $this->exdate )) ? array_keys( $this->exdate ) : array(); + while( is_array( $this->exdate ) && !isset( $this->exdate[$propix] ) && ( 0 < count( $this->exdate )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->exdate[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->exdate[$propix] : $this->exdate[$propix]['value']; + break; + case 'EXRULE': + $ak = ( is_array( $this->exrule )) ? array_keys( $this->exrule ) : array(); + while( is_array( $this->exrule ) && !isset( $this->exrule[$propix] ) && ( 0 < count( $this->exrule )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->exrule[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->exrule[$propix] : $this->exrule[$propix]['value']; + break; + case 'FREEBUSY': + $ak = ( is_array( $this->freebusy )) ? array_keys( $this->freebusy ) : array(); + while( is_array( $this->freebusy ) && !isset( $this->freebusy[$propix] ) && ( 0 < count( $this->freebusy )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->freebusy[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->freebusy[$propix] : $this->freebusy[$propix]['value']; + break; + case 'GEO': + if( isset( $this->geo['value'] )) return ( $inclParam ) ? $this->geo : $this->geo['value']; + break; + case 'LAST-MODIFIED': + if( isset( $this->lastmodified['value'] )) return ( $inclParam ) ? $this->lastmodified : $this->lastmodified['value']; + break; + case 'LOCATION': + if( isset( $this->location['value'] )) return ( $inclParam ) ? $this->location : $this->location['value']; + break; + case 'ORGANIZER': + if( isset( $this->organizer['value'] )) return ( $inclParam ) ? $this->organizer : $this->organizer['value']; + break; + case 'PERCENT-COMPLETE': + if( isset( $this->percentcomplete['value'] )) return ( $inclParam ) ? $this->percentcomplete : $this->percentcomplete['value']; + break; + case 'PRIORITY': + if( isset( $this->priority['value'] )) return ( $inclParam ) ? $this->priority : $this->priority['value']; + break; + case 'RDATE': + $ak = ( is_array( $this->rdate )) ? array_keys( $this->rdate ) : array(); + while( is_array( $this->rdate ) && !isset( $this->rdate[$propix] ) && ( 0 < count( $this->rdate )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->rdate[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->rdate[$propix] : $this->rdate[$propix]['value']; + break; + case 'RECURRENCE-ID': + if( isset( $this->recurrenceid['value'] )) return ( $inclParam ) ? $this->recurrenceid : $this->recurrenceid['value']; + break; + case 'RELATED-TO': + $ak = ( is_array( $this->relatedto )) ? array_keys( $this->relatedto ) : array(); + while( is_array( $this->relatedto ) && !isset( $this->relatedto[$propix] ) && ( 0 < count( $this->relatedto )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->relatedto[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->relatedto[$propix] : $this->relatedto[$propix]['value']; + break; + case 'REPEAT': + if( isset( $this->repeat['value'] )) return ( $inclParam ) ? $this->repeat : $this->repeat['value']; + break; + case 'REQUEST-STATUS': + $ak = ( is_array( $this->requeststatus )) ? array_keys( $this->requeststatus ) : array(); + while( is_array( $this->requeststatus ) && !isset( $this->requeststatus[$propix] ) && ( 0 < count( $this->requeststatus )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->requeststatus[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->requeststatus[$propix] : $this->requeststatus[$propix]['value']; + break; + case 'RESOURCES': + $ak = ( is_array( $this->resources )) ? array_keys( $this->resources ) : array(); + while( is_array( $this->resources ) && !isset( $this->resources[$propix] ) && ( 0 < count( $this->resources )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->resources[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->resources[$propix] : $this->resources[$propix]['value']; + break; + case 'RRULE': + $ak = ( is_array( $this->rrule )) ? array_keys( $this->rrule ) : array(); + while( is_array( $this->rrule ) && !isset( $this->rrule[$propix] ) && ( 0 < count( $this->rrule )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->rrule[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->rrule[$propix] : $this->rrule[$propix]['value']; + break; + case 'SEQUENCE': + if( isset( $this->sequence['value'] )) return ( $inclParam ) ? $this->sequence : $this->sequence['value']; + break; + case 'STATUS': + if( isset( $this->status['value'] )) return ( $inclParam ) ? $this->status : $this->status['value']; + break; + case 'SUMMARY': + if( isset( $this->summary['value'] )) return ( $inclParam ) ? $this->summary : $this->summary['value']; + break; + case 'TRANSP': + if( isset( $this->transp['value'] )) return ( $inclParam ) ? $this->transp : $this->transp['value']; + break; + case 'TRIGGER': + if( isset( $this->trigger['value'] )) return ( $inclParam ) ? $this->trigger : $this->trigger['value']; + break; + case 'TZID': + if( isset( $this->tzid['value'] )) return ( $inclParam ) ? $this->tzid : $this->tzid['value']; + break; + case 'TZNAME': + $ak = ( is_array( $this->tzname )) ? array_keys( $this->tzname ) : array(); + while( is_array( $this->tzname ) && !isset( $this->tzname[$propix] ) && ( 0 < count( $this->tzname )) && ( $propix < end( $ak ))) + $propix++; + $this->propix[$propName] = $propix; + if( !isset( $this->tzname[$propix] )) { unset( $this->propix[$propName] ); return FALSE; } + return ( $inclParam ) ? $this->tzname[$propix] : $this->tzname[$propix]['value']; + break; + case 'TZOFFSETFROM': + if( isset( $this->tzoffsetfrom['value'] )) return ( $inclParam ) ? $this->tzoffsetfrom : $this->tzoffsetfrom['value']; + break; + case 'TZOFFSETTO': + if( isset( $this->tzoffsetto['value'] )) return ( $inclParam ) ? $this->tzoffsetto : $this->tzoffsetto['value']; + break; + case 'TZURL': + if( isset( $this->tzurl['value'] )) return ( $inclParam ) ? $this->tzurl : $this->tzurl['value']; + break; + case 'UID': + if( in_array( $this->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) + return FALSE; + if( empty( $this->uid['value'] )) + $this->_makeuid(); + return ( $inclParam ) ? $this->uid : $this->uid['value']; + break; + case 'URL': + if( isset( $this->url['value'] )) return ( $inclParam ) ? $this->url : $this->url['value']; + break; + default: + if( $propName != 'X-PROP' ) { + if( !isset( $this->xprop[$propName] )) return FALSE; + return ( $inclParam ) ? array( $propName, $this->xprop[$propName] ) + : array( $propName, $this->xprop[$propName]['value'] ); + } + else { + if( empty( $this->xprop )) return FALSE; + $xpropno = 0; + foreach( $this->xprop as $xpropkey => $xpropvalue ) { + if( $propix == $xpropno ) + return ( $inclParam ) ? array( $xpropkey, $this->xprop[$xpropkey] ) + : array( $xpropkey, $this->xprop[$xpropkey]['value'] ); + else + $xpropno++; + } + return FALSE; // not found ?? + } + } + return FALSE; + } +/** + * returns calendar property unique values for 'ATTENDEE', 'CATEGORIES', 'CONTACT', 'RELATED-TO' or 'RESOURCES' and for each, number of occurrence + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.13.4 - 2012-08-07 + * @param string $propName + * @param array $output, incremented result array + */ + function _getProperties( $propName, & $output ) { + if( empty( $output )) + $output = array(); + if( !in_array( strtoupper( $propName ), array( 'ATTENDEE', 'CATEGORIES', 'CONTACT', 'RELATED-TO', 'RESOURCES' ))) + return $output; + while( FALSE !== ( $content = $this->getProperty( $propName ))) { + if( empty( $content )) + continue; + if( is_array( $content )) { + foreach( $content as $part ) { + if( FALSE !== strpos( $part, ',' )) { + $part = explode( ',', $part ); + foreach( $part as $thePart ) { + $thePart = trim( $thePart ); + if( !empty( $thePart )) { + if( !isset( $output[$thePart] )) + $output[$thePart] = 1; + else + $output[$thePart] += 1; + } + } + } + else { + $part = trim( $part ); + if( !isset( $output[$part] )) + $output[$part] = 1; + else + $output[$part] += 1; + } + } + } // end if( is_array( $content )) + elseif( FALSE !== strpos( $content, ',' )) { + $content = explode( ',', $content ); + foreach( $content as $thePart ) { + $thePart = trim( $thePart ); + if( !empty( $thePart )) { + if( !isset( $output[$thePart] )) + $output[$thePart] = 1; + else + $output[$thePart] += 1; + } + } + } // end elseif( FALSE !== strpos( $content, ',' )) + else { + $content = trim( $content ); + if( !empty( $content )) { + if( !isset( $output[$content] )) + $output[$content] = 1; + else + $output[$content] += 1; + } + } + } + ksort( $output ); + } +/** + * general component property setting + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-11-05 + * @param mixed $args variable number of function arguments, + * first argument is ALWAYS component name, + * second ALWAYS component value! + * @return void + */ + function setProperty() { + $numargs = func_num_args(); + if( 1 > $numargs ) return FALSE; + $arglist = func_get_args(); + if( $this->_notExistProp( $arglist[0] )) return FALSE; + if( !$this->getConfig( 'allowEmpty' ) && ( !isset( $arglist[1] ) || empty( $arglist[1] ))) + return FALSE; + $arglist[0] = strtoupper( $arglist[0] ); + for( $argix=$numargs; $argix < 12; $argix++ ) { + if( !isset( $arglist[$argix] )) + $arglist[$argix] = null; + } + switch( $arglist[0] ) { + case 'ACTION': + return $this->setAction( $arglist[1], $arglist[2] ); + case 'ATTACH': + return $this->setAttach( $arglist[1], $arglist[2], $arglist[3] ); + case 'ATTENDEE': + return $this->setAttendee( $arglist[1], $arglist[2], $arglist[3] ); + case 'CATEGORIES': + return $this->setCategories( $arglist[1], $arglist[2], $arglist[3] ); + case 'CLASS': + return $this->setClass( $arglist[1], $arglist[2] ); + case 'COMMENT': + return $this->setComment( $arglist[1], $arglist[2], $arglist[3] ); + case 'COMPLETED': + return $this->setCompleted( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); + case 'CONTACT': + return $this->setContact( $arglist[1], $arglist[2], $arglist[3] ); + case 'CREATED': + return $this->setCreated( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); + case 'DESCRIPTION': + return $this->setDescription( $arglist[1], $arglist[2], $arglist[3] ); + case 'DTEND': + return $this->setDtend( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); + case 'DTSTAMP': + return $this->setDtstamp( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); + case 'DTSTART': + return $this->setDtstart( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); + case 'DUE': + return $this->setDue( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); + case 'DURATION': + return $this->setDuration( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6] ); + case 'EXDATE': + return $this->setExdate( $arglist[1], $arglist[2], $arglist[3] ); + case 'EXRULE': + return $this->setExrule( $arglist[1], $arglist[2], $arglist[3] ); + case 'FREEBUSY': + return $this->setFreebusy( $arglist[1], $arglist[2], $arglist[3], $arglist[4] ); + case 'GEO': + return $this->setGeo( $arglist[1], $arglist[2], $arglist[3] ); + case 'LAST-MODIFIED': + return $this->setLastModified( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7] ); + case 'LOCATION': + return $this->setLocation( $arglist[1], $arglist[2] ); + case 'ORGANIZER': + return $this->setOrganizer( $arglist[1], $arglist[2] ); + case 'PERCENT-COMPLETE': + return $this->setPercentComplete( $arglist[1], $arglist[2] ); + case 'PRIORITY': + return $this->setPriority( $arglist[1], $arglist[2] ); + case 'RDATE': + return $this->setRdate( $arglist[1], $arglist[2], $arglist[3] ); + case 'RECURRENCE-ID': + return $this->setRecurrenceid( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8] ); + case 'RELATED-TO': + return $this->setRelatedTo( $arglist[1], $arglist[2], $arglist[3] ); + case 'REPEAT': + return $this->setRepeat( $arglist[1], $arglist[2] ); + case 'REQUEST-STATUS': + return $this->setRequestStatus( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5] ); + case 'RESOURCES': + return $this->setResources( $arglist[1], $arglist[2], $arglist[3] ); + case 'RRULE': + return $this->setRrule( $arglist[1], $arglist[2], $arglist[3] ); + case 'SEQUENCE': + return $this->setSequence( $arglist[1], $arglist[2] ); + case 'STATUS': + return $this->setStatus( $arglist[1], $arglist[2] ); + case 'SUMMARY': + return $this->setSummary( $arglist[1], $arglist[2] ); + case 'TRANSP': + return $this->setTransp( $arglist[1], $arglist[2] ); + case 'TRIGGER': + return $this->setTrigger( $arglist[1], $arglist[2], $arglist[3], $arglist[4], $arglist[5], $arglist[6], $arglist[7], $arglist[8], $arglist[9], $arglist[10], $arglist[11] ); + case 'TZID': + return $this->setTzid( $arglist[1], $arglist[2] ); + case 'TZNAME': + return $this->setTzname( $arglist[1], $arglist[2], $arglist[3] ); + case 'TZOFFSETFROM': + return $this->setTzoffsetfrom( $arglist[1], $arglist[2] ); + case 'TZOFFSETTO': + return $this->setTzoffsetto( $arglist[1], $arglist[2] ); + case 'TZURL': + return $this->setTzurl( $arglist[1], $arglist[2] ); + case 'UID': + return $this->setUid( $arglist[1], $arglist[2] ); + case 'URL': + return $this->setUrl( $arglist[1], $arglist[2] ); + default: + return $this->setXprop( $arglist[0], $arglist[1], $arglist[2] ); + } + return FALSE; + } +/*********************************************************************************/ +/** + * parse component unparsed data into properties + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.26 - 2013-07-02 + * @param mixed $unparsedtext, optional, strict rfc2445 formatted, single property string or array of strings + * @return bool FALSE if error occurs during parsing + * + */ + function parse( $unparsedtext=null ) { + $nl = $this->getConfig( 'nl' ); + if( !empty( $unparsedtext )) { + if( is_array( $unparsedtext )) + $unparsedtext = implode( '\n'.$nl, $unparsedtext ); + $unparsedtext = explode( $nl, iCalUtilityFunctions::convEolChar( $unparsedtext, $nl )); + } + elseif( !isset( $this->unparsed )) + $unparsedtext = array(); + else + $unparsedtext = $this->unparsed; + /* skip leading (empty/invalid) lines */ + foreach( $unparsedtext as $lix => $line ) { + $tst = trim( $line ); + if(( '\n' == $tst ) || empty( $tst )) + unset( $unparsedtext[$lix] ); + else + break; + } + $this->unparsed = array(); + $comp = & $this; + $config = $this->getConfig(); + $compsync = $subsync = 0; + foreach ( $unparsedtext as $lix => $line ) { + if( 'END:VALARM' == strtoupper( substr( $line, 0, 10 ))) { + if( 1 != $subsync ) return FALSE; + $this->components[] = $comp->copy(); + $subsync--; + } + elseif( 'END:DAYLIGHT' == strtoupper( substr( $line, 0, 12 ))) { + if( 1 != $subsync ) return FALSE; + $this->components[] = $comp->copy(); + $subsync--; + } + elseif( 'END:STANDARD' == strtoupper( substr( $line, 0, 12 ))) { + if( 1 != $subsync ) return FALSE; + array_unshift( $this->components, $comp->copy()); + $subsync--; + } + elseif( 'END:' == strtoupper( substr( $line, 0, 4 ))) { // end: + if( 1 != $compsync ) return FALSE; + if( 0 < $subsync ) + $this->components[] = $comp->copy(); + $compsync--; + break; /* skip trailing empty lines */ + } + elseif( 'BEGIN:VALARM' == strtoupper( substr( $line, 0, 12 ))) { + $comp = new valarm( $config); + $subsync++; + } + elseif( 'BEGIN:STANDARD' == strtoupper( substr( $line, 0, 14 ))) { + $comp = new vtimezone( 'standard', $config ); + $subsync++; + } + elseif( 'BEGIN:DAYLIGHT' == strtoupper( substr( $line, 0, 14 ))) { + $comp = new vtimezone( 'daylight', $config ); + $subsync++; + } + elseif( 'BEGIN:' == strtoupper( substr( $line, 0, 6 ))) // begin: + $compsync++; + else + $comp->unparsed[] = $line; + } + if( 0 < $subsync ) + $this->components[] = $comp->copy(); + unset( $config ); + /* concatenate property values spread over several lines */ + $lastix = -1; + $propnames = array( 'action', 'attach', 'attendee', 'categories', 'comment', 'completed' + , 'contact', 'class', 'created', 'description', 'dtend', 'dtstart' + , 'dtstamp', 'due', 'duration', 'exdate', 'exrule', 'freebusy', 'geo' + , 'last-modified', 'location', 'organizer', 'percent-complete' + , 'priority', 'rdate', 'recurrence-id', 'related-to', 'repeat' + , 'request-status', 'resources', 'rrule', 'sequence', 'status' + , 'summary', 'transp', 'trigger', 'tzid', 'tzname', 'tzoffsetfrom' + , 'tzoffsetto', 'tzurl', 'uid', 'url', 'x-' ); + $proprows = array(); + for( $i = 0; $i < count( $this->unparsed ); $i++ ) { // concatenate lines + $line = rtrim( $this->unparsed[$i], $nl ); + while( isset( $this->unparsed[$i+1] ) && !empty( $this->unparsed[$i+1] ) && ( ' ' == $this->unparsed[$i+1]{0} )) + $line .= rtrim( substr( $this->unparsed[++$i], 1 ), $nl ); + $proprows[] = $line; + } + /* parse each property 'line' */ + $paramMStz = array( 'utc-', 'utc+', 'gmt-', 'gmt+' ); + $paramProto3 = array( 'fax:', 'cid:', 'sms:', 'tel:', 'urn:' ); + $paramProto4 = array( 'crid:', 'news:', 'pres:' ); + foreach( $proprows as $line ) { + if( '\n' == substr( $line, -2 )) + $line = substr( $line, 0, -2 ); + /* get propname */ + $propname = null; + $cix = 0; + while( isset( $line[$cix] )) { + if( in_array( $line[$cix], array( ':', ';' ))) + break; + else + $propname .= $line[$cix]; + $cix++; + } + if(( 'x-' == substr( $propname, 0, 2 )) || ( 'X-' == substr( $propname, 0, 2 ))) { + $propname2 = $propname; + $propname = 'X-'; + } + if( !in_array( strtolower( $propname ), $propnames )) // skip non standard property names + continue; + /* rest of the line is opt.params and value */ + $line = substr( $line, $cix ); + /* separate attributes from value */ + $attr = array(); + $attrix = -1; + $clen = strlen( $line ); + $WithinQuotes = FALSE; + $cix = 0; + while( FALSE !== substr( $line, $cix, 1 )) { + if( ( ':' == $line[$cix] ) && + ( substr( $line,$cix, 3 ) != '://' ) && + ( !in_array( strtolower( substr( $line,$cix - 6, 4 )), $paramMStz )) && + ( !in_array( strtolower( substr( $line,$cix - 3, 4 )), $paramProto3 )) && + ( !in_array( strtolower( substr( $line,$cix - 4, 5 )), $paramProto4 )) && + ( strtolower( substr( $line,$cix - 6, 7 )) != 'mailto:' ) && + !$WithinQuotes ) { + $attrEnd = TRUE; + if(( $cix < ( $clen - 4 )) && + ctype_digit( substr( $line, $cix+1, 4 ))) { // an URI with a (4pos) portnr?? + for( $c2ix = $cix; 3 < $c2ix; $c2ix-- ) { + if( '://' == substr( $line, $c2ix - 2, 3 )) { + $attrEnd = FALSE; + break; // an URI with a portnr!! + } + } + } + if( $attrEnd) { + $line = substr( $line, ( $cix + 1 )); + break; + } + $cix++; + } + if( '"' == $line[$cix] ) + $WithinQuotes = ( FALSE === $WithinQuotes ) ? TRUE : FALSE; + if( ';' == $line[$cix] ) + $attr[++$attrix] = null; + else + $attr[$attrix] .= $line[$cix]; + $cix++; + } + /* make attributes in array format */ + $propattr = array(); + foreach( $attr as $attribute ) { + $attrsplit = explode( '=', $attribute, 2 ); + if( 1 < count( $attrsplit )) + $propattr[$attrsplit[0]] = $attrsplit[1]; + else + $propattr[] = $attribute; + } + /* call setProperty( $propname.. . */ + switch( strtoupper( $propname )) { + case 'ATTENDEE': + foreach( $propattr as $pix => $attr ) { + if( !in_array( strtoupper( $pix ), array( 'MEMBER', 'DELEGATED-TO', 'DELEGATED-FROM' ))) + continue; + $attr2 = explode( ',', $attr ); + if( 1 < count( $attr2 )) + $propattr[$pix] = $attr2; + } + $this->setProperty( $propname, $line, $propattr ); + break; + case 'CATEGORIES': + case 'RESOURCES': + if( FALSE !== strpos( $line, ',' )) { + $content = array( 0 => '' ); + $cix = $lix = 0; + while( FALSE !== substr( $line, $lix, 1 )) { + if(( ',' == $line[$lix] ) && ( "\\" != $line[( $lix - 1 )])) { + $cix++; + $content[$cix] = ''; + } + else + $content[$cix] .= $line[$lix]; + $lix++; + } + if( 1 < count( $content )) { + $content = array_values( $content ); + foreach( $content as $cix => $contentPart ) + $content[$cix] = iCalUtilityFunctions::_strunrep( $contentPart ); + $this->setProperty( $propname, $content, $propattr ); + break; + } + else + $line = reset( $content ); + } + case 'COMMENT': + case 'CONTACT': + case 'DESCRIPTION': + case 'LOCATION': + case 'SUMMARY': + if( empty( $line )) + $propattr = null; + $this->setProperty( $propname, iCalUtilityFunctions::_strunrep( $line ), $propattr ); + break; + case 'REQUEST-STATUS': + $values = explode( ';', $line, 3 ); + $values[1] = ( !isset( $values[1] )) ? null : iCalUtilityFunctions::_strunrep( $values[1] ); + $values[2] = ( !isset( $values[2] )) ? null : iCalUtilityFunctions::_strunrep( $values[2] ); + $this->setProperty( $propname + , $values[0] // statcode + , $values[1] // statdesc + , $values[2] // extdata + , $propattr ); + break; + case 'FREEBUSY': + $fbtype = ( isset( $propattr['FBTYPE'] )) ? $propattr['FBTYPE'] : ''; // force setting default, if missing + unset( $propattr['FBTYPE'] ); + $values = explode( ',', $line ); + foreach( $values as $vix => $value ) { + $value2 = explode( '/', $value ); + if( 1 < count( $value2 )) + $values[$vix] = $value2; + } + $this->setProperty( $propname, $fbtype, $values, $propattr ); + break; + case 'GEO': + $value = explode( ';', $line, 2 ); + if( 2 > count( $value )) + $value[1] = null; + $this->setProperty( $propname, $value[0], $value[1], $propattr ); + break; + case 'EXDATE': + $values = ( !empty( $line )) ? explode( ',', $line ) : null; + $this->setProperty( $propname, $values, $propattr ); + break; + case 'RDATE': + if( empty( $line )) { + $this->setProperty( $propname, $line, $propattr ); + break; + } + $values = explode( ',', $line ); + foreach( $values as $vix => $value ) { + $value2 = explode( '/', $value ); + if( 1 < count( $value2 )) + $values[$vix] = $value2; + } + $this->setProperty( $propname, $values, $propattr ); + break; + case 'EXRULE': + case 'RRULE': + $values = explode( ';', $line ); + $recur = array(); + foreach( $values as $value2 ) { + if( empty( $value2 )) + continue; // ;-char in ending position ??? + $value3 = explode( '=', $value2, 2 ); + $rulelabel = strtoupper( $value3[0] ); + switch( $rulelabel ) { + case 'BYDAY': { + $value4 = explode( ',', $value3[1] ); + if( 1 < count( $value4 )) { + foreach( $value4 as $v5ix => $value5 ) { + $value6 = array(); + $dayno = $dayname = null; + $value5 = trim( (string) $value5 ); + if(( ctype_alpha( substr( $value5, -1 ))) && + ( ctype_alpha( substr( $value5, -2, 1 )))) { + $dayname = substr( $value5, -2, 2 ); + if( 2 < strlen( $value5 )) + $dayno = substr( $value5, 0, ( strlen( $value5 ) - 2 )); + } + if( $dayno ) + $value6[] = $dayno; + if( $dayname ) + $value6['DAY'] = $dayname; + $value4[$v5ix] = $value6; + } + } + else { + $value4 = array(); + $dayno = $dayname = null; + $value5 = trim( (string) $value3[1] ); + if(( ctype_alpha( substr( $value5, -1 ))) && + ( ctype_alpha( substr( $value5, -2, 1 )))) { + $dayname = substr( $value5, -2, 2 ); + if( 2 < strlen( $value5 )) + $dayno = substr( $value5, 0, ( strlen( $value5 ) - 2 )); + } + if( $dayno ) + $value4[] = $dayno; + if( $dayname ) + $value4['DAY'] = $dayname; + } + $recur[$rulelabel] = $value4; + break; + } + default: { + $value4 = explode( ',', $value3[1] ); + if( 1 < count( $value4 )) + $value3[1] = $value4; + $recur[$rulelabel] = $value3[1]; + break; + } + } // end - switch $rulelabel + } // end - foreach( $values.. . + $this->setProperty( $propname, $recur, $propattr ); + break; + case 'X-': + $propname = ( isset( $propname2 )) ? $propname2 : $propname; + unset( $propname2 ); + case 'ACTION': + case 'CLASSIFICATION': + case 'STATUS': + case 'TRANSP': + case 'UID': + case 'TZID': + case 'RELATED-TO': + case 'TZNAME': + $line = iCalUtilityFunctions::_strunrep( $line ); + default: + $this->setProperty( $propname, $line, $propattr ); + break; + } // end switch( $propname.. . + } // end - foreach( $proprows.. . + unset( $unparsedtext, $this->unparsed, $proprows ); + if( isset( $this->components ) && is_array( $this->components ) && ( 0 < count( $this->components ))) { + $ckeys = array_keys( $this->components ); + foreach( $ckeys as $ckey ) { + if( !empty( $this->components[$ckey] ) && !empty( $this->components[$ckey]->unparsed )) { + $this->components[$ckey]->parse(); + } + } + } + return TRUE; + } +/*********************************************************************************/ +/*********************************************************************************/ +/** + * return a copy of this component + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.15.4 - 2012-10-18 + * @return object + */ + function copy() { + return unserialize( serialize( $this )); + } +/*********************************************************************************/ +/*********************************************************************************/ +/** + * delete calendar subcomponent from component container + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.8 - 2011-03-15 + * @param mixed $arg1 ordno / component type / component uid + * @param mixed $arg2 optional, ordno if arg1 = component type + * @return void + */ + function deleteComponent( $arg1, $arg2=FALSE ) { + if( !isset( $this->components )) return FALSE; + $argType = $index = null; + if ( ctype_digit( (string) $arg1 )) { + $argType = 'INDEX'; + $index = (int) $arg1 - 1; + } + elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { + $argType = strtolower( $arg1 ); + $index = ( !empty( $arg2 ) && ctype_digit( (string) $arg2 )) ? (( int ) $arg2 - 1 ) : 0; + } + $cix2dC = 0; + foreach ( $this->components as $cix => $component) { + if( empty( $component )) continue; + if(( 'INDEX' == $argType ) && ( $index == $cix )) { + unset( $this->components[$cix] ); + return TRUE; + } + elseif( $argType == $component->objName ) { + if( $index == $cix2dC ) { + unset( $this->components[$cix] ); + return TRUE; + } + $cix2dC++; + } + elseif( !$argType && ($arg1 == $component->getProperty( 'uid' ))) { + unset( $this->components[$cix] ); + return TRUE; + } + } + return FALSE; + } +/** + * get calendar component subcomponent from component container + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.8 - 2011-03-15 + * @param mixed $arg1 optional, ordno/component type/ component uid + * @param mixed $arg2 optional, ordno if arg1 = component type + * @return object + */ + function getComponent ( $arg1=FALSE, $arg2=FALSE ) { + if( !isset( $this->components )) return FALSE; + $index = $argType = null; + if ( !$arg1 ) { + $argType = 'INDEX'; + $index = $this->compix['INDEX'] = + ( isset( $this->compix['INDEX'] )) ? $this->compix['INDEX'] + 1 : 1; + } + elseif ( ctype_digit( (string) $arg1 )) { + $argType = 'INDEX'; + $index = (int) $arg1; + unset( $this->compix ); + } + elseif(( strlen( $arg1 ) <= strlen( 'vfreebusy' )) && ( FALSE === strpos( $arg1, '@' ))) { + unset( $this->compix['INDEX'] ); + $argType = strtolower( $arg1 ); + if( !$arg2 ) + $index = $this->compix[$argType] = ( isset( $this->compix[$argType] )) ? $this->compix[$argType] + 1 : 1; + else + $index = (int) $arg2; + } + $index -= 1; + $ckeys = array_keys( $this->components ); + if( !empty( $index) && ( $index > end( $ckeys ))) + return FALSE; + $cix2gC = 0; + foreach( $this->components as $cix => $component ) { + if( empty( $component )) continue; + if(( 'INDEX' == $argType ) && ( $index == $cix )) + return $component->copy(); + elseif( $argType == $component->objName ) { + if( $index == $cix2gC ) + return $component->copy(); + $cix2gC++; + } + elseif( !$argType && ( $arg1 == $component->getProperty( 'uid' ))) + return $component->copy(); + } + /* not found.. . */ + unset( $this->compix ); + return false; + } +/** + * add calendar component as subcomponent to container for subcomponents + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 1.x.x - 2007-04-24 + * @param object $component calendar component + * @return void + */ + function addSubComponent ( $component ) { + $this->setComponent( $component ); + } +/** + * create new calendar component subcomponent, already included within component + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.6.33 - 2011-01-03 + * @param string $compType subcomponent type + * @return object (reference) + */ + function & newComponent( $compType ) { + $config = $this->getConfig(); + $keys = array_keys( $this->components ); + $ix = end( $keys) + 1; + switch( strtoupper( $compType )) { + case 'ALARM': + case 'VALARM': + $this->components[$ix] = new valarm( $config ); + break; + case 'STANDARD': + array_unshift( $this->components, new vtimezone( 'STANDARD', $config )); + $ix = 0; + break; + case 'DAYLIGHT': + $this->components[$ix] = new vtimezone( 'DAYLIGHT', $config ); + break; + default: + return FALSE; + } + return $this->components[$ix]; + } +/** + * add calendar component as subcomponent to container for subcomponents + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.8 - 2011-03-15 + * @param object $component calendar component + * @param mixed $arg1 optional, ordno/component type/ component uid + * @param mixed $arg2 optional, ordno if arg1 = component type + * @return bool + */ + function setComponent( $component, $arg1=FALSE, $arg2=FALSE ) { + if( !isset( $this->components )) return FALSE; + $component->setConfig( $this->getConfig(), FALSE, TRUE ); + if( !in_array( $component->objName, array( 'valarm', 'vtimezone', 'standard', 'daylight' ))) { + /* make sure dtstamp and uid is set */ + $dummy = $component->getProperty( 'dtstamp' ); + $dummy = $component->getProperty( 'uid' ); + } + if( !$arg1 ) { // plain insert, last in chain + $this->components[] = $component->copy(); + return TRUE; + } + $argType = $index = null; + if ( ctype_digit( (string) $arg1 )) { // index insert/replace + $argType = 'INDEX'; + $index = (int) $arg1 - 1; + } + elseif( in_array( strtolower( $arg1 ), array( 'vevent', 'vtodo', 'vjournal', 'vfreebusy', 'valarm', 'vtimezone' ))) { + $argType = strtolower( $arg1 ); + $index = ( ctype_digit( (string) $arg2 )) ? ((int) $arg2) - 1 : 0; + } + // else if arg1 is set, arg1 must be an UID + $cix2sC = 0; + foreach ( $this->components as $cix => $component2 ) { + if( empty( $component2 )) continue; + if(( 'INDEX' == $argType ) && ( $index == $cix )) { // index insert/replace + $this->components[$cix] = $component->copy(); + return TRUE; + } + elseif( $argType == $component2->objName ) { // component Type index insert/replace + if( $index == $cix2sC ) { + $this->components[$cix] = $component->copy(); + return TRUE; + } + $cix2sC++; + } + elseif( !$argType && ( $arg1 == $component2->getProperty( 'uid' ))) { // UID insert/replace + $this->components[$cix] = $component->copy(); + return TRUE; + } + } + /* arg1=index and not found.. . insert at index .. .*/ + if( 'INDEX' == $argType ) { + $this->components[$index] = $component->copy(); + ksort( $this->components, SORT_NUMERIC ); + } + else /* not found.. . insert last in chain anyway .. .*/ + $this->components[] = $component->copy(); + return TRUE; + } +/** + * creates formatted output for subcomponents + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.11.20 - 2012-02-06 + * @param array $xcaldecl + * @return string + */ + function createSubComponent() { + $output = null; + if( 'vtimezone' == $this->objName ) { // sort subComponents, first standard, then daylight, in dtstart order + $stdarr = $dlarr = array(); + foreach( $this->components as $component ) { + if( empty( $component )) + continue; + $dt = $component->getProperty( 'dtstart' ); + $key = sprintf( '%04d%02d%02d%02d%02d%02d000', $dt['year'], $dt['month'], $dt['day'], $dt['hour'], $dt['min'], $dt['sec'] ); + if( 'standard' == $component->objName ) { + while( isset( $stdarr[$key] )) + $key += 1; + $stdarr[$key] = $component->copy(); + } + elseif( 'daylight' == $component->objName ) { + while( isset( $dlarr[$key] )) + $key += 1; + $dlarr[$key] = $component->copy(); + } + } // end foreach( $this->components as $component ) + $this->components = array(); + ksort( $stdarr, SORT_NUMERIC ); + foreach( $stdarr as $std ) + $this->components[] = $std->copy(); + unset( $stdarr ); + ksort( $dlarr, SORT_NUMERIC ); + foreach( $dlarr as $dl ) + $this->components[] = $dl->copy(); + unset( $dlarr ); + } // end if( 'vtimezone' == $this->objName ) + foreach( $this->components as $component ) { + $component->setConfig( $this->getConfig(), FALSE, TRUE ); + $output .= $component->createComponent( $this->xcaldecl ); + } + return $output; + } +} +/*********************************************************************************/ +/*********************************************************************************/ +/** + * class for calendar component VEVENT + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-12 + */ +class vevent extends calendarComponent { + var $attach; + var $attendee; + var $categories; + var $comment; + var $contact; + var $class; + var $created; + var $description; + var $dtend; + var $dtstart; + var $duration; + var $exdate; + var $exrule; + var $geo; + var $lastmodified; + var $location; + var $organizer; + var $priority; + var $rdate; + var $recurrenceid; + var $relatedto; + var $requeststatus; + var $resources; + var $rrule; + var $sequence; + var $status; + var $summary; + var $transp; + var $url; + var $xprop; + // component subcomponents container + var $components; +/** + * constructor for calendar component VEVENT object + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.2 - 2011-05-01 + * @param array $config + * @return void + */ + function __construct( $config = array()) { + parent::__construct(); + + $this->attach = ''; + $this->attendee = ''; + $this->categories = ''; + $this->class = ''; + $this->comment = ''; + $this->contact = ''; + $this->created = ''; + $this->description = ''; + $this->dtstart = ''; + $this->dtend = ''; + $this->duration = ''; + $this->exdate = ''; + $this->exrule = ''; + $this->geo = ''; + $this->lastmodified = ''; + $this->location = ''; + $this->organizer = ''; + $this->priority = ''; + $this->rdate = ''; + $this->recurrenceid = ''; + $this->relatedto = ''; + $this->requeststatus = ''; + $this->resources = ''; + $this->rrule = ''; + $this->sequence = ''; + $this->status = ''; + $this->summary = ''; + $this->transp = ''; + $this->url = ''; + $this->xprop = ''; + + $this->components = array(); + + if( defined( 'ICAL_LANG' ) && !isset( $config['language'] )) + $config['language'] = ICAL_LANG; + if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE; + if( !isset( $config['nl'] )) $config['nl'] = "\r\n"; + if( !isset( $config['format'] )) $config['format'] = 'iCal'; + if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR; + $this->setConfig( $config ); + + } +/** + * create formatted output for calendar component VEVENT object instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.16 - 2011-10-28 + * @param array $xcaldecl + * @return string + */ + function createComponent( &$xcaldecl ) { + $objectname = $this->_createFormat(); + $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; + $component .= $this->createUid(); + $component .= $this->createDtstamp(); + $component .= $this->createAttach(); + $component .= $this->createAttendee(); + $component .= $this->createCategories(); + $component .= $this->createComment(); + $component .= $this->createContact(); + $component .= $this->createClass(); + $component .= $this->createCreated(); + $component .= $this->createDescription(); + $component .= $this->createDtstart(); + $component .= $this->createDtend(); + $component .= $this->createDuration(); + $component .= $this->createExdate(); + $component .= $this->createExrule(); + $component .= $this->createGeo(); + $component .= $this->createLastModified(); + $component .= $this->createLocation(); + $component .= $this->createOrganizer(); + $component .= $this->createPriority(); + $component .= $this->createRdate(); + $component .= $this->createRrule(); + $component .= $this->createRelatedTo(); + $component .= $this->createRequestStatus(); + $component .= $this->createRecurrenceid(); + $component .= $this->createResources(); + $component .= $this->createSequence(); + $component .= $this->createStatus(); + $component .= $this->createSummary(); + $component .= $this->createTransp(); + $component .= $this->createUrl(); + $component .= $this->createXprop(); + $component .= $this->createSubComponent(); + $component .= $this->componentEnd1.$objectname.$this->componentEnd2; + if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { + foreach( $this->xcaldecl as $localxcaldecl ) + $xcaldecl[] = $localxcaldecl; + } + return $component; + } +} +/*********************************************************************************/ +/*********************************************************************************/ +/** + * class for calendar component VTODO + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-12 + */ +class vtodo extends calendarComponent { + var $attach; + var $attendee; + var $categories; + var $comment; + var $completed; + var $contact; + var $class; + var $created; + var $description; + var $dtstart; + var $due; + var $duration; + var $exdate; + var $exrule; + var $geo; + var $lastmodified; + var $location; + var $organizer; + var $percentcomplete; + var $priority; + var $rdate; + var $recurrenceid; + var $relatedto; + var $requeststatus; + var $resources; + var $rrule; + var $sequence; + var $status; + var $summary; + var $url; + var $xprop; + // component subcomponents container + var $components; +/** + * constructor for calendar component VTODO object + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.2 - 2011-05-01 + * @param array $config + * @return void + */ + function __construct( $config = array()) { + parent::__construct(); + + $this->attach = ''; + $this->attendee = ''; + $this->categories = ''; + $this->class = ''; + $this->comment = ''; + $this->completed = ''; + $this->contact = ''; + $this->created = ''; + $this->description = ''; + $this->dtstart = ''; + $this->due = ''; + $this->duration = ''; + $this->exdate = ''; + $this->exrule = ''; + $this->geo = ''; + $this->lastmodified = ''; + $this->location = ''; + $this->organizer = ''; + $this->percentcomplete = ''; + $this->priority = ''; + $this->rdate = ''; + $this->recurrenceid = ''; + $this->relatedto = ''; + $this->requeststatus = ''; + $this->resources = ''; + $this->rrule = ''; + $this->sequence = ''; + $this->status = ''; + $this->summary = ''; + $this->url = ''; + $this->xprop = ''; + + $this->components = array(); + + if( defined( 'ICAL_LANG' ) && !isset( $config['language'] )) + $config['language'] = ICAL_LANG; + if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE; + if( !isset( $config['nl'] )) $config['nl'] = "\r\n"; + if( !isset( $config['format'] )) $config['format'] = 'iCal'; + if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR; + $this->setConfig( $config ); + + } +/** + * create formatted output for calendar component VTODO object instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-11-07 + * @param array $xcaldecl + * @return string + */ + function createComponent( &$xcaldecl ) { + $objectname = $this->_createFormat(); + $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; + $component .= $this->createUid(); + $component .= $this->createDtstamp(); + $component .= $this->createAttach(); + $component .= $this->createAttendee(); + $component .= $this->createCategories(); + $component .= $this->createClass(); + $component .= $this->createComment(); + $component .= $this->createCompleted(); + $component .= $this->createContact(); + $component .= $this->createCreated(); + $component .= $this->createDescription(); + $component .= $this->createDtstart(); + $component .= $this->createDue(); + $component .= $this->createDuration(); + $component .= $this->createExdate(); + $component .= $this->createExrule(); + $component .= $this->createGeo(); + $component .= $this->createLastModified(); + $component .= $this->createLocation(); + $component .= $this->createOrganizer(); + $component .= $this->createPercentComplete(); + $component .= $this->createPriority(); + $component .= $this->createRdate(); + $component .= $this->createRelatedTo(); + $component .= $this->createRequestStatus(); + $component .= $this->createRecurrenceid(); + $component .= $this->createResources(); + $component .= $this->createRrule(); + $component .= $this->createSequence(); + $component .= $this->createStatus(); + $component .= $this->createSummary(); + $component .= $this->createUrl(); + $component .= $this->createXprop(); + $component .= $this->createSubComponent(); + $component .= $this->componentEnd1.$objectname.$this->componentEnd2; + if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { + foreach( $this->xcaldecl as $localxcaldecl ) + $xcaldecl[] = $localxcaldecl; + } + return $component; + } +} +/*********************************************************************************/ +/*********************************************************************************/ +/** + * class for calendar component VJOURNAL + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-12 + */ +class vjournal extends calendarComponent { + var $attach; + var $attendee; + var $categories; + var $comment; + var $contact; + var $class; + var $created; + var $description; + var $dtstart; + var $exdate; + var $exrule; + var $lastmodified; + var $organizer; + var $rdate; + var $recurrenceid; + var $relatedto; + var $requeststatus; + var $rrule; + var $sequence; + var $status; + var $summary; + var $url; + var $xprop; +/** + * constructor for calendar component VJOURNAL object + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.2 - 2011-05-01 + * @param array $config + * @return void + */ + function __construct( $config = array()) { + parent::__construct(); + + $this->attach = ''; + $this->attendee = ''; + $this->categories = ''; + $this->class = ''; + $this->comment = ''; + $this->contact = ''; + $this->created = ''; + $this->description = ''; + $this->dtstart = ''; + $this->exdate = ''; + $this->exrule = ''; + $this->lastmodified = ''; + $this->organizer = ''; + $this->rdate = ''; + $this->recurrenceid = ''; + $this->relatedto = ''; + $this->requeststatus = ''; + $this->rrule = ''; + $this->sequence = ''; + $this->status = ''; + $this->summary = ''; + $this->url = ''; + $this->xprop = ''; + + if( defined( 'ICAL_LANG' ) && !isset( $config['language'] )) + $config['language'] = ICAL_LANG; + if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE; + if( !isset( $config['nl'] )) $config['nl'] = "\r\n"; + if( !isset( $config['format'] )) $config['format'] = 'iCal'; + if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR; + $this->setConfig( $config ); + + } +/** + * create formatted output for calendar component VJOURNAL object instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-12 + * @param array $xcaldecl + * @return string + */ + function createComponent( &$xcaldecl ) { + $objectname = $this->_createFormat(); + $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; + $component .= $this->createUid(); + $component .= $this->createDtstamp(); + $component .= $this->createAttach(); + $component .= $this->createAttendee(); + $component .= $this->createCategories(); + $component .= $this->createClass(); + $component .= $this->createComment(); + $component .= $this->createContact(); + $component .= $this->createCreated(); + $component .= $this->createDescription(); + $component .= $this->createDtstart(); + $component .= $this->createExdate(); + $component .= $this->createExrule(); + $component .= $this->createLastModified(); + $component .= $this->createOrganizer(); + $component .= $this->createRdate(); + $component .= $this->createRequestStatus(); + $component .= $this->createRecurrenceid(); + $component .= $this->createRelatedTo(); + $component .= $this->createRrule(); + $component .= $this->createSequence(); + $component .= $this->createStatus(); + $component .= $this->createSummary(); + $component .= $this->createUrl(); + $component .= $this->createXprop(); + $component .= $this->componentEnd1.$objectname.$this->componentEnd2; + if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { + foreach( $this->xcaldecl as $localxcaldecl ) + $xcaldecl[] = $localxcaldecl; + } + return $component; + } +} +/*********************************************************************************/ +/*********************************************************************************/ +/** + * class for calendar component VFREEBUSY + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-12 + */ +class vfreebusy extends calendarComponent { + var $attendee; + var $comment; + var $contact; + var $dtend; + var $dtstart; + var $duration; + var $freebusy; + var $organizer; + var $requeststatus; + var $url; + var $xprop; + // component subcomponents container + var $components; +/** + * constructor for calendar component VFREEBUSY object + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.2 - 2011-05-01 + * @param array $config + * @return void + */ + function __construct( $config = array()) { + parent::__construct(); + + $this->attendee = ''; + $this->comment = ''; + $this->contact = ''; + $this->dtend = ''; + $this->dtstart = ''; + $this->duration = ''; + $this->freebusy = ''; + $this->organizer = ''; + $this->requeststatus = ''; + $this->url = ''; + $this->xprop = ''; + + if( defined( 'ICAL_LANG' ) && !isset( $config['language'] )) + $config['language'] = ICAL_LANG; + if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE; + if( !isset( $config['nl'] )) $config['nl'] = "\r\n"; + if( !isset( $config['format'] )) $config['format'] = 'iCal'; + if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR; + $this->setConfig( $config ); + + } +/** + * create formatted output for calendar component VFREEBUSY object instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.3.1 - 2007-11-19 + * @param array $xcaldecl + * @return string + */ + function createComponent( &$xcaldecl ) { + $objectname = $this->_createFormat(); + $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; + $component .= $this->createUid(); + $component .= $this->createDtstamp(); + $component .= $this->createAttendee(); + $component .= $this->createComment(); + $component .= $this->createContact(); + $component .= $this->createDtstart(); + $component .= $this->createDtend(); + $component .= $this->createDuration(); + $component .= $this->createFreebusy(); + $component .= $this->createOrganizer(); + $component .= $this->createRequestStatus(); + $component .= $this->createUrl(); + $component .= $this->createXprop(); + $component .= $this->componentEnd1.$objectname.$this->componentEnd2; + if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { + foreach( $this->xcaldecl as $localxcaldecl ) + $xcaldecl[] = $localxcaldecl; + } + return $component; + } +} +/*********************************************************************************/ +/*********************************************************************************/ +/** + * class for calendar component VALARM + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-12 + */ +class valarm extends calendarComponent { + var $action; + var $attach; + var $attendee; + var $description; + var $duration; + var $repeat; + var $summary; + var $trigger; + var $xprop; +/** + * constructor for calendar component VALARM object + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.2 - 2011-05-01 + * @param array $config + * @return void + */ + function __construct( $config = array()) { + parent::__construct(); + + $this->action = ''; + $this->attach = ''; + $this->attendee = ''; + $this->description = ''; + $this->duration = ''; + $this->repeat = ''; + $this->summary = ''; + $this->trigger = ''; + $this->xprop = ''; + + if( defined( 'ICAL_LANG' ) && !isset( $config['language'] )) + $config['language'] = ICAL_LANG; + if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE; + if( !isset( $config['nl'] )) $config['nl'] = "\r\n"; + if( !isset( $config['format'] )) $config['format'] = 'iCal'; + if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR; + $this->setConfig( $config ); + + } +/** + * create formatted output for calendar component VALARM object instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-22 + * @param array $xcaldecl + * @return string + */ + function createComponent( &$xcaldecl ) { + $objectname = $this->_createFormat(); + $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; + $component .= $this->createAction(); + $component .= $this->createAttach(); + $component .= $this->createAttendee(); + $component .= $this->createDescription(); + $component .= $this->createDuration(); + $component .= $this->createRepeat(); + $component .= $this->createSummary(); + $component .= $this->createTrigger(); + $component .= $this->createXprop(); + $component .= $this->componentEnd1.$objectname.$this->componentEnd2; + if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { + foreach( $this->xcaldecl as $localxcaldecl ) + $xcaldecl[] = $localxcaldecl; + } + return $component; + } +} +/********************************************************************************** +/*********************************************************************************/ +/** + * class for calendar component VTIMEZONE + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-12 + */ +class vtimezone extends calendarComponent { + var $timezonetype; + + var $comment; + var $dtstart; + var $lastmodified; + var $rdate; + var $rrule; + var $tzid; + var $tzname; + var $tzoffsetfrom; + var $tzoffsetto; + var $tzurl; + var $xprop; + // component subcomponents container + var $components; +/** + * constructor for calendar component VTIMEZONE object + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.8.2 - 2011-05-01 + * @param mixed $timezonetype optional, default FALSE ( STANDARD / DAYLIGHT ) + * @param array $config + * @return void + */ + function __construct( $timezonetype=FALSE, $config = array()) { + if( is_array( $timezonetype )) { + $config = $timezonetype; + $timezonetype = FALSE; + } + if( !$timezonetype ) + $this->timezonetype = 'VTIMEZONE'; + else + $this->timezonetype = strtoupper( $timezonetype ); + parent::__construct(); + + $this->comment = ''; + $this->dtstart = ''; + $this->lastmodified = ''; + $this->rdate = ''; + $this->rrule = ''; + $this->tzid = ''; + $this->tzname = ''; + $this->tzoffsetfrom = ''; + $this->tzoffsetto = ''; + $this->tzurl = ''; + $this->xprop = ''; + + $this->components = array(); + + if( defined( 'ICAL_LANG' ) && !isset( $config['language'] )) + $config['language'] = ICAL_LANG; + if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE; + if( !isset( $config['nl'] )) $config['nl'] = "\r\n"; + if( !isset( $config['format'] )) $config['format'] = 'iCal'; + if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR; + $this->setConfig( $config ); + + } +/** + * create formatted output for calendar component VTIMEZONE object instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.5.1 - 2008-10-25 + * @param array $xcaldecl + * @return string + */ + function createComponent( &$xcaldecl ) { + $objectname = $this->_createFormat(); + $component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl; + $component .= $this->createTzid(); + $component .= $this->createLastModified(); + $component .= $this->createTzurl(); + $component .= $this->createDtstart(); + $component .= $this->createTzoffsetfrom(); + $component .= $this->createTzoffsetto(); + $component .= $this->createComment(); + $component .= $this->createRdate(); + $component .= $this->createRrule(); + $component .= $this->createTzname(); + $component .= $this->createXprop(); + $component .= $this->createSubComponent(); + $component .= $this->componentEnd1.$objectname.$this->componentEnd2; + if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) { + foreach( $this->xcaldecl as $localxcaldecl ) + $xcaldecl[] = $localxcaldecl; + } + return $component; + } +} +/*********************************************************************************/ +/*********************************************************************************/ +/** + * moving all utility (static) functions to a utility class + * 20111223 - move iCalUtilityFunctions class to the end of the iCalcreator class file + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.1 - 2011-07-16 + * + */ +class iCalUtilityFunctions { + // Store the single instance of iCalUtilityFunctions + private static $m_pInstance; + + // Private constructor to limit object instantiation to within the class + private function __construct() { + $m_pInstance = FALSE; + } + + // Getter method for creating/returning the single instance of this class + public static function getInstance() { + if (!self::$m_pInstance) + self::$m_pInstance = new iCalUtilityFunctions(); + + return self::$m_pInstance; + } +/** + * ensures internal date-time/date format (keyed array) for an input date-time/date array (keyed or unkeyed) + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.24 - 2013-06-26 + * @param array $datetime + * @param int $parno optional, default FALSE + * @return array + */ + public static function _date_time_array( $datetime, $parno=FALSE ) { + return iCalUtilityFunctions::_chkDateArr( $datetime, $parno ); + } + public static function _chkDateArr( $datetime, $parno=FALSE ) { + $output = array(); + if(( !$parno || ( 6 <= $parno )) && isset( $datetime[3] ) && !isset( $datetime[4] )) { // Y-m-d with tz + $temp = $datetime[3]; + $datetime[3] = $datetime[4] = $datetime[5] = 0; + $datetime[6] = $temp; + } + foreach( $datetime as $dateKey => $datePart ) { + switch ( $dateKey ) { + case '0': case 'year': $output['year'] = $datePart; break; + case '1': case 'month': $output['month'] = $datePart; break; + case '2': case 'day': $output['day'] = $datePart; break; + } + if( 3 != $parno ) { + switch ( $dateKey ) { + case '0': + case '1': + case '2': break; + case '3': case 'hour': $output['hour'] = $datePart; break; + case '4': case 'min' : $output['min'] = $datePart; break; + case '5': case 'sec' : $output['sec'] = $datePart; break; + case '6': case 'tz' : $output['tz'] = $datePart; break; + } + } + } + if( 3 != $parno ) { + if( !isset( $output['hour'] )) $output['hour'] = 0; + if( !isset( $output['min'] )) $output['min'] = 0; + if( !isset( $output['sec'] )) $output['sec'] = 0; + if( isset( $output['tz'] ) && + (( '+0000' == $output['tz'] ) || ( '-0000' == $output['tz'] ) || ( '+000000' == $output['tz'] ) || ( '-000000' == $output['tz'] ))) + $output['tz'] = 'Z'; + } + return $output; + } +/** + * check date(-time) and params arrays for an opt. timezone and if it is a DATE-TIME or DATE (updates $parno and params) + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.30 - 2012-01-16 + * @param array $date, date to check + * @param int $parno, no of date parts (i.e. year, month.. .) + * @param array $params, property parameters + * @return void + */ + public static function _chkdatecfg( $theDate, & $parno, & $params ) { + if( isset( $params['TZID'] )) + $parno = 6; + elseif( isset( $params['VALUE'] ) && ( 'DATE' == $params['VALUE'] )) + $parno = 3; + else { + if( isset( $params['VALUE'] ) && ( 'PERIOD' == $params['VALUE'] )) + $parno = 7; + if( is_array( $theDate )) { + if( isset( $theDate['timestamp'] )) + $tzid = ( isset( $theDate['tz'] )) ? $theDate['tz'] : null; + else + $tzid = ( isset( $theDate['tz'] )) ? $theDate['tz'] : ( 7 == count( $theDate )) ? end( $theDate ) : null; + if( !empty( $tzid )) { + $parno = 7; + if( !iCalUtilityFunctions::_isOffset( $tzid )) + $params['TZID'] = $tzid; // save only timezone + } + elseif( !$parno && ( 3 == count( $theDate )) && + ( isset( $params['VALUE'] ) && ( 'DATE' == $params['VALUE'] ))) + $parno = 3; + else + $parno = 6; + } + else { // string + $date = trim( $theDate ); + if( 'Z' == substr( $date, -1 )) + $parno = 7; // UTC DATE-TIME + elseif((( 8 == strlen( $date ) && ctype_digit( $date )) || ( 11 >= strlen( $date ))) && + ( !isset( $params['VALUE'] ) || !in_array( $params['VALUE'], array( 'DATE-TIME', 'PERIOD' )))) + $parno = 3; // DATE + $date = iCalUtilityFunctions::_strdate2date( $date, $parno ); + unset( $date['unparsedtext'] ); + if( !empty( $date['tz'] )) { + $parno = 7; + if( !iCalUtilityFunctions::_isOffset( $date['tz'] )) + $params['TZID'] = $date['tz']; // save only timezone + } + elseif( empty( $parno )) + $parno = 6; + } + if( isset( $params['TZID'] )) + $parno = 6; + } + } +/** + * vcalendar sort callback function + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-17 + * @param array $a + * @param array $b + * @return int + */ + public static function _cmpfcn( $a, $b ) { + if( empty( $a )) return -1; + if( empty( $b )) return 1; + if( 'vtimezone' == $a->objName ) { + if( 'vtimezone' != $b->objName ) return -1; + elseif( $a->srtk[0] <= $b->srtk[0] ) return -1; + else return 1; + } + elseif( 'vtimezone' == $b->objName ) return 1; + $sortkeys = array( 'year', 'month', 'day', 'hour', 'min', 'sec' ); + for( $k = 0; $k < 4 ; $k++ ) { + if( empty( $a->srtk[$k] )) return -1; + elseif( empty( $b->srtk[$k] )) return 1; + if( is_array( $a->srtk[$k] )) { + if( is_array( $b->srtk[$k] )) { + foreach( $sortkeys as $key ) { + if ( !isset( $a->srtk[$k][$key] )) return -1; + elseif( !isset( $b->srtk[$k][$key] )) return 1; + if ( empty( $a->srtk[$k][$key] )) return -1; + elseif( empty( $b->srtk[$k][$key] )) return 1; + if ( $a->srtk[$k][$key] == $b->srtk[$k][$key]) + continue; + if (( (int) $a->srtk[$k][$key] ) < ((int) $b->srtk[$k][$key] )) + return -1; + elseif(( (int) $a->srtk[$k][$key] ) > ((int) $b->srtk[$k][$key] )) + return 1; + } + } + else return -1; + } + elseif( is_array( $b->srtk[$k] )) return 1; + elseif( $a->srtk[$k] < $b->srtk[$k] ) return -1; + elseif( $a->srtk[$k] > $b->srtk[$k] ) return 1; + } + return 0; + } +/** + * byte oriented line folding fix + * + * remove any line-endings that may include spaces or tabs + * and convert all line endings (iCal default '\r\n'), + * takes care of '\r\n', '\r' and '\n' and mixed '\r\n'+'\r', '\r\n'+'\n' + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.12.17 - 2012-07-12 + * @param string $text + * @param string $nl + * @return string + */ + public static function convEolChar( & $text, $nl ) { + $outp = ''; + $cix = 0; + while( isset( $text[$cix] )) { + if( isset( $text[$cix + 2] ) && ( "\r" == $text[$cix] ) && ( "\n" == $text[$cix + 1] ) && + (( " " == $text[$cix + 2] ) || ( "\t" == $text[$cix + 2] ))) // 2 pos eolchar + ' ' or '\t' + $cix += 2; // skip 3 + elseif( isset( $text[$cix + 1] ) && ( "\r" == $text[$cix] ) && ( "\n" == $text[$cix + 1] )) { + $outp .= $nl; // 2 pos eolchar + $cix += 1; // replace with $nl + } + elseif( isset( $text[$cix + 1] ) && (( "\r" == $text[$cix] ) || ( "\n" == $text[$cix] )) && + (( " " == $text[$cix + 1] ) || ( "\t" == $text[$cix + 1] ))) // 1 pos eolchar + ' ' or '\t' + $cix += 1; // skip 2 + elseif(( "\r" == $text[$cix] ) || ( "\n" == $text[$cix] )) // 1 pos eolchar + $outp .= $nl; // replace with $nl + else + $outp .= $text[$cix]; // add any other byte + $cix += 1; + } + return $outp; + } +/** + * create a calendar timezone and standard/daylight components + * + * Result when 'Europe/Stockholm' and no from/to arguments is used as timezone: + * + * BEGIN:VTIMEZONE + * TZID:Europe/Stockholm + * BEGIN:STANDARD + * DTSTART:20101031T020000 + * TZOFFSETFROM:+0200 + * TZOFFSETTO:+0100 + * TZNAME:CET + * END:STANDARD + * BEGIN:DAYLIGHT + * DTSTART:20100328T030000 + * TZOFFSETFROM:+0100 + * TZOFFSETTO:+0200 + * TZNAME:CEST + * END:DAYLIGHT + * END:VTIMEZONE + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.1 - 2012-11-26 + * Generates components for all transitions in a date range, based on contribution by Yitzchok Lavi + * Additional changes jpirkey + * @param object $calendar, reference to an iCalcreator calendar instance + * @param string $timezone, a PHP5 (DateTimeZone) valid timezone + * @param array $xProp, *[x-propName => x-propValue], optional + * @param int $from a unix timestamp + * @param int $to a unix timestamp + * @return bool + */ + public static function createTimezone( & $calendar, $timezone, $xProp=array(), $from=null, $to=null ) { + if( empty( $timezone )) + return FALSE; + if( !empty( $from ) && !is_int( $from )) + return FALSE; + if( !empty( $to ) && !is_int( $to )) + return FALSE; + try { + $dtz = new DateTimeZone( $timezone ); + $transitions = $dtz->getTransitions(); + $utcTz = new DateTimeZone( 'UTC' ); + } + catch( Exception $e ) { return FALSE; } + if( empty( $to )) { + $dates = array_keys( $calendar->getProperty( 'dtstart' )); + if( empty( $dates )) + $dates = array( date( 'Ymd' )); + } + if( !empty( $from )) + $dateFrom = new DateTime( "@$from" ); // set lowest date (UTC) + else { + $from = reset( $dates ); // set lowest date to the lowest dtstart date + $dateFrom = new DateTime( $from.'T000000', $dtz ); + $dateFrom->modify( '-1 month' ); // set $dateFrom to one month before the lowest date + $dateFrom->setTimezone( $utcTz ); // convert local date to UTC + } + $dateFromYmd = $dateFrom->format('Y-m-d' ); + if( !empty( $to )) + $dateTo = new DateTime( "@$to" ); // set end date (UTC) + else { + $to = end( $dates ); // set highest date to the highest dtstart date + $dateTo = new DateTime( $to.'T235959', $dtz ); + $dateTo->modify( '+1 year' ); // set $dateTo to one year after the highest date + $dateTo->setTimezone( $utcTz ); // convert local date to UTC + } + $dateToYmd = $dateTo->format('Y-m-d' ); + unset( $dtz ); + $transTemp = array(); + $prevOffsetfrom = 0; + $stdIx = $dlghtIx = null; + $prevTrans = FALSE; + foreach( $transitions as $tix => $trans ) { // all transitions in date-time order!! + $date = new DateTime( "@{$trans['ts']}" ); // set transition date (UTC) + $transDateYmd = $date->format('Y-m-d' ); + if ( $transDateYmd < $dateFromYmd ) { + $prevOffsetfrom = $trans['offset']; // previous trans offset will be 'next' trans offsetFrom + $prevTrans = $trans; // save it in case we don't find any that match + $prevTrans['offsetfrom'] = ( 0 < $tix ) ? $transitions[$tix-1]['offset'] : 0; + continue; + } + if( $transDateYmd > $dateToYmd ) + break; // loop always (?) breaks here + if( !empty( $prevOffsetfrom ) || ( 0 == $prevOffsetfrom )) { + $trans['offsetfrom'] = $prevOffsetfrom; // i.e. set previous offsetto as offsetFrom + $date->modify( $trans['offsetfrom'].'seconds' ); // convert utc date to local date + $d = $date->format( 'Y-n-j-G-i-s' ); // set date to array to ease up dtstart and (opt) rdate setting + $d = explode( '-', $d ); + $trans['time'] = array( 'year' => $d[0], 'month' => $d[1], 'day' => $d[2], 'hour' => $d[3], 'min' => $d[4], 'sec' => $d[5] ); + } + $prevOffsetfrom = $trans['offset']; + if( TRUE !== $trans['isdst'] ) { // standard timezone + if( !empty( $stdIx ) && isset( $transTemp[$stdIx]['offsetfrom'] ) && // check for any repeating rdate's (in order) + ( $transTemp[$stdIx]['abbr'] == $trans['abbr'] ) && + ( $transTemp[$stdIx]['offsetfrom'] == $trans['offsetfrom'] ) && + ( $transTemp[$stdIx]['offset'] == $trans['offset'] )) { + $transTemp[$stdIx]['rdate'][] = $trans['time']; + continue; + } + $stdIx = $tix; + } // end standard timezone + else { // daylight timezone + if( !empty( $dlghtIx ) && isset( $transTemp[$dlghtIx]['offsetfrom'] ) && // check for any repeating rdate's (in order) + ( $transTemp[$dlghtIx]['abbr'] == $trans['abbr'] ) && + ( $transTemp[$dlghtIx]['offsetfrom'] == $trans['offsetfrom'] ) && + ( $transTemp[$dlghtIx]['offset'] == $trans['offset'] )) { + $transTemp[$dlghtIx]['rdate'][] = $trans['time']; + continue; + } + $dlghtIx = $tix; + } // end daylight timezone + $transTemp[$tix] = $trans; + } // end foreach( $transitions as $tix => $trans ) + $tz = & $calendar->newComponent( 'vtimezone' ); + $tz->setproperty( 'tzid', $timezone ); + if( !empty( $xProp )) { + foreach( $xProp as $xPropName => $xPropValue ) + if( 'x-' == strtolower( substr( $xPropName, 0, 2 ))) + $tz->setproperty( $xPropName, $xPropValue ); + } + if( empty( $transTemp )) { // if no match found + if( $prevTrans ) { // then we use the last transition (before startdate) for the tz info + $date = new DateTime( "@{$prevTrans['ts']}" ); // set transition date (UTC) + $date->modify( $prevTrans['offsetfrom'].'seconds' ); // convert utc date to local date + $d = $date->format( 'Y-n-j-G-i-s' ); // set date to array to ease up dtstart setting + $d = explode( '-', $d ); + $prevTrans['time'] = array( 'year' => $d[0], 'month' => $d[1], 'day' => $d[2], 'hour' => $d[3], 'min' => $d[4], 'sec' => $d[5] ); + $transTemp[0] = $prevTrans; + } + else { // or we use the timezone identifier to BUILD the standard tz info (?) + $date = new DateTime( 'now', new DateTimeZone( $timezone )); + $transTemp[0] = array( 'time' => $date->format( 'Y-m-d\TH:i:s O' ) + , 'offset' => $date->format( 'Z' ) + , 'offsetfrom' => $date->format( 'Z' ) + , 'isdst' => FALSE ); + } + } + unset( $transitions, $date, $prevTrans ); + foreach( $transTemp as $tix => $trans ) { + $type = ( TRUE !== $trans['isdst'] ) ? 'standard' : 'daylight'; + $scomp = & $tz->newComponent( $type ); + $scomp->setProperty( 'dtstart', $trans['time'] ); +// $scomp->setProperty( 'x-utc-timestamp', $tix.' : '.$trans['ts'] ); // test ### + if( !empty( $trans['abbr'] )) + $scomp->setProperty( 'tzname', $trans['abbr'] ); + if( isset( $trans['offsetfrom'] )) + $scomp->setProperty( 'tzoffsetfrom', iCalUtilityFunctions::offsetSec2His( $trans['offsetfrom'] )); + $scomp->setProperty( 'tzoffsetto', iCalUtilityFunctions::offsetSec2His( $trans['offset'] )); + if( isset( $trans['rdate'] )) + $scomp->setProperty( 'RDATE', $trans['rdate'] ); + } + return TRUE; + } +/** + * creates formatted output for calendar component property data value type date/date-time + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.1 - 2012-09-17 + * @param array $datetime + * @param int $parno, optional, default 6 + * @return string + */ + public static function _format_date_time( $datetime, $parno=6 ) { + return iCalUtilityFunctions::_date2strdate( $datetime, $parno ); + } + public static function _date2strdate( $datetime, $parno=6 ) { + if( !isset( $datetime['year'] ) && + !isset( $datetime['month'] ) && + !isset( $datetime['day'] ) && + !isset( $datetime['hour'] ) && + !isset( $datetime['min'] ) && + !isset( $datetime['sec'] )) + return; + $output = null; + foreach( $datetime as $dkey => & $dvalue ) + if( 'tz' != $dkey ) $dvalue = (integer) $dvalue; + $output = sprintf( '%04d%02d%02d', $datetime['year'], $datetime['month'], $datetime['day'] ); + if( 3 == $parno ) + return $output; + if( !isset( $datetime['hour'] )) $datetime['hour'] = 0; + if( !isset( $datetime['min'] )) $datetime['min'] = 0; + if( !isset( $datetime['sec'] )) $datetime['sec'] = 0; + $output .= sprintf( 'T%02d%02d%02d', $datetime['hour'], $datetime['min'], $datetime['sec'] ); + if( isset( $datetime['tz'] ) && ( '' < trim( $datetime['tz'] ))) { + $datetime['tz'] = trim( $datetime['tz'] ); + if( 'Z' == $datetime['tz'] ) + $parno = 7; + elseif( iCalUtilityFunctions::_isOffset( $datetime['tz'] )) { + $parno = 7; + $offset = iCalUtilityFunctions::_tz2offset( $datetime['tz'] ); + try { + $d = new DateTime( $output, new DateTimeZone( 'UTC' )); + if( 0 != $offset ) // adjust för offset + $d->modify( "$offset seconds" ); + $output = $d->format( 'Ymd\THis' ); + } + catch( Exception $e ) { + $output = date( 'Ymd\THis', mktime( $datetime['hour'], $datetime['min'], ($datetime['sec'] - $offset), $datetime['month'], $datetime['day'], $datetime['year'] )); + } + } + if( 7 == $parno ) + $output .= 'Z'; + } + return $output; + } +/** + * convert a date/datetime (array) to timestamp + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.1 - 2012-09-29 + * @param array $datetime datetime(/date) + * @param string $wtz timezone + * @return int + */ + public static function _date2timestamp( $datetime, $wtz=null ) { + if( !isset( $datetime['hour'] )) $datetime['hour'] = 0; + if( !isset( $datetime['min'] )) $datetime['min'] = 0; + if( !isset( $datetime['sec'] )) $datetime['sec'] = 0; + if( empty( $wtz ) && ( !isset( $datetime['tz'] ) || empty( $datetime['tz'] ))) + return mktime( $datetime['hour'], $datetime['min'], $datetime['sec'], $datetime['month'], $datetime['day'], $datetime['year'] ); + $output = $offset = 0; + if( empty( $wtz )) { + if( iCalUtilityFunctions::_isOffset( $datetime['tz'] )) { + $offset = iCalUtilityFunctions::_tz2offset( $datetime['tz'] ) * -1; + $wtz = 'UTC'; + } + else + $wtz = $datetime['tz']; + } + if(( 'Z' == $wtz ) || ( 'GMT' == strtoupper( $wtz ))) + $wtz = 'UTC'; + try { + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d', $datetime['year'], $datetime['month'], $datetime['day'], $datetime['hour'], $datetime['min'], $datetime['sec'] ); + $d = new DateTime( $strdate, new DateTimeZone( $wtz )); + if( 0 != $offset ) // adjust for offset + $d->modify( $offset.' seconds' ); + $output = $d->format( 'U' ); + unset( $d ); + } + catch( Exception $e ) { + $output = mktime( $datetime['hour'], $datetime['min'], $datetime['sec'], $datetime['month'], $datetime['day'], $datetime['year'] ); + } + return $output; + } +/** + * ensures internal duration format for input in array format + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.23 - 2013-06-23 + * @param array $duration + * @return array + */ + public static function _duration_array( $duration ) { + return iCalUtilityFunctions::_duration2arr( $duration ); + } + public static function _duration2arr( $duration ) { + $seconds = 0; + foreach( $duration as $durKey => $durValue ) { + if( empty( $durValue )) continue; + switch ( $durKey ) { + case '0': case 'week': + $seconds += (((int) $durValue ) * 60 * 60 * 24 * 7 ); + break; + case '1': case 'day': + $seconds += (((int) $durValue ) * 60 * 60 * 24 ); + break; + case '2': case 'hour': + $seconds += (((int) $durValue ) * 60 * 60 ); + break; + case '3': case 'min': + $seconds += (((int) $durValue ) * 60 ); + break; + case '4': case 'sec': + $seconds += (int) $durValue; + break; + } + } + $output = array(); + $output['week'] = (int) floor( $seconds / ( 60 * 60 * 24 * 7 )); + $seconds = ( $seconds % ( 60 * 60 * 24 * 7 )); + $output['day'] = (int) floor( $seconds / ( 60 * 60 * 24 )); + $seconds = ( $seconds % ( 60 * 60 * 24 )); + $output['hour'] = (int) floor( $seconds / ( 60 * 60 )); + $seconds = ( $seconds % ( 60 * 60 )); + $output['min'] = (int) floor( $seconds / 60 ); + $output['sec'] = ( $seconds % 60 ); + if( !empty( $output['week'] )) + unset( $output['day'], $output['hour'], $output['min'], $output['sec'] ); + else { + unset( $output['week'] ); + if( empty( $output['day'] )) + unset( $output['day'] ); + if(( 0 == $output['hour'] ) && ( 0 == $output['min'] ) && ( 0 == $output['sec'] )) + unset( $output['hour'], $output['min'], $output['sec'] ); + } + return $output; + } +/** + * convert startdate+duration to a array format datetime + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.15.12 - 2012-10-31 + * @param array $startdate + * @param array $duration + * @return array, date format + */ + public static function _duration2date( $startdate, $duration ) { + $dateOnly = ( isset( $startdate['hour'] ) || isset( $startdate['min'] ) || isset( $startdate['sec'] )) ? FALSE : TRUE; + $startdate['hour'] = ( isset( $startdate['hour'] )) ? $startdate['hour'] : 0; + $startdate['min'] = ( isset( $startdate['min'] )) ? $startdate['min'] : 0; + $startdate['sec'] = ( isset( $startdate['sec'] )) ? $startdate['sec'] : 0; + $dtend = 0; + if( isset( $duration['week'] )) $dtend += ( $duration['week'] * 7 * 24 * 60 * 60 ); + if( isset( $duration['day'] )) $dtend += ( $duration['day'] * 24 * 60 * 60 ); + if( isset( $duration['hour'] )) $dtend += ( $duration['hour'] * 60 *60 ); + if( isset( $duration['min'] )) $dtend += ( $duration['min'] * 60 ); + if( isset( $duration['sec'] )) $dtend += $duration['sec']; + $date = date( 'Y-m-d-H-i-s', mktime((int) $startdate['hour'], (int) $startdate['min'], (int) ( $startdate['sec'] + $dtend ), (int) $startdate['month'], (int) $startdate['day'], (int) $startdate['year'] )); + $d = explode( '-', $date ); + $dtend2 = array( 'year' => $d[0], 'month' => $d[1], 'day' => $d[2], 'hour' => $d[3], 'min' => $d[4], 'sec' => $d[5] ); + if( isset( $startdate['tz'] )) + $dtend2['tz'] = $startdate['tz']; + if( $dateOnly && (( 0 == $dtend2['hour'] ) && ( 0 == $dtend2['min'] ) && ( 0 == $dtend2['sec'] ))) + unset( $dtend2['hour'], $dtend2['min'], $dtend2['sec'] ); + return $dtend2; + } +/** + * ensures internal duration format for an input string (iCal) formatted duration + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.1 - 2012-09-25 + * @param string $duration + * @return array + */ + public static function _duration_string( $duration ) { + return iCalUtilityFunctions::_durationStr2arr( $duration ); + } + public static function _durationStr2arr( $duration ) { + $duration = (string) trim( $duration ); + while( 'P' != strtoupper( substr( $duration, 0, 1 ))) { + if( 0 < strlen( $duration )) + $duration = substr( $duration, 1 ); + else + return false; // no leading P !?!? + } + $duration = substr( $duration, 1 ); // skip P + $duration = str_replace ( 't', 'T', $duration ); + $duration = str_replace ( 'T', '', $duration ); + $output = array(); + $val = null; + for( $ix=0; $ix < strlen( $duration ); $ix++ ) { + switch( strtoupper( substr( $duration, $ix, 1 ))) { + case 'W': + $output['week'] = $val; + $val = null; + break; + case 'D': + $output['day'] = $val; + $val = null; + break; + case 'H': + $output['hour'] = $val; + $val = null; + break; + case 'M': + $output['min'] = $val; + $val = null; + break; + case 'S': + $output['sec'] = $val; + $val = null; + break; + default: + if( !ctype_digit( substr( $duration, $ix, 1 ))) + return false; // unknown duration control character !?!? + else + $val .= substr( $duration, $ix, 1 ); + } + } + return iCalUtilityFunctions::_duration2arr( $output ); + } +/** + * creates formatted output for calendar component property data value type duration + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.15.8 - 2012-10-30 + * @param array $duration, array( week, day, hour, min, sec ) + * @return string + */ + public static function _format_duration( $duration ) { + return iCalUtilityFunctions::_duration2str( $duration ); + } + public static function _duration2str( $duration ) { + if( isset( $duration['week'] ) || + isset( $duration['day'] ) || + isset( $duration['hour'] ) || + isset( $duration['min'] ) || + isset( $duration['sec'] )) + $ok = TRUE; + else + return; + if( isset( $duration['week'] ) && ( 0 < $duration['week'] )) + return 'P'.$duration['week'].'W'; + $output = 'P'; + if( isset($duration['day'] ) && ( 0 < $duration['day'] )) + $output .= $duration['day'].'D'; + if(( isset( $duration['hour']) && ( 0 < $duration['hour'] )) || + ( isset( $duration['min']) && ( 0 < $duration['min'] )) || + ( isset( $duration['sec']) && ( 0 < $duration['sec'] ))) { + $output .= 'T'; + $output .= ( isset( $duration['hour']) && ( 0 < $duration['hour'] )) ? $duration['hour'].'H' : '0H'; + $output .= ( isset( $duration['min']) && ( 0 < $duration['min'] )) ? $duration['min']. 'M' : '0M'; + $output .= ( isset( $duration['sec']) && ( 0 < $duration['sec'] )) ? $duration['sec']. 'S' : '0S'; + } + if( 'P' == $output ) + $output = 'PT0H0M0S'; + return $output; + } +/** + * removes expkey+expvalue from array and returns hitval (if found) else returns elseval + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.16 - 2008-11-08 + * @param array $array + * @param string $expkey, expected key + * @param string $expval, expected value + * @param int $hitVal optional, return value if found + * @param int $elseVal optional, return value if not found + * @param int $preSet optional, return value if already preset + * @return int + */ + public static function _existRem( &$array, $expkey, $expval=FALSE, $hitVal=null, $elseVal=null, $preSet=null ) { + if( $preSet ) + return $preSet; + if( !is_array( $array ) || ( 0 == count( $array ))) + return $elseVal; + foreach( $array as $key => $value ) { + if( strtoupper( $expkey ) == strtoupper( $key )) { + if( !$expval || ( strtoupper( $expval ) == strtoupper( $array[$key] ))) { + unset( $array[$key] ); + return $hitVal; + } + } + } + return $elseVal; + } +/** + * checks if input contains a (array formatted) date/time + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.24 - 2013-07-02 + * @param array $input + * @return bool + */ + public static function _isArrayDate( $input ) { + if( !is_array( $input ) || isset( $input['week'] ) || isset( $input['timestamp'] ) || ( 3 > count( $input ))) + return FALSE; + if( 7 == count( $input )) + return TRUE; + if( isset( $input['year'] ) && isset( $input['month'] ) && isset( $input['day'] )) + return checkdate( (int) $input['month'], (int) $input['day'], (int) $input['year'] ); + if( isset( $input['day'] ) || isset( $input['hour'] ) || isset( $input['min'] ) || isset( $input['sec'] )) + return FALSE; + if(( 0 == $input[0] ) || ( 0 == $input[1] ) || ( 0 == $input[2] )) + return FALSE; + if(( 1970 > $input[0] ) || ( 12 < $input[1] ) || ( 31 < $input[2] )) + return FALSE; + if(( isset( $input[0] ) && isset( $input[1] ) && isset( $input[2] )) && + checkdate((int) $input[1], (int) $input[2], (int) $input[0] )) + return TRUE; + $input = iCalUtilityFunctions::_strdate2date( $input[1].'/'.$input[2].'/'.$input[0], 3 ); // m - d - Y + if( isset( $input['year'] ) && isset( $input['month'] ) && isset( $input['day'] )) + return checkdate( (int) $input['month'], (int) $input['day'], (int) $input['year'] ); + return FALSE; + } +/** + * checks if input array contains a timestamp date + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.4.16 - 2008-10-18 + * @param array $input + * @return bool + */ + public static function _isArrayTimestampDate( $input ) { + return ( is_array( $input ) && isset( $input['timestamp'] )) ? TRUE : FALSE ; + } +/** + * controls if input string contains (trailing) UTC/iCal offset + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.1 - 2012-09-21 + * @param string $input + * @return bool + */ + public static function _isOffset( $input ) { + $input = trim( (string) $input ); + if( 'Z' == substr( $input, -1 )) + return TRUE; + elseif(( 5 <= strlen( $input )) && + ( in_array( substr( $input, -5, 1 ), array( '+', '-' ))) && + ( '0000' <= substr( $input, -4 )) && ( '9999' >= substr( $input, -4 ))) + return TRUE; + elseif(( 7 <= strlen( $input )) && + ( in_array( substr( $input, -7, 1 ), array( '+', '-' ))) && + ( '000000' <= substr( $input, -6 )) && ( '999999' >= substr( $input, -6 ))) + return TRUE; + return FALSE; + } +/** + * (very simple) conversion of a MS timezone to a PHP5 valid (Date-)timezone + * matching (MS) UCT offset and time zone descriptors + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.1 - 2012-09-16 + * @param string $timezone, input/output variable reference + * @return bool + */ + public static function ms2phpTZ( & $timezone ) { + if( empty( $timezone )) + return FALSE; + $search = str_replace( '"', '', $timezone ); + $search = str_replace( array('GMT', 'gmt', 'utc' ), 'UTC', $search ); + if( '(UTC' != substr( $search, 0, 4 )) + return FALSE; + if( FALSE === ( $pos = strpos( $search, ')' ))) + return FALSE; + $pos = strpos( $search, ')' ); + $searchOffset = substr( $search, 4, ( $pos - 4 )); + $searchOffset = iCalUtilityFunctions::_tz2offset( str_replace( ':', '', $searchOffset )); + while( ' ' ==substr( $search, ( $pos + 1 ))) + $pos += 1; + $searchText = trim( str_replace( array( '(', ')', '&', ',', ' ' ), ' ', substr( $search, ( $pos + 1 )) )); + $searchWords = explode( ' ', $searchText ); + $timezone_abbreviations = DateTimeZone::listAbbreviations(); + $hits = array(); + foreach( $timezone_abbreviations as $name => $transitions ) { + foreach( $transitions as $cnt => $transition ) { + if( empty( $transition['offset'] ) || + empty( $transition['timezone_id'] ) || + ( $transition['offset'] != $searchOffset )) + continue; + $cWords = explode( '/', $transition['timezone_id'] ); + $cPrio = $hitCnt = $rank = 0; + foreach( $cWords as $cWord ) { + if( empty( $cWord )) + continue; + $cPrio += 1; + $sPrio = 0; + foreach( $searchWords as $sWord ) { + if( empty( $sWord ) || ( 'time' == strtolower( $sWord ))) + continue; + $sPrio += 1; + if( strtolower( $cWord ) == strtolower( $sWord )) { + $hitCnt += 1; + $rank += ( $cPrio + $sPrio ); + } + else + $rank += 10; + } + } + if( 0 < $hitCnt ) { + $hits[$rank][] = $transition['timezone_id']; + } + } + } + unset( $timezone_abbreviations ); + if( empty( $hits )) + return FALSE; + ksort( $hits ); + foreach( $hits as $rank => $tzs ) { + if( !empty( $tzs )) { + $timezone = reset( $tzs ); + return TRUE; + } + } + return FALSE; + } +/** + * transforms offset in seconds to [-/+]hhmm[ss] + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2011-05-02 + * @param string $seconds + * @return string + */ + public static function offsetSec2His( $seconds ) { + if( '-' == substr( $seconds, 0, 1 )) { + $prefix = '-'; + $seconds = substr( $seconds, 1 ); + } + elseif( '+' == substr( $seconds, 0, 1 )) { + $prefix = '+'; + $seconds = substr( $seconds, 1 ); + } + else + $prefix = '+'; + $output = ''; + $hour = (int) floor( $seconds / 3600 ); + if( 10 > $hour ) + $hour = '0'.$hour; + $seconds = $seconds % 3600; + $min = (int) floor( $seconds / 60 ); + if( 10 > $min ) + $min = '0'.$min; + $output = $hour.$min; + $seconds = $seconds % 60; + if( 0 < $seconds) { + if( 9 < $seconds) + $output .= $seconds; + else + $output .= '0'.$seconds; + } + return $prefix.$output; + } +/** + * updates an array with dates based on a recur pattern + * + * if missing, UNTIL is set 1 year from startdate (emergency break) + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.10.19 - 2011-10-31 + * @param array $result, array to update, array([timestamp] => timestamp) + * @param array $recur, pattern for recurrency (only value part, params ignored) + * @param array $wdate, component start date + * @param array $startdate, start date + * @param array $enddate, optional + * @return void + * @todo BYHOUR, BYMINUTE, BYSECOND, WEEKLY at year end/start + */ + public static function _recur2date( & $result, $recur, $wdate, $startdate, $enddate=FALSE ) { + foreach( $wdate as $k => $v ) if( ctype_digit( $v )) $wdate[$k] = (int) $v; + $wdateStart = $wdate; + $wdatets = iCalUtilityFunctions::_date2timestamp( $wdate ); + $startdatets = iCalUtilityFunctions::_date2timestamp( $startdate ); + if( !$enddate ) { + $enddate = $startdate; + $enddate['year'] += 1; + } +// echo "recur __in_ comp start ".implode('-',$wdate)." period start ".implode('-',$startdate)." period end ".implode('-',$enddate)."
    \n";print_r($recur);echo "
    \n";//test### + $endDatets = iCalUtilityFunctions::_date2timestamp( $enddate ); // fix break + if( !isset( $recur['COUNT'] ) && !isset( $recur['UNTIL'] )) + $recur['UNTIL'] = $enddate; // create break + if( isset( $recur['UNTIL'] )) { + $tdatets = iCalUtilityFunctions::_date2timestamp( $recur['UNTIL'] ); + if( $endDatets > $tdatets ) { + $endDatets = $tdatets; // emergency break + $enddate = iCalUtilityFunctions::_timestamp2date( $endDatets, 6 ); + } + else + $recur['UNTIL'] = iCalUtilityFunctions::_timestamp2date( $endDatets, 6 ); + } + if( $wdatets > $endDatets ) { +// echo "recur out of date ".date('Y-m-d H:i:s',$wdatets)."
    \n";//test + return array(); // nothing to do.. . + } + if( !isset( $recur['FREQ'] )) // "MUST be specified.. ." + $recur['FREQ'] = 'DAILY'; // ?? + $wkst = ( isset( $recur['WKST'] ) && ( 'SU' == $recur['WKST'] )) ? 24*60*60 : 0; // ?? + $weekStart = (int) date( 'W', ( $wdatets + $wkst )); + if( !isset( $recur['INTERVAL'] )) + $recur['INTERVAL'] = 1; + $countcnt = ( !isset( $recur['BYSETPOS'] )) ? 1 : 0; // DTSTART counts as the first occurrence + /* find out how to step up dates and set index for interval count */ + $step = array(); + if( 'YEARLY' == $recur['FREQ'] ) + $step['year'] = 1; + elseif( 'MONTHLY' == $recur['FREQ'] ) + $step['month'] = 1; + elseif( 'WEEKLY' == $recur['FREQ'] ) + $step['day'] = 7; + else + $step['day'] = 1; + if( isset( $step['year'] ) && isset( $recur['BYMONTH'] )) + $step = array( 'month' => 1 ); + if( empty( $step ) && isset( $recur['BYWEEKNO'] )) // ?? + $step = array( 'day' => 7 ); + if( isset( $recur['BYYEARDAY'] ) || isset( $recur['BYMONTHDAY'] ) || isset( $recur['BYDAY'] )) + $step = array( 'day' => 1 ); + $intervalarr = array(); + if( 1 < $recur['INTERVAL'] ) { + $intervalix = iCalUtilityFunctions::_recurIntervalIx( $recur['FREQ'], $wdate, $wkst ); + $intervalarr = array( $intervalix => 0 ); + } + if( isset( $recur['BYSETPOS'] )) { // save start date + weekno + $bysetposymd1 = $bysetposymd2 = $bysetposw1 = $bysetposw2 = array(); +// echo "bysetposXold_start=$bysetposYold $bysetposMold $bysetposDold
    \n"; // test ### + if( is_array( $recur['BYSETPOS'] )) { + foreach( $recur['BYSETPOS'] as $bix => $bval ) + $recur['BYSETPOS'][$bix] = (int) $bval; + } + else + $recur['BYSETPOS'] = array( (int) $recur['BYSETPOS'] ); + if( 'YEARLY' == $recur['FREQ'] ) { + $wdate['month'] = $wdate['day'] = 1; // start from beginning of year + $wdatets = iCalUtilityFunctions::_date2timestamp( $wdate ); + iCalUtilityFunctions::_stepdate( $enddate, $endDatets, array( 'year' => 1 )); // make sure to count whole last year + } + elseif( 'MONTHLY' == $recur['FREQ'] ) { + $wdate['day'] = 1; // start from beginning of month + $wdatets = iCalUtilityFunctions::_date2timestamp( $wdate ); + iCalUtilityFunctions::_stepdate( $enddate, $endDatets, array( 'month' => 1 )); // make sure to count whole last month + } + else + iCalUtilityFunctions::_stepdate( $enddate, $endDatets, $step); // make sure to count whole last period +// echo "BYSETPOS endDat++ =".implode('-',$enddate).' step='.var_export($step,TRUE)."
    \n";//test### + $bysetposWold = (int) date( 'W', ( $wdatets + $wkst )); + $bysetposYold = $wdate['year']; + $bysetposMold = $wdate['month']; + $bysetposDold = $wdate['day']; + } + else + iCalUtilityFunctions::_stepdate( $wdate, $wdatets, $step); + $year_old = null; + $daynames = array( 'SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA' ); + /* MAIN LOOP */ +// echo "recur start ".implode('-',$wdate)." end ".implode('-',$enddate)."
    \n";//test + while( TRUE ) { + if( isset( $endDatets ) && ( $wdatets > $endDatets )) + break; + if( isset( $recur['COUNT'] ) && ( $countcnt >= $recur['COUNT'] )) + break; + if( $year_old != $wdate['year'] ) { + $year_old = $wdate['year']; + $daycnts = array(); + $yeardays = $weekno = 0; + $yeardaycnt = array(); + foreach( $daynames as $dn ) + $yeardaycnt[$dn] = 0; + for( $m = 1; $m <= 12; $m++ ) { // count up and update up-counters + $daycnts[$m] = array(); + $weekdaycnt = array(); + foreach( $daynames as $dn ) + $weekdaycnt[$dn] = 0; + $mcnt = date( 't', mktime( 0, 0, 0, $m, 1, $wdate['year'] )); + for( $d = 1; $d <= $mcnt; $d++ ) { + $daycnts[$m][$d] = array(); + if( isset( $recur['BYYEARDAY'] )) { + $yeardays++; + $daycnts[$m][$d]['yearcnt_up'] = $yeardays; + } + if( isset( $recur['BYDAY'] )) { + $day = date( 'w', mktime( 0, 0, 0, $m, $d, $wdate['year'] )); + $day = $daynames[$day]; + $daycnts[$m][$d]['DAY'] = $day; + $weekdaycnt[$day]++; + $daycnts[$m][$d]['monthdayno_up'] = $weekdaycnt[$day]; + $yeardaycnt[$day]++; + $daycnts[$m][$d]['yeardayno_up'] = $yeardaycnt[$day]; + } + if( isset( $recur['BYWEEKNO'] ) || ( $recur['FREQ'] == 'WEEKLY' )) + $daycnts[$m][$d]['weekno_up'] =(int)date('W',mktime(0,0,$wkst,$m,$d,$wdate['year'])); + } + } + $daycnt = 0; + $yeardaycnt = array(); + if( isset( $recur['BYWEEKNO'] ) || ( $recur['FREQ'] == 'WEEKLY' )) { + $weekno = null; + for( $d=31; $d > 25; $d-- ) { // get last weekno for year + if( !$weekno ) + $weekno = $daycnts[12][$d]['weekno_up']; + elseif( $weekno < $daycnts[12][$d]['weekno_up'] ) { + $weekno = $daycnts[12][$d]['weekno_up']; + break; + } + } + } + for( $m = 12; $m > 0; $m-- ) { // count down and update down-counters + $weekdaycnt = array(); + foreach( $daynames as $dn ) + $yeardaycnt[$dn] = $weekdaycnt[$dn] = 0; + $monthcnt = 0; + $mcnt = date( 't', mktime( 0, 0, 0, $m, 1, $wdate['year'] )); + for( $d = $mcnt; $d > 0; $d-- ) { + if( isset( $recur['BYYEARDAY'] )) { + $daycnt -= 1; + $daycnts[$m][$d]['yearcnt_down'] = $daycnt; + } + if( isset( $recur['BYMONTHDAY'] )) { + $monthcnt -= 1; + $daycnts[$m][$d]['monthcnt_down'] = $monthcnt; + } + if( isset( $recur['BYDAY'] )) { + $day = $daycnts[$m][$d]['DAY']; + $weekdaycnt[$day] -= 1; + $daycnts[$m][$d]['monthdayno_down'] = $weekdaycnt[$day]; + $yeardaycnt[$day] -= 1; + $daycnts[$m][$d]['yeardayno_down'] = $yeardaycnt[$day]; + } + if( isset( $recur['BYWEEKNO'] ) || ( $recur['FREQ'] == 'WEEKLY' )) + $daycnts[$m][$d]['weekno_down'] = ($daycnts[$m][$d]['weekno_up'] - $weekno - 1); + } + } + } + /* check interval */ + if( 1 < $recur['INTERVAL'] ) { + /* create interval index */ + $intervalix = iCalUtilityFunctions::_recurIntervalIx( $recur['FREQ'], $wdate, $wkst ); + /* check interval */ + $currentKey = array_keys( $intervalarr ); + $currentKey = end( $currentKey ); // get last index + if( $currentKey != $intervalix ) + $intervalarr = array( $intervalix => ( $intervalarr[$currentKey] + 1 )); + if(( $recur['INTERVAL'] != $intervalarr[$intervalix] ) && + ( 0 != $intervalarr[$intervalix] )) { + /* step up date */ +// echo "skip: ".implode('-',$wdate)." ix=$intervalix old=$currentKey interval=".$intervalarr[$intervalix]."
    \n";//test + iCalUtilityFunctions::_stepdate( $wdate, $wdatets, $step); + continue; + } + else // continue within the selected interval + $intervalarr[$intervalix] = 0; +// echo "cont: ".implode('-',$wdate)." ix=$intervalix old=$currentKey interval=".$intervalarr[$intervalix]."
    \n";//test + } + $updateOK = TRUE; + if( $updateOK && isset( $recur['BYMONTH'] )) + $updateOK = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYMONTH'] + , $wdate['month'] + ,($wdate['month'] - 13)); + if( $updateOK && isset( $recur['BYWEEKNO'] )) + $updateOK = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYWEEKNO'] + , $daycnts[$wdate['month']][$wdate['day']]['weekno_up'] + , $daycnts[$wdate['month']][$wdate['day']]['weekno_down'] ); + if( $updateOK && isset( $recur['BYYEARDAY'] )) + $updateOK = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYYEARDAY'] + , $daycnts[$wdate['month']][$wdate['day']]['yearcnt_up'] + , $daycnts[$wdate['month']][$wdate['day']]['yearcnt_down'] ); + if( $updateOK && isset( $recur['BYMONTHDAY'] )) + $updateOK = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYMONTHDAY'] + , $wdate['day'] + , $daycnts[$wdate['month']][$wdate['day']]['monthcnt_down'] ); +// echo "efter BYMONTHDAY: ".implode('-',$wdate).' status: '; echo ($updateOK) ? 'TRUE' : 'FALSE'; echo "
    \n";//test### + if( $updateOK && isset( $recur['BYDAY'] )) { + $updateOK = FALSE; + $m = $wdate['month']; + $d = $wdate['day']; + if( isset( $recur['BYDAY']['DAY'] )) { // single day, opt with year/month day order no + $daynoexists = $daynosw = $daynamesw = FALSE; + if( $recur['BYDAY']['DAY'] == $daycnts[$m][$d]['DAY'] ) + $daynamesw = TRUE; + if( isset( $recur['BYDAY'][0] )) { + $daynoexists = TRUE; + if(( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'MONTHLY' )) || isset( $recur['BYMONTH'] )) + $daynosw = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYDAY'][0] + , $daycnts[$m][$d]['monthdayno_up'] + , $daycnts[$m][$d]['monthdayno_down'] ); + elseif( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'YEARLY' )) + $daynosw = iCalUtilityFunctions::_recurBYcntcheck( $recur['BYDAY'][0] + , $daycnts[$m][$d]['yeardayno_up'] + , $daycnts[$m][$d]['yeardayno_down'] ); + } + if(( $daynoexists && $daynosw && $daynamesw ) || + ( !$daynoexists && !$daynosw && $daynamesw )) { + $updateOK = TRUE; +// echo "m=$m d=$d day=".$daycnts[$m][$d]['DAY']." yeardayno_up=".$daycnts[$m][$d]['yeardayno_up']." daynoexists:$daynoexists daynosw:$daynosw daynamesw:$daynamesw updateOK:$updateOK
    \n"; // test ### + } +// echo "m=$m d=$d day=".$daycnts[$m][$d]['DAY']." yeardayno_up=".$daycnts[$m][$d]['yeardayno_up']." daynoexists:$daynoexists daynosw:$daynosw daynamesw:$daynamesw updateOK:$updateOK
    \n"; // test ### + } + else { + foreach( $recur['BYDAY'] as $bydayvalue ) { + $daynoexists = $daynosw = $daynamesw = FALSE; + if( isset( $bydayvalue['DAY'] ) && + ( $bydayvalue['DAY'] == $daycnts[$m][$d]['DAY'] )) + $daynamesw = TRUE; + if( isset( $bydayvalue[0] )) { + $daynoexists = TRUE; + if(( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'MONTHLY' )) || + isset( $recur['BYMONTH'] )) + $daynosw = iCalUtilityFunctions::_recurBYcntcheck( $bydayvalue['0'] + , $daycnts[$m][$d]['monthdayno_up'] + , $daycnts[$m][$d]['monthdayno_down'] ); + elseif( isset( $recur['FREQ'] ) && ( $recur['FREQ'] == 'YEARLY' )) + $daynosw = iCalUtilityFunctions::_recurBYcntcheck( $bydayvalue['0'] + , $daycnts[$m][$d]['yeardayno_up'] + , $daycnts[$m][$d]['yeardayno_down'] ); + } +// echo "daynoexists:$daynoexists daynosw:$daynosw daynamesw:$daynamesw
    \n"; // test ### + if(( $daynoexists && $daynosw && $daynamesw ) || + ( !$daynoexists && !$daynosw && $daynamesw )) { + $updateOK = TRUE; + break; + } + } + } + } +// echo "efter BYDAY: ".implode('-',$wdate).' status: '; echo ($updateOK) ? 'TRUE' : 'FALSE'; echo "
    \n"; // test ### + /* check BYSETPOS */ + if( $updateOK ) { + if( isset( $recur['BYSETPOS'] ) && + ( in_array( $recur['FREQ'], array( 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY' )))) { + if( isset( $recur['WEEKLY'] )) { + if( $bysetposWold == $daycnts[$wdate['month']][$wdate['day']]['weekno_up'] ) + $bysetposw1[] = $wdatets; + else + $bysetposw2[] = $wdatets; + } + else { + if(( isset( $recur['FREQ'] ) && ( 'YEARLY' == $recur['FREQ'] ) && + ( $bysetposYold == $wdate['year'] )) || + ( isset( $recur['FREQ'] ) && ( 'MONTHLY' == $recur['FREQ'] ) && + (( $bysetposYold == $wdate['year'] ) && + ( $bysetposMold == $wdate['month'] ))) || + ( isset( $recur['FREQ'] ) && ( 'DAILY' == $recur['FREQ'] ) && + (( $bysetposYold == $wdate['year'] ) && + ( $bysetposMold == $wdate['month']) && + ( $bysetposDold == $wdate['day'] )))) { +// echo "bysetposymd1[]=".date('Y-m-d H:i:s',$wdatets)."
    \n";//test + $bysetposymd1[] = $wdatets; + } + else { +// echo "bysetposymd2[]=".date('Y-m-d H:i:s',$wdatets)."
    \n";//test + $bysetposymd2[] = $wdatets; + } + } + } + else { + /* update result array if BYSETPOS is set */ + $countcnt++; + if( $startdatets <= $wdatets ) { // only output within period + $result[$wdatets] = TRUE; +// echo "recur ".date('Y-m-d H:i:s',$wdatets)."
    \n";//test + } +// echo "recur undate ".date('Y-m-d H:i:s',$wdatets)." okdatstart ".date('Y-m-d H:i:s',$startdatets)."
    \n";//test + $updateOK = FALSE; + } + } + /* step up date */ + iCalUtilityFunctions::_stepdate( $wdate, $wdatets, $step); + /* check if BYSETPOS is set for updating result array */ + if( $updateOK && isset( $recur['BYSETPOS'] )) { + $bysetpos = FALSE; + if( isset( $recur['FREQ'] ) && ( 'YEARLY' == $recur['FREQ'] ) && + ( $bysetposYold != $wdate['year'] )) { + $bysetpos = TRUE; + $bysetposYold = $wdate['year']; + } + elseif( isset( $recur['FREQ'] ) && ( 'MONTHLY' == $recur['FREQ'] && + (( $bysetposYold != $wdate['year'] ) || ( $bysetposMold != $wdate['month'] )))) { + $bysetpos = TRUE; + $bysetposYold = $wdate['year']; + $bysetposMold = $wdate['month']; + } + elseif( isset( $recur['FREQ'] ) && ( 'WEEKLY' == $recur['FREQ'] )) { + $weekno = (int) date( 'W', mktime( 0, 0, $wkst, $wdate['month'], $wdate['day'], $wdate['year'])); + if( $bysetposWold != $weekno ) { + $bysetposWold = $weekno; + $bysetpos = TRUE; + } + } + elseif( isset( $recur['FREQ'] ) && ( 'DAILY' == $recur['FREQ'] ) && + (( $bysetposYold != $wdate['year'] ) || + ( $bysetposMold != $wdate['month'] ) || + ( $bysetposDold != $wdate['day'] ))) { + $bysetpos = TRUE; + $bysetposYold = $wdate['year']; + $bysetposMold = $wdate['month']; + $bysetposDold = $wdate['day']; + } + if( $bysetpos ) { + if( isset( $recur['BYWEEKNO'] )) { + $bysetposarr1 = & $bysetposw1; + $bysetposarr2 = & $bysetposw2; + } + else { + $bysetposarr1 = & $bysetposymd1; + $bysetposarr2 = & $bysetposymd2; + } +// echo 'test före out startYMD (weekno)='.$wdateStart['year'].':'.$wdateStart['month'].':'.$wdateStart['day']." ($weekStart) "; // test ### + foreach( $recur['BYSETPOS'] as $ix ) { + if( 0 > $ix ) // both positive and negative BYSETPOS allowed + $ix = ( count( $bysetposarr1 ) + $ix + 1); + $ix--; + if( isset( $bysetposarr1[$ix] )) { + if( $startdatets <= $bysetposarr1[$ix] ) { // only output within period +// $testdate = iCalUtilityFunctions::_timestamp2date( $bysetposarr1[$ix], 6 ); // test ### +// $testweekno = (int) date( 'W', mktime( 0, 0, $wkst, $testdate['month'], $testdate['day'], $testdate['year'] )); // test ### +// echo " testYMD (weekno)=".$testdate['year'].':'.$testdate['month'].':'.$testdate['day']." ($testweekno)"; // test ### + $result[$bysetposarr1[$ix]] = TRUE; +// echo " recur ".date('Y-m-d H:i:s',$bysetposarr1[$ix]); // test ### + } + $countcnt++; + } + if( isset( $recur['COUNT'] ) && ( $countcnt >= $recur['COUNT'] )) + break; + } +// echo "
    \n"; // test ### + $bysetposarr1 = $bysetposarr2; + $bysetposarr2 = array(); + } + } + } + } + public static function _recurBYcntcheck( $BYvalue, $upValue, $downValue ) { + if( is_array( $BYvalue ) && + ( in_array( $upValue, $BYvalue ) || in_array( $downValue, $BYvalue ))) + return TRUE; + elseif(( $BYvalue == $upValue ) || ( $BYvalue == $downValue )) + return TRUE; + else + return FALSE; + } + public static function _recurIntervalIx( $freq, $date, $wkst ) { + /* create interval index */ + switch( $freq ) { + case 'YEARLY': + $intervalix = $date['year']; + break; + case 'MONTHLY': + $intervalix = $date['year'].'-'.$date['month']; + break; + case 'WEEKLY': + $wdatets = iCalUtilityFunctions::_date2timestamp( $date ); + $intervalix = (int) date( 'W', ( $wdatets + $wkst )); + break; + case 'DAILY': + default: + $intervalix = $date['year'].'-'.$date['month'].'-'.$date['day']; + break; + } + return $intervalix; + } + public static function _recurBydaySort( $bydaya, $bydayb ) { + static $days = array( 'SU' => 0, 'MO' => 1, 'TU' => 2, 'WE' => 3, 'TH' => 4, 'FR' => 5, 'SA' => 6 ); + return ( $days[substr( $bydaya, -2 )] < $days[substr( $bydayb, -2 )] ) ? -1 : 1; + } +/** + * convert input format for exrule and rrule to internal format + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.1 - 2012-09-24 + * @param array $rexrule + * @return array + */ + public static function _setRexrule( $rexrule ) { + $input = array(); + if( empty( $rexrule )) + return $input; + foreach( $rexrule as $rexrulelabel => $rexrulevalue ) { + $rexrulelabel = strtoupper( $rexrulelabel ); + if( 'UNTIL' != $rexrulelabel ) + $input[$rexrulelabel] = $rexrulevalue; + else { + iCalUtilityFunctions::_strDate2arr( $rexrulevalue ); + if( iCalUtilityFunctions::_isArrayTimestampDate( $rexrulevalue )) // timestamp, always date-time UTC + $input[$rexrulelabel] = iCalUtilityFunctions::_timestamp2date( $rexrulevalue, 7, 'UTC' ); + elseif( iCalUtilityFunctions::_isArrayDate( $rexrulevalue )) { // date or UTC date-time + $parno = ( isset( $rexrulevalue['hour'] ) || isset( $rexrulevalue[4] )) ? 7 : 3; + $d = iCalUtilityFunctions::_chkDateArr( $rexrulevalue, $parno ); + if(( 3 < $parno ) && isset( $d['tz'] ) && ( 'Z' != $d['tz'] ) && iCalUtilityFunctions::_isOffset( $d['tz'] )) { + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $d['tz'] ); + $input[$rexrulelabel] = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $input[$rexrulelabel]['unparsedtext'] ); + } + else + $input[$rexrulelabel] = $d; + } + elseif( 8 <= strlen( trim( $rexrulevalue ))) { // ex. textual date-time 2006-08-03 10:12:18 => UTC + $input[$rexrulelabel] = iCalUtilityFunctions::_strdate2date( $rexrulevalue ); + unset( $input['$rexrulelabel']['unparsedtext'] ); + } + if(( 3 < count( $input[$rexrulelabel] )) && !isset( $input[$rexrulelabel]['tz'] )) + $input[$rexrulelabel]['tz'] = 'Z'; + } + } + /* set recurrence rule specification in rfc2445 order */ + $input2 = array(); + if( isset( $input['FREQ'] )) + $input2['FREQ'] = $input['FREQ']; + if( isset( $input['UNTIL'] )) + $input2['UNTIL'] = $input['UNTIL']; + elseif( isset( $input['COUNT'] )) + $input2['COUNT'] = $input['COUNT']; + if( isset( $input['INTERVAL'] )) + $input2['INTERVAL'] = $input['INTERVAL']; + if( isset( $input['BYSECOND'] )) + $input2['BYSECOND'] = $input['BYSECOND']; + if( isset( $input['BYMINUTE'] )) + $input2['BYMINUTE'] = $input['BYMINUTE']; + if( isset( $input['BYHOUR'] )) + $input2['BYHOUR'] = $input['BYHOUR']; + if( isset( $input['BYDAY'] )) { + if( !is_array( $input['BYDAY'] )) // ensure upper case.. . + $input2['BYDAY'] = strtoupper( $input['BYDAY'] ); + else { + foreach( $input['BYDAY'] as $BYDAYx => $BYDAYv ) { + if( 'DAY' == strtoupper( $BYDAYx )) + $input2['BYDAY']['DAY'] = strtoupper( $BYDAYv ); + elseif( !is_array( $BYDAYv )) { + $input2['BYDAY'][$BYDAYx] = $BYDAYv; + } + else { + foreach( $BYDAYv as $BYDAYx2 => $BYDAYv2 ) { + if( 'DAY' == strtoupper( $BYDAYx2 )) + $input2['BYDAY'][$BYDAYx]['DAY'] = strtoupper( $BYDAYv2 ); + else + $input2['BYDAY'][$BYDAYx][$BYDAYx2] = $BYDAYv2; + } + } + } + } + } + if( isset( $input['BYMONTHDAY'] )) + $input2['BYMONTHDAY'] = $input['BYMONTHDAY']; + if( isset( $input['BYYEARDAY'] )) + $input2['BYYEARDAY'] = $input['BYYEARDAY']; + if( isset( $input['BYWEEKNO'] )) + $input2['BYWEEKNO'] = $input['BYWEEKNO']; + if( isset( $input['BYMONTH'] )) + $input2['BYMONTH'] = $input['BYMONTH']; + if( isset( $input['BYSETPOS'] )) + $input2['BYSETPOS'] = $input['BYSETPOS']; + if( isset( $input['WKST'] )) + $input2['WKST'] = $input['WKST']; + return $input2; + } +/** + * convert format for input date to internal date with parameters + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.24 - 2013-06-26 + * @param mixed $year + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param string $tz optional + * @param array $params optional + * @param string $caller optional + * @param string $objName optional + * @param string $tzid optional + * @return array + */ + public static function _setDate( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $tz=FALSE, $params=FALSE, $caller=null, $objName=null, $tzid=FALSE ) { + $input = $parno = null; + $localtime = (( 'dtstart' == $caller ) && in_array( $objName, array( 'vtimezone', 'standard', 'daylight' ))) ? TRUE : FALSE; + iCalUtilityFunctions::_strDate2arr( $year ); + if( iCalUtilityFunctions::_isArrayDate( $year )) { + $input['value'] = iCalUtilityFunctions::_chkDateArr( $year, FALSE ); //$parno ); + if( 100 > $input['value']['year'] ) + $input['value']['year'] += 2000; + if( $localtime ) + unset( $month['VALUE'], $month['TZID'] ); + elseif( !isset( $month['TZID'] ) && isset( $tzid )) + $month['TZID'] = $tzid; + if( isset( $input['value']['tz'] ) && iCalUtilityFunctions::_isOffset( $input['value']['tz'] )) + unset( $month['TZID'] ); + elseif( !isset( $input['value']['tz'] ) && isset( $month['TZID'] ) && iCalUtilityFunctions::_isOffset( $month['TZID'] )) { + $input['value']['tz'] = $month['TZID']; + unset( $month['TZID'] ); + } + $input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); + $hitval = ( isset( $input['value']['tz'] )) ? 7 : 6; + $parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval ); + $parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE', 3, count( $input['value'] ), $parno ); + if( 6 > $parno ) + unset( $input['value']['tz'], $input['params']['TZID'], $tzid ); + if(( 6 <= $parno ) && isset( $input['value']['tz'] ) && ( 'Z' != $input['value']['tz'] ) && iCalUtilityFunctions::_isOffset( $input['value']['tz'] )) { + $d = $input['value']; + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $d['tz'] ); + $input['value'] = iCalUtilityFunctions::_strdate2date( $strdate, $parno ); + unset( $input['value']['unparsedtext'], $input['params']['TZID'] ); + } + if( isset( $input['value']['tz'] ) && !iCalUtilityFunctions::_isOffset( $input['value']['tz'] )) { + $input['params']['TZID'] = $input['value']['tz']; + unset( $input['value']['tz'] ); + } + } // end if( iCalUtilityFunctions::_isArrayDate( $year )) + elseif( iCalUtilityFunctions::_isArrayTimestampDate( $year )) { + if( $localtime ) unset ( $month['VALUE'], $month['TZID'] ); + $input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); + $parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE', 3 ); + $hitval = 7; + $parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval, $parno ); + if( isset( $year['tz'] ) && !empty( $year['tz'] )) { + if( !iCalUtilityFunctions::_isOffset( $year['tz'] )) { + $input['params']['TZID'] = $year['tz']; + unset( $year['tz'], $tzid ); + } + else { + if( isset( $input['params']['TZID'] ) && !empty( $input['params']['TZID'] )) { + if( !iCalUtilityFunctions::_isOffset( $input['params']['TZID'] )) + unset( $tzid ); + else + unset( $input['params']['TZID']); + } + elseif( isset( $tzid ) && !iCalUtilityFunctions::_isOffset( $tzid )) + $input['params']['TZID'] = $tzid; + } + } + elseif( isset( $input['params']['TZID'] ) && !empty( $input['params']['TZID'] )) { + if( iCalUtilityFunctions::_isOffset( $input['params']['TZID'] )) { + $year['tz'] = $input['params']['TZID']; + unset( $input['params']['TZID']); + if( isset( $tzid ) && !empty( $tzid ) && !iCalUtilityFunctions::_isOffset( $tzid )) + $input['params']['TZID'] = $tzid; + } + } + elseif( isset( $tzid ) && !empty( $tzid )) { + if( iCalUtilityFunctions::_isOffset( $tzid )) { + $year['tz'] = $tzid; + unset( $input['params']['TZID']); + } + else + $input['params']['TZID'] = $tzid; + } + $input['value'] = iCalUtilityFunctions::_timestamp2date( $year, $parno ); + } // end elseif( iCalUtilityFunctions::_isArrayTimestampDate( $year )) + elseif( 8 <= strlen( trim( $year ))) { // ex. 2006-08-03 10:12:18 [[[+/-]1234[56]] / timezone] + if( $localtime ) + unset( $month['VALUE'], $month['TZID'] ); + elseif( !isset( $month['TZID'] ) && !empty( $tzid )) + $month['TZID'] = $tzid; + $input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); + $parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', 7, $parno ); + $parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE', 3, $parno, $parno ); + $input['value'] = iCalUtilityFunctions::_strdate2date( $year, $parno ); + if( 3 == $parno ) + unset( $input['value']['tz'], $input['params']['TZID'] ); + unset( $input['value']['unparsedtext'] ); + if( isset( $input['value']['tz'] )) { + if( iCalUtilityFunctions::_isOffset( $input['value']['tz'] )) { + $d = $input['value']; + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $d['tz'] ); + $input['value'] = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $input['value']['unparsedtext'], $input['params']['TZID'] ); + } + else { + $input['params']['TZID'] = $input['value']['tz']; + unset( $input['value']['tz'] ); + } + } + elseif( isset( $input['params']['TZID'] ) && iCalUtilityFunctions::_isOffset( $input['params']['TZID'] )) { + $d = $input['value']; + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $input['params']['TZID'] ); + $input['value'] = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $input['value']['unparsedtext'], $input['params']['TZID'] ); + } + } // end elseif( 8 <= strlen( trim( $year ))) + else { + if( is_array( $params )) + $input['params'] = iCalUtilityFunctions::_setParams( $params, array( 'VALUE' => 'DATE-TIME' )); + elseif( is_array( $tz )) { + $input['params'] = iCalUtilityFunctions::_setParams( $tz, array( 'VALUE' => 'DATE-TIME' )); + $tz = FALSE; + } + elseif( is_array( $hour )) { + $input['params'] = iCalUtilityFunctions::_setParams( $hour, array( 'VALUE' => 'DATE-TIME' )); + $hour = $min = $sec = $tz = FALSE; + } + if( $localtime ) + unset ( $input['params']['VALUE'], $input['params']['TZID'] ); + elseif( !isset( $tz ) && !isset( $input['params']['TZID'] ) && !empty( $tzid )) + $input['params']['TZID'] = $tzid; + elseif( isset( $tz ) && iCalUtilityFunctions::_isOffset( $tz )) + unset( $input['params']['TZID'] ); + elseif( isset( $input['params']['TZID'] ) && iCalUtilityFunctions::_isOffset( $input['params']['TZID'] )) { + $tz = $input['params']['TZID']; + unset( $input['params']['TZID'] ); + } + $parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE', 3 ); + $hitval = ( iCalUtilityFunctions::_isOffset( $tz )) ? 7 : 6; + $parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', $hitval, $parno, $parno ); + $input['value'] = array( 'year' => $year, 'month' => $month, 'day' => $day ); + if( 3 != $parno ) { + $input['value']['hour'] = ( $hour ) ? $hour : '0'; + $input['value']['min'] = ( $min ) ? $min : '0'; + $input['value']['sec'] = ( $sec ) ? $sec : '0'; + if( !empty( $tz )) + $input['value']['tz'] = $tz; + $strdate = iCalUtilityFunctions::_date2strdate( $input['value'], $parno ); + if( !empty( $tz ) && !iCalUtilityFunctions::_isOffset( $tz )) + $strdate .= ( 'Z' == $tz ) ? $tz : ' '.$tz; + $input['value'] = iCalUtilityFunctions::_strdate2date( $strdate, $parno ); + unset( $input['value']['unparsedtext'] ); + if( isset( $input['value']['tz'] )) { + if( iCalUtilityFunctions::_isOffset( $input['value']['tz'] )) { + $d = $input['value']; + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $d['tz'] ); + $input['value'] = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $input['value']['unparsedtext'], $input['params']['TZID'] ); + } + else { + $input['params']['TZID'] = $input['value']['tz']; + unset( $input['value']['tz'] ); + } + } + elseif( isset( $input['params']['TZID'] ) && iCalUtilityFunctions::_isOffset( $input['params']['TZID'] )) { + $d = $input['value']; + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $input['params']['TZID'] ); + $input['value'] = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $input['value']['unparsedtext'], $input['params']['TZID'] ); + } + } + } // end else (i.e. using all arguments) + if(( 3 == $parno ) || ( isset( $input['params']['VALUE'] ) && ( 'DATE' == $input['params']['VALUE'] ))) { + $input['params']['VALUE'] = 'DATE'; + unset( $input['value']['hour'], $input['value']['min'], $input['value']['sec'], $input['value']['tz'], $input['params']['TZID'] ); + } + elseif( isset( $input['params']['TZID'] )) { + if(( 'UTC' == strtoupper( $input['params']['TZID'] )) || ( 'GMT' == strtoupper( $input['params']['TZID'] ))) { + $input['value']['tz'] = 'Z'; + unset( $input['params']['TZID'] ); + } + else + unset( $input['value']['tz'] ); + } + elseif( isset( $input['value']['tz'] )) { + if(( 'UTC' == strtoupper( $input['value']['tz'] )) || ( 'GMT' == strtoupper( $input['value']['tz'] ))) + $input['value']['tz'] = 'Z'; + if( 'Z' != $input['value']['tz'] ) { + $input['params']['TZID'] = $input['value']['tz']; + unset( $input['value']['tz'] ); + } + else + unset( $input['params']['TZID'] ); + } + if( $localtime ) + unset( $input['value']['tz'], $input['params']['TZID'] ); + return $input; + } +/** + * convert format for input date (UTC) to internal date with parameters + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.24 - 2013-07-01 + * @param mixed $year + * @param mixed $month optional + * @param int $day optional + * @param int $hour optional + * @param int $min optional + * @param int $sec optional + * @param array $params optional + * @return array + */ + public static function _setDate2( $year, $month=FALSE, $day=FALSE, $hour=FALSE, $min=FALSE, $sec=FALSE, $params=FALSE ) { + $input = null; + iCalUtilityFunctions::_strDate2arr( $year ); + if( iCalUtilityFunctions::_isArrayDate( $year )) { + $input['value'] = iCalUtilityFunctions::_chkDateArr( $year, 7 ); + if( isset( $input['value']['year'] ) && ( 100 > $input['value']['year'] )) + $input['value']['year'] += 2000; + $input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); + unset( $input['params']['VALUE'] ); + if( isset( $input['value']['tz'] ) && iCalUtilityFunctions::_isOffset( $input['value']['tz'] )) + $tzid = $input['value']['tz']; + elseif( isset( $input['params']['TZID'] ) && iCalUtilityFunctions::_isOffset( $input['params']['TZID'] )) + $tzid = $input['params']['TZID']; + else + $tzid = ''; + unset( $input['params']['VALUE'], $input['params']['TZID'] ); + if( !empty( $tzid ) && ( 'Z' != $tzid ) && iCalUtilityFunctions::_isOffset( $tzid )) { + $d = $input['value']; + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $tzid ); + $input['value'] = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $input['value']['unparsedtext'] ); + } + } + elseif( iCalUtilityFunctions::_isArrayTimestampDate( $year )) { + if( isset( $year['tz'] ) && ! iCalUtilityFunctions::_isOffset( $year['tz'] )) + $year['tz'] = 'UTC'; + elseif( isset( $input['params']['TZID'] ) && iCalUtilityFunctions::_isOffset( $input['params']['TZID'] )) + $year['tz'] = $input['params']['TZID']; + else + $year['tz'] = 'UTC'; + $input['value'] = iCalUtilityFunctions::_timestamp2date( $year, 7 ); + $input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); + unset( $input['params']['VALUE'], $input['params']['TZID'] ); + } + elseif( 8 <= strlen( trim( $year ))) { // ex. 2006-08-03 10:12:18 + $input['value'] = iCalUtilityFunctions::_strdate2date( $year, 7 ); + unset( $input['value']['unparsedtext'] ); + $input['params'] = iCalUtilityFunctions::_setParams( $month, array( 'VALUE' => 'DATE-TIME' )); + if(( !isset( $input['value']['tz'] ) || empty( $input['value']['tz'] )) && isset( $input['params']['TZID'] ) && iCalUtilityFunctions::_isOffset( $input['params']['TZID'] )) { + $d = $input['value']; + $strdate = sprintf( '%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $input['params']['TZID'] ); + $input['value'] = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $input['value']['unparsedtext'] ); + } + unset( $input['params']['VALUE'], $input['params']['TZID'] ); + } + else { + $input['value'] = array( 'year' => $year + , 'month' => $month + , 'day' => $day + , 'hour' => $hour + , 'min' => $min + , 'sec' => $sec ); + if( isset( $tz )) $input['value']['tz'] = $tz; + if(( isset( $tz ) && iCalUtilityFunctions::_isOffset( $tz )) || + ( isset( $input['params']['TZID'] ) && iCalUtilityFunctions::_isOffset( $input['params']['TZID'] ))) { + if( !isset( $tz ) && isset( $input['params']['TZID'] ) && iCalUtilityFunctions::_isOffset( $input['params']['TZID'] )) + $input['value']['tz'] = $input['params']['TZID']; + unset( $input['params']['TZID'] ); + $strdate = iCalUtilityFunctions::_date2strdate( $input['value'], 7 ); + $input['value'] = iCalUtilityFunctions::_strdate2date( $strdate, 7 ); + unset( $input['value']['unparsedtext'] ); + } + $input['params'] = iCalUtilityFunctions::_setParams( $params, array( 'VALUE' => 'DATE-TIME' )); + unset( $input['params']['VALUE'] ); + } + $parno = iCalUtilityFunctions::_existRem( $input['params'], 'VALUE', 'DATE-TIME', 7 ); // remove default + if( !isset( $input['value']['hour'] )) $input['value']['hour'] = 0; + if( !isset( $input['value']['min'] )) $input['value']['min'] = 0; + if( !isset( $input['value']['sec'] )) $input['value']['sec'] = 0; + $input['value']['tz'] = 'Z'; + return $input; + } +/** + * check index and set (an indexed) content in multiple value array + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.6.12 - 2011-01-03 + * @param array $valArr + * @param mixed $value + * @param array $params + * @param array $defaults + * @param int $index + * @return void + */ + public static function _setMval( & $valArr, $value, $params=FALSE, $defaults=FALSE, $index=FALSE ) { + if( !is_array( $valArr )) $valArr = array(); + if( $index ) + $index = $index - 1; + elseif( 0 < count( $valArr )) { + $keys = array_keys( $valArr ); + $index = end( $keys ) + 1; + } + else + $index = 0; + $valArr[$index] = array( 'value' => $value, 'params' => iCalUtilityFunctions::_setParams( $params, $defaults )); + ksort( $valArr ); + } +/** + * set input (formatted) parameters- component property attributes + * + * default parameters can be set, if missing + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 1.x.x - 2007-05-01 + * @param array $params + * @param array $defaults + * @return array + */ + public static function _setParams( $params, $defaults=FALSE ) { + if( !is_array( $params)) + $params = array(); + $input = array(); + foreach( $params as $paramKey => $paramValue ) { + if( is_array( $paramValue )) { + foreach( $paramValue as $pkey => $pValue ) { + if(( '"' == substr( $pValue, 0, 1 )) && ( '"' == substr( $pValue, -1 ))) + $paramValue[$pkey] = substr( $pValue, 1, ( strlen( $pValue ) - 2 )); + } + } + elseif(( '"' == substr( $paramValue, 0, 1 )) && ( '"' == substr( $paramValue, -1 ))) + $paramValue = substr( $paramValue, 1, ( strlen( $paramValue ) - 2 )); + if( 'VALUE' == strtoupper( $paramKey )) + $input['VALUE'] = strtoupper( $paramValue ); + else + $input[strtoupper( $paramKey )] = $paramValue; + } + if( is_array( $defaults )) { + foreach( $defaults as $paramKey => $paramValue ) { + if( !isset( $input[$paramKey] )) + $input[$paramKey] = $paramValue; + } + } + return (0 < count( $input )) ? $input : null; + } +/** + * break lines at pos 75 + * + * Lines of text SHOULD NOT be longer than 75 octets, excluding the line + * break. Long content lines SHOULD be split into a multiple line + * representations using a line "folding" technique. That is, a long + * line can be split between any two characters by inserting a CRLF + * immediately followed by a single linear white space character (i.e., + * SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence + * of CRLF followed immediately by a single linear white space character + * is ignored (i.e., removed) when processing the content type. + * + * Edited 2007-08-26 by Anders Litzell, anders@litzell.se to fix bug where + * the reserved expression "\n" in the arg $string could be broken up by the + * folding of lines, causing ambiguity in the return string. + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @param string $value + * @return string + */ + public static function _size75( $string, $nl ) { + $tmp = $string; + $string = ''; + $cCnt = $x = 0; + while( TRUE ) { + if( !isset( $tmp[$x] )) { + $string .= $nl; // loop breakes here + break; + } + elseif(( 74 <= $cCnt ) && ( '\\' == $tmp[$x] ) && ( 'n' == $tmp[$x+1] )) { + $string .= $nl.' \n'; // don't break lines inside '\n' + $x += 2; + if( !isset( $tmp[$x] )) { + $string .= $nl; + break; + } + $cCnt = 3; + } + elseif( 75 <= $cCnt ) { + $string .= $nl.' '; + $cCnt = 1; + } + $byte = ord( $tmp[$x] ); + $string .= $tmp[$x]; + switch( TRUE ) { // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + case(( $byte >= 0x20 ) && ( $byte <= 0x7F )): // characters U-00000000 - U-0000007F (same as ASCII) + $cCnt += 1; + break; // add a one byte character + case(( $byte & 0xE0) == 0xC0 ): // characters U-00000080 - U-000007FF, mask 110XXXXX + if( isset( $tmp[$x+1] )) { + $cCnt += 1; + $string .= $tmp[$x+1]; + $x += 1; // add a two bytes character + } + break; + case(( $byte & 0xF0 ) == 0xE0 ): // characters U-00000800 - U-0000FFFF, mask 1110XXXX + if( isset( $tmp[$x+2] )) { + $cCnt += 1; + $string .= $tmp[$x+1].$tmp[$x+2]; + $x += 2; // add a three bytes character + } + break; + case(( $byte & 0xF8 ) == 0xF0 ): // characters U-00010000 - U-001FFFFF, mask 11110XXX + if( isset( $tmp[$x+3] )) { + $cCnt += 1; + $string .= $tmp[$x+1].$tmp[$x+2].$tmp[$x+3]; + $x += 3; // add a four bytes character + } + break; + case(( $byte & 0xFC ) == 0xF8 ): // characters U-00200000 - U-03FFFFFF, mask 111110XX + if( isset( $tmp[$x+4] )) { + $cCnt += 1; + $string .= $tmp[$x+1].$tmp[$x+2].$tmp[$x+3].$tmp[$x+4]; + $x += 4; // add a five bytes character + } + break; + case(( $byte & 0xFE ) == 0xFC ): // characters U-04000000 - U-7FFFFFFF, mask 1111110X + if( isset( $tmp[$x+5] )) { + $cCnt += 1; + $string .= $tmp[$x+1].$tmp[$x+2].$tmp[$x+3].$tmp[$x+4].$tmp[$x+5]; + $x += 5; // add a six bytes character + } + default: // add any other byte without counting up $cCnt + break; + } // end switch( TRUE ) + $x += 1; // next 'byte' to test + } // end while( TRUE ) { + return $string; + } +/** + * sort callback functions for exdate + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.11 - 2013-01-12 + * @param array $a + * @param array $b + * @return int + */ + public static function _sortExdate1( $a, $b ) { + $as = sprintf( '%04d%02d%02d', $a['year'], $a['month'], $a['day'] ); + $as .= ( isset( $a['hour'] )) ? sprintf( '%02d%02d%02d', $a['hour'], $a['min'], $a['sec'] ) : ''; + $bs = sprintf( '%04d%02d%02d', $b['year'], $b['month'], $b['day'] ); + $bs .= ( isset( $b['hour'] )) ? sprintf( '%02d%02d%02d', $b['hour'], $b['min'], $b['sec'] ) : ''; + return strcmp( $as, $bs ); + } + public static function _sortExdate2( $a, $b ) { + $val = reset( $a['value'] ); + $as = sprintf( '%04d%02d%02d', $val['year'], $val['month'], $val['day'] ); + $as .= ( isset( $val['hour'] )) ? sprintf( '%02d%02d%02d', $val['hour'], $val['min'], $val['sec'] ) : ''; + $val = reset( $b['value'] ); + $bs = sprintf( '%04d%02d%02d', $val['year'], $val['month'], $val['day'] ); + $bs .= ( isset( $val['hour'] )) ? sprintf( '%02d%02d%02d', $val['hour'], $val['min'], $val['sec'] ) : ''; + return strcmp( $as, $bs ); + } +/** + * sort callback functions for rdate + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.27 - 2013-07-05 + * @param array $a + * @param array $b + * @return int + */ + public static function _sortRdate1( $a, $b ) { + $val = isset( $a['year'] ) ? $a : $a[0]; + $as = sprintf( '%04d%02d%02d', $val['year'], $val['month'], $val['day'] ); + $as .= ( isset( $val['hour'] )) ? sprintf( '%02d%02d%02d', $val['hour'], $val['min'], $val['sec'] ) : ''; + $val = isset( $b['year'] ) ? $b : $b[0]; + $bs = sprintf( '%04d%02d%02d', $val['year'], $val['month'], $val['day'] ); + $bs .= ( isset( $val['hour'] )) ? sprintf( '%02d%02d%02d', $val['hour'], $val['min'], $val['sec'] ) : ''; + return strcmp( $as, $bs ); + } + public static function _sortRdate2( $a, $b ) { + $val = isset( $a['value'][0]['year'] ) ? $a['value'][0] : $a['value'][0][0]; + if( empty( $val )) + $as = ''; + else { + $as = sprintf( '%04d%02d%02d', $val['year'], $val['month'], $val['day'] ); + $as .= ( isset( $val['hour'] )) ? sprintf( '%02d%02d%02d', $val['hour'], $val['min'], $val['sec'] ) : ''; + } + $val = isset( $b['value'][0]['year'] ) ? $b['value'][0] : $b['value'][0][0]; + if( empty( $val )) + $bs = ''; + else { + $bs = sprintf( '%04d%02d%02d', $val['year'], $val['month'], $val['day'] ); + $bs .= ( isset( $val['hour'] )) ? sprintf( '%02d%02d%02d', $val['hour'], $val['min'], $val['sec'] ) : ''; + } + return strcmp( $as, $bs ); + } +/** + * step date, return updated date, array and timpstamp + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.14.1 - 2012-09-24 + * @param array $date, date to step + * @param int $timestamp + * @param array $step, default array( 'day' => 1 ) + * @return void + */ + public static function _stepdate( &$date, &$timestamp, $step=array( 'day' => 1 )) { + if( !isset( $date['hour'] )) $date['hour'] = 0; + if( !isset( $date['min'] )) $date['min'] = 0; + if( !isset( $date['sec'] )) $date['sec'] = 0; + foreach( $step as $stepix => $stepvalue ) + $date[$stepix] += $stepvalue; + $timestamp = mktime( $date['hour'], $date['min'], $date['sec'], $date['month'], $date['day'], $date['year'] ); + $d = date( 'Y-m-d-H-i-s', $timestamp); + $d = explode( '-', $d ); + $date = array( 'year' => $d[0], 'month' => $d[1], 'day' => $d[2], 'hour' => $d[3], 'min' => $d[4], 'sec' => $d[5] ); + foreach( $date as $k => $v ) + $date[$k] = (int) $v; + } +/** + * convert a date from specific string to array format + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.11.8 - 2012-01-27 + * @param mixed $input + * @return bool, TRUE on success + */ + public static function _strDate2arr( & $input ) { + if( is_array( $input )) + return FALSE; + if( 5 > strlen( (string) $input )) + return FALSE; + $work = $input; + if( 2 == substr_count( $work, '-' )) + $work = str_replace( '-', '', $work ); + if( 2 == substr_count( $work, '/' )) + $work = str_replace( '/', '', $work ); + if( !ctype_digit( substr( $work, 0, 8 ))) + return FALSE; + $temp = array( 'year' => (int) substr( $work, 0, 4 ) + , 'month' => (int) substr( $work, 4, 2 ) + , 'day' => (int) substr( $work, 6, 2 )); + if( !checkdate( $temp['month'], $temp['day'], $temp['year'] )) + return FALSE; + if( 8 == strlen( $work )) { + $input = $temp; + return TRUE; + } + if(( ' ' == substr( $work, 8, 1 )) || ( 'T' == substr( $work, 8, 1 )) || ( 't' == substr( $work, 8, 1 ))) + $work = substr( $work, 9 ); + elseif( ctype_digit( substr( $work, 8, 1 ))) + $work = substr( $work, 8 ); + else + return FALSE; + if( 2 == substr_count( $work, ':' )) + $work = str_replace( ':', '', $work ); + if( !ctype_digit( substr( $work, 0, 4 ))) + return FALSE; + $temp['hour'] = substr( $work, 0, 2 ); + $temp['min'] = substr( $work, 2, 2 ); + if((( 0 > $temp['hour'] ) || ( $temp['hour'] > 23 )) || + (( 0 > $temp['min'] ) || ( $temp['min'] > 59 ))) + return FALSE; + if( ctype_digit( substr( $work, 4, 2 ))) { + $temp['sec'] = substr( $work, 4, 2 ); + if(( 0 > $temp['sec'] ) || ( $temp['sec'] > 59 )) + return FALSE; + $len = 6; + } + else { + $temp['sec'] = 0; + $len = 4; + } + if( $len < strlen( $work)) + $temp['tz'] = trim( substr( $work, 6 )); + $input = $temp; + return TRUE; + } +/** + * ensures internal date-time/date format for input date-time/date in string fromat + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.24 - 2013-06-26 + * Modified to also return original string value by Yitzchok Lavi + * @param array $datetime + * @param int $parno optional, default FALSE + * @param moxed $wtz optional, default null + * @return array + */ + public static function _date_time_string( $datetime, $parno=FALSE ) { + return iCalUtilityFunctions::_strdate2date( $datetime, $parno, null ); + } + public static function _strdate2date( $datetime, $parno=FALSE, $wtz=null ) { + // save original input string to return it later + $unparseddatetime = $datetime; + $datetime = (string) trim( $datetime ); + $tz = null; + $offset = 0; + $tzSts = FALSE; + $len = strlen( $datetime ); + if( 'Z' == substr( $datetime, -1 )) { + $tz = 'Z'; + $datetime = trim( substr( $datetime, 0, ( $len - 1 ))); + $tzSts = TRUE; + } + if( iCalUtilityFunctions::_isOffset( substr( $datetime, -5, 5 ))) { // [+/-]NNNN offset + $tz = substr( $datetime, -5, 5 ); + $datetime = trim( substr( $datetime, 0, ($len - 5))); + } + elseif( iCalUtilityFunctions::_isOffset( substr( $datetime, -7, 7 ))) { // [+/-]NNNNNN offset + $tz = substr( $datetime, -7, 7 ); + $datetime = trim( substr( $datetime, 0, ($len - 7))); + } + elseif( empty( $wtz ) && ctype_digit( substr( $datetime, 0, 4 )) && ctype_digit( substr( $datetime, -2, 2 )) && iCalUtilityFunctions::_strDate2arr( $datetime )) { + $output = $datetime; + if( !empty( $tz )) + $output['tz'] = 'Z'; + $output['unparsedtext'] = $unparseddatetime; + return $output; + } + else { + $cx = $tx = 0; // find any trailing timezone or offset + $len = strlen( $datetime ); + for( $cx = -1; $cx > ( 9 - $len ); $cx-- ) { + $char = substr( $datetime, $cx, 1 ); + if(( ' ' == $char ) || ctype_digit( $char )) + break; // if exists, tz ends here.. . ? + else + $tx--; // tz length counter + } + if( 0 > $tx ) { // if any + $tz = substr( $datetime, $tx ); + $datetime = trim( substr( $datetime, 0, $len + $tx )); + } + if(( ctype_digit( substr( $datetime, 0, 8 )) && ( 'T' == substr( $datetime, 8, 1 )) && ctype_digit( substr( $datetime, -6, 6 ))) || + ( ctype_digit( substr( $datetime, 0, 14 )))) + $tzSts = TRUE; + } + if( empty( $tz ) && !empty( $wtz )) + $tz = $wtz; + if( 3 == $parno ) + $tz = null; + if( !empty( $tz )) { // tz set + if(( 'Z' != $tz ) && ( iCalUtilityFunctions::_isOffset( $tz ))) { + $offset = (string) iCalUtilityFunctions::_tz2offset( $tz ) * -1; + $tz = 'UTC'; + $tzSts = TRUE; + } + elseif( !empty( $wtz )) + $tzSts = TRUE; + $tz = trim( $tz ); + if(( 'Z' == $tz ) || ( 'GMT' == strtoupper( $tz ))) + $tz = 'UTC'; + if( 0 < substr_count( $datetime, '-' )) + $datetime = str_replace( '-', '/', $datetime ); + try { + $d = new DateTime( $datetime, new DateTimeZone( $tz )); + if( 0 != $offset ) // adjust for offset + $d->modify( $offset.' seconds' ); + $datestring = $d->format( 'Y-m-d-H-i-s' ); + unset( $d ); + } + catch( Exception $e ) { + $datestring = date( 'Y-m-d-H-i-s', strtotime( $datetime )); + } + } // end if( !empty( $tz )) + else + $datestring = date( 'Y-m-d-H-i-s', strtotime( $datetime )); + if( 'UTC' == $tz ) + $tz = 'Z'; + $d = explode( '-', $datestring ); + $output = array( 'year' => $d[0], 'month' => $d[1], 'day' => $d[2] ); + if( !$parno || ( 3 != $parno )) { // parno is set to 6 or 7 + $output['hour'] = $d[3]; + $output['min'] = $d[4]; + $output['sec'] = $d[5]; + if(( $tzSts || ( 7 == $parno )) && !empty( $tz )) + $output['tz'] = $tz; + } + // return original string in the array in case strtotime failed to make sense of it + $output['unparsedtext'] = $unparseddatetime; + return $output; + } +/********************************************************************************/ +/** + * special characters management output + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @param string $string + * @param string $format + * @param string $nl + * @return string + */ + public static function _strrep( $string, $format, $nl ) { + switch( $format ) { + case 'xcal': + $string = str_replace( '\n', $nl, $string); + $string = htmlspecialchars( strip_tags( stripslashes( urldecode ( $string )))); + break; + default: + $pos = 0; + $specChars = array( 'n', 'N', 'r', ',', ';' ); + while( isset( $string[$pos] )) { + if( FALSE === ( $pos = strpos( $string, "\\", $pos ))) + break; + if( !in_array( substr( $string, $pos, 1 ), $specChars )) { + $string = substr( $string, 0, $pos )."\\".substr( $string, ( $pos + 1 )); + $pos += 1; + } + $pos += 1; + } + if( FALSE !== strpos( $string, '"' )) + $string = str_replace('"', "'", $string); + if( FALSE !== strpos( $string, ',' )) + $string = str_replace(',', '\,', $string); + if( FALSE !== strpos( $string, ';' )) + $string = str_replace(';', '\;', $string); + if( FALSE !== strpos( $string, "\r\n" )) + $string = str_replace( "\r\n", '\n', $string); + elseif( FALSE !== strpos( $string, "\r" )) + $string = str_replace( "\r", '\n', $string); + elseif( FALSE !== strpos( $string, "\n" )) + $string = str_replace( "\n", '\n', $string); + if( FALSE !== strpos( $string, '\N' )) + $string = str_replace( '\N', '\n', $string); +// if( FALSE !== strpos( $string, $nl )) + $string = str_replace( $nl, '\n', $string); + break; + } + return $string; + } +/** + * special characters management input (from iCal file) + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.2 - 2012-12-18 + * @param string $string + * @return string + */ + public static function _strunrep( $string ) { + $string = str_replace( '\\\\', '\\', $string); + $string = str_replace( '\,', ',', $string); + $string = str_replace( '\;', ';', $string); +// $string = str_replace( '\n', $nl, $string); // ?? + return $string; + } +/** + * convert timestamp to date array, default UTC or adjusted for offset/timezone + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.15.1 - 2012-10-17 + * @param mixed $timestamp + * @param int $parno + * @param string $wtz + * @return array + */ + public static function _timestamp2date( $timestamp, $parno=6, $wtz=null ) { + if( is_array( $timestamp )) { + $tz = ( isset( $timestamp['tz'] )) ? $timestamp['tz'] : $wtz; + $timestamp = $timestamp['timestamp']; + } + $tz = ( isset( $tz )) ? $tz : $wtz; + $offset = 0; + if( empty( $tz ) || ( 'Z' == $tz ) || ( 'GMT' == strtoupper( $tz ))) + $tz = 'UTC'; + elseif( iCalUtilityFunctions::_isOffset( $tz )) { + $offset = iCalUtilityFunctions::_tz2offset( $tz ); +// $tz = 'UTC'; + } + try { + $d = new DateTime( "@$timestamp" ); // set UTC date + if( 0 != $offset ) // adjust for offset + $d->modify( $offset.' seconds' ); + elseif( 'UTC' != $tz ) + $d->setTimezone( new DateTimeZone( $tz )); // convert to local date + $date = $d->format( 'Y-m-d-H-i-s' ); + unset( $d ); + } + catch( Exception $e ) { + $date = date( 'Y-m-d-H-i-s', $timestamp ); + } + $date = explode( '-', $date ); + $output = array( 'year' => $date[0], 'month' => $date[1], 'day' => $date[2] ); + if( 3 != $parno ) { + $output['hour'] = $date[3]; + $output['min'] = $date[4]; + $output['sec'] = $date[5]; + if(( 'UTC' == $tz ) || ( 0 == $offset )) + $output['tz'] = 'Z'; + } + return $output; + } +/** + * convert timestamp (seconds) to duration in array format + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.6.23 - 2010-10-23 + * @param int $timestamp + * @return array, duration format + */ + public static function _timestamp2duration( $timestamp ) { + $dur = array(); + $dur['week'] = (int) floor( $timestamp / ( 7 * 24 * 60 * 60 )); + $timestamp = $timestamp % ( 7 * 24 * 60 * 60 ); + $dur['day'] = (int) floor( $timestamp / ( 24 * 60 * 60 )); + $timestamp = $timestamp % ( 24 * 60 * 60 ); + $dur['hour'] = (int) floor( $timestamp / ( 60 * 60 )); + $timestamp = $timestamp % ( 60 * 60 ); + $dur['min'] = (int) floor( $timestamp / ( 60 )); + $dur['sec'] = (int) $timestamp % ( 60 ); + return $dur; + } +/** + * transforms a dateTime from a timezone to another using PHP DateTime and DateTimeZone class (PHP >= PHP 5.2.0) + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.15.1 - 2012-10-17 + * @param mixed $date, date to alter + * @param string $tzFrom, PHP valid 'from' timezone + * @param string $tzTo, PHP valid 'to' timezone, default 'UTC' + * @param string $format, date output format, default 'Ymd\THis' + * @return bool + */ + public static function transformDateTime( & $date, $tzFrom, $tzTo='UTC', $format = 'Ymd\THis' ) { + if( is_array( $date ) && isset( $date['timestamp'] )) { + try { + $d = new DateTime( "@{$date['timestamp']}" ); // set UTC date + $d->setTimezone(new DateTimeZone( $tzFrom )); // convert to 'from' date + } + catch( Exception $e ) { return FALSE; } + } + else { + if( iCalUtilityFunctions::_isArrayDate( $date )) { + if( isset( $date['tz'] )) + unset( $date['tz'] ); + $date = iCalUtilityFunctions::_date2strdate( iCalUtilityFunctions::_chkDateArr( $date )); + } + if( 'Z' == substr( $date, -1 )) + $date = substr( $date, 0, ( strlen( $date ) - 2 )); + try { $d = new DateTime( $date, new DateTimeZone( $tzFrom )); } + catch( Exception $e ) { return FALSE; } + } + try { $d->setTimezone( new DateTimeZone( $tzTo )); } + catch( Exception $e ) { return FALSE; } + $date = $d->format( $format ); + return TRUE; + } +/** + * convert offset, [+/-]HHmm[ss], to seconds, used when correcting UTC to localtime or v.v. + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.11.4 - 2012-01-11 + * @param string $offset + * @return integer + */ + public static function _tz2offset( $tz ) { + $tz = trim( (string) $tz ); + $offset = 0; + if((( 5 != strlen( $tz )) && ( 7 != strlen( $tz ))) || + (( '+' != substr( $tz, 0, 1 )) && ( '-' != substr( $tz, 0, 1 ))) || + (( '0000' >= substr( $tz, 1, 4 )) && ( '9999' < substr( $tz, 1, 4 ))) || + (( 7 == strlen( $tz )) && ( '00' > substr( $tz, 5, 2 )) && ( '99' < substr( $tz, 5, 2 )))) + return $offset; + $hours2sec = (int) substr( $tz, 1, 2 ) * 3600; + $min2sec = (int) substr( $tz, 3, 2 ) * 60; + $sec = ( 7 == strlen( $tz )) ? (int) substr( $tz, -2 ) : '00'; + $offset = $hours2sec + $min2sec + $sec; + $offset = ('-' == substr( $tz, 0, 1 )) ? $offset * -1 : $offset; + return $offset; + } +} +/*********************************************************************************/ +/* iCalcreator vCard helper functions */ +/*********************************************************************************/ +/** + * convert single ATTENDEE, CONTACT or ORGANIZER (in email format) to vCard + * returns vCard/TRUE or if directory (if set) or file write is unvalid, FALSE + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.12.2 - 2012-07-11 + * @param object $email + * $param string $version, vCard version (default 2.1) + * $param string $directory, where to save vCards (default FALSE) + * $param string $ext, vCard file extension (default 'vcf') + * @return mixed + */ +function iCal2vCard( $email, $version='2.1', $directory=FALSE, $ext='vcf' ) { + if( FALSE === ( $pos = strpos( $email, '@' ))) + return FALSE; + if( $directory ) { + if( DIRECTORY_SEPARATOR != substr( $directory, ( 0 - strlen( DIRECTORY_SEPARATOR )))) + $directory .= DIRECTORY_SEPARATOR; + if( !is_dir( $directory ) || !is_writable( $directory )) + return FALSE; + } + /* prepare vCard */ + $email = str_replace( 'MAILTO:', '', $email ); + $name = $person = substr( $email, 0, $pos ); + if( ctype_upper( $name ) || ctype_lower( $name )) + $name = array( $name ); + else { + if( FALSE !== ( $pos = strpos( $name, '.' ))) { + $name = explode( '.', $name ); + foreach( $name as $k => $part ) + $name[$k] = ucfirst( $part ); + } + else { // split camelCase + $chars = $name; + $name = array( $chars[0] ); + $k = 0; + $x = 1; + while( FALSE !== ( $char = substr( $chars, $x, 1 ))) { + if( ctype_upper( $char )) { + $k += 1; + $name[$k] = ''; + } + $name[$k] .= $char; + $x++; + } + } + } + $nl = "\r\n"; + $FN = 'FN:'.implode( ' ', $name ).$nl; + $name = array_reverse( $name ); + $N = 'N:'.array_shift( $name ); + $scCnt = 0; + while( NULL != ( $part = array_shift( $name ))) { + if(( '4.0' != $version ) || ( 4 > $scCnt )) + $scCnt += 1; + $N .= ';'.$part; + } + while(( '4.0' == $version ) && ( 4 > $scCnt )) { + $N .= ';'; + $scCnt += 1; + } + $N .= $nl; + $EMAIL = 'EMAIL:'.$email.$nl; + /* create vCard */ + $vCard = 'BEGIN:VCARD'.$nl; + $vCard .= "VERSION:$version$nl"; + $vCard .= 'PRODID:-//kigkonsult.se '.ICALCREATOR_VERSION."//$nl"; + $vCard .= $N; + $vCard .= $FN; + $vCard .= $EMAIL; + $vCard .= 'REV:'.gmdate( 'Ymd\THis\Z' ).$nl; + $vCard .= 'END:VCARD'.$nl; + /* save each vCard as (unique) single file */ + if( $directory ) { + $fname = $directory.preg_replace( '/[^a-z0-9.]/i', '', $email ); + $cnt = 1; + $dbl = ''; + while( is_file ( $fname.$dbl.'.'.$ext )) { + $cnt += 1; + $dbl = "_$cnt"; + } + if( FALSE === file_put_contents( $fname, $fname.$dbl.'.'.$ext )) + return FALSE; + return TRUE; + } + /* return vCard */ + else + return $vCard; +} +/** + * convert ATTENDEEs, CONTACTs and ORGANIZERs (in email format) to vCards + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.12.2 - 2012-05-07 + * @param object $calendar, iCalcreator vcalendar instance reference + * $param string $version, vCard version (default 2.1) + * $param string $directory, where to save vCards (default FALSE) + * $param string $ext, vCard file extension (default 'vcf') + * @return mixed + */ +function iCal2vCards( & $calendar, $version='2.1', $directory=FALSE, $ext='vcf' ) { + $hits = array(); + $vCardP = array( 'ATTENDEE', 'CONTACT', 'ORGANIZER' ); + foreach( $vCardP as $prop ) { + $hits2 = $calendar->getProperty( $prop ); + foreach( $hits2 as $propValue => $occCnt ) { + if( FALSE === ( $pos = strpos( $propValue, '@' ))) + continue; + $propValue = str_replace( 'MAILTO:', '', $propValue ); + if( isset( $hits[$propValue] )) + $hits[$propValue] += $occCnt; + else + $hits[$propValue] = $occCnt; + } + } + if( empty( $hits )) + return FALSE; + ksort( $hits ); + $output = ''; + foreach( $hits as $email => $skip ) { + $res = iCal2vCard( $email, $version, $directory, $ext ); + if( $directory && !$res ) + return FALSE; + elseif( !$res ) + return $res; + else + $output .= $res; + } + if( $directory ) + return TRUE; + if( !empty( $output )) + return $output; + return FALSE; +} +/*********************************************************************************/ +/* iCalcreator XML (rfc6321) helper functions */ +/*********************************************************************************/ +/** + * format iCal XML output, rfc6321, using PHP SimpleXMLElement + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.22 - 2013-06-27 + * @param object $calendar, iCalcreator vcalendar instance reference + * @return string + */ +function iCal2XML( & $calendar ) { + /** fix an SimpleXMLElement instance and create root element */ + $xmlstr = ''; + $xmlstr .= ''; + $xmlstr .= ''; + $xml = new SimpleXMLElement( $xmlstr ); + $vcalendar = $xml->addChild( 'vcalendar' ); + /** fix calendar properties */ + $properties = $vcalendar->addChild( 'properties' ); + $calProps = array( 'version', 'prodid', 'calscale', 'method' ); + foreach( $calProps as $calProp ) { + if( FALSE !== ( $content = $calendar->getProperty( $calProp ))) + _addXMLchild( $properties, $calProp, 'text', $content ); + } + while( FALSE !== ( $content = $calendar->getProperty( FALSE, FALSE, TRUE ))) + _addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] ); + $langCal = $calendar->getConfig( 'language' ); + /** prepare to fix components with properties */ + $components = $vcalendar->addChild( 'components' ); + /** fix component properties */ + while( FALSE !== ( $component = $calendar->getComponent())) { + $compName = $component->objName; + $child = $components->addChild( $compName ); + $properties = $child->addChild( 'properties' ); + $langComp = $component->getConfig( 'language' ); + $props = $component->getConfig( 'setPropertyNames' ); + foreach( $props as $prop ) { + switch( strtolower( $prop )) { + case 'attach': // may occur multiple times, below + while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + $type = ( isset( $content['params']['VALUE'] ) && ( 'BINARY' == $content['params']['VALUE'] )) ? 'binary' : 'uri'; + unset( $content['params']['VALUE'] ); + _addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] ); + } + break; + case 'attendee': + while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) { + if( $langComp ) + $content['params']['LANGUAGE'] = $langComp; + elseif( $langCal ) + $content['params']['LANGUAGE'] = $langCal; + } + _addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] ); + } + break; + case 'exdate': + while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + $type = ( isset( $content['params']['VALUE'] ) && ( 'DATE' == $content['params']['VALUE'] )) ? 'date' : 'date-time'; + unset( $content['params']['VALUE'] ); + _addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] ); + } + break; + case 'freebusy': + while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + if( is_array( $content ) && isset( $content['value']['fbtype'] )) { + $content['params']['FBTYPE'] = $content['value']['fbtype']; + unset( $content['value']['fbtype'] ); + } + _addXMLchild( $properties, $prop, 'period', $content['value'], $content['params'] ); + } + break; + case 'request-status': + while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + if( !isset( $content['params']['LANGUAGE'] )) { + if( $langComp ) + $content['params']['LANGUAGE'] = $langComp; + elseif( $langCal ) + $content['params']['LANGUAGE'] = $langCal; + } + _addXMLchild( $properties, $prop, 'rstatus', $content['value'], $content['params'] ); + } + break; + case 'rdate': + while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + $type = 'date-time'; + if( isset( $content['params']['VALUE'] )) { + if( 'DATE' == $content['params']['VALUE'] ) + $type = 'date'; + elseif( 'PERIOD' == $content['params']['VALUE'] ) + $type = 'period'; + } + unset( $content['params']['VALUE'] ); + _addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] ); + } + break; + case 'categories': + case 'comment': + case 'contact': + case 'description': + case 'related-to': + case 'resources': + while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + if(( 'related-to' != $prop ) && !isset( $content['params']['LANGUAGE'] )) { + if( $langComp ) + $content['params']['LANGUAGE'] = $langComp; + elseif( $langCal ) + $content['params']['LANGUAGE'] = $langCal; + } + _addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] ); + } + break; + case 'x-prop': + while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] ); + break; + case 'created': // single occurence below, if set + case 'completed': + case 'dtstamp': + case 'last-modified': + $utcDate = TRUE; + case 'dtstart': + case 'dtend': + case 'due': + case 'recurrence-id': + if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + $type = ( isset( $content['params']['VALUE'] ) && ( 'DATE' == $content['params']['VALUE'] )) ? 'date' : 'date-time'; + unset( $content['params']['VALUE'] ); + if(( isset( $content['params']['TZID'] ) && empty( $content['params']['TZID'] )) || @is_null( $content['params']['TZID'] )) + unset( $content['params']['TZID'] ); + _addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] ); + } + unset( $utcDate ); + break; + case 'duration': + if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $prop, 'duration', $content['value'], $content['params'] ); + break; + case 'exrule': + case 'rrule': + while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $prop, 'recur', $content['value'], $content['params'] ); + break; + case 'class': + case 'location': + case 'status': + case 'summary': + case 'transp': + case 'tzid': + case 'uid': + if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + if((( 'location' == $prop ) || ( 'summary' == $prop )) && !isset( $content['params']['LANGUAGE'] )) { + if( $langComp ) + $content['params']['LANGUAGE'] = $langComp; + elseif( $langCal ) + $content['params']['LANGUAGE'] = $langCal; + } + _addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] ); + } + break; + case 'geo': + if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $prop, 'geo', $content['value'], $content['params'] ); + break; + case 'organizer': + if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) { + if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) { + if( $langComp ) + $content['params']['LANGUAGE'] = $langComp; + elseif( $langCal ) + $content['params']['LANGUAGE'] = $langCal; + } + _addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] ); + } + break; + case 'percent-complete': + case 'priority': + case 'sequence': + if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $prop, 'integer', $content['value'], $content['params'] ); + break; + case 'tzurl': + case 'url': + if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $prop, 'uri', $content['value'], $content['params'] ); + break; + } // end switch( $prop ) + } // end foreach( $props as $prop ) + /** fix subComponent properties, if any */ + while( FALSE !== ( $subcomp = $component->getComponent())) { + $subCompName = $subcomp->objName; + $child2 = $child->addChild( $subCompName ); + $properties = $child2->addChild( 'properties' ); + $langComp = $subcomp->getConfig( 'language' ); + $subCompProps = $subcomp->getConfig( 'setPropertyNames' ); + foreach( $subCompProps as $prop ) { + switch( strtolower( $prop )) { + case 'attach': // may occur multiple times, below + while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) { + $type = ( isset( $content['params']['VALUE'] ) && ( 'BINARY' == $content['params']['VALUE'] )) ? 'binary' : 'uri'; + unset( $content['params']['VALUE'] ); + _addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] ); + } + break; + case 'attendee': + while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) { + if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) { + if( $langComp ) + $content['params']['LANGUAGE'] = $langComp; + elseif( $langCal ) + $content['params']['LANGUAGE'] = $langCal; + } + _addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] ); + } + break; + case 'comment': + case 'tzname': + while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) { + if( !isset( $content['params']['LANGUAGE'] )) { + if( $langComp ) + $content['params']['LANGUAGE'] = $langComp; + elseif( $langCal ) + $content['params']['LANGUAGE'] = $langCal; + } + _addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] ); + } + break; + case 'rdate': + while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) { + $type = 'date-time'; + if( isset( $content['params']['VALUE'] )) { + if( 'DATE' == $content['params']['VALUE'] ) + $type = 'date'; + elseif( 'PERIOD' == $content['params']['VALUE'] ) + $type = 'period'; + } + unset( $content['params']['VALUE'] ); + _addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] ); + } + break; + case 'x-prop': + while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] ); + break; + case 'action': // single occurence below, if set + case 'description': + case 'summary': + if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) { + if(( 'action' != $prop ) && !isset( $content['params']['LANGUAGE'] )) { + if( $langComp ) + $content['params']['LANGUAGE'] = $langComp; + elseif( $langCal ) + $content['params']['LANGUAGE'] = $langCal; + } + _addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] ); + } + break; + case 'dtstart': + if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) { + unset( $content['value']['tz'], $content['params']['VALUE'] ); // always local time + _addXMLchild( $properties, $prop, 'date-time', $content['value'], $content['params'] ); + } + break; + case 'duration': + if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $prop, 'duration', $content['value'], $content['params'] ); + break; + case 'repeat': + if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $prop, 'integer', $content['value'], $content['params'] ); + break; + case 'trigger': + if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) { + if( isset( $content['value']['year'] ) && + isset( $content['value']['month'] ) && + isset( $content['value']['day'] )) + $type = 'date-time'; + else { + $type = 'duration'; + if( !isset( $content['value']['relatedStart'] ) || ( TRUE !== $content['value']['relatedStart'] )) + $content['params']['RELATED'] = 'END'; + } + _addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] ); + } + break; + case 'tzoffsetto': + case 'tzoffsetfrom': + if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $prop, 'utc-offset', $content['value'], $content['params'] ); + break; + case 'rrule': + while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) + _addXMLchild( $properties, $prop, 'recur', $content['value'], $content['params'] ); + break; + } // switch( $prop ) + } // end foreach( $subCompProps as $prop ) + } // end while( FALSE !== ( $subcomp = $component->getComponent())) + } // end while( FALSE !== ( $component = $calendar->getComponent())) + return $xml->asXML(); +} +/** + * Add children to a SimpleXMLelement + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.22 - 2013-06-24 + * @param object $parent, reference to a SimpleXMLelement node + * @param string $name, new element node name + * @param string $type, content type, subelement(-s) name + * @param string $content, new subelement content + * @param array $params, new element 'attributes' + * @return void + */ +function _addXMLchild( & $parent, $name, $type, $content, $params=array()) { + /** create new child node */ + $name = strtolower( $name ); + $child = $parent->addChild( $name ); + if( !empty( $params )) { + $parameters = $child->addChild( 'parameters' ); + foreach( $params as $param => $parVal ) { + if( 'VALUE' == $param ) + continue; + $param = strtolower( $param ); + if( 'x-' == substr( $param, 0, 2 )) { + $p1 = $parameters->addChild( $param ); + $p2 = $p1->addChild( 'unknown', htmlspecialchars( $parVal )); + } + else { + $p1 = $parameters->addChild( $param ); + switch( $param ) { + case 'altrep': + case 'dir': $ptype = 'uri'; break; + case 'delegated-from': + case 'delegated-to': + case 'member': + case 'sent-by': $ptype = 'cal-address'; break; + case 'rsvp': $ptype = 'boolean'; break ; + default: $ptype = 'text'; break; + } + if( is_array( $parVal )) { + foreach( $parVal as $pV ) + $p2 = $p1->addChild( $ptype, htmlspecialchars( $pV )); + } + else + $p2 = $p1->addChild( $ptype, htmlspecialchars( $parVal )); + } + } + } // end if( !empty( $params )) + if(( empty( $content ) && ( '0' != $content )) || ( !is_array( $content) && ( '-' != substr( $content, 0, 1 ) && ( 0 > $content )))) + return; + /** store content */ + switch( $type ) { + case 'binary': + $v = $child->addChild( $type, $content ); + break; + case 'boolean': + break; + case 'cal-address': + $v = $child->addChild( $type, $content ); + break; + case 'date': + if( array_key_exists( 'year', $content )) + $content = array( $content ); + foreach( $content as $date ) { + $str = sprintf( '%04d-%02d-%02d', $date['year'], $date['month'], $date['day'] ); + $v = $child->addChild( $type, $str ); + } + break; + case 'date-time': + if( array_key_exists( 'year', $content )) + $content = array( $content ); + foreach( $content as $dt ) { + if( !isset( $dt['hour'] )) $dt['hour'] = 0; + if( !isset( $dt['min'] )) $dt['min'] = 0; + if( !isset( $dt['sec'] )) $dt['sec'] = 0; + $str = sprintf( '%04d-%02d-%02dT%02d:%02d:%02d', $dt['year'], $dt['month'], $dt['day'], $dt['hour'], $dt['min'], $dt['sec'] ); + if( isset( $dt['tz'] ) && ( 'Z' == $dt['tz'] )) + $str .= 'Z'; + $v = $child->addChild( $type, $str ); + } + break; + case 'duration': + $output = (( 'trigger' == $name ) && ( FALSE !== $content['before'] )) ? '-' : ''; + $v = $child->addChild( $type, $output.iCalUtilityFunctions::_duration2str( $content ) ); + break; + case 'geo': + if( !empty( $content )) { + $v1 = $child->addChild( 'latitude', number_format( (float) $content['latitude'], 6, '.', '' )); + $v1 = $child->addChild( 'longitude', number_format( (float) $content['longitude'], 6, '.', '' )); + } + break; + case 'integer': + $v = $child->addChild( $type, (string) $content ); + break; + case 'period': + if( !is_array( $content )) + break; + foreach( $content as $period ) { + $v1 = $child->addChild( $type ); + $str = sprintf( '%04d-%02d-%02dT%02d:%02d:%02d', $period[0]['year'], $period[0]['month'], $period[0]['day'], $period[0]['hour'], $period[0]['min'], $period[0]['sec'] ); + if( isset( $period[0]['tz'] ) && ( 'Z' == $period[0]['tz'] )) + $str .= 'Z'; + $v2 = $v1->addChild( 'start', $str ); + if( array_key_exists( 'year', $period[1] )) { + $str = sprintf( '%04d-%02d-%02dT%02d:%02d:%02d', $period[1]['year'], $period[1]['month'], $period[1]['day'], $period[1]['hour'], $period[1]['min'], $period[1]['sec'] ); + if( isset($period[1]['tz'] ) && ( 'Z' == $period[1]['tz'] )) + $str .= 'Z'; + $v2 = $v1->addChild( 'end', $str ); + } + else + $v2 = $v1->addChild( 'duration', iCalUtilityFunctions::_duration2str( $period[1] )); + } + break; + case 'recur': + foreach( $content as $rulelabel => $rulevalue ) { + $rulelabel = strtolower( $rulelabel ); + switch( $rulelabel ) { + case 'until': + if( isset( $rulevalue['hour'] )) + $str = sprintf( '%04d-%02d-%02dT%02d:%02d:%02dZ', $rulevalue['year'], $rulevalue['month'], $rulevalue['day'], $rulevalue['hour'], $rulevalue['min'], $rulevalue['sec'] ); + else + $str = sprintf( '%04d-%02d-%02d', $rulevalue['year'], $rulevalue['month'], $rulevalue['day'] ); + $v = $child->addChild( $rulelabel, $str ); + break; + case 'bysecond': + case 'byminute': + case 'byhour': + case 'bymonthday': + case 'byyearday': + case 'byweekno': + case 'bymonth': + case 'bysetpos': { + if( is_array( $rulevalue )) { + foreach( $rulevalue as $vix => $valuePart ) + $v = $child->addChild( $rulelabel, $valuePart ); + } + else + $v = $child->addChild( $rulelabel, $rulevalue ); + break; + } + case 'byday': { + if( isset( $rulevalue['DAY'] )) { + $str = ( isset( $rulevalue[0] )) ? $rulevalue[0] : ''; + $str .= $rulevalue['DAY']; + $p = $child->addChild( $rulelabel, $str ); + } + else { + foreach( $rulevalue as $valuePart ) { + if( isset( $valuePart['DAY'] )) { + $str = ( isset( $valuePart[0] )) ? $valuePart[0] : ''; + $str .= $valuePart['DAY']; + $p = $child->addChild( $rulelabel, $str ); + } + else + $p = $child->addChild( $rulelabel, $valuePart ); + } + } + break; + } + case 'freq': + case 'count': + case 'interval': + case 'wkst': + default: + $p = $child->addChild( $rulelabel, $rulevalue ); + break; + } // end switch( $rulelabel ) + } // end foreach( $content as $rulelabel => $rulevalue ) + break; + case 'rstatus': + $v = $child->addChild( 'code', number_format( (float) $content['statcode'], 2, '.', '')); + $v = $child->addChild( 'description', htmlspecialchars( $content['text'] )); + if( isset( $content['extdata'] )) + $v = $child->addChild( 'data', htmlspecialchars( $content['extdata'] )); + break; + case 'text': + if( !is_array( $content )) + $content = array( $content ); + foreach( $content as $part ) + $v = $child->addChild( $type, htmlspecialchars( $part )); + break; + case 'time': + break; + case 'uri': + $v = $child->addChild( $type, $content ); + break; + case 'utc-offset': + if( in_array( substr( $content, 0, 1 ), array( '-', '+' ))) { + $str = substr( $content, 0, 1 ); + $content = substr( $content, 1 ); + } + else + $str = '+'; + $str .= substr( $content, 0, 2 ).':'.substr( $content, 2, 2 ); + if( 4 < strlen( $content )) + $str .= ':'.substr( $content, 4 ); + $v = $child->addChild( $type, $str ); + break; + case 'unknown': + default: + if( is_array( $content )) + $content = implode( '', $content ); + $v = $child->addChild( 'unknown', htmlspecialchars( $content )); + break; + } +} +/** + * parse xml file into iCalcreator instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.22 - 2013-06-18 + * @param string $xmlfile + * @param array $iCalcfg iCalcreator config array (opt) + * @return mixediCalcreator instance or FALSE on error + */ +function XMLfile2iCal( $xmlfile, $iCalcfg=array()) { + if( FALSE === ( $xmlstr = file_get_contents( $xmlfile ))) + return FALSE; + return xml2iCal( $xmlstr, $iCalcfg ); +} +/** + * parse xml string into iCalcreator instance, alias of XML2iCal + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.22 - 2013-06-18 + * @param string $xmlstr + * @param array $iCalcfg iCalcreator config array (opt) + * @return mixed iCalcreator instance or FALSE on error + */ +function XMLstr2iCal( $xmlstr, $iCalcfg=array()) { + return XML2iCal( $xmlstr, $iCalcfg); +} +/** + * parse xml string into iCalcreator instance + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.22 - 2013-06-20 + * @param string $xmlstr + * @param array $iCalcfg iCalcreator config array (opt) + * @return mixed iCalcreator instance or FALSE on error + */ +function XML2iCal( $xmlstr, $iCalcfg=array()) { + $xmlstr = str_replace( array( "\r\n", "\n\r", "\n", "\r" ), '', $xmlstr ); + $xml = XMLgetTagContent1( $xmlstr, 'vcalendar', $endIx ); + $iCal = new vcalendar( $iCalcfg ); + XMLgetComps( $iCal, $xmlstr ); + unset( $xmlstr ); + return $iCal; +} +/** + * parse XML string into iCalcreator components + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.22 - 2013-06-20 + * @param object $iCal, iCalcreator vcalendar or component object instance + * @param string $xml + * @return bool + */ +function XMLgetComps( $iCal, $xml ) { + static $comps = array( 'vtimezone', 'standard', 'daylight', 'vevent', 'vtodo', 'vjournal', 'vfreebusy', 'valarm' ); + $sx = 0; + while(( FALSE !== substr( $xml, ( $sx + 11 ), 1 )) && + ( '' != substr( $xml, $sx, 12 )) && ( '' != substr( $xml, $sx, 12 ))) + $sx += 1; + if( FALSE === substr( $xml, ( $sx + 11 ), 1 )) + return FALSE; + if( '' == substr( $xml, $sx, 12 )) { + $xml2 = XMLgetTagContent1( $xml, 'properties', $endIx ); + XMLgetProps( $iCal, $xml2 ); + $xml = substr( $xml, $endIx ); + } + if( '' == substr( $xml, 0, 12 )) + $xml = XMLgetTagContent1( $xml, 'components', $endIx ); + while( ! empty( $xml )) { + $xml2 = XMLgetTagContent2( $xml, $tagName, $endIx ); + if( in_array( strtolower( $tagName ), $comps ) && ( FALSE !== ( $subComp = $iCal->newComponent( $tagName )))) + XMLgetComps( $subComp, $xml2 ); + $xml = substr( $xml, $endIx); + } + unset( $xml ); + return $iCal; +} +/** + * parse XML into iCalcreator properties + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.21 - 2013-06-23 + * @param array $iCal iCalcreator calendar/component instance + * @param string $xml + * @return void + */ +function XMLgetProps( $iCal, $xml) { + while( ! empty( $xml )) { + $xml2 = XMLgetTagContent2( $xml, $propName, $endIx ); + $propName = strtoupper( $propName ); + if( empty( $xml2 ) && ( '0' != $xml2 )) { + $iCal->setProperty( $propName ); + $xml = substr( $xml, $endIx); + continue; + } + $params = array(); + if( '' == substr( $xml2, 0, 13 )) + $xml2 = substr( $xml2, 13 ); + elseif( '' == substr( $xml2, 0, 12 )) { + $xml3 = XMLgetTagContent1( $xml2, 'parameters', $endIx2 ); + while( ! empty( $xml3 )) { + $xml4 = XMLgetTagContent2( $xml3, $paramKey, $endIx3 ); + $pType = FALSE; // skip parameter valueType + $paramKey = strtoupper( $paramKey ); + if( in_array( $paramKey, array( 'DELEGATED-FROM', 'DELEGATED-TO', 'MEMBER' ))) { + while( ! empty( $xml4 )) { + if( ! isset( $params[$paramKey] )) + $params[$paramKey] = array( XMLgetTagContent1( $xml4, 'cal-address', $endIx4 )); + else + $params[$paramKey][] = XMLgetTagContent1( $xml4, 'cal-address', $endIx4 ); + $xml4 = substr( $xml4, $endIx4 ); + } + } + else { + if( ! isset( $params[$paramKey] )) + $params[$paramKey] = html_entity_decode( XMLgetTagContent2( $xml4, $pType, $endIx4 )); + else + $params[$paramKey] .= ','.html_entity_decode( XMLgetTagContent2( $xml4, $pType, $endIx4 )); + } + $xml3 = substr( $xml3, $endIx3 ); + } + $xml2 = substr( $xml2, $endIx2 ); + } // if( '' == substr( $xml2, 0, 12 )) + $valueType = FALSE; + $value = ( ! empty( $xml2 ) || ( '0' == $xml2 )) ? XMLgetTagContent2( $xml2, $valueType, $endIx3 ) : ''; + switch( $propName ) { + case 'CATEGORIES': + case 'RESOURCES': + $tValue = array(); + while( ! empty( $xml2 )) { + $tValue[] = html_entity_decode( XMLgetTagContent2( $xml2, $valueType, $endIx4 )); + $xml2 = substr( $xml2, $endIx4 ); + } + $value = $tValue; + break; + case 'EXDATE': // multiple single-date(-times) may exist + case 'RDATE': + if( 'period' != $valueType ) { + if( 'date' == $valueType ) + $params['VALUE'] = 'DATE'; + $t = array(); + while( ! empty( $xml2 ) && ( '' == substr( $xml2, 0, 8 ))) { + $xml3 = XMLgetTagContent1( $xml2, 'period', $endIx4 ); // period + $t = array(); + while( ! empty( $xml3 )) { + $t[] = XMLgetTagContent2( $xml3, $pType, $endIx5 ); // start - end/duration + $xml3 = substr( $xml3, $endIx5 ); + } + $value[] = $t; + $xml2 = substr( $xml2, $endIx4 ); + } + break; + case 'TZOFFSETTO': + case 'TZOFFSETFROM': + $value = str_replace( ':', '', $value ); + break; + case 'GEO': + $tValue = array( 'latitude' => $value ); + $tValue['longitude'] = XMLgetTagContent1( substr( $xml2, $endIx3 ), 'longitude', $endIx3 ); + $value = $tValue; + break; + case 'EXRULE': + case 'RRULE': + $tValue = array( $valueType => $value ); + $xml2 = substr( $xml2, $endIx3 ); + $valueType = FALSE; + while( ! empty( $xml2 )) { + $t = XMLgetTagContent2( $xml2, $valueType, $endIx4 ); + switch( $valueType ) { + case 'freq': + case 'count': + case 'until': + case 'interval': + case 'wkst': + $tValue[$valueType] = $t; + break; + case 'byday': + if( 2 == strlen( $t )) + $tValue[$valueType][] = array( 'DAY' => $t ); + else { + $day = substr( $t, -2 ); + $key = substr( $t, 0, ( strlen( $t ) - 2 )); + $tValue[$valueType][] = array( $key, 'DAY' => $day ); + } + break; + default: + $tValue[$valueType][] = $t; + } + $xml2 = substr( $xml2, $endIx4 ); + } + $value = $tValue; + break; + case 'REQUEST-STATUS': + $tValue = array(); + while( ! empty( $xml2 )) { + $t = html_entity_decode( XMLgetTagContent2( $xml2, $valueType, $endIx4 )); + $tValue[$valueType] = $t; + $xml2 = substr( $xml2, $endIx4 ); + } + if( ! empty( $tValue )) + $value = $tValue; + else + $value = array( 'code' => null, 'description' => null ); + break; + default: + switch( $valueType ) { + case 'binary': $params['VALUE'] = 'BINARY'; break; + case 'date': $params['VALUE'] = 'DATE'; break; + case 'date-time': $params['VALUE'] = 'DATE-TIME'; break; + case 'text': + case 'unknown': $value = html_entity_decode( $value ); break; + } + break; + } // end switch( $propName ) + if( 'FREEBUSY' == $propName ) { + $fbtype = $params['FBTYPE']; + unset( $params['FBTYPE'] ); + $iCal->setProperty( $propName, $fbtype, $value, $params ); + } + elseif( 'GEO' == $propName ) + $iCal->setProperty( $propName, $value['latitude'], $value['longitude'], $params ); + elseif( 'REQUEST-STATUS' == $propName ) { + if( !isset( $value['data'] )) + $value['data'] = FALSE; + $iCal->setProperty( $propName, $value['code'], $value['description'], $value['data'], $params ); + } + else { + if( empty( $value ) && ( is_array( $value ) || ( '0' > $value ))) + $value = ''; + $iCal->setProperty( $propName, $value, $params ); + } + $xml = substr( $xml, $endIx); + } // end while( ! empty( $xml )) +} +/** + * fetch a specific XML tag content + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.22 - 2013-06-20 + * @param string $xml + * @param string $tagName + * @param int $endIx + * @return mixed + */ +function XMLgetTagContent1( $xml, $tagName, & $endIx=0 ) { + $strlen = strlen( $tagName ); + $sx1 = 0; + while( FALSE !== substr( $xml, $sx1, 1 )) { + if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 1 ), 1 )) && + ( strtolower( "<$tagName>" ) == strtolower( substr( $xml, $sx1, ( $strlen + 2 ))))) + break; + if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 3 ), 1 )) && + ( strtolower( "<$tagName />" ) == strtolower( substr( $xml, $sx1, ( $strlen + 4 ))))) { // empty tag + $endIx = $strlen + 5; + return ''; + } + if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 2 ), 1 )) && + ( strtolower( "<$tagName/>" ) == strtolower( substr( $xml, $sx1, ( $strlen + 3 ))))) { // empty tag + $endIx = $strlen + 4; + return ''; + } + $sx1 += 1; + } + if( FALSE === substr( $xml, $sx1, 1 )) { + $endIx = ( empty( $sx )) ? 0 : $sx - 1; + return ''; + } + if( FALSE === ( $pos = stripos( $xml, "" ))) { // missing end tag?? + $endIx = strlen( $xml ) + 1; + return ''; + } + $endIx = $pos + $strlen + 3; + return substr( $xml, ( $sx1 + $strlen + 2 ), ( $pos - $sx1 - 2 - $strlen )); +} +/** + * fetch next (unknown) XML tagname AND content + * + * @author Kjell-Inge Gustafsson, kigkonsult + * @since 2.16.22 - 2013-06-20 + * @param string $xml + * @param string $tagName + * @param int $endIx + * @return mixed + */ +function XMLgetTagContent2( $xml, & $tagName, & $endIx ) { + $endIx = strlen( $xml ) + 1; // just in case.. . + $sx1 = 0; + while( FALSE !== substr( $xml, $sx1, 1 )) { + if( '<' == substr( $xml, $sx1, 1 )) { + if(( FALSE !== substr( $xml, ( $sx1 + 3 ), 1 )) && ( ' + + +*/ + +(function() { + function addIcon(el, entity) { + var html = el.innerHTML; + el.innerHTML = '' + entity + '' + html; + } + var icons = { + 'iCicon-header-before': '', + 'iCicon-header-after': '', + 'iCicon-iclogo': '', + 'iCicon-thumbs': '', + 'iCicon-form': '', + 'iCicon-location': '', + 'iCicon-clock': '', + 'iCicon-calendar': '', + 'iCicon-calendar-2': '', + 'iCicon-print': '', + 'iCicon-disk': '', + 'iCicon-reset': '', + 'iCicon-people': '', + 'iCicon-search': '', + 'iCicon-private': '', + 'iCicon-options': '', + 'iCicon-register': '', + 'iCicon-timezone': '', + 'iCicon-earth': '', + 'iCicon-blocked': '', + 'iCicon-nextic': '▶', + 'iCicon-backic': '◀', + 'iCicon-backicY': '◁', + 'iCicon-nexticY': '▷', + 'iCicon-filter': '', + 'iCicon-filter-2': '', + 'iCicon-screen': '', + 'iCicon-minus': '', + 'iCicon-info': '', + 'iCicon-info-circle': '', + 'iCicon-icons': '', + 'iCicon-navigation': '', + 'iCicon-arrow-down': '', + 'iCicon-arrow-up': '', + '0': 0 + }, + els = document.getElementsByTagName('*'), + i, c, el; + for (i = 0; ; i += 1) { + el = els[i]; + if(!el) { + break; + } + c = el.className; + c = c.match(/iCicon-[^\s'"]+/); + if (c && icons[c[0]]) { + addIcon(el, icons[c[0]]); + } + } +}()); diff --git a/deployed/icagenda/media/com_icagenda/icicons/index.html b/deployed/icagenda/media/com_icagenda/icicons/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/icicons/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/icicons/style.css b/deployed/icagenda/media/com_icagenda/icicons/style.css new file mode 100644 index 00000000..1ca3390f --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/icicons/style.css @@ -0,0 +1,215 @@ +/** + *------------------------------------------------------------------------------ + * iCicons font by Jooml!C + *------------------------------------------------------------------------------ + * @copyright Copyright (c)2012-2019 Cyril Rezé, Jooml!C - All rights reserved + * + * @license GNU General Public License version 3 or later; see LICENSE.txt + * @author Cyril Rezé (Lyr!C) + * @link https://www.joomlic.com + * + * @version 3.7.0 2018-05-24 + * @since 3.2.2 + *------------------------------------------------------------------------------ +*/ + +@font-face { + font-family: 'iCicons'; + src: url('fonts/iCicons.eot?3kxpik'); + src: url('fonts/iCicons.eot?3kxpik#iefix') format('embedded-opentype'), + url('fonts/iCicons.ttf?3kxpik') format('truetype'), + url('fonts/iCicons.woff?3kxpik') format('woff'), + url('fonts/iCicons.svg?3kxpik#iCicons') format('svg'); + font-weight: normal; + font-style: normal; +} +[data-icon]:before { + font-family: 'iCicons'; + content: attr(data-icon); + speak: none; +} +[class^="iCicon-"], [class*=" iCicon-"] { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'iCicons' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +[class^="iCicon-"]:before, +[class*=" iCicon-"]:before { + font-family: 'iCicons' !important; /* !important to fix conflict with some templates font icons */ + font-style: normal; + speak: none; +} +[class^="iCicon-"].disabled, +[class*=" iCicon-"].disabled { + font-weight: normal; +} + +.iCicon-nextic:before { + content: "\25b6"; +} +.iCicon-nexticY:before { + content: "\25b7"; +} +.iCicon-backic:before { + content: "\25c0"; +} +.iCicon-backicY:before { + content: "\25c1"; +} +.iCicon-earth:before { + content: "\e600"; +} +.iCicon-timezone:before { + content: "\e601"; +} +.iCicon-print:before { + content: "\e602"; +} +.iCicon-calendar-2:before { + content: "\e603"; +} +.iCicon-calendar:before { + content: "\e604"; +} +.iCicon-location:before { + content: "\e605"; +} +.iCicon-iclogo:before { + content: "\e606"; +} +.iCicon-disk:before { + content: "\e607"; +} +.iCicon-private:before { + content: "\e608"; +} +.iCicon-register:before { + content: "\e609"; +} +.iCicon-blocked:before { + content: "\e60a"; +} +.iCicon-people:before { + content: "\e60b"; +} +.iCicon-thumbs:before { + content: "\e60c"; +} +.iCicon-clock:before { + content: "\e60d"; +} +.iCicon-screen:before { + content: "\e60e"; +} +.iCicon-options:before { + content: "\e60f"; +} +.iCicon-icons:before { + content: "\e610"; +} +.iCicon-filter:before { + content: "\e611"; +} +.iCicon-minus:before { + content: "\e612"; +} +.iCicon-info:before { + content: "\e613"; +} +.iCicon-info-circle:before { + content: "\e614"; +} +.iCicon-navigation:before { + content: "\e615"; +} +.iCicon-form:before { + content: "\e616"; +} +.iCicon-header-after:before { + content: "\e617"; +} +.iCicon-header-before:before { + content: "\e618"; +} +.iCicon-reset:before { + content: "\e900"; +} +.iCicon-search:before { + content: "\e901"; +} +.iCicon-filter-2:before { + content: "\e902"; +} +.iCicon-arrow-down:before { + content: "\e903"; +} +.iCicon-arrow-up:before { + content: "\e904"; +} +.iCicon-eye:before { + content: "\e905"; +} +.iCicon-eye-close:before { + content: "\e906"; +} +.iCicon-avatar:before { + content: "\e907"; +} + +/* Multiple icons */ +.iCicon-eyes-1:before { + content: "\e905\e905\e905"; + vertical-align: middle; + letter-spacing: 4px; +} +.iCicon-eyes-2:before { + content: "\e906\e905\e905"; + vertical-align: middle; + letter-spacing: 4px; +} +.iCicon-eyes-3:before { + content: "\e906\e906\e905"; + vertical-align: middle; + letter-spacing: 4px; +} +.iCicon-eyes-4:before { + content: "\e906\e906\e906"; + vertical-align: middle; + letter-spacing: 4px; +} + +/* BI-COLOR ICONS */ +.iCicon-bi-color-header:before { + content: "\e618"; + letter-spacing: -1em; + color: #bebebe; +} +.iCicon-bi-color-header:after { + content: "\e617"; + color: #ca0000; +} + +/* ONE-COLOR ICONS */ +.iCicon-iclogo:before { + content: "\e606"; + color: #990000; +} + +/* ADDITIONAL STYLES */ +.iCicon-info-circle:active, +.iCicon-info-circle:hover, +.iCicon-info-circle:focus { + text-decoration: none !important; + background: none; + text-shadow:0px 0px 5px rgba(0,0,0,0.3);; + cursor: help; +} diff --git a/deployed/icagenda/media/com_icagenda/images/addthis_16.png b/deployed/icagenda/media/com_icagenda/images/addthis_16.png new file mode 100644 index 00000000..00b24676 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/addthis_16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/addthis_16x16.png b/deployed/icagenda/media/com_icagenda/images/addthis_16x16.png new file mode 100644 index 00000000..10970c03 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/addthis_16x16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/addthis_32x32.png b/deployed/icagenda/media/com_icagenda/images/addthis_32x32.png new file mode 100644 index 00000000..c139c7d6 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/addthis_32x32.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/all_cats-16.png b/deployed/icagenda/media/com_icagenda/images/all_cats-16.png new file mode 100644 index 00000000..1f771d35 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/all_cats-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/all_cats-48.png b/deployed/icagenda/media/com_icagenda/images/all_cats-48.png new file mode 100644 index 00000000..714ab06c Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/all_cats-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/all_events-16.png b/deployed/icagenda/media/com_icagenda/images/all_events-16.png new file mode 100644 index 00000000..ad493be2 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/all_events-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/all_events-48.png b/deployed/icagenda/media/com_icagenda/images/all_events-48.png new file mode 100644 index 00000000..20a39c97 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/all_events-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/blanck.png b/deployed/icagenda/media/com_icagenda/images/blanck.png new file mode 100644 index 00000000..aa06dfeb Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/blanck.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/border_title.png b/deployed/icagenda/media/com_icagenda/images/border_title.png new file mode 100644 index 00000000..78150d69 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/border_title.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/btn-regis.png b/deployed/icagenda/media/com_icagenda/images/btn-regis.png new file mode 100644 index 00000000..c86dd178 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/btn-regis.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/apple_ical-16.png b/deployed/icagenda/media/com_icagenda/images/cal/apple_ical-16.png new file mode 100644 index 00000000..d21d4103 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/apple_ical-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/apple_ical-24.png b/deployed/icagenda/media/com_icagenda/images/cal/apple_ical-24.png new file mode 100644 index 00000000..4792f407 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/apple_ical-24.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/apple_ical-32.png b/deployed/icagenda/media/com_icagenda/images/cal/apple_ical-32.png new file mode 100644 index 00000000..4232975b Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/apple_ical-32.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/google_cal-16.png b/deployed/icagenda/media/com_icagenda/images/cal/google_cal-16.png new file mode 100644 index 00000000..43089890 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/google_cal-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/google_cal-24.png b/deployed/icagenda/media/com_icagenda/images/cal/google_cal-24.png new file mode 100644 index 00000000..b26585ac Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/google_cal-24.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/google_cal-32.png b/deployed/icagenda/media/com_icagenda/images/cal/google_cal-32.png new file mode 100644 index 00000000..eafeaf45 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/google_cal-32.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/index.html b/deployed/icagenda/media/com_icagenda/images/cal/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/images/cal/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/images/cal/outlook_cal-16.png b/deployed/icagenda/media/com_icagenda/images/cal/outlook_cal-16.png new file mode 100644 index 00000000..88d250cf Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/outlook_cal-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/outlook_cal-24.png b/deployed/icagenda/media/com_icagenda/images/cal/outlook_cal-24.png new file mode 100644 index 00000000..c62ff94d Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/outlook_cal-24.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/outlook_cal-32.png b/deployed/icagenda/media/com_icagenda/images/cal/outlook_cal-32.png new file mode 100644 index 00000000..35cbc7e1 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/outlook_cal-32.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/windows-live_cal-16.png b/deployed/icagenda/media/com_icagenda/images/cal/windows-live_cal-16.png new file mode 100644 index 00000000..8833c23b Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/windows-live_cal-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/windows-live_cal-24.png b/deployed/icagenda/media/com_icagenda/images/cal/windows-live_cal-24.png new file mode 100644 index 00000000..9bedb218 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/windows-live_cal-24.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/windows-live_cal-32.png b/deployed/icagenda/media/com_icagenda/images/cal/windows-live_cal-32.png new file mode 100644 index 00000000..56e2f7ba Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/windows-live_cal-32.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/yahoo_cal-16.png b/deployed/icagenda/media/com_icagenda/images/cal/yahoo_cal-16.png new file mode 100644 index 00000000..caad396a Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/yahoo_cal-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/yahoo_cal-24.png b/deployed/icagenda/media/com_icagenda/images/cal/yahoo_cal-24.png new file mode 100644 index 00000000..961a6058 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/yahoo_cal-24.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/cal/yahoo_cal-32.png b/deployed/icagenda/media/com_icagenda/images/cal/yahoo_cal-32.png new file mode 100644 index 00000000..0fd861d1 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/cal/yahoo_cal-32.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/customfields-16.png b/deployed/icagenda/media/com_icagenda/images/customfields-16.png new file mode 100644 index 00000000..8213f010 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/customfields-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/customfields-48.png b/deployed/icagenda/media/com_icagenda/images/customfields-48.png new file mode 100644 index 00000000..5e59074b Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/customfields-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/features-16.png b/deployed/icagenda/media/com_icagenda/images/features-16.png new file mode 100644 index 00000000..2e034043 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/features-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/features-48.png b/deployed/icagenda/media/com_icagenda/images/features-48.png new file mode 100644 index 00000000..2d0ac40e Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/features-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/generic-48.png b/deployed/icagenda/media/com_icagenda/images/generic-48.png new file mode 100644 index 00000000..8995374e Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/generic-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/global_options-48.png b/deployed/icagenda/media/com_icagenda/images/global_options-48.png new file mode 100644 index 00000000..8995374e Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/global_options-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/icon-add-16.png b/deployed/icagenda/media/com_icagenda/images/icon-add-16.png new file mode 100644 index 00000000..adf14cf7 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/icon-add-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/icon-edit.png b/deployed/icagenda/media/com_icagenda/images/icon-edit.png new file mode 100644 index 00000000..cd2a58ef Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/icon-edit.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/icon_all-events.png b/deployed/icagenda/media/com_icagenda/images/icon_all-events.png new file mode 100644 index 00000000..20a39c97 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/icon_all-events.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/iconevent-add48.png b/deployed/icagenda/media/com_icagenda/images/iconevent-add48.png new file mode 100644 index 00000000..c6f86e94 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/iconevent-add48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/iconevent48.png b/deployed/icagenda/media/com_icagenda/images/iconevent48.png new file mode 100644 index 00000000..20a39c97 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/iconevent48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/iconicagenda16.png b/deployed/icagenda/media/com_icagenda/images/iconicagenda16.png new file mode 100644 index 00000000..a0aa5394 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/iconicagenda16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/iconicagenda16_agenda.png b/deployed/icagenda/media/com_icagenda/images/iconicagenda16_agenda.png new file mode 100644 index 00000000..bca66642 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/iconicagenda16_agenda.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/iconicagenda36.png b/deployed/icagenda/media/com_icagenda/images/iconicagenda36.png new file mode 100644 index 00000000..13924c13 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/iconicagenda36.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/iconicagenda48.png b/deployed/icagenda/media/com_icagenda/images/iconicagenda48.png new file mode 100644 index 00000000..13074f13 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/iconicagenda48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/image.png b/deployed/icagenda/media/com_icagenda/images/image.png new file mode 100644 index 00000000..0a1f8291 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/image.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/index.html b/deployed/icagenda/media/com_icagenda/images/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/images/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/images/info-16.png b/deployed/icagenda/media/com_icagenda/images/info-16.png new file mode 100644 index 00000000..cb6b2f02 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/info-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/info-48.png b/deployed/icagenda/media/com_icagenda/images/info-48.png new file mode 100644 index 00000000..cee5dbe7 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/info-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/info.png b/deployed/icagenda/media/com_icagenda/images/info.png new file mode 100644 index 00000000..41e1a5be Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/info.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/joomlic_iCagenda.png b/deployed/icagenda/media/com_icagenda/images/joomlic_iCagenda.png new file mode 100644 index 00000000..1c8c7d60 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/joomlic_iCagenda.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/loader.gif b/deployed/icagenda/media/com_icagenda/images/loader.gif new file mode 100644 index 00000000..294e8e41 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/loader.gif differ diff --git a/deployed/icagenda/media/com_icagenda/images/logo_icagenda.png b/deployed/icagenda/media/com_icagenda/images/logo_icagenda.png new file mode 100644 index 00000000..ac55080a Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/logo_icagenda.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/logo_joomlic.png b/deployed/icagenda/media/com_icagenda/images/logo_joomlic.png new file mode 100644 index 00000000..5650bdbf Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/logo_joomlic.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/manager/approval_16.png b/deployed/icagenda/media/com_icagenda/images/manager/approval_16.png new file mode 100644 index 00000000..08a83aeb Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/manager/approval_16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/manager/index.html b/deployed/icagenda/media/com_icagenda/images/manager/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/images/manager/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/images/new_cat-16.png b/deployed/icagenda/media/com_icagenda/images/new_cat-16.png new file mode 100644 index 00000000..c0c3d0ec Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/new_cat-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/new_cat-48.png b/deployed/icagenda/media/com_icagenda/images/new_cat-48.png new file mode 100644 index 00000000..eb85e1a4 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/new_cat-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/new_event-16.png b/deployed/icagenda/media/com_icagenda/images/new_event-16.png new file mode 100644 index 00000000..746c01f5 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/new_event-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/new_event-48.png b/deployed/icagenda/media/com_icagenda/images/new_event-48.png new file mode 100644 index 00000000..bdead8f0 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/new_event-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/newsletter-16.png b/deployed/icagenda/media/com_icagenda/images/newsletter-16.png new file mode 100644 index 00000000..8dd73fa1 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/newsletter-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/newsletter-48.png b/deployed/icagenda/media/com_icagenda/images/newsletter-48.png new file mode 100644 index 00000000..94125162 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/newsletter-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/no-photo.jpg b/deployed/icagenda/media/com_icagenda/images/no-photo.jpg new file mode 100644 index 00000000..f2b2342e Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/no-photo.jpg differ diff --git a/deployed/icagenda/media/com_icagenda/images/nophoto.jpg b/deployed/icagenda/media/com_icagenda/images/nophoto.jpg new file mode 100644 index 00000000..d99a4f38 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/nophoto.jpg differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/all_cats-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/all_cats-48.png new file mode 100644 index 00000000..a9c4b19c Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/all_cats-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/all_events-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/all_events-48.png new file mode 100644 index 00000000..b7932dbb Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/all_events-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/customfields-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/customfields-48.png new file mode 100644 index 00000000..f3a646df Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/customfields-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/features-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/features-48.png new file mode 100644 index 00000000..f0004bca Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/features-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/global_options-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/global_options-48.png new file mode 100644 index 00000000..23acf549 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/global_options-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/index.html b/deployed/icagenda/media/com_icagenda/images/panel_denied/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/images/panel_denied/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/info-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/info-48.png new file mode 100644 index 00000000..01e5ffef Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/info-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/new_cat-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/new_cat-48.png new file mode 100644 index 00000000..bbe54f29 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/new_cat-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/new_event-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/new_event-48.png new file mode 100644 index 00000000..d187859e Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/new_event-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/newsletter-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/newsletter-48.png new file mode 100644 index 00000000..48810155 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/newsletter-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/registration-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/registration-48.png new file mode 100644 index 00000000..a5be9287 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/registration-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/panel_denied/themes-48.png b/deployed/icagenda/media/com_icagenda/images/panel_denied/themes-48.png new file mode 100644 index 00000000..a1faa8a2 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/panel_denied/themes-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/payment/icon_cca.gif b/deployed/icagenda/media/com_icagenda/images/payment/icon_cca.gif new file mode 100644 index 00000000..2b29e742 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/payment/icon_cca.gif differ diff --git a/deployed/icagenda/media/com_icagenda/images/payment/icon_chk.gif b/deployed/icagenda/media/com_icagenda/images/payment/icon_chk.gif new file mode 100644 index 00000000..5863a22b Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/payment/icon_chk.gif differ diff --git a/deployed/icagenda/media/com_icagenda/images/payment/icon_pal.gif b/deployed/icagenda/media/com_icagenda/images/payment/icon_pal.gif new file mode 100644 index 00000000..358c0b32 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/payment/icon_pal.gif differ diff --git a/deployed/icagenda/media/com_icagenda/images/payment/icon_wtr.gif b/deployed/icagenda/media/com_icagenda/images/payment/icon_wtr.gif new file mode 100644 index 00000000..1fcabccb Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/payment/icon_wtr.gif differ diff --git a/deployed/icagenda/media/com_icagenda/images/payment/index.html b/deployed/icagenda/media/com_icagenda/images/payment/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/images/payment/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/images/photo.jpg b/deployed/icagenda/media/com_icagenda/images/photo.jpg new file mode 100644 index 00000000..36194c57 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/photo.jpg differ diff --git a/deployed/icagenda/media/com_icagenda/images/registration-16.png b/deployed/icagenda/media/com_icagenda/images/registration-16.png new file mode 100644 index 00000000..3f34a605 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/registration-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/registration-48.png b/deployed/icagenda/media/com_icagenda/images/registration-48.png new file mode 100644 index 00000000..6c73d735 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/registration-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/shadow.png b/deployed/icagenda/media/com_icagenda/images/shadow.png new file mode 100644 index 00000000..d8dcdf0f Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/shadow.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/technical_requirements-16.png b/deployed/icagenda/media/com_icagenda/images/technical_requirements-16.png new file mode 100644 index 00000000..bca2c6b0 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/technical_requirements-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/themes-16.png b/deployed/icagenda/media/com_icagenda/images/themes-16.png new file mode 100644 index 00000000..6e6e8521 Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/themes-16.png differ diff --git a/deployed/icagenda/media/com_icagenda/images/themes-48.png b/deployed/icagenda/media/com_icagenda/images/themes-48.png new file mode 100644 index 00000000..1be785ba Binary files /dev/null and b/deployed/icagenda/media/com_icagenda/images/themes-48.png differ diff --git a/deployed/icagenda/media/com_icagenda/index.html b/deployed/icagenda/media/com_icagenda/index.html new file mode 100644 index 00000000..fa6d84e8 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/js/Chart.js b/deployed/icagenda/media/com_icagenda/js/Chart.js new file mode 100644 index 00000000..c264262b --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/Chart.js @@ -0,0 +1,3477 @@ +/*! + * Chart.js + * http://chartjs.org/ + * Version: 1.0.2 + * + * Copyright 2015 Nick Downie + * Released under the MIT license + * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md + */ + + +(function(){ + + "use strict"; + + //Declare root variable - window in the browser, global on the server + var root = this, + previous = root.Chart; + + //Occupy the global variable of Chart, and create a simple base class + var Chart = function(context){ + var chart = this; + this.canvas = context.canvas; + + this.ctx = context; + + //Variables global to the chart + var computeDimension = function(element,dimension) + { + if (element['offset'+dimension]) + { + return element['offset'+dimension]; + } + else + { + return document.defaultView.getComputedStyle(element).getPropertyValue(dimension); + } + } + + var width = this.width = computeDimension(context.canvas,'Width'); + var height = this.height = computeDimension(context.canvas,'Height'); + + // Firefox requires this to work correctly + context.canvas.width = width; + context.canvas.height = height; + + var width = this.width = context.canvas.width; + var height = this.height = context.canvas.height; + this.aspectRatio = this.width / this.height; + //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale. + helpers.retinaScale(this); + + return this; + }; + //Globally expose the defaults to allow for user updating/changing + Chart.defaults = { + global: { + // Boolean - Whether to animate the chart + animation: true, + + // Number - Number of animation steps + animationSteps: 60, + + // String - Animation easing effect + animationEasing: "easeOutQuart", + + // Boolean - If we should show the scale at all + showScale: true, + + // Boolean - If we want to override with a hard coded scale + scaleOverride: false, + + // ** Required if scaleOverride is true ** + // Number - The number of steps in a hard coded scale + scaleSteps: null, + // Number - The value jump in the hard coded scale + scaleStepWidth: null, + // Number - The scale starting value + scaleStartValue: null, + + // String - Colour of the scale line + scaleLineColor: "rgba(0,0,0,.1)", + + // Number - Pixel width of the scale line + scaleLineWidth: 1, + + // Boolean - Whether to show labels on the scale + scaleShowLabels: true, + + // Interpolated JS string - can access value + scaleLabel: "<%=value%>", + + // Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there + scaleIntegersOnly: true, + + // Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value + scaleBeginAtZero: false, + + // String - Scale label font declaration for the scale label + scaleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + + // Number - Scale label font size in pixels + scaleFontSize: 12, + + // String - Scale label font weight style + scaleFontStyle: "normal", + + // String - Scale label font colour + scaleFontColor: "#666", + + // Boolean - whether or not the chart should be responsive and resize when the browser does. + responsive: false, + + // Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container + maintainAspectRatio: true, + + // Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove + showTooltips: true, + + // Boolean - Determines whether to draw built-in tooltip or call custom tooltip function + customTooltips: false, + + // Array - Array of string names to attach tooltip events + tooltipEvents: ["mousemove", "touchstart", "touchmove", "mouseout"], + + // String - Tooltip background colour + tooltipFillColor: "rgba(0,0,0,0.8)", + + // String - Tooltip label font declaration for the scale label + tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + + // Number - Tooltip label font size in pixels + tooltipFontSize: 14, + + // String - Tooltip font weight style + tooltipFontStyle: "normal", + + // String - Tooltip label font colour + tooltipFontColor: "#fff", + + // String - Tooltip title font declaration for the scale label + tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + + // Number - Tooltip title font size in pixels + tooltipTitleFontSize: 14, + + // String - Tooltip title font weight style + tooltipTitleFontStyle: "bold", + + // String - Tooltip title font colour + tooltipTitleFontColor: "#fff", + + // Number - pixel width of padding around tooltip text + tooltipYPadding: 6, + + // Number - pixel width of padding around tooltip text + tooltipXPadding: 6, + + // Number - Size of the caret on the tooltip + tooltipCaretSize: 8, + + // Number - Pixel radius of the tooltip border + tooltipCornerRadius: 6, + + // Number - Pixel offset from point x to tooltip edge + tooltipXOffset: 10, + + // String - Template string for single tooltips + tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>", + + // String - Template string for single tooltips + multiTooltipTemplate: "<%= value %>", + + // String - Colour behind the legend colour block + multiTooltipKeyBackground: '#fff', + + // Function - Will fire on animation progression. + onAnimationProgress: function(){}, + + // Function - Will fire on animation completion. + onAnimationComplete: function(){} + + } + }; + + //Create a dictionary of chart types, to allow for extension of existing types + Chart.types = {}; + + //Global Chart helpers object for utility methods and classes + var helpers = Chart.helpers = {}; + + //-- Basic js utility methods + var each = helpers.each = function(loopable,callback,self){ + var additionalArgs = Array.prototype.slice.call(arguments, 3); + // Check to see if null or undefined firstly. + if (loopable){ + if (loopable.length === +loopable.length){ + var i; + for (i=0; i= 0; i--) { + var currentItem = arrayToSearch[i]; + if (filterCallback(currentItem)){ + return currentItem; + } + } + }, + inherits = helpers.inherits = function(extensions){ + //Basic javascript inheritance based on the model created in Backbone.js + var parent = this; + var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function(){ return parent.apply(this, arguments); }; + + var Surrogate = function(){ this.constructor = ChartElement;}; + Surrogate.prototype = parent.prototype; + ChartElement.prototype = new Surrogate(); + + ChartElement.extend = inherits; + + if (extensions) extend(ChartElement.prototype, extensions); + + ChartElement.__super__ = parent.prototype; + + return ChartElement; + }, + noop = helpers.noop = function(){}, + uid = helpers.uid = (function(){ + var id=0; + return function(){ + return "chart-" + id++; + }; + })(), + warn = helpers.warn = function(str){ + //Method for warning of errors + if (window.console && typeof window.console.warn == "function") console.warn(str); + }, + amd = helpers.amd = (typeof define == 'function' && define.amd), + //-- Math methods + isNumber = helpers.isNumber = function(n){ + return !isNaN(parseFloat(n)) && isFinite(n); + }, + max = helpers.max = function(array){ + return Math.max.apply( Math, array ); + }, + min = helpers.min = function(array){ + return Math.min.apply( Math, array ); + }, + cap = helpers.cap = function(valueToCap,maxValue,minValue){ + if(isNumber(maxValue)) { + if( valueToCap > maxValue ) { + return maxValue; + } + } + else if(isNumber(minValue)){ + if ( valueToCap < minValue ){ + return minValue; + } + } + return valueToCap; + }, + getDecimalPlaces = helpers.getDecimalPlaces = function(num){ + if (num%1!==0 && isNumber(num)){ + return num.toString().split(".")[1].length; + } + else { + return 0; + } + }, + toRadians = helpers.radians = function(degrees){ + return degrees * (Math.PI/180); + }, + // Gets the angle from vertical upright to the point about a centre. + getAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint){ + var distanceFromXCenter = anglePoint.x - centrePoint.x, + distanceFromYCenter = anglePoint.y - centrePoint.y, + radialDistanceFromCenter = Math.sqrt( distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); + + + var angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter); + + //If the segment is in the top left quadrant, we need to add another rotation to the angle + if (distanceFromXCenter < 0 && distanceFromYCenter < 0){ + angle += Math.PI*2; + } + + return { + angle: angle, + distance: radialDistanceFromCenter + }; + }, + aliasPixel = helpers.aliasPixel = function(pixelWidth){ + return (pixelWidth % 2 === 0) ? 0 : 0.5; + }, + splineCurve = helpers.splineCurve = function(FirstPoint,MiddlePoint,AfterPoint,t){ + //Props to Rob Spencer at scaled innovation for his post on splining between points + //http://scaledinnovation.com/analytics/splines/aboutSplines.html + var d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)), + d12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)), + fa=t*d01/(d01+d12),// scaling factor for triangle Ta + fb=t*d12/(d01+d12); + return { + inner : { + x : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x), + y : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y) + }, + outer : { + x: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x), + y : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y) + } + }; + }, + calculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val){ + return Math.floor(Math.log(val) / Math.LN10); + }, + calculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly){ + + //Set a minimum step of two - a point at the top of the graph, and a point at the base + var minSteps = 2, + maxSteps = Math.floor(drawingSize/(textSize * 1.5)), + skipFitting = (minSteps >= maxSteps); + + var maxValue = max(valuesArray), + minValue = min(valuesArray); + + // We need some degree of seperation here to calculate the scales if all the values are the same + // Adding/minusing 0.5 will give us a range of 1. + if (maxValue === minValue){ + maxValue += 0.5; + // So we don't end up with a graph with a negative start value if we've said always start from zero + if (minValue >= 0.5 && !startFromZero){ + minValue -= 0.5; + } + else{ + // Make up a whole number above the values + maxValue += 0.5; + } + } + + var valueRange = Math.abs(maxValue - minValue), + rangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange), + graphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude), + graphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude), + graphRange = graphMax - graphMin, + stepValue = Math.pow(10, rangeOrderOfMagnitude), + numberOfSteps = Math.round(graphRange / stepValue); + + //If we have more space on the graph we'll use it to give more definition to the data + while((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) { + if(numberOfSteps > maxSteps){ + stepValue *=2; + numberOfSteps = Math.round(graphRange/stepValue); + // Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps. + if (numberOfSteps % 1 !== 0){ + skipFitting = true; + } + } + //We can fit in double the amount of scale points on the scale + else{ + //If user has declared ints only, and the step value isn't a decimal + if (integersOnly && rangeOrderOfMagnitude >= 0){ + //If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float + if(stepValue/2 % 1 === 0){ + stepValue /=2; + numberOfSteps = Math.round(graphRange/stepValue); + } + //If it would make it a float break out of the loop + else{ + break; + } + } + //If the scale doesn't have to be an int, make the scale more granular anyway. + else{ + stepValue /=2; + numberOfSteps = Math.round(graphRange/stepValue); + } + + } + } + + if (skipFitting){ + numberOfSteps = minSteps; + stepValue = graphRange / numberOfSteps; + } + + return { + steps : numberOfSteps, + stepValue : stepValue, + min : graphMin, + max : graphMin + (numberOfSteps * stepValue) + }; + + }, + /* jshint ignore:start */ + // Blows up jshint errors based on the new Function constructor + //Templating methods + //Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/ + template = helpers.template = function(templateString, valuesObject){ + + // If templateString is function rather than string-template - call the function for valuesObject + + if(templateString instanceof Function){ + return templateString(valuesObject); + } + + var cache = {}; + function tmpl(str, data){ + // Figure out if we're getting a template, or if we need to + // load the template - and be sure to cache the result. + var fn = !/\W/.test(str) ? + cache[str] = cache[str] : + + // Generate a reusable function that will serve as a template + // generator (and which will be cached). + new Function("obj", + "var p=[],print=function(){p.push.apply(p,arguments);};" + + + // Introduce the data as local variables using with(){} + "with(obj){p.push('" + + + // Convert the template into pure JavaScript + str + .replace(/[\r\t\n]/g, " ") + .split("<%").join("\t") + .replace(/((^|%>)[^\t]*)'/g, "$1\r") + .replace(/\t=(.*?)%>/g, "',$1,'") + .split("\t").join("');") + .split("%>").join("p.push('") + .split("\r").join("\\'") + + "');}return p.join('');" + ); + + // Provide some basic currying to the user + return data ? fn( data ) : fn; + } + return tmpl(templateString,valuesObject); + }, + /* jshint ignore:end */ + generateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){ + var labelsArray = new Array(numberOfSteps); + if (labelTemplateString){ + each(labelsArray,function(val,index){ + labelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))}); + }); + } + return labelsArray; + }, + //--Animation methods + //Easing functions adapted from Robert Penner's easing equations + //http://www.robertpenner.com/easing/ + easingEffects = helpers.easingEffects = { + linear: function (t) { + return t; + }, + easeInQuad: function (t) { + return t * t; + }, + easeOutQuad: function (t) { + return -1 * t * (t - 2); + }, + easeInOutQuad: function (t) { + if ((t /= 1 / 2) < 1) return 1 / 2 * t * t; + return -1 / 2 * ((--t) * (t - 2) - 1); + }, + easeInCubic: function (t) { + return t * t * t; + }, + easeOutCubic: function (t) { + return 1 * ((t = t / 1 - 1) * t * t + 1); + }, + easeInOutCubic: function (t) { + if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t; + return 1 / 2 * ((t -= 2) * t * t + 2); + }, + easeInQuart: function (t) { + return t * t * t * t; + }, + easeOutQuart: function (t) { + return -1 * ((t = t / 1 - 1) * t * t * t - 1); + }, + easeInOutQuart: function (t) { + if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t; + return -1 / 2 * ((t -= 2) * t * t * t - 2); + }, + easeInQuint: function (t) { + return 1 * (t /= 1) * t * t * t * t; + }, + easeOutQuint: function (t) { + return 1 * ((t = t / 1 - 1) * t * t * t * t + 1); + }, + easeInOutQuint: function (t) { + if ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t * t; + return 1 / 2 * ((t -= 2) * t * t * t * t + 2); + }, + easeInSine: function (t) { + return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1; + }, + easeOutSine: function (t) { + return 1 * Math.sin(t / 1 * (Math.PI / 2)); + }, + easeInOutSine: function (t) { + return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1); + }, + easeInExpo: function (t) { + return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1)); + }, + easeOutExpo: function (t) { + return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1); + }, + easeInOutExpo: function (t) { + if (t === 0) return 0; + if (t === 1) return 1; + if ((t /= 1 / 2) < 1) return 1 / 2 * Math.pow(2, 10 * (t - 1)); + return 1 / 2 * (-Math.pow(2, -10 * --t) + 2); + }, + easeInCirc: function (t) { + if (t >= 1) return t; + return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1); + }, + easeOutCirc: function (t) { + return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t); + }, + easeInOutCirc: function (t) { + if ((t /= 1 / 2) < 1) return -1 / 2 * (Math.sqrt(1 - t * t) - 1); + return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1); + }, + easeInElastic: function (t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) return 0; + if ((t /= 1) == 1) return 1; + if (!p) p = 1 * 0.3; + if (a < Math.abs(1)) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); + }, + easeOutElastic: function (t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) return 0; + if ((t /= 1) == 1) return 1; + if (!p) p = 1 * 0.3; + if (a < Math.abs(1)) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1; + }, + easeInOutElastic: function (t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) return 0; + if ((t /= 1 / 2) == 2) return 1; + if (!p) p = 1 * (0.3 * 1.5); + if (a < Math.abs(1)) { + a = 1; + s = p / 4; + } else s = p / (2 * Math.PI) * Math.asin(1 / a); + if (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1; + }, + easeInBack: function (t) { + var s = 1.70158; + return 1 * (t /= 1) * t * ((s + 1) * t - s); + }, + easeOutBack: function (t) { + var s = 1.70158; + return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1); + }, + easeInOutBack: function (t) { + var s = 1.70158; + if ((t /= 1 / 2) < 1) return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)); + return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); + }, + easeInBounce: function (t) { + return 1 - easingEffects.easeOutBounce(1 - t); + }, + easeOutBounce: function (t) { + if ((t /= 1) < (1 / 2.75)) { + return 1 * (7.5625 * t * t); + } else if (t < (2 / 2.75)) { + return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75); + } else if (t < (2.5 / 2.75)) { + return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375); + } else { + return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375); + } + }, + easeInOutBounce: function (t) { + if (t < 1 / 2) return easingEffects.easeInBounce(t * 2) * 0.5; + return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5; + } + }, + //Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ + requestAnimFrame = helpers.requestAnimFrame = (function(){ + return window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback) { + return window.setTimeout(callback, 1000 / 60); + }; + })(), + cancelAnimFrame = helpers.cancelAnimFrame = (function(){ + return window.cancelAnimationFrame || + window.webkitCancelAnimationFrame || + window.mozCancelAnimationFrame || + window.oCancelAnimationFrame || + window.msCancelAnimationFrame || + function(callback) { + return window.clearTimeout(callback, 1000 / 60); + }; + })(), + animationLoop = helpers.animationLoop = function(callback,totalSteps,easingString,onProgress,onComplete,chartInstance){ + + var currentStep = 0, + easingFunction = easingEffects[easingString] || easingEffects.linear; + + var animationFrame = function(){ + currentStep++; + var stepDecimal = currentStep/totalSteps; + var easeDecimal = easingFunction(stepDecimal); + + callback.call(chartInstance,easeDecimal,stepDecimal, currentStep); + onProgress.call(chartInstance,easeDecimal,stepDecimal); + if (currentStep < totalSteps){ + chartInstance.animationFrame = requestAnimFrame(animationFrame); + } else{ + onComplete.apply(chartInstance); + } + }; + requestAnimFrame(animationFrame); + }, + //-- DOM methods + getRelativePosition = helpers.getRelativePosition = function(evt){ + var mouseX, mouseY; + var e = evt.originalEvent || evt, + canvas = evt.currentTarget || evt.srcElement, + boundingRect = canvas.getBoundingClientRect(); + + if (e.touches){ + mouseX = e.touches[0].clientX - boundingRect.left; + mouseY = e.touches[0].clientY - boundingRect.top; + + } + else{ + mouseX = e.clientX - boundingRect.left; + mouseY = e.clientY - boundingRect.top; + } + + return { + x : mouseX, + y : mouseY + }; + + }, + addEvent = helpers.addEvent = function(node,eventType,method){ + if (node.addEventListener){ + node.addEventListener(eventType,method); + } else if (node.attachEvent){ + node.attachEvent("on"+eventType, method); + } else { + node["on"+eventType] = method; + } + }, + removeEvent = helpers.removeEvent = function(node, eventType, handler){ + if (node.removeEventListener){ + node.removeEventListener(eventType, handler, false); + } else if (node.detachEvent){ + node.detachEvent("on"+eventType,handler); + } else{ + node["on" + eventType] = noop; + } + }, + bindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler){ + // Create the events object if it's not already present + if (!chartInstance.events) chartInstance.events = {}; + + each(arrayOfEvents,function(eventName){ + chartInstance.events[eventName] = function(){ + handler.apply(chartInstance, arguments); + }; + addEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]); + }); + }, + unbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) { + each(arrayOfEvents, function(handler,eventName){ + removeEvent(chartInstance.chart.canvas, eventName, handler); + }); + }, + getMaximumWidth = helpers.getMaximumWidth = function(domNode){ + var container = domNode.parentNode; + // TODO = check cross browser stuff with this. + return container.clientWidth; + }, + getMaximumHeight = helpers.getMaximumHeight = function(domNode){ + var container = domNode.parentNode; + // TODO = check cross browser stuff with this. + return container.clientHeight; + }, + getMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support + retinaScale = helpers.retinaScale = function(chart){ + var ctx = chart.ctx, + width = chart.canvas.width, + height = chart.canvas.height; + + if (window.devicePixelRatio) { + ctx.canvas.style.width = width + "px"; + ctx.canvas.style.height = height + "px"; + ctx.canvas.height = height * window.devicePixelRatio; + ctx.canvas.width = width * window.devicePixelRatio; + ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + } + }, + //-- Canvas methods + clear = helpers.clear = function(chart){ + chart.ctx.clearRect(0,0,chart.width,chart.height); + }, + fontString = helpers.fontString = function(pixelSize,fontStyle,fontFamily){ + return fontStyle + " " + pixelSize+"px " + fontFamily; + }, + longestText = helpers.longestText = function(ctx,font,arrayOfStrings){ + ctx.font = font; + var longest = 0; + each(arrayOfStrings,function(string){ + var textWidth = ctx.measureText(string).width; + longest = (textWidth > longest) ? textWidth : longest; + }); + return longest; + }, + drawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx,x,y,width,height,radius){ + ctx.beginPath(); + ctx.moveTo(x + radius, y); + ctx.lineTo(x + width - radius, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + radius); + ctx.lineTo(x + width, y + height - radius); + ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + ctx.lineTo(x + radius, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + ctx.lineTo(x, y + radius); + ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.closePath(); + }; + + + //Store a reference to each instance - allowing us to globally resize chart instances on window resize. + //Destroy method on the chart will remove the instance of the chart from this reference. + Chart.instances = {}; + + Chart.Type = function(data,options,chart){ + this.options = options; + this.chart = chart; + this.id = uid(); + //Add the chart instance to the global namespace + Chart.instances[this.id] = this; + + // Initialize is always called when a chart type is created + // By default it is a no op, but it should be extended + if (options.responsive){ + this.resize(); + } + this.initialize.call(this,data); + }; + + //Core methods that'll be a part of every chart type + extend(Chart.Type.prototype,{ + initialize : function(){return this;}, + clear : function(){ + clear(this.chart); + return this; + }, + stop : function(){ + // Stops any current animation loop occuring + cancelAnimFrame(this.animationFrame); + return this; + }, + resize : function(callback){ + this.stop(); + var canvas = this.chart.canvas, + newWidth = getMaximumWidth(this.chart.canvas), + newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas); + + canvas.width = this.chart.width = newWidth; + canvas.height = this.chart.height = newHeight; + + retinaScale(this.chart); + + if (typeof callback === "function"){ + callback.apply(this, Array.prototype.slice.call(arguments, 1)); + } + return this; + }, + reflow : noop, + render : function(reflow){ + if (reflow){ + this.reflow(); + } + if (this.options.animation && !reflow){ + helpers.animationLoop( + this.draw, + this.options.animationSteps, + this.options.animationEasing, + this.options.onAnimationProgress, + this.options.onAnimationComplete, + this + ); + } + else{ + this.draw(); + this.options.onAnimationComplete.call(this); + } + return this; + }, + generateLegend : function(){ + return template(this.options.legendTemplate,this); + }, + destroy : function(){ + this.clear(); + unbindEvents(this, this.events); + var canvas = this.chart.canvas; + + // Reset canvas height/width attributes starts a fresh with the canvas context + canvas.width = this.chart.width; + canvas.height = this.chart.height; + + // < IE9 doesn't support removeProperty + if (canvas.style.removeProperty) { + canvas.style.removeProperty('width'); + canvas.style.removeProperty('height'); + } else { + canvas.style.removeAttribute('width'); + canvas.style.removeAttribute('height'); + } + + delete Chart.instances[this.id]; + }, + showTooltip : function(ChartElements, forceRedraw){ + // Only redraw the chart if we've actually changed what we're hovering on. + if (typeof this.activeElements === 'undefined') this.activeElements = []; + + var isChanged = (function(Elements){ + var changed = false; + + if (Elements.length !== this.activeElements.length){ + changed = true; + return changed; + } + + each(Elements, function(element, index){ + if (element !== this.activeElements[index]){ + changed = true; + } + }, this); + return changed; + }).call(this, ChartElements); + + if (!isChanged && !forceRedraw){ + return; + } + else{ + this.activeElements = ChartElements; + } + this.draw(); + if(this.options.customTooltips){ + this.options.customTooltips(false); + } + if (ChartElements.length > 0){ + // If we have multiple datasets, show a MultiTooltip for all of the data points at that index + if (this.datasets && this.datasets.length > 1) { + var dataArray, + dataIndex; + + for (var i = this.datasets.length - 1; i >= 0; i--) { + dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments; + dataIndex = indexOf(dataArray, ChartElements[0]); + if (dataIndex !== -1){ + break; + } + } + var tooltipLabels = [], + tooltipColors = [], + medianPosition = (function(index) { + + // Get all the points at that particular index + var Elements = [], + dataCollection, + xPositions = [], + yPositions = [], + xMax, + yMax, + xMin, + yMin; + helpers.each(this.datasets, function(dataset){ + dataCollection = dataset.points || dataset.bars || dataset.segments; + if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){ + Elements.push(dataCollection[dataIndex]); + } + }); + + helpers.each(Elements, function(element) { + xPositions.push(element.x); + yPositions.push(element.y); + + + //Include any colour information about the element + tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element)); + tooltipColors.push({ + fill: element._saved.fillColor || element.fillColor, + stroke: element._saved.strokeColor || element.strokeColor + }); + + }, this); + + yMin = min(yPositions); + yMax = max(yPositions); + + xMin = min(xPositions); + xMax = max(xPositions); + + return { + x: (xMin > this.chart.width/2) ? xMin : xMax, + y: (yMin + yMax)/2 + }; + }).call(this, dataIndex); + + new Chart.MultiTooltip({ + x: medianPosition.x, + y: medianPosition.y, + xPadding: this.options.tooltipXPadding, + yPadding: this.options.tooltipYPadding, + xOffset: this.options.tooltipXOffset, + fillColor: this.options.tooltipFillColor, + textColor: this.options.tooltipFontColor, + fontFamily: this.options.tooltipFontFamily, + fontStyle: this.options.tooltipFontStyle, + fontSize: this.options.tooltipFontSize, + titleTextColor: this.options.tooltipTitleFontColor, + titleFontFamily: this.options.tooltipTitleFontFamily, + titleFontStyle: this.options.tooltipTitleFontStyle, + titleFontSize: this.options.tooltipTitleFontSize, + cornerRadius: this.options.tooltipCornerRadius, + labels: tooltipLabels, + legendColors: tooltipColors, + legendColorBackground : this.options.multiTooltipKeyBackground, + title: ChartElements[0].label, + chart: this.chart, + ctx: this.chart.ctx, + custom: this.options.customTooltips + }).draw(); + + } else { + each(ChartElements, function(Element) { + var tooltipPosition = Element.tooltipPosition(); + new Chart.Tooltip({ + x: Math.round(tooltipPosition.x), + y: Math.round(tooltipPosition.y), + xPadding: this.options.tooltipXPadding, + yPadding: this.options.tooltipYPadding, + fillColor: this.options.tooltipFillColor, + textColor: this.options.tooltipFontColor, + fontFamily: this.options.tooltipFontFamily, + fontStyle: this.options.tooltipFontStyle, + fontSize: this.options.tooltipFontSize, + caretHeight: this.options.tooltipCaretSize, + cornerRadius: this.options.tooltipCornerRadius, + text: template(this.options.tooltipTemplate, Element), + chart: this.chart, + custom: this.options.customTooltips + }).draw(); + }, this); + } + } + return this; + }, + toBase64Image : function(){ + return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments); + } + }); + + Chart.Type.extend = function(extensions){ + + var parent = this; + + var ChartType = function(){ + return parent.apply(this,arguments); + }; + + //Copy the prototype object of the this class + ChartType.prototype = clone(parent.prototype); + //Now overwrite some of the properties in the base class with the new extensions + extend(ChartType.prototype, extensions); + + ChartType.extend = Chart.Type.extend; + + if (extensions.name || parent.prototype.name){ + + var chartName = extensions.name || parent.prototype.name; + //Assign any potential default values of the new chart type + + //If none are defined, we'll use a clone of the chart type this is being extended from. + //I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart + //doesn't define some defaults of their own. + + var baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {}; + + Chart.defaults[chartName] = extend(baseDefaults,extensions.defaults); + + Chart.types[chartName] = ChartType; + + //Register this new chart type in the Chart prototype + Chart.prototype[chartName] = function(data,options){ + var config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {}); + return new ChartType(data,config,this); + }; + } else{ + warn("Name not provided for this chart, so it hasn't been registered"); + } + return parent; + }; + + Chart.Element = function(configuration){ + extend(this,configuration); + this.initialize.apply(this,arguments); + this.save(); + }; + extend(Chart.Element.prototype,{ + initialize : function(){}, + restore : function(props){ + if (!props){ + extend(this,this._saved); + } else { + each(props,function(key){ + this[key] = this._saved[key]; + },this); + } + return this; + }, + save : function(){ + this._saved = clone(this); + delete this._saved._saved; + return this; + }, + update : function(newProps){ + each(newProps,function(value,key){ + this._saved[key] = this[key]; + this[key] = value; + },this); + return this; + }, + transition : function(props,ease){ + each(props,function(value,key){ + this[key] = ((value - this._saved[key]) * ease) + this._saved[key]; + },this); + return this; + }, + tooltipPosition : function(){ + return { + x : this.x, + y : this.y + }; + }, + hasValue: function(){ + return isNumber(this.value); + } + }); + + Chart.Element.extend = inherits; + + + Chart.Point = Chart.Element.extend({ + display: true, + inRange: function(chartX,chartY){ + var hitDetectionRange = this.hitDetectionRadius + this.radius; + return ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2)); + }, + draw : function(){ + if (this.display){ + var ctx = this.ctx; + ctx.beginPath(); + + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2); + ctx.closePath(); + + ctx.strokeStyle = this.strokeColor; + ctx.lineWidth = this.strokeWidth; + + ctx.fillStyle = this.fillColor; + + ctx.fill(); + ctx.stroke(); + } + + + //Quick debug for bezier curve splining + //Highlights control points and the line between them. + //Handy for dev - stripped in the min version. + + // ctx.save(); + // ctx.fillStyle = "black"; + // ctx.strokeStyle = "black" + // ctx.beginPath(); + // ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2); + // ctx.fill(); + + // ctx.beginPath(); + // ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2); + // ctx.fill(); + + // ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y); + // ctx.lineTo(this.x, this.y); + // ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y); + // ctx.stroke(); + + // ctx.restore(); + + + + } + }); + + Chart.Arc = Chart.Element.extend({ + inRange : function(chartX,chartY){ + + var pointRelativePosition = helpers.getAngleFromPoint(this, { + x: chartX, + y: chartY + }); + + //Check if within the range of the open/close angle + var betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle), + withinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius); + + return (betweenAngles && withinRadius); + //Ensure within the outside of the arc centre, but inside arc outer + }, + tooltipPosition : function(){ + var centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2), + rangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius; + return { + x : this.x + (Math.cos(centreAngle) * rangeFromCentre), + y : this.y + (Math.sin(centreAngle) * rangeFromCentre) + }; + }, + draw : function(animationPercent){ + + var easingDecimal = animationPercent || 1; + + var ctx = this.ctx; + + ctx.beginPath(); + + ctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle); + + ctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true); + + ctx.closePath(); + ctx.strokeStyle = this.strokeColor; + ctx.lineWidth = this.strokeWidth; + + ctx.fillStyle = this.fillColor; + + ctx.fill(); + ctx.lineJoin = 'bevel'; + + if (this.showStroke){ + ctx.stroke(); + } + } + }); + + Chart.Rectangle = Chart.Element.extend({ + draw : function(){ + var ctx = this.ctx, + halfWidth = this.width/2, + leftX = this.x - halfWidth, + rightX = this.x + halfWidth, + top = this.base - (this.base - this.y), + halfStroke = this.strokeWidth / 2; + + // Canvas doesn't allow us to stroke inside the width so we can + // adjust the sizes to fit if we're setting a stroke on the line + if (this.showStroke){ + leftX += halfStroke; + rightX -= halfStroke; + top += halfStroke; + } + + ctx.beginPath(); + + ctx.fillStyle = this.fillColor; + ctx.strokeStyle = this.strokeColor; + ctx.lineWidth = this.strokeWidth; + + // It'd be nice to keep this class totally generic to any rectangle + // and simply specify which border to miss out. + ctx.moveTo(leftX, this.base); + ctx.lineTo(leftX, top); + ctx.lineTo(rightX, top); + ctx.lineTo(rightX, this.base); + ctx.fill(); + if (this.showStroke){ + ctx.stroke(); + } + }, + height : function(){ + return this.base - this.y; + }, + inRange : function(chartX,chartY){ + return (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base); + } + }); + + Chart.Tooltip = Chart.Element.extend({ + draw : function(){ + + var ctx = this.chart.ctx; + + ctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily); + + this.xAlign = "center"; + this.yAlign = "above"; + + //Distance between the actual element.y position and the start of the tooltip caret + var caretPadding = this.caretPadding = 2; + + var tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding, + tooltipRectHeight = this.fontSize + 2*this.yPadding, + tooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding; + + if (this.x + tooltipWidth/2 >this.chart.width){ + this.xAlign = "left"; + } else if (this.x - tooltipWidth/2 < 0){ + this.xAlign = "right"; + } + + if (this.y - tooltipHeight < 0){ + this.yAlign = "below"; + } + + + var tooltipX = this.x - tooltipWidth/2, + tooltipY = this.y - tooltipHeight; + + ctx.fillStyle = this.fillColor; + + // Custom Tooltips + if(this.custom){ + this.custom(this); + } + else{ + switch(this.yAlign) + { + case "above": + //Draw a caret above the x/y + ctx.beginPath(); + ctx.moveTo(this.x,this.y - caretPadding); + ctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight)); + ctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight)); + ctx.closePath(); + ctx.fill(); + break; + case "below": + tooltipY = this.y + caretPadding + this.caretHeight; + //Draw a caret below the x/y + ctx.beginPath(); + ctx.moveTo(this.x, this.y + caretPadding); + ctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight); + ctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight); + ctx.closePath(); + ctx.fill(); + break; + } + + switch(this.xAlign) + { + case "left": + tooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight); + break; + case "right": + tooltipX = this.x - (this.cornerRadius + this.caretHeight); + break; + } + + drawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius); + + ctx.fill(); + + ctx.fillStyle = this.textColor; + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + ctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2); + } + } + }); + + Chart.MultiTooltip = Chart.Element.extend({ + initialize : function(){ + this.font = fontString(this.fontSize,this.fontStyle,this.fontFamily); + + this.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily); + + this.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5; + + this.ctx.font = this.titleFont; + + var titleWidth = this.ctx.measureText(this.title).width, + //Label has a legend square as well so account for this. + labelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3, + longestTextWidth = max([labelWidth,titleWidth]); + + this.width = longestTextWidth + (this.xPadding*2); + + + var halfHeight = this.height/2; + + //Check to ensure the height will fit on the canvas + if (this.y - halfHeight < 0 ){ + this.y = halfHeight; + } else if (this.y + halfHeight > this.chart.height){ + this.y = this.chart.height - halfHeight; + } + + //Decide whether to align left or right based on position on canvas + if (this.x > this.chart.width/2){ + this.x -= this.xOffset + this.width; + } else { + this.x += this.xOffset; + } + + + }, + getLineHeight : function(index){ + var baseLineHeight = this.y - (this.height/2) + this.yPadding, + afterTitleIndex = index-1; + + //If the index is zero, we're getting the title + if (index === 0){ + return baseLineHeight + this.titleFontSize/2; + } else{ + return baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5; + } + + }, + draw : function(){ + // Custom Tooltips + if(this.custom){ + this.custom(this); + } + else{ + drawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius); + var ctx = this.ctx; + ctx.fillStyle = this.fillColor; + ctx.fill(); + ctx.closePath(); + + ctx.textAlign = "left"; + ctx.textBaseline = "middle"; + ctx.fillStyle = this.titleTextColor; + ctx.font = this.titleFont; + + ctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0)); + + ctx.font = this.font; + helpers.each(this.labels,function(label,index){ + ctx.fillStyle = this.textColor; + ctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1)); + + //A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas) + //ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize); + //Instead we'll make a white filled block to put the legendColour palette over. + + ctx.fillStyle = this.legendColorBackground; + ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize); + + ctx.fillStyle = this.legendColors[index].fill; + ctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize); + + + },this); + } + } + }); + + Chart.Scale = Chart.Element.extend({ + initialize : function(){ + this.fit(); + }, + buildYLabels : function(){ + this.yLabels = []; + + var stepDecimalPlaces = getDecimalPlaces(this.stepValue); + + for (var i=0; i<=this.steps; i++){ + this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)})); + } + this.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) : 0; + }, + addXLabel : function(label){ + this.xLabels.push(label); + this.valuesCount++; + this.fit(); + }, + removeXLabel : function(){ + this.xLabels.shift(); + this.valuesCount--; + this.fit(); + }, + // Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use + fit: function(){ + // First we need the width of the yLabels, assuming the xLabels aren't rotated + + // To do that we need the base line at the top and base of the chart, assuming there is no x label rotation + this.startPoint = (this.display) ? this.fontSize : 0; + this.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels + + // Apply padding settings to the start and end point. + this.startPoint += this.padding; + this.endPoint -= this.padding; + + // Cache the starting height, so can determine if we need to recalculate the scale yAxis + var cachedHeight = this.endPoint - this.startPoint, + cachedYLabelWidth; + + // Build the current yLabels so we have an idea of what size they'll be to start + /* + * This sets what is returned from calculateScaleRange as static properties of this class: + * + this.steps; + this.stepValue; + this.min; + this.max; + * + */ + this.calculateYRange(cachedHeight); + + // With these properties set we can now build the array of yLabels + // and also the width of the largest yLabel + this.buildYLabels(); + + this.calculateXLabelRotation(); + + while((cachedHeight > this.endPoint - this.startPoint)){ + cachedHeight = this.endPoint - this.startPoint; + cachedYLabelWidth = this.yLabelWidth; + + this.calculateYRange(cachedHeight); + this.buildYLabels(); + + // Only go through the xLabel loop again if the yLabel width has changed + if (cachedYLabelWidth < this.yLabelWidth){ + this.calculateXLabelRotation(); + } + } + + }, + calculateXLabelRotation : function(){ + //Get the width of each grid by calculating the difference + //between x offsets between 0 and 1. + + this.ctx.font = this.font; + + var firstWidth = this.ctx.measureText(this.xLabels[0]).width, + lastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width, + firstRotated, + lastRotated; + + + this.xScalePaddingRight = lastWidth/2 + 3; + this.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10; + + this.xLabelRotation = 0; + if (this.display){ + var originalLabelWidth = longestText(this.ctx,this.font,this.xLabels), + cosRotation, + firstRotatedWidth; + this.xLabelWidth = originalLabelWidth; + //Allow 3 pixels x2 padding either side for label readability + var xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6; + + //Max label rotate should be 90 - also act as a loop counter + while ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){ + cosRotation = Math.cos(toRadians(this.xLabelRotation)); + + firstRotated = cosRotation * firstWidth; + lastRotated = cosRotation * lastWidth; + + // We're right aligning the text now. + if (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8){ + this.xScalePaddingLeft = firstRotated + this.fontSize / 2; + } + this.xScalePaddingRight = this.fontSize/2; + + + this.xLabelRotation++; + this.xLabelWidth = cosRotation * originalLabelWidth; + + } + if (this.xLabelRotation > 0){ + this.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3; + } + } + else{ + this.xLabelWidth = 0; + this.xScalePaddingRight = this.padding; + this.xScalePaddingLeft = this.padding; + } + + }, + // Needs to be overidden in each Chart type + // Otherwise we need to pass all the data into the scale class + calculateYRange: noop, + drawingArea: function(){ + return this.startPoint - this.endPoint; + }, + calculateY : function(value){ + var scalingFactor = this.drawingArea() / (this.min - this.max); + return this.endPoint - (scalingFactor * (value - this.min)); + }, + calculateX : function(index){ + var isRotated = (this.xLabelRotation > 0), + // innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding, + innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight), + valueWidth = innerWidth/Math.max((this.valuesCount - ((this.offsetGridLines) ? 0 : 1)), 1), + valueOffset = (valueWidth * index) + this.xScalePaddingLeft; + + if (this.offsetGridLines){ + valueOffset += (valueWidth/2); + } + + return Math.round(valueOffset); + }, + update : function(newProps){ + helpers.extend(this, newProps); + this.fit(); + }, + draw : function(){ + var ctx = this.ctx, + yLabelGap = (this.endPoint - this.startPoint) / this.steps, + xStart = Math.round(this.xScalePaddingLeft); + if (this.display){ + ctx.fillStyle = this.textColor; + ctx.font = this.font; + each(this.yLabels,function(labelString,index){ + var yLabelCenter = this.endPoint - (yLabelGap * index), + linePositionY = Math.round(yLabelCenter), + drawHorizontalLine = this.showHorizontalLines; + + ctx.textAlign = "right"; + ctx.textBaseline = "middle"; + if (this.showLabels){ + ctx.fillText(labelString,xStart - 10,yLabelCenter); + } + + // This is X axis, so draw it + if (index === 0 && !drawHorizontalLine){ + drawHorizontalLine = true; + } + + if (drawHorizontalLine){ + ctx.beginPath(); + } + + if (index > 0){ + // This is a grid line in the centre, so drop that + ctx.lineWidth = this.gridLineWidth; + ctx.strokeStyle = this.gridLineColor; + } else { + // This is the first line on the scale + ctx.lineWidth = this.lineWidth; + ctx.strokeStyle = this.lineColor; + } + + linePositionY += helpers.aliasPixel(ctx.lineWidth); + + if(drawHorizontalLine){ + ctx.moveTo(xStart, linePositionY); + ctx.lineTo(this.width, linePositionY); + ctx.stroke(); + ctx.closePath(); + } + + ctx.lineWidth = this.lineWidth; + ctx.strokeStyle = this.lineColor; + ctx.beginPath(); + ctx.moveTo(xStart - 5, linePositionY); + ctx.lineTo(xStart, linePositionY); + ctx.stroke(); + ctx.closePath(); + + },this); + + each(this.xLabels,function(label,index){ + var xPos = this.calculateX(index) + aliasPixel(this.lineWidth), + // Check to see if line/bar here and decide where to place the line + linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth), + isRotated = (this.xLabelRotation > 0), + drawVerticalLine = this.showVerticalLines; + + // This is Y axis, so draw it + if (index === 0 && !drawVerticalLine){ + drawVerticalLine = true; + } + + if (drawVerticalLine){ + ctx.beginPath(); + } + + if (index > 0){ + // This is a grid line in the centre, so drop that + ctx.lineWidth = this.gridLineWidth; + ctx.strokeStyle = this.gridLineColor; + } else { + // This is the first line on the scale + ctx.lineWidth = this.lineWidth; + ctx.strokeStyle = this.lineColor; + } + + if (drawVerticalLine){ + ctx.moveTo(linePos,this.endPoint); + ctx.lineTo(linePos,this.startPoint - 3); + ctx.stroke(); + ctx.closePath(); + } + + + ctx.lineWidth = this.lineWidth; + ctx.strokeStyle = this.lineColor; + + + // Small lines at the bottom of the base grid line + ctx.beginPath(); + ctx.moveTo(linePos,this.endPoint); + ctx.lineTo(linePos,this.endPoint + 5); + ctx.stroke(); + ctx.closePath(); + + ctx.save(); + ctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8); + ctx.rotate(toRadians(this.xLabelRotation)*-1); + ctx.font = this.font; + ctx.textAlign = (isRotated) ? "right" : "center"; + ctx.textBaseline = (isRotated) ? "middle" : "top"; + ctx.fillText(label, 0, 0); + ctx.restore(); + },this); + + } + } + + }); + + Chart.RadialScale = Chart.Element.extend({ + initialize: function(){ + this.size = min([this.height, this.width]); + this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2); + }, + calculateCenterOffset: function(value){ + // Take into account half font size + the yPadding of the top value + var scalingFactor = this.drawingArea / (this.max - this.min); + + return (value - this.min) * scalingFactor; + }, + update : function(){ + if (!this.lineArc){ + this.setScaleSize(); + } else { + this.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2); + } + this.buildYLabels(); + }, + buildYLabels: function(){ + this.yLabels = []; + + var stepDecimalPlaces = getDecimalPlaces(this.stepValue); + + for (var i=0; i<=this.steps; i++){ + this.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)})); + } + }, + getCircumference : function(){ + return ((Math.PI*2) / this.valuesCount); + }, + setScaleSize: function(){ + /* + * Right, this is really confusing and there is a lot of maths going on here + * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9 + * + * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif + * + * Solution: + * + * We assume the radius of the polygon is half the size of the canvas at first + * at each index we check if the text overlaps. + * + * Where it does, we store that angle and that index. + * + * After finding the largest index and angle we calculate how much we need to remove + * from the shape radius to move the point inwards by that x. + * + * We average the left and right distances to get the maximum shape radius that can fit in the box + * along with labels. + * + * Once we have that, we can find the centre point for the chart, by taking the x text protrusion + * on each side, removing that from the size, halving it and adding the left x protrusion width. + * + * This will mean we have a shape fitted to the canvas, as large as it can be with the labels + * and position it in the most space efficient manner + * + * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif + */ + + + // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. + // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points + var largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]), + pointPosition, + i, + textWidth, + halfTextWidth, + furthestRight = this.width, + furthestRightIndex, + furthestRightAngle, + furthestLeft = 0, + furthestLeftIndex, + furthestLeftAngle, + xProtrusionLeft, + xProtrusionRight, + radiusReductionRight, + radiusReductionLeft, + maxWidthRadius; + this.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily); + for (i=0;i furthestRight) { + furthestRight = pointPosition.x + halfTextWidth; + furthestRightIndex = i; + } + if (pointPosition.x - halfTextWidth < furthestLeft) { + furthestLeft = pointPosition.x - halfTextWidth; + furthestLeftIndex = i; + } + } + else if (i < this.valuesCount/2) { + // Less than half the values means we'll left align the text + if (pointPosition.x + textWidth > furthestRight) { + furthestRight = pointPosition.x + textWidth; + furthestRightIndex = i; + } + } + else if (i > this.valuesCount/2){ + // More than half the values means we'll right align the text + if (pointPosition.x - textWidth < furthestLeft) { + furthestLeft = pointPosition.x - textWidth; + furthestLeftIndex = i; + } + } + } + + xProtrusionLeft = furthestLeft; + + xProtrusionRight = Math.ceil(furthestRight - this.width); + + furthestRightAngle = this.getIndexAngle(furthestRightIndex); + + furthestLeftAngle = this.getIndexAngle(furthestLeftIndex); + + radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2); + + radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2); + + // Ensure we actually need to reduce the size of the chart + radiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0; + radiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0; + + this.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2; + + //this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2]) + this.setCenterPoint(radiusReductionLeft, radiusReductionRight); + + }, + setCenterPoint: function(leftMovement, rightMovement){ + + var maxRight = this.width - rightMovement - this.drawingArea, + maxLeft = leftMovement + this.drawingArea; + + this.xCenter = (maxLeft + maxRight)/2; + // Always vertically in the centre as the text height doesn't change + this.yCenter = (this.height/2); + }, + + getIndexAngle : function(index){ + var angleMultiplier = (Math.PI * 2) / this.valuesCount; + // Start from the top instead of right, so remove a quarter of the circle + + return index * angleMultiplier - (Math.PI/2); + }, + getPointPosition : function(index, distanceFromCenter){ + var thisAngle = this.getIndexAngle(index); + return { + x : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter, + y : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter + }; + }, + draw: function(){ + if (this.display){ + var ctx = this.ctx; + each(this.yLabels, function(label, index){ + // Don't draw a centre value + if (index > 0){ + var yCenterOffset = index * (this.drawingArea/this.steps), + yHeight = this.yCenter - yCenterOffset, + pointPosition; + + // Draw circular lines around the scale + if (this.lineWidth > 0){ + ctx.strokeStyle = this.lineColor; + ctx.lineWidth = this.lineWidth; + + if(this.lineArc){ + ctx.beginPath(); + ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2); + ctx.closePath(); + ctx.stroke(); + } else{ + ctx.beginPath(); + for (var i=0;i= 0; i--) { + if (this.angleLineWidth > 0){ + var outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max)); + ctx.beginPath(); + ctx.moveTo(this.xCenter, this.yCenter); + ctx.lineTo(outerPosition.x, outerPosition.y); + ctx.stroke(); + ctx.closePath(); + } + // Extra 3px out for some label spacing + var pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5); + ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily); + ctx.fillStyle = this.pointLabelFontColor; + + var labelsCount = this.labels.length, + halfLabelsCount = this.labels.length/2, + quarterLabelsCount = halfLabelsCount/2, + upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount), + exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount); + if (i === 0){ + ctx.textAlign = 'center'; + } else if(i === halfLabelsCount){ + ctx.textAlign = 'center'; + } else if (i < halfLabelsCount){ + ctx.textAlign = 'left'; + } else { + ctx.textAlign = 'right'; + } + + // Set the correct text baseline based on outer positioning + if (exactQuarter){ + ctx.textBaseline = 'middle'; + } else if (upperHalf){ + ctx.textBaseline = 'bottom'; + } else { + ctx.textBaseline = 'top'; + } + + ctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y); + } + } + } + } + }); + + // Attach global event to resize each chart instance when the browser resizes + helpers.addEvent(window, "resize", (function(){ + // Basic debounce of resize function so it doesn't hurt performance when resizing browser. + var timeout; + return function(){ + clearTimeout(timeout); + timeout = setTimeout(function(){ + each(Chart.instances,function(instance){ + // If the responsive flag is set in the chart instance config + // Cascade the resize event down to the chart. + if (instance.options.responsive){ + instance.resize(instance.render, true); + } + }); + }, 50); + }; + })()); + + + if (amd) { + define(function(){ + return Chart; + }); + } else if (typeof module === 'object' && module.exports) { + module.exports = Chart; + } + + root.Chart = Chart; + + Chart.noConflict = function(){ + root.Chart = previous; + return Chart; + }; + +}).call(this); + +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + helpers = Chart.helpers; + + + var defaultConfig = { + //Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value + scaleBeginAtZero : true, + + //Boolean - Whether grid lines are shown across the chart + scaleShowGridLines : true, + + //String - Colour of the grid lines + scaleGridLineColor : "rgba(0,0,0,.05)", + + //Number - Width of the grid lines + scaleGridLineWidth : 1, + + //Boolean - Whether to show horizontal lines (except X axis) + scaleShowHorizontalLines: true, + + //Boolean - Whether to show vertical lines (except Y axis) + scaleShowVerticalLines: true, + + //Boolean - If there is a stroke on each bar + barShowStroke : true, + + //Number - Pixel width of the bar stroke + barStrokeWidth : 2, + + //Number - Spacing between each of the X value sets + barValueSpacing : 5, + + //Number - Spacing between data sets within X values + barDatasetSpacing : 1, + + //String - A legend template + legendTemplate : "
      -legend\"><% for (var i=0; i
    • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
    • <%}%>
    " + + }; + + + Chart.Type.extend({ + name: "Bar", + defaults : defaultConfig, + initialize: function(data){ + + //Expose options as a scope variable here so we can access it in the ScaleClass + var options = this.options; + + this.ScaleClass = Chart.Scale.extend({ + offsetGridLines : true, + calculateBarX : function(datasetCount, datasetIndex, barIndex){ + //Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar + var xWidth = this.calculateBaseWidth(), + xAbsolute = this.calculateX(barIndex) - (xWidth/2), + barWidth = this.calculateBarWidth(datasetCount); + + return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2; + }, + calculateBaseWidth : function(){ + return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing); + }, + calculateBarWidth : function(datasetCount){ + //The padding between datasets is to the right of each bar, providing that there are more than 1 dataset + var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing); + + return (baseWidth / datasetCount); + } + }); + + this.datasets = []; + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : []; + + this.eachBars(function(bar){ + bar.restore(['fillColor', 'strokeColor']); + }); + helpers.each(activeBars, function(activeBar){ + activeBar.fillColor = activeBar.highlightFill; + activeBar.strokeColor = activeBar.highlightStroke; + }); + this.showTooltip(activeBars); + }); + } + + //Declare the extension of the default point, to cater for the options passed in to the constructor + this.BarClass = Chart.Rectangle.extend({ + strokeWidth : this.options.barStrokeWidth, + showStroke : this.options.barShowStroke, + ctx : this.chart.ctx + }); + + //Iterate through each of the datasets, and build this into a property of the chart + helpers.each(data.datasets,function(dataset,datasetIndex){ + + var datasetObject = { + label : dataset.label || null, + fillColor : dataset.fillColor, + strokeColor : dataset.strokeColor, + bars : [] + }; + + this.datasets.push(datasetObject); + + helpers.each(dataset.data,function(dataPoint,index){ + //Add a new point for each piece of data, passing any required data to draw. + datasetObject.bars.push(new this.BarClass({ + value : dataPoint, + label : data.labels[index], + datasetLabel: dataset.label, + strokeColor : dataset.strokeColor, + fillColor : dataset.fillColor, + highlightFill : dataset.highlightFill || dataset.fillColor, + highlightStroke : dataset.highlightStroke || dataset.strokeColor + })); + },this); + + },this); + + this.buildScale(data.labels); + + this.BarClass.prototype.base = this.scale.endPoint; + + this.eachBars(function(bar, index, datasetIndex){ + helpers.extend(bar, { + width : this.scale.calculateBarWidth(this.datasets.length), + x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index), + y: this.scale.endPoint + }); + bar.save(); + }, this); + + this.render(); + }, + update : function(){ + this.scale.update(); + // Reset any highlight colours before updating. + helpers.each(this.activeElements, function(activeElement){ + activeElement.restore(['fillColor', 'strokeColor']); + }); + + this.eachBars(function(bar){ + bar.save(); + }); + this.render(); + }, + eachBars : function(callback){ + helpers.each(this.datasets,function(dataset, datasetIndex){ + helpers.each(dataset.bars, callback, this, datasetIndex); + },this); + }, + getBarsAtEvent : function(e){ + var barsArray = [], + eventPosition = helpers.getRelativePosition(e), + datasetIterator = function(dataset){ + barsArray.push(dataset.bars[barIndex]); + }, + barIndex; + + for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) { + for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) { + if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){ + helpers.each(this.datasets, datasetIterator); + return barsArray; + } + } + } + + return barsArray; + }, + buildScale : function(labels){ + var self = this; + + var dataTotal = function(){ + var values = []; + self.eachBars(function(bar){ + values.push(bar.value); + }); + return values; + }; + + var scaleOptions = { + templateString : this.options.scaleLabel, + height : this.chart.height, + width : this.chart.width, + ctx : this.chart.ctx, + textColor : this.options.scaleFontColor, + fontSize : this.options.scaleFontSize, + fontStyle : this.options.scaleFontStyle, + fontFamily : this.options.scaleFontFamily, + valuesCount : labels.length, + beginAtZero : this.options.scaleBeginAtZero, + integersOnly : this.options.scaleIntegersOnly, + calculateYRange: function(currentHeight){ + var updatedRanges = helpers.calculateScaleRange( + dataTotal(), + currentHeight, + this.fontSize, + this.beginAtZero, + this.integersOnly + ); + helpers.extend(this, updatedRanges); + }, + xLabels : labels, + font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily), + lineWidth : this.options.scaleLineWidth, + lineColor : this.options.scaleLineColor, + showHorizontalLines : this.options.scaleShowHorizontalLines, + showVerticalLines : this.options.scaleShowVerticalLines, + gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0, + gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)", + padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0, + showLabels : this.options.scaleShowLabels, + display : this.options.showScale + }; + + if (this.options.scaleOverride){ + helpers.extend(scaleOptions, { + calculateYRange: helpers.noop, + steps: this.options.scaleSteps, + stepValue: this.options.scaleStepWidth, + min: this.options.scaleStartValue, + max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth) + }); + } + + this.scale = new this.ScaleClass(scaleOptions); + }, + addData : function(valuesArray,label){ + //Map the values array for each of the datasets + helpers.each(valuesArray,function(value,datasetIndex){ + //Add a new point for each piece of data, passing any required data to draw. + this.datasets[datasetIndex].bars.push(new this.BarClass({ + value : value, + label : label, + x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1), + y: this.scale.endPoint, + width : this.scale.calculateBarWidth(this.datasets.length), + base : this.scale.endPoint, + strokeColor : this.datasets[datasetIndex].strokeColor, + fillColor : this.datasets[datasetIndex].fillColor + })); + },this); + + this.scale.addXLabel(label); + //Then re-render the chart. + this.update(); + }, + removeData : function(){ + this.scale.removeXLabel(); + //Then re-render the chart. + helpers.each(this.datasets,function(dataset){ + dataset.bars.shift(); + },this); + this.update(); + }, + reflow : function(){ + helpers.extend(this.BarClass.prototype,{ + y: this.scale.endPoint, + base : this.scale.endPoint + }); + var newScaleProps = helpers.extend({ + height : this.chart.height, + width : this.chart.width + }); + this.scale.update(newScaleProps); + }, + draw : function(ease){ + var easingDecimal = ease || 1; + this.clear(); + + var ctx = this.chart.ctx; + + this.scale.draw(easingDecimal); + + //Draw all the bars for each dataset + helpers.each(this.datasets,function(dataset,datasetIndex){ + helpers.each(dataset.bars,function(bar,index){ + if (bar.hasValue()){ + bar.base = this.scale.endPoint; + //Transition then draw + bar.transition({ + x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index), + y : this.scale.calculateY(bar.value), + width : this.scale.calculateBarWidth(this.datasets.length) + }, easingDecimal).draw(); + } + },this); + + },this); + } + }); + + +}).call(this); + +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + //Cache a local reference to Chart.helpers + helpers = Chart.helpers; + + var defaultConfig = { + //Boolean - Whether we should show a stroke on each segment + segmentShowStroke : true, + + //String - The colour of each segment stroke + segmentStrokeColor : "#fff", + + //Number - The width of each segment stroke + segmentStrokeWidth : 2, + + //The percentage of the chart that we cut out of the middle. + percentageInnerCutout : 50, + + //Number - Amount of animation steps + animationSteps : 100, + + //String - Animation easing effect + animationEasing : "easeOutBounce", + + //Boolean - Whether we animate the rotation of the Doughnut + animateRotate : true, + + //Boolean - Whether we animate scaling the Doughnut from the centre + animateScale : false, + + //String - A legend template + legendTemplate : "
      -legend\"><% for (var i=0; i
    • \"><%if(segments[i].label){%><%=segments[i].label%><%}%>
    • <%}%>
    " + + }; + + + Chart.Type.extend({ + //Passing in a name registers this chart in the Chart namespace + name: "Doughnut", + //Providing a defaults will also register the deafults in the chart namespace + defaults : defaultConfig, + //Initialize is fired when the chart is initialized - Data is passed in as a parameter + //Config is automatically merged by the core of Chart.js, and is available at this.options + initialize: function(data){ + + //Declare segments as a static property to prevent inheriting across the Chart type prototype + this.segments = []; + this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2; + + this.SegmentArc = Chart.Arc.extend({ + ctx : this.chart.ctx, + x : this.chart.width/2, + y : this.chart.height/2 + }); + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : []; + + helpers.each(this.segments,function(segment){ + segment.restore(["fillColor"]); + }); + helpers.each(activeSegments,function(activeSegment){ + activeSegment.fillColor = activeSegment.highlightColor; + }); + this.showTooltip(activeSegments); + }); + } + this.calculateTotal(data); + + helpers.each(data,function(datapoint, index){ + this.addData(datapoint, index, true); + },this); + + this.render(); + }, + getSegmentsAtEvent : function(e){ + var segmentsArray = []; + + var location = helpers.getRelativePosition(e); + + helpers.each(this.segments,function(segment){ + if (segment.inRange(location.x,location.y)) segmentsArray.push(segment); + },this); + return segmentsArray; + }, + addData : function(segment, atIndex, silent){ + var index = atIndex || this.segments.length; + this.segments.splice(index, 0, new this.SegmentArc({ + value : segment.value, + outerRadius : (this.options.animateScale) ? 0 : this.outerRadius, + innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout, + fillColor : segment.color, + highlightColor : segment.highlight || segment.color, + showStroke : this.options.segmentShowStroke, + strokeWidth : this.options.segmentStrokeWidth, + strokeColor : this.options.segmentStrokeColor, + startAngle : Math.PI * 1.5, + circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value), + label : segment.label + })); + if (!silent){ + this.reflow(); + this.update(); + } + }, + calculateCircumference : function(value){ + return (Math.PI*2)*(Math.abs(value) / this.total); + }, + calculateTotal : function(data){ + this.total = 0; + helpers.each(data,function(segment){ + this.total += Math.abs(segment.value); + },this); + }, + update : function(){ + this.calculateTotal(this.segments); + + // Reset any highlight colours before updating. + helpers.each(this.activeElements, function(activeElement){ + activeElement.restore(['fillColor']); + }); + + helpers.each(this.segments,function(segment){ + segment.save(); + }); + this.render(); + }, + + removeData: function(atIndex){ + var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1; + this.segments.splice(indexToDelete, 1); + this.reflow(); + this.update(); + }, + + reflow : function(){ + helpers.extend(this.SegmentArc.prototype,{ + x : this.chart.width/2, + y : this.chart.height/2 + }); + this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2; + helpers.each(this.segments, function(segment){ + segment.update({ + outerRadius : this.outerRadius, + innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout + }); + }, this); + }, + draw : function(easeDecimal){ + var animDecimal = (easeDecimal) ? easeDecimal : 1; + this.clear(); + helpers.each(this.segments,function(segment,index){ + segment.transition({ + circumference : this.calculateCircumference(segment.value), + outerRadius : this.outerRadius, + innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout + },animDecimal); + + segment.endAngle = segment.startAngle + segment.circumference; + + segment.draw(); + if (index === 0){ + segment.startAngle = Math.PI * 1.5; + } + //Check to see if it's the last segment, if not get the next and update the start angle + if (index < this.segments.length-1){ + this.segments[index+1].startAngle = segment.endAngle; + } + },this); + + } + }); + + Chart.types.Doughnut.extend({ + name : "Pie", + defaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0}) + }); + +}).call(this); +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + helpers = Chart.helpers; + + var defaultConfig = { + + ///Boolean - Whether grid lines are shown across the chart + scaleShowGridLines : true, + + //String - Colour of the grid lines + scaleGridLineColor : "rgba(0,0,0,.05)", + + //Number - Width of the grid lines + scaleGridLineWidth : 1, + + //Boolean - Whether to show horizontal lines (except X axis) + scaleShowHorizontalLines: true, + + //Boolean - Whether to show vertical lines (except Y axis) + scaleShowVerticalLines: true, + + //Boolean - Whether the line is curved between points + bezierCurve : true, + + //Number - Tension of the bezier curve between points + bezierCurveTension : 0.4, + + //Boolean - Whether to show a dot for each point + pointDot : true, + + //Number - Radius of each point dot in pixels + pointDotRadius : 4, + + //Number - Pixel width of point dot stroke + pointDotStrokeWidth : 1, + + //Number - amount extra to add to the radius to cater for hit detection outside the drawn point + pointHitDetectionRadius : 20, + + //Boolean - Whether to show a stroke for datasets + datasetStroke : true, + + //Number - Pixel width of dataset stroke + datasetStrokeWidth : 2, + + //Boolean - Whether to fill the dataset with a colour + datasetFill : true, + + //String - A legend template + legendTemplate : "
      -legend\"><% for (var i=0; i
    • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
    • <%}%>
    " + + }; + + + Chart.Type.extend({ + name: "Line", + defaults : defaultConfig, + initialize: function(data){ + //Declare the extension of the default point, to cater for the options passed in to the constructor + this.PointClass = Chart.Point.extend({ + strokeWidth : this.options.pointDotStrokeWidth, + radius : this.options.pointDotRadius, + display: this.options.pointDot, + hitDetectionRadius : this.options.pointHitDetectionRadius, + ctx : this.chart.ctx, + inRange : function(mouseX){ + return (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2)); + } + }); + + this.datasets = []; + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : []; + this.eachPoints(function(point){ + point.restore(['fillColor', 'strokeColor']); + }); + helpers.each(activePoints, function(activePoint){ + activePoint.fillColor = activePoint.highlightFill; + activePoint.strokeColor = activePoint.highlightStroke; + }); + this.showTooltip(activePoints); + }); + } + + //Iterate through each of the datasets, and build this into a property of the chart + helpers.each(data.datasets,function(dataset){ + + var datasetObject = { + label : dataset.label || null, + fillColor : dataset.fillColor, + strokeColor : dataset.strokeColor, + pointColor : dataset.pointColor, + pointStrokeColor : dataset.pointStrokeColor, + points : [] + }; + + this.datasets.push(datasetObject); + + + helpers.each(dataset.data,function(dataPoint,index){ + //Add a new point for each piece of data, passing any required data to draw. + datasetObject.points.push(new this.PointClass({ + value : dataPoint, + label : data.labels[index], + datasetLabel: dataset.label, + strokeColor : dataset.pointStrokeColor, + fillColor : dataset.pointColor, + highlightFill : dataset.pointHighlightFill || dataset.pointColor, + highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor + })); + },this); + + this.buildScale(data.labels); + + + this.eachPoints(function(point, index){ + helpers.extend(point, { + x: this.scale.calculateX(index), + y: this.scale.endPoint + }); + point.save(); + }, this); + + },this); + + + this.render(); + }, + update : function(){ + this.scale.update(); + // Reset any highlight colours before updating. + helpers.each(this.activeElements, function(activeElement){ + activeElement.restore(['fillColor', 'strokeColor']); + }); + this.eachPoints(function(point){ + point.save(); + }); + this.render(); + }, + eachPoints : function(callback){ + helpers.each(this.datasets,function(dataset){ + helpers.each(dataset.points,callback,this); + },this); + }, + getPointsAtEvent : function(e){ + var pointsArray = [], + eventPosition = helpers.getRelativePosition(e); + helpers.each(this.datasets,function(dataset){ + helpers.each(dataset.points,function(point){ + if (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point); + }); + },this); + return pointsArray; + }, + buildScale : function(labels){ + var self = this; + + var dataTotal = function(){ + var values = []; + self.eachPoints(function(point){ + values.push(point.value); + }); + + return values; + }; + + var scaleOptions = { + templateString : this.options.scaleLabel, + height : this.chart.height, + width : this.chart.width, + ctx : this.chart.ctx, + textColor : this.options.scaleFontColor, + fontSize : this.options.scaleFontSize, + fontStyle : this.options.scaleFontStyle, + fontFamily : this.options.scaleFontFamily, + valuesCount : labels.length, + beginAtZero : this.options.scaleBeginAtZero, + integersOnly : this.options.scaleIntegersOnly, + calculateYRange : function(currentHeight){ + var updatedRanges = helpers.calculateScaleRange( + dataTotal(), + currentHeight, + this.fontSize, + this.beginAtZero, + this.integersOnly + ); + helpers.extend(this, updatedRanges); + }, + xLabels : labels, + font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily), + lineWidth : this.options.scaleLineWidth, + lineColor : this.options.scaleLineColor, + showHorizontalLines : this.options.scaleShowHorizontalLines, + showVerticalLines : this.options.scaleShowVerticalLines, + gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0, + gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)", + padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth, + showLabels : this.options.scaleShowLabels, + display : this.options.showScale + }; + + if (this.options.scaleOverride){ + helpers.extend(scaleOptions, { + calculateYRange: helpers.noop, + steps: this.options.scaleSteps, + stepValue: this.options.scaleStepWidth, + min: this.options.scaleStartValue, + max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth) + }); + } + + + this.scale = new Chart.Scale(scaleOptions); + }, + addData : function(valuesArray,label){ + //Map the values array for each of the datasets + + helpers.each(valuesArray,function(value,datasetIndex){ + //Add a new point for each piece of data, passing any required data to draw. + this.datasets[datasetIndex].points.push(new this.PointClass({ + value : value, + label : label, + x: this.scale.calculateX(this.scale.valuesCount+1), + y: this.scale.endPoint, + strokeColor : this.datasets[datasetIndex].pointStrokeColor, + fillColor : this.datasets[datasetIndex].pointColor + })); + },this); + + this.scale.addXLabel(label); + //Then re-render the chart. + this.update(); + }, + removeData : function(){ + this.scale.removeXLabel(); + //Then re-render the chart. + helpers.each(this.datasets,function(dataset){ + dataset.points.shift(); + },this); + this.update(); + }, + reflow : function(){ + var newScaleProps = helpers.extend({ + height : this.chart.height, + width : this.chart.width + }); + this.scale.update(newScaleProps); + }, + draw : function(ease){ + var easingDecimal = ease || 1; + this.clear(); + + var ctx = this.chart.ctx; + + // Some helper methods for getting the next/prev points + var hasValue = function(item){ + return item.value !== null; + }, + nextPoint = function(point, collection, index){ + return helpers.findNextWhere(collection, hasValue, index) || point; + }, + previousPoint = function(point, collection, index){ + return helpers.findPreviousWhere(collection, hasValue, index) || point; + }; + + this.scale.draw(easingDecimal); + + + helpers.each(this.datasets,function(dataset){ + var pointsWithValues = helpers.where(dataset.points, hasValue); + + //Transition each point first so that the line and point drawing isn't out of sync + //We can use this extra loop to calculate the control points of this dataset also in this loop + + helpers.each(dataset.points, function(point, index){ + if (point.hasValue()){ + point.transition({ + y : this.scale.calculateY(point.value), + x : this.scale.calculateX(index) + }, easingDecimal); + } + },this); + + + // Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point + // This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed + if (this.options.bezierCurve){ + helpers.each(pointsWithValues, function(point, index){ + var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0; + point.controlPoints = helpers.splineCurve( + previousPoint(point, pointsWithValues, index), + point, + nextPoint(point, pointsWithValues, index), + tension + ); + + // Prevent the bezier going outside of the bounds of the graph + + // Cap puter bezier handles to the upper/lower scale bounds + if (point.controlPoints.outer.y > this.scale.endPoint){ + point.controlPoints.outer.y = this.scale.endPoint; + } + else if (point.controlPoints.outer.y < this.scale.startPoint){ + point.controlPoints.outer.y = this.scale.startPoint; + } + + // Cap inner bezier handles to the upper/lower scale bounds + if (point.controlPoints.inner.y > this.scale.endPoint){ + point.controlPoints.inner.y = this.scale.endPoint; + } + else if (point.controlPoints.inner.y < this.scale.startPoint){ + point.controlPoints.inner.y = this.scale.startPoint; + } + },this); + } + + + //Draw the line between all the points + ctx.lineWidth = this.options.datasetStrokeWidth; + ctx.strokeStyle = dataset.strokeColor; + ctx.beginPath(); + + helpers.each(pointsWithValues, function(point, index){ + if (index === 0){ + ctx.moveTo(point.x, point.y); + } + else{ + if(this.options.bezierCurve){ + var previous = previousPoint(point, pointsWithValues, index); + + ctx.bezierCurveTo( + previous.controlPoints.outer.x, + previous.controlPoints.outer.y, + point.controlPoints.inner.x, + point.controlPoints.inner.y, + point.x, + point.y + ); + } + else{ + ctx.lineTo(point.x,point.y); + } + } + }, this); + + ctx.stroke(); + + if (this.options.datasetFill && pointsWithValues.length > 0){ + //Round off the line by going to the base of the chart, back to the start, then fill. + ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint); + ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint); + ctx.fillStyle = dataset.fillColor; + ctx.closePath(); + ctx.fill(); + } + + //Now draw the points over the line + //A little inefficient double looping, but better than the line + //lagging behind the point positions + helpers.each(pointsWithValues,function(point){ + point.draw(); + }); + },this); + } + }); + + +}).call(this); + +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + //Cache a local reference to Chart.helpers + helpers = Chart.helpers; + + var defaultConfig = { + //Boolean - Show a backdrop to the scale label + scaleShowLabelBackdrop : true, + + //String - The colour of the label backdrop + scaleBackdropColor : "rgba(255,255,255,0.75)", + + // Boolean - Whether the scale should begin at zero + scaleBeginAtZero : true, + + //Number - The backdrop padding above & below the label in pixels + scaleBackdropPaddingY : 2, + + //Number - The backdrop padding to the side of the label in pixels + scaleBackdropPaddingX : 2, + + //Boolean - Show line for each value in the scale + scaleShowLine : true, + + //Boolean - Stroke a line around each segment in the chart + segmentShowStroke : true, + + //String - The colour of the stroke on each segement. + segmentStrokeColor : "#fff", + + //Number - The width of the stroke value in pixels + segmentStrokeWidth : 2, + + //Number - Amount of animation steps + animationSteps : 100, + + //String - Animation easing effect. + animationEasing : "easeOutBounce", + + //Boolean - Whether to animate the rotation of the chart + animateRotate : true, + + //Boolean - Whether to animate scaling the chart from the centre + animateScale : false, + + //String - A legend template + legendTemplate : "
      -legend\"><% for (var i=0; i
    • \"><%if(segments[i].label){%><%=segments[i].label%><%}%>
    • <%}%>
    " + }; + + + Chart.Type.extend({ + //Passing in a name registers this chart in the Chart namespace + name: "PolarArea", + //Providing a defaults will also register the deafults in the chart namespace + defaults : defaultConfig, + //Initialize is fired when the chart is initialized - Data is passed in as a parameter + //Config is automatically merged by the core of Chart.js, and is available at this.options + initialize: function(data){ + this.segments = []; + //Declare segment class as a chart instance specific class, so it can share props for this instance + this.SegmentArc = Chart.Arc.extend({ + showStroke : this.options.segmentShowStroke, + strokeWidth : this.options.segmentStrokeWidth, + strokeColor : this.options.segmentStrokeColor, + ctx : this.chart.ctx, + innerRadius : 0, + x : this.chart.width/2, + y : this.chart.height/2 + }); + this.scale = new Chart.RadialScale({ + display: this.options.showScale, + fontStyle: this.options.scaleFontStyle, + fontSize: this.options.scaleFontSize, + fontFamily: this.options.scaleFontFamily, + fontColor: this.options.scaleFontColor, + showLabels: this.options.scaleShowLabels, + showLabelBackdrop: this.options.scaleShowLabelBackdrop, + backdropColor: this.options.scaleBackdropColor, + backdropPaddingY : this.options.scaleBackdropPaddingY, + backdropPaddingX: this.options.scaleBackdropPaddingX, + lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0, + lineColor: this.options.scaleLineColor, + lineArc: true, + width: this.chart.width, + height: this.chart.height, + xCenter: this.chart.width/2, + yCenter: this.chart.height/2, + ctx : this.chart.ctx, + templateString: this.options.scaleLabel, + valuesCount: data.length + }); + + this.updateScaleRange(data); + + this.scale.update(); + + helpers.each(data,function(segment,index){ + this.addData(segment,index,true); + },this); + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : []; + helpers.each(this.segments,function(segment){ + segment.restore(["fillColor"]); + }); + helpers.each(activeSegments,function(activeSegment){ + activeSegment.fillColor = activeSegment.highlightColor; + }); + this.showTooltip(activeSegments); + }); + } + + this.render(); + }, + getSegmentsAtEvent : function(e){ + var segmentsArray = []; + + var location = helpers.getRelativePosition(e); + + helpers.each(this.segments,function(segment){ + if (segment.inRange(location.x,location.y)) segmentsArray.push(segment); + },this); + return segmentsArray; + }, + addData : function(segment, atIndex, silent){ + var index = atIndex || this.segments.length; + + this.segments.splice(index, 0, new this.SegmentArc({ + fillColor: segment.color, + highlightColor: segment.highlight || segment.color, + label: segment.label, + value: segment.value, + outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value), + circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(), + startAngle: Math.PI * 1.5 + })); + if (!silent){ + this.reflow(); + this.update(); + } + }, + removeData: function(atIndex){ + var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1; + this.segments.splice(indexToDelete, 1); + this.reflow(); + this.update(); + }, + calculateTotal: function(data){ + this.total = 0; + helpers.each(data,function(segment){ + this.total += segment.value; + },this); + this.scale.valuesCount = this.segments.length; + }, + updateScaleRange: function(datapoints){ + var valuesArray = []; + helpers.each(datapoints,function(segment){ + valuesArray.push(segment.value); + }); + + var scaleSizes = (this.options.scaleOverride) ? + { + steps: this.options.scaleSteps, + stepValue: this.options.scaleStepWidth, + min: this.options.scaleStartValue, + max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth) + } : + helpers.calculateScaleRange( + valuesArray, + helpers.min([this.chart.width, this.chart.height])/2, + this.options.scaleFontSize, + this.options.scaleBeginAtZero, + this.options.scaleIntegersOnly + ); + + helpers.extend( + this.scale, + scaleSizes, + { + size: helpers.min([this.chart.width, this.chart.height]), + xCenter: this.chart.width/2, + yCenter: this.chart.height/2 + } + ); + + }, + update : function(){ + this.calculateTotal(this.segments); + + helpers.each(this.segments,function(segment){ + segment.save(); + }); + + this.reflow(); + this.render(); + }, + reflow : function(){ + helpers.extend(this.SegmentArc.prototype,{ + x : this.chart.width/2, + y : this.chart.height/2 + }); + this.updateScaleRange(this.segments); + this.scale.update(); + + helpers.extend(this.scale,{ + xCenter: this.chart.width/2, + yCenter: this.chart.height/2 + }); + + helpers.each(this.segments, function(segment){ + segment.update({ + outerRadius : this.scale.calculateCenterOffset(segment.value) + }); + }, this); + + }, + draw : function(ease){ + var easingDecimal = ease || 1; + //Clear & draw the canvas + this.clear(); + helpers.each(this.segments,function(segment, index){ + segment.transition({ + circumference : this.scale.getCircumference(), + outerRadius : this.scale.calculateCenterOffset(segment.value) + },easingDecimal); + + segment.endAngle = segment.startAngle + segment.circumference; + + // If we've removed the first segment we need to set the first one to + // start at the top. + if (index === 0){ + segment.startAngle = Math.PI * 1.5; + } + + //Check to see if it's the last segment, if not get the next and update the start angle + if (index < this.segments.length - 1){ + this.segments[index+1].startAngle = segment.endAngle; + } + segment.draw(); + }, this); + this.scale.draw(); + } + }); + +}).call(this); +(function(){ + "use strict"; + + var root = this, + Chart = root.Chart, + helpers = Chart.helpers; + + + + Chart.Type.extend({ + name: "Radar", + defaults:{ + //Boolean - Whether to show lines for each scale point + scaleShowLine : true, + + //Boolean - Whether we show the angle lines out of the radar + angleShowLineOut : true, + + //Boolean - Whether to show labels on the scale + scaleShowLabels : false, + + // Boolean - Whether the scale should begin at zero + scaleBeginAtZero : true, + + //String - Colour of the angle line + angleLineColor : "rgba(0,0,0,.1)", + + //Number - Pixel width of the angle line + angleLineWidth : 1, + + //String - Point label font declaration + pointLabelFontFamily : "'Arial'", + + //String - Point label font weight + pointLabelFontStyle : "normal", + + //Number - Point label font size in pixels + pointLabelFontSize : 10, + + //String - Point label font colour + pointLabelFontColor : "#666", + + //Boolean - Whether to show a dot for each point + pointDot : true, + + //Number - Radius of each point dot in pixels + pointDotRadius : 3, + + //Number - Pixel width of point dot stroke + pointDotStrokeWidth : 1, + + //Number - amount extra to add to the radius to cater for hit detection outside the drawn point + pointHitDetectionRadius : 20, + + //Boolean - Whether to show a stroke for datasets + datasetStroke : true, + + //Number - Pixel width of dataset stroke + datasetStrokeWidth : 2, + + //Boolean - Whether to fill the dataset with a colour + datasetFill : true, + + //String - A legend template + legendTemplate : "
      -legend\"><% for (var i=0; i
    • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
    • <%}%>
    " + + }, + + initialize: function(data){ + this.PointClass = Chart.Point.extend({ + strokeWidth : this.options.pointDotStrokeWidth, + radius : this.options.pointDotRadius, + display: this.options.pointDot, + hitDetectionRadius : this.options.pointHitDetectionRadius, + ctx : this.chart.ctx + }); + + this.datasets = []; + + this.buildScale(data); + + //Set up tooltip events on the chart + if (this.options.showTooltips){ + helpers.bindEvents(this, this.options.tooltipEvents, function(evt){ + var activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : []; + + this.eachPoints(function(point){ + point.restore(['fillColor', 'strokeColor']); + }); + helpers.each(activePointsCollection, function(activePoint){ + activePoint.fillColor = activePoint.highlightFill; + activePoint.strokeColor = activePoint.highlightStroke; + }); + + this.showTooltip(activePointsCollection); + }); + } + + //Iterate through each of the datasets, and build this into a property of the chart + helpers.each(data.datasets,function(dataset){ + + var datasetObject = { + label: dataset.label || null, + fillColor : dataset.fillColor, + strokeColor : dataset.strokeColor, + pointColor : dataset.pointColor, + pointStrokeColor : dataset.pointStrokeColor, + points : [] + }; + + this.datasets.push(datasetObject); + + helpers.each(dataset.data,function(dataPoint,index){ + //Add a new point for each piece of data, passing any required data to draw. + var pointPosition; + if (!this.scale.animation){ + pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint)); + } + datasetObject.points.push(new this.PointClass({ + value : dataPoint, + label : data.labels[index], + datasetLabel: dataset.label, + x: (this.options.animation) ? this.scale.xCenter : pointPosition.x, + y: (this.options.animation) ? this.scale.yCenter : pointPosition.y, + strokeColor : dataset.pointStrokeColor, + fillColor : dataset.pointColor, + highlightFill : dataset.pointHighlightFill || dataset.pointColor, + highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor + })); + },this); + + },this); + + this.render(); + }, + eachPoints : function(callback){ + helpers.each(this.datasets,function(dataset){ + helpers.each(dataset.points,callback,this); + },this); + }, + + getPointsAtEvent : function(evt){ + var mousePosition = helpers.getRelativePosition(evt), + fromCenter = helpers.getAngleFromPoint({ + x: this.scale.xCenter, + y: this.scale.yCenter + }, mousePosition); + + var anglePerIndex = (Math.PI * 2) /this.scale.valuesCount, + pointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex), + activePointsCollection = []; + + // If we're at the top, make the pointIndex 0 to get the first of the array. + if (pointIndex >= this.scale.valuesCount || pointIndex < 0){ + pointIndex = 0; + } + + if (fromCenter.distance <= this.scale.drawingArea){ + helpers.each(this.datasets, function(dataset){ + activePointsCollection.push(dataset.points[pointIndex]); + }); + } + + return activePointsCollection; + }, + + buildScale : function(data){ + this.scale = new Chart.RadialScale({ + display: this.options.showScale, + fontStyle: this.options.scaleFontStyle, + fontSize: this.options.scaleFontSize, + fontFamily: this.options.scaleFontFamily, + fontColor: this.options.scaleFontColor, + showLabels: this.options.scaleShowLabels, + showLabelBackdrop: this.options.scaleShowLabelBackdrop, + backdropColor: this.options.scaleBackdropColor, + backdropPaddingY : this.options.scaleBackdropPaddingY, + backdropPaddingX: this.options.scaleBackdropPaddingX, + lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0, + lineColor: this.options.scaleLineColor, + angleLineColor : this.options.angleLineColor, + angleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0, + // Point labels at the edge of each line + pointLabelFontColor : this.options.pointLabelFontColor, + pointLabelFontSize : this.options.pointLabelFontSize, + pointLabelFontFamily : this.options.pointLabelFontFamily, + pointLabelFontStyle : this.options.pointLabelFontStyle, + height : this.chart.height, + width: this.chart.width, + xCenter: this.chart.width/2, + yCenter: this.chart.height/2, + ctx : this.chart.ctx, + templateString: this.options.scaleLabel, + labels: data.labels, + valuesCount: data.datasets[0].data.length + }); + + this.scale.setScaleSize(); + this.updateScaleRange(data.datasets); + this.scale.buildYLabels(); + }, + updateScaleRange: function(datasets){ + var valuesArray = (function(){ + var totalDataArray = []; + helpers.each(datasets,function(dataset){ + if (dataset.data){ + totalDataArray = totalDataArray.concat(dataset.data); + } + else { + helpers.each(dataset.points, function(point){ + totalDataArray.push(point.value); + }); + } + }); + return totalDataArray; + })(); + + + var scaleSizes = (this.options.scaleOverride) ? + { + steps: this.options.scaleSteps, + stepValue: this.options.scaleStepWidth, + min: this.options.scaleStartValue, + max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth) + } : + helpers.calculateScaleRange( + valuesArray, + helpers.min([this.chart.width, this.chart.height])/2, + this.options.scaleFontSize, + this.options.scaleBeginAtZero, + this.options.scaleIntegersOnly + ); + + helpers.extend( + this.scale, + scaleSizes + ); + + }, + addData : function(valuesArray,label){ + //Map the values array for each of the datasets + this.scale.valuesCount++; + helpers.each(valuesArray,function(value,datasetIndex){ + var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value)); + this.datasets[datasetIndex].points.push(new this.PointClass({ + value : value, + label : label, + x: pointPosition.x, + y: pointPosition.y, + strokeColor : this.datasets[datasetIndex].pointStrokeColor, + fillColor : this.datasets[datasetIndex].pointColor + })); + },this); + + this.scale.labels.push(label); + + this.reflow(); + + this.update(); + }, + removeData : function(){ + this.scale.valuesCount--; + this.scale.labels.shift(); + helpers.each(this.datasets,function(dataset){ + dataset.points.shift(); + },this); + this.reflow(); + this.update(); + }, + update : function(){ + this.eachPoints(function(point){ + point.save(); + }); + this.reflow(); + this.render(); + }, + reflow: function(){ + helpers.extend(this.scale, { + width : this.chart.width, + height: this.chart.height, + size : helpers.min([this.chart.width, this.chart.height]), + xCenter: this.chart.width/2, + yCenter: this.chart.height/2 + }); + this.updateScaleRange(this.datasets); + this.scale.setScaleSize(); + this.scale.buildYLabels(); + }, + draw : function(ease){ + var easeDecimal = ease || 1, + ctx = this.chart.ctx; + this.clear(); + this.scale.draw(); + + helpers.each(this.datasets,function(dataset){ + + //Transition each point first so that the line and point drawing isn't out of sync + helpers.each(dataset.points,function(point,index){ + if (point.hasValue()){ + point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal); + } + },this); + + + + //Draw the line between all the points + ctx.lineWidth = this.options.datasetStrokeWidth; + ctx.strokeStyle = dataset.strokeColor; + ctx.beginPath(); + helpers.each(dataset.points,function(point,index){ + if (index === 0){ + ctx.moveTo(point.x,point.y); + } + else{ + ctx.lineTo(point.x,point.y); + } + },this); + ctx.closePath(); + ctx.stroke(); + + ctx.fillStyle = dataset.fillColor; + ctx.fill(); + + //Now draw the points over the line + //A little inefficient double looping, but better than the line + //lagging behind the point positions + helpers.each(dataset.points,function(point){ + if (point.hasValue()){ + point.draw(); + } + }); + + },this); + + } + + }); + + + + + +}).call(this); \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/js/Chart.min.js b/deployed/icagenda/media/com_icagenda/js/Chart.min.js new file mode 100644 index 00000000..3a0a2c87 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/Chart.min.js @@ -0,0 +1,11 @@ +/*! + * Chart.js + * http://chartjs.org/ + * Version: 1.0.2 + * + * Copyright 2015 Nick Downie + * Released under the MIT license + * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md + */ +(function(){"use strict";var t=this,i=t.Chart,e=function(t){this.canvas=t.canvas,this.ctx=t;var i=function(t,i){return t["offset"+i]?t["offset"+i]:document.defaultView.getComputedStyle(t).getPropertyValue(i)},e=this.width=i(t.canvas,"Width"),n=this.height=i(t.canvas,"Height");t.canvas.width=e,t.canvas.height=n;var e=this.width=t.canvas.width,n=this.height=t.canvas.height;return this.aspectRatio=this.width/this.height,s.retinaScale(this),this};e.defaults={global:{animation:!0,animationSteps:60,animationEasing:"easeOutQuart",showScale:!0,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleIntegersOnly:!0,scaleBeginAtZero:!1,scaleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",responsive:!1,maintainAspectRatio:!0,showTooltips:!0,customTooltips:!1,tooltipEvents:["mousemove","touchstart","touchmove","mouseout"],tooltipFillColor:"rgba(0,0,0,0.8)",tooltipFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipFontSize:14,tooltipFontStyle:"normal",tooltipFontColor:"#fff",tooltipTitleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipTitleFontSize:14,tooltipTitleFontStyle:"bold",tooltipTitleFontColor:"#fff",tooltipYPadding:6,tooltipXPadding:6,tooltipCaretSize:8,tooltipCornerRadius:6,tooltipXOffset:10,tooltipTemplate:"<%if (label){%><%=label%>: <%}%><%= value %>",multiTooltipTemplate:"<%= value %>",multiTooltipKeyBackground:"#fff",onAnimationProgress:function(){},onAnimationComplete:function(){}}},e.types={};var s=e.helpers={},n=s.each=function(t,i,e){var s=Array.prototype.slice.call(arguments,3);if(t)if(t.length===+t.length){var n;for(n=0;n=0;s--){var n=t[s];if(i(n))return n}},s.inherits=function(t){var i=this,e=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return i.apply(this,arguments)},s=function(){this.constructor=e};return s.prototype=i.prototype,e.prototype=new s,e.extend=r,t&&a(e.prototype,t),e.__super__=i.prototype,e}),c=s.noop=function(){},u=s.uid=function(){var t=0;return function(){return"chart-"+t++}}(),d=s.warn=function(t){window.console&&"function"==typeof window.console.warn&&console.warn(t)},p=s.amd="function"==typeof define&&define.amd,f=s.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},g=s.max=function(t){return Math.max.apply(Math,t)},m=s.min=function(t){return Math.min.apply(Math,t)},v=(s.cap=function(t,i,e){if(f(i)){if(t>i)return i}else if(f(e)&&e>t)return e;return t},s.getDecimalPlaces=function(t){return t%1!==0&&f(t)?t.toString().split(".")[1].length:0}),S=s.radians=function(t){return t*(Math.PI/180)},x=(s.getAngleFromPoint=function(t,i){var e=i.x-t.x,s=i.y-t.y,n=Math.sqrt(e*e+s*s),o=2*Math.PI+Math.atan2(s,e);return 0>e&&0>s&&(o+=2*Math.PI),{angle:o,distance:n}},s.aliasPixel=function(t){return t%2===0?0:.5}),y=(s.splineCurve=function(t,i,e,s){var n=Math.sqrt(Math.pow(i.x-t.x,2)+Math.pow(i.y-t.y,2)),o=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),a=s*n/(n+o),h=s*o/(n+o);return{inner:{x:i.x-a*(e.x-t.x),y:i.y-a*(e.y-t.y)},outer:{x:i.x+h*(e.x-t.x),y:i.y+h*(e.y-t.y)}}},s.calculateOrderOfMagnitude=function(t){return Math.floor(Math.log(t)/Math.LN10)}),C=(s.calculateScaleRange=function(t,i,e,s,n){var o=2,a=Math.floor(i/(1.5*e)),h=o>=a,l=g(t),r=m(t);l===r&&(l+=.5,r>=.5&&!s?r-=.5:l+=.5);for(var c=Math.abs(l-r),u=y(c),d=Math.ceil(l/(1*Math.pow(10,u)))*Math.pow(10,u),p=s?0:Math.floor(r/(1*Math.pow(10,u)))*Math.pow(10,u),f=d-p,v=Math.pow(10,u),S=Math.round(f/v);(S>a||a>2*S)&&!h;)if(S>a)v*=2,S=Math.round(f/v),S%1!==0&&(h=!0);else if(n&&u>=0){if(v/2%1!==0)break;v/=2,S=Math.round(f/v)}else v/=2,S=Math.round(f/v);return h&&(S=o,v=f/S),{steps:S,stepValue:v,min:p,max:p+S*v}},s.template=function(t,i){function e(t,i){var e=/\W/.test(t)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+t.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"):s[t]=s[t];return i?e(i):e}if(t instanceof Function)return t(i);var s={};return e(t,i)}),w=(s.generateLabels=function(t,i,e,s){var o=new Array(i);return labelTemplateString&&n(o,function(i,n){o[n]=C(t,{value:e+s*(n+1)})}),o},s.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),st?-.5*s*Math.pow(2,10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e):s*Math.pow(2,-10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e)*.5+1)},easeInBack:function(t){var i=1.70158;return 1*(t/=1)*t*((i+1)*t-i)},easeOutBack:function(t){var i=1.70158;return 1*((t=t/1-1)*t*((i+1)*t+i)+1)},easeInOutBack:function(t){var i=1.70158;return(t/=.5)<1?.5*t*t*(((i*=1.525)+1)*t-i):.5*((t-=2)*t*(((i*=1.525)+1)*t+i)+2)},easeInBounce:function(t){return 1-w.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?7.5625*t*t:2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*w.easeInBounce(2*t):.5*w.easeOutBounce(2*t-1)+.5}}),b=s.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),P=s.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),L=(s.animationLoop=function(t,i,e,s,n,o){var a=0,h=w[e]||w.linear,l=function(){a++;var e=a/i,r=h(e);t.call(o,r,e,a),s.call(o,r,e),i>a?o.animationFrame=b(l):n.apply(o)};b(l)},s.getRelativePosition=function(t){var i,e,s=t.originalEvent||t,n=t.currentTarget||t.srcElement,o=n.getBoundingClientRect();return s.touches?(i=s.touches[0].clientX-o.left,e=s.touches[0].clientY-o.top):(i=s.clientX-o.left,e=s.clientY-o.top),{x:i,y:e}},s.addEvent=function(t,i,e){t.addEventListener?t.addEventListener(i,e):t.attachEvent?t.attachEvent("on"+i,e):t["on"+i]=e}),k=s.removeEvent=function(t,i,e){t.removeEventListener?t.removeEventListener(i,e,!1):t.detachEvent?t.detachEvent("on"+i,e):t["on"+i]=c},F=(s.bindEvents=function(t,i,e){t.events||(t.events={}),n(i,function(i){t.events[i]=function(){e.apply(t,arguments)},L(t.chart.canvas,i,t.events[i])})},s.unbindEvents=function(t,i){n(i,function(i,e){k(t.chart.canvas,e,i)})}),R=s.getMaximumWidth=function(t){var i=t.parentNode;return i.clientWidth},T=s.getMaximumHeight=function(t){var i=t.parentNode;return i.clientHeight},A=(s.getMaximumSize=s.getMaximumWidth,s.retinaScale=function(t){var i=t.ctx,e=t.canvas.width,s=t.canvas.height;window.devicePixelRatio&&(i.canvas.style.width=e+"px",i.canvas.style.height=s+"px",i.canvas.height=s*window.devicePixelRatio,i.canvas.width=e*window.devicePixelRatio,i.scale(window.devicePixelRatio,window.devicePixelRatio))}),M=s.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},W=s.fontString=function(t,i,e){return i+" "+t+"px "+e},z=s.longestText=function(t,i,e){t.font=i;var s=0;return n(e,function(i){var e=t.measureText(i).width;s=e>s?e:s}),s},B=s.drawRoundedRectangle=function(t,i,e,s,n,o){t.beginPath(),t.moveTo(i+o,e),t.lineTo(i+s-o,e),t.quadraticCurveTo(i+s,e,i+s,e+o),t.lineTo(i+s,e+n-o),t.quadraticCurveTo(i+s,e+n,i+s-o,e+n),t.lineTo(i+o,e+n),t.quadraticCurveTo(i,e+n,i,e+n-o),t.lineTo(i,e+o),t.quadraticCurveTo(i,e,i+o,e),t.closePath()};e.instances={},e.Type=function(t,i,s){this.options=i,this.chart=s,this.id=u(),e.instances[this.id]=this,i.responsive&&this.resize(),this.initialize.call(this,t)},a(e.Type.prototype,{initialize:function(){return this},clear:function(){return M(this.chart),this},stop:function(){return P(this.animationFrame),this},resize:function(t){this.stop();var i=this.chart.canvas,e=R(this.chart.canvas),s=this.options.maintainAspectRatio?e/this.chart.aspectRatio:T(this.chart.canvas);return i.width=this.chart.width=e,i.height=this.chart.height=s,A(this.chart),"function"==typeof t&&t.apply(this,Array.prototype.slice.call(arguments,1)),this},reflow:c,render:function(t){return t&&this.reflow(),this.options.animation&&!t?s.animationLoop(this.draw,this.options.animationSteps,this.options.animationEasing,this.options.onAnimationProgress,this.options.onAnimationComplete,this):(this.draw(),this.options.onAnimationComplete.call(this)),this},generateLegend:function(){return C(this.options.legendTemplate,this)},destroy:function(){this.clear(),F(this,this.events);var t=this.chart.canvas;t.width=this.chart.width,t.height=this.chart.height,t.style.removeProperty?(t.style.removeProperty("width"),t.style.removeProperty("height")):(t.style.removeAttribute("width"),t.style.removeAttribute("height")),delete e.instances[this.id]},showTooltip:function(t,i){"undefined"==typeof this.activeElements&&(this.activeElements=[]);var o=function(t){var i=!1;return t.length!==this.activeElements.length?i=!0:(n(t,function(t,e){t!==this.activeElements[e]&&(i=!0)},this),i)}.call(this,t);if(o||i){if(this.activeElements=t,this.draw(),this.options.customTooltips&&this.options.customTooltips(!1),t.length>0)if(this.datasets&&this.datasets.length>1){for(var a,h,r=this.datasets.length-1;r>=0&&(a=this.datasets[r].points||this.datasets[r].bars||this.datasets[r].segments,h=l(a,t[0]),-1===h);r--);var c=[],u=[],d=function(){var t,i,e,n,o,a=[],l=[],r=[];return s.each(this.datasets,function(i){t=i.points||i.bars||i.segments,t[h]&&t[h].hasValue()&&a.push(t[h])}),s.each(a,function(t){l.push(t.x),r.push(t.y),c.push(s.template(this.options.multiTooltipTemplate,t)),u.push({fill:t._saved.fillColor||t.fillColor,stroke:t._saved.strokeColor||t.strokeColor})},this),o=m(r),e=g(r),n=m(l),i=g(l),{x:n>this.chart.width/2?n:i,y:(o+e)/2}}.call(this,h);new e.MultiTooltip({x:d.x,y:d.y,xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,xOffset:this.options.tooltipXOffset,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,titleTextColor:this.options.tooltipTitleFontColor,titleFontFamily:this.options.tooltipTitleFontFamily,titleFontStyle:this.options.tooltipTitleFontStyle,titleFontSize:this.options.tooltipTitleFontSize,cornerRadius:this.options.tooltipCornerRadius,labels:c,legendColors:u,legendColorBackground:this.options.multiTooltipKeyBackground,title:t[0].label,chart:this.chart,ctx:this.chart.ctx,custom:this.options.customTooltips}).draw()}else n(t,function(t){var i=t.tooltipPosition();new e.Tooltip({x:Math.round(i.x),y:Math.round(i.y),xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,caretHeight:this.options.tooltipCaretSize,cornerRadius:this.options.tooltipCornerRadius,text:C(this.options.tooltipTemplate,t),chart:this.chart,custom:this.options.customTooltips}).draw()},this);return this}},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)}}),e.Type.extend=function(t){var i=this,s=function(){return i.apply(this,arguments)};if(s.prototype=o(i.prototype),a(s.prototype,t),s.extend=e.Type.extend,t.name||i.prototype.name){var n=t.name||i.prototype.name,l=e.defaults[i.prototype.name]?o(e.defaults[i.prototype.name]):{};e.defaults[n]=a(l,t.defaults),e.types[n]=s,e.prototype[n]=function(t,i){var o=h(e.defaults.global,e.defaults[n],i||{});return new s(t,o,this)}}else d("Name not provided for this chart, so it hasn't been registered");return i},e.Element=function(t){a(this,t),this.initialize.apply(this,arguments),this.save()},a(e.Element.prototype,{initialize:function(){},restore:function(t){return t?n(t,function(t){this[t]=this._saved[t]},this):a(this,this._saved),this},save:function(){return this._saved=o(this),delete this._saved._saved,this},update:function(t){return n(t,function(t,i){this._saved[i]=this[i],this[i]=t},this),this},transition:function(t,i){return n(t,function(t,e){this[e]=(t-this._saved[e])*i+this._saved[e]},this),this},tooltipPosition:function(){return{x:this.x,y:this.y}},hasValue:function(){return f(this.value)}}),e.Element.extend=r,e.Point=e.Element.extend({display:!0,inRange:function(t,i){var e=this.hitDetectionRadius+this.radius;return Math.pow(t-this.x,2)+Math.pow(i-this.y,2)=this.startAngle&&e.angle<=this.endAngle,o=e.distance>=this.innerRadius&&e.distance<=this.outerRadius;return n&&o},tooltipPosition:function(){var t=this.startAngle+(this.endAngle-this.startAngle)/2,i=(this.outerRadius-this.innerRadius)/2+this.innerRadius;return{x:this.x+Math.cos(t)*i,y:this.y+Math.sin(t)*i}},draw:function(t){var i=this.ctx;i.beginPath(),i.arc(this.x,this.y,this.outerRadius,this.startAngle,this.endAngle),i.arc(this.x,this.y,this.innerRadius,this.endAngle,this.startAngle,!0),i.closePath(),i.strokeStyle=this.strokeColor,i.lineWidth=this.strokeWidth,i.fillStyle=this.fillColor,i.fill(),i.lineJoin="bevel",this.showStroke&&i.stroke()}}),e.Rectangle=e.Element.extend({draw:function(){var t=this.ctx,i=this.width/2,e=this.x-i,s=this.x+i,n=this.base-(this.base-this.y),o=this.strokeWidth/2;this.showStroke&&(e+=o,s-=o,n+=o),t.beginPath(),t.fillStyle=this.fillColor,t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.moveTo(e,this.base),t.lineTo(e,n),t.lineTo(s,n),t.lineTo(s,this.base),t.fill(),this.showStroke&&t.stroke()},height:function(){return this.base-this.y},inRange:function(t,i){return t>=this.x-this.width/2&&t<=this.x+this.width/2&&i>=this.y&&i<=this.base}}),e.Tooltip=e.Element.extend({draw:function(){var t=this.chart.ctx;t.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.xAlign="center",this.yAlign="above";var i=this.caretPadding=2,e=t.measureText(this.text).width+2*this.xPadding,s=this.fontSize+2*this.yPadding,n=s+this.caretHeight+i;this.x+e/2>this.chart.width?this.xAlign="left":this.x-e/2<0&&(this.xAlign="right"),this.y-n<0&&(this.yAlign="below");var o=this.x-e/2,a=this.y-n;if(t.fillStyle=this.fillColor,this.custom)this.custom(this);else{switch(this.yAlign){case"above":t.beginPath(),t.moveTo(this.x,this.y-i),t.lineTo(this.x+this.caretHeight,this.y-(i+this.caretHeight)),t.lineTo(this.x-this.caretHeight,this.y-(i+this.caretHeight)),t.closePath(),t.fill();break;case"below":a=this.y+i+this.caretHeight,t.beginPath(),t.moveTo(this.x,this.y+i),t.lineTo(this.x+this.caretHeight,this.y+i+this.caretHeight),t.lineTo(this.x-this.caretHeight,this.y+i+this.caretHeight),t.closePath(),t.fill()}switch(this.xAlign){case"left":o=this.x-e+(this.cornerRadius+this.caretHeight);break;case"right":o=this.x-(this.cornerRadius+this.caretHeight)}B(t,o,a,e,s,this.cornerRadius),t.fill(),t.fillStyle=this.textColor,t.textAlign="center",t.textBaseline="middle",t.fillText(this.text,o+e/2,a+s/2)}}}),e.MultiTooltip=e.Element.extend({initialize:function(){this.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.titleFont=W(this.titleFontSize,this.titleFontStyle,this.titleFontFamily),this.height=this.labels.length*this.fontSize+(this.labels.length-1)*(this.fontSize/2)+2*this.yPadding+1.5*this.titleFontSize,this.ctx.font=this.titleFont;var t=this.ctx.measureText(this.title).width,i=z(this.ctx,this.font,this.labels)+this.fontSize+3,e=g([i,t]);this.width=e+2*this.xPadding;var s=this.height/2;this.y-s<0?this.y=s:this.y+s>this.chart.height&&(this.y=this.chart.height-s),this.x>this.chart.width/2?this.x-=this.xOffset+this.width:this.x+=this.xOffset},getLineHeight:function(t){var i=this.y-this.height/2+this.yPadding,e=t-1;return 0===t?i+this.titleFontSize/2:i+(1.5*this.fontSize*e+this.fontSize/2)+1.5*this.titleFontSize},draw:function(){if(this.custom)this.custom(this);else{B(this.ctx,this.x,this.y-this.height/2,this.width,this.height,this.cornerRadius);var t=this.ctx;t.fillStyle=this.fillColor,t.fill(),t.closePath(),t.textAlign="left",t.textBaseline="middle",t.fillStyle=this.titleTextColor,t.font=this.titleFont,t.fillText(this.title,this.x+this.xPadding,this.getLineHeight(0)),t.font=this.font,s.each(this.labels,function(i,e){t.fillStyle=this.textColor,t.fillText(i,this.x+this.xPadding+this.fontSize+3,this.getLineHeight(e+1)),t.fillStyle=this.legendColorBackground,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize),t.fillStyle=this.legendColors[e].fill,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize)},this)}}}),e.Scale=e.Element.extend({initialize:function(){this.fit()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}));this.yLabelWidth=this.display&&this.showLabels?z(this.ctx,this.font,this.yLabels):0},addXLabel:function(t){this.xLabels.push(t),this.valuesCount++,this.fit()},removeXLabel:function(){this.xLabels.shift(),this.valuesCount--,this.fit()},fit:function(){this.startPoint=this.display?this.fontSize:0,this.endPoint=this.display?this.height-1.5*this.fontSize-5:this.height,this.startPoint+=this.padding,this.endPoint-=this.padding;var t,i=this.endPoint-this.startPoint;for(this.calculateYRange(i),this.buildYLabels(),this.calculateXLabelRotation();i>this.endPoint-this.startPoint;)i=this.endPoint-this.startPoint,t=this.yLabelWidth,this.calculateYRange(i),this.buildYLabels(),tthis.yLabelWidth+10?e/2:this.yLabelWidth+10,this.xLabelRotation=0,this.display){var n,o=z(this.ctx,this.font,this.xLabels);this.xLabelWidth=o;for(var a=Math.floor(this.calculateX(1)-this.calculateX(0))-6;this.xLabelWidth>a&&0===this.xLabelRotation||this.xLabelWidth>a&&this.xLabelRotation<=90&&this.xLabelRotation>0;)n=Math.cos(S(this.xLabelRotation)),t=n*e,i=n*s,t+this.fontSize/2>this.yLabelWidth+8&&(this.xScalePaddingLeft=t+this.fontSize/2),this.xScalePaddingRight=this.fontSize/2,this.xLabelRotation++,this.xLabelWidth=n*o;this.xLabelRotation>0&&(this.endPoint-=Math.sin(S(this.xLabelRotation))*o+3)}else this.xLabelWidth=0,this.xScalePaddingRight=this.padding,this.xScalePaddingLeft=this.padding},calculateYRange:c,drawingArea:function(){return this.startPoint-this.endPoint},calculateY:function(t){var i=this.drawingArea()/(this.min-this.max);return this.endPoint-i*(t-this.min)},calculateX:function(t){var i=(this.xLabelRotation>0,this.width-(this.xScalePaddingLeft+this.xScalePaddingRight)),e=i/Math.max(this.valuesCount-(this.offsetGridLines?0:1),1),s=e*t+this.xScalePaddingLeft;return this.offsetGridLines&&(s+=e/2),Math.round(s)},update:function(t){s.extend(this,t),this.fit()},draw:function(){var t=this.ctx,i=(this.endPoint-this.startPoint)/this.steps,e=Math.round(this.xScalePaddingLeft);this.display&&(t.fillStyle=this.textColor,t.font=this.font,n(this.yLabels,function(n,o){var a=this.endPoint-i*o,h=Math.round(a),l=this.showHorizontalLines;t.textAlign="right",t.textBaseline="middle",this.showLabels&&t.fillText(n,e-10,a),0!==o||l||(l=!0),l&&t.beginPath(),o>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),h+=s.aliasPixel(t.lineWidth),l&&(t.moveTo(e,h),t.lineTo(this.width,h),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(e-5,h),t.lineTo(e,h),t.stroke(),t.closePath()},this),n(this.xLabels,function(i,e){var s=this.calculateX(e)+x(this.lineWidth),n=this.calculateX(e-(this.offsetGridLines?.5:0))+x(this.lineWidth),o=this.xLabelRotation>0,a=this.showVerticalLines;0!==e||a||(a=!0),a&&t.beginPath(),e>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),a&&(t.moveTo(n,this.endPoint),t.lineTo(n,this.startPoint-3),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(n,this.endPoint),t.lineTo(n,this.endPoint+5),t.stroke(),t.closePath(),t.save(),t.translate(s,o?this.endPoint+12:this.endPoint+8),t.rotate(-1*S(this.xLabelRotation)),t.font=this.font,t.textAlign=o?"right":"center",t.textBaseline=o?"middle":"top",t.fillText(i,0,0),t.restore()},this))}}),e.RadialScale=e.Element.extend({initialize:function(){this.size=m([this.height,this.width]),this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2},calculateCenterOffset:function(t){var i=this.drawingArea/(this.max-this.min);return(t-this.min)*i},update:function(){this.lineArc?this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2:this.setScaleSize(),this.buildYLabels()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}))},getCircumference:function(){return 2*Math.PI/this.valuesCount},setScaleSize:function(){var t,i,e,s,n,o,a,h,l,r,c,u,d=m([this.height/2-this.pointLabelFontSize-5,this.width/2]),p=this.width,g=0;for(this.ctx.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),i=0;ip&&(p=t.x+s,n=i),t.x-sp&&(p=t.x+e,n=i):i>this.valuesCount/2&&t.x-e0){var s,n=e*(this.drawingArea/this.steps),o=this.yCenter-n;if(this.lineWidth>0)if(t.strokeStyle=this.lineColor,t.lineWidth=this.lineWidth,this.lineArc)t.beginPath(),t.arc(this.xCenter,this.yCenter,n,0,2*Math.PI),t.closePath(),t.stroke();else{t.beginPath();for(var a=0;a=0;i--){if(this.angleLineWidth>0){var e=this.getPointPosition(i,this.calculateCenterOffset(this.max));t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(e.x,e.y),t.stroke(),t.closePath()}var s=this.getPointPosition(i,this.calculateCenterOffset(this.max)+5);t.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),t.fillStyle=this.pointLabelFontColor;var o=this.labels.length,a=this.labels.length/2,h=a/2,l=h>i||i>o-h,r=i===h||i===o-h;t.textAlign=0===i?"center":i===a?"center":a>i?"left":"right",t.textBaseline=r?"middle":l?"bottom":"top",t.fillText(this.labels[i],s.x,s.y)}}}}}),s.addEvent(window,"resize",function(){var t;return function(){clearTimeout(t),t=setTimeout(function(){n(e.instances,function(t){t.options.responsive&&t.resize(t.render,!0)})},50)}}()),p?define(function(){return e}):"object"==typeof module&&module.exports&&(module.exports=e),t.Chart=e,e.noConflict=function(){return t.Chart=i,e}}).call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleBeginAtZero:!0,scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,scaleShowHorizontalLines:!0,scaleShowVerticalLines:!0,barShowStroke:!0,barStrokeWidth:2,barValueSpacing:5,barDatasetSpacing:1,legendTemplate:'
      <% for (var i=0; i
    • <%if(datasets[i].label){%><%=datasets[i].label%><%}%>
    • <%}%>
    '};i.Type.extend({name:"Bar",defaults:s,initialize:function(t){var s=this.options;this.ScaleClass=i.Scale.extend({offsetGridLines:!0,calculateBarX:function(t,i,e){var n=this.calculateBaseWidth(),o=this.calculateX(e)-n/2,a=this.calculateBarWidth(t);return o+a*i+i*s.barDatasetSpacing+a/2},calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)-2*s.barValueSpacing},calculateBarWidth:function(t){var i=this.calculateBaseWidth()-(t-1)*s.barDatasetSpacing;return i/t}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getBarsAtEvent(t):[];this.eachBars(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),this.BarClass=i.Rectangle.extend({strokeWidth:this.options.barStrokeWidth,showStroke:this.options.barShowStroke,ctx:this.chart.ctx}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,bars:[]};this.datasets.push(s),e.each(i.data,function(e,n){s.bars.push(new this.BarClass({value:e,label:t.labels[n],datasetLabel:i.label,strokeColor:i.strokeColor,fillColor:i.fillColor,highlightFill:i.highlightFill||i.fillColor,highlightStroke:i.highlightStroke||i.strokeColor}))},this)},this),this.buildScale(t.labels),this.BarClass.prototype.base=this.scale.endPoint,this.eachBars(function(t,i,s){e.extend(t,{width:this.scale.calculateBarWidth(this.datasets.length),x:this.scale.calculateBarX(this.datasets.length,s,i),y:this.scale.endPoint}),t.save()},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachBars(function(t){t.save()}),this.render()},eachBars:function(t){e.each(this.datasets,function(i,s){e.each(i.bars,t,this,s)},this)},getBarsAtEvent:function(t){for(var i,s=[],n=e.getRelativePosition(t),o=function(t){s.push(t.bars[i])},a=0;a<% for (var i=0; i
  • <%if(segments[i].label){%><%=segments[i].label%><%}%>
  • <%}%>'};i.Type.extend({name:"Doughnut",defaults:s,initialize:function(t){this.segments=[],this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,this.SegmentArc=i.Arc.extend({ctx:this.chart.ctx,x:this.chart.width/2,y:this.chart.height/2}),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.calculateTotal(t),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({value:t.value,outerRadius:this.options.animateScale?0:this.outerRadius,innerRadius:this.options.animateScale?0:this.outerRadius/100*this.options.percentageInnerCutout,fillColor:t.color,highlightColor:t.highlight||t.color,showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,startAngle:1.5*Math.PI,circumference:this.options.animateRotate?0:this.calculateCircumference(t.value),label:t.label})),e||(this.reflow(),this.update())},calculateCircumference:function(t){return 2*Math.PI*(Math.abs(t)/this.total)},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=Math.abs(t.value)},this)},update:function(){this.calculateTotal(this.segments),e.each(this.activeElements,function(t){t.restore(["fillColor"])}),e.each(this.segments,function(t){t.save()}),this.render()},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,e.each(this.segments,function(t){t.update({outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout})},this)},draw:function(t){var i=t?t:1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.calculateCircumference(t.value),outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout},i),t.endAngle=t.startAngle+t.circumference,t.draw(),0===e&&(t.startAngle=1.5*Math.PI),e<% for (var i=0; i
  • <%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>'};i.Type.extend({name:"Line",defaults:s,initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx,inRange:function(t){return Math.pow(t-this.x,2)0&&ithis.scale.endPoint?t.controlPoints.outer.y=this.scale.endPoint:t.controlPoints.outer.ythis.scale.endPoint?t.controlPoints.inner.y=this.scale.endPoint:t.controlPoints.inner.y0&&(s.lineTo(h[h.length-1].x,this.scale.endPoint),s.lineTo(h[0].x,this.scale.endPoint),s.fillStyle=t.fillColor,s.closePath(),s.fill()),e.each(h,function(t){t.draw()})},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBeginAtZero:!0,scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,scaleShowLine:!0,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'
      <% for (var i=0; i
    • <%if(segments[i].label){%><%=segments[i].label%><%}%>
    • <%}%>
    '};i.Type.extend({name:"PolarArea",defaults:s,initialize:function(t){this.segments=[],this.SegmentArc=i.Arc.extend({showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,ctx:this.chart.ctx,innerRadius:0,x:this.chart.width/2,y:this.chart.height/2}),this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,lineArc:!0,width:this.chart.width,height:this.chart.height,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,valuesCount:t.length}),this.updateScaleRange(t),this.scale.update(),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({fillColor:t.color,highlightColor:t.highlight||t.color,label:t.label,value:t.value,outerRadius:this.options.animateScale?0:this.scale.calculateCenterOffset(t.value),circumference:this.options.animateRotate?0:this.scale.getCircumference(),startAngle:1.5*Math.PI})),e||(this.reflow(),this.update())},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=t.value},this),this.scale.valuesCount=this.segments.length},updateScaleRange:function(t){var i=[];e.each(t,function(t){i.push(t.value)});var s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s,{size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2})},update:function(){this.calculateTotal(this.segments),e.each(this.segments,function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.updateScaleRange(this.segments),this.scale.update(),e.extend(this.scale,{xCenter:this.chart.width/2,yCenter:this.chart.height/2}),e.each(this.segments,function(t){t.update({outerRadius:this.scale.calculateCenterOffset(t.value)})},this)},draw:function(t){var i=t||1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.scale.getCircumference(),outerRadius:this.scale.calculateCenterOffset(t.value)},i),t.endAngle=t.startAngle+t.circumference,0===e&&(t.startAngle=1.5*Math.PI),e<% for (var i=0; i
  • <%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>'},initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx}),this.datasets=[],this.buildScale(t),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){var o;this.scale.animation||(o=this.scale.getPointPosition(n,this.scale.calculateCenterOffset(e))),s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,x:this.options.animation?this.scale.xCenter:o.x,y:this.options.animation?this.scale.yCenter:o.y,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this)},this),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=e.getRelativePosition(t),s=e.getAngleFromPoint({x:this.scale.xCenter,y:this.scale.yCenter},i),n=2*Math.PI/this.scale.valuesCount,o=Math.round((s.angle-1.5*Math.PI)/n),a=[];return(o>=this.scale.valuesCount||0>o)&&(o=0),s.distance<=this.scale.drawingArea&&e.each(this.datasets,function(t){a.push(t.points[o])}),a},buildScale:function(t){this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,angleLineColor:this.options.angleLineColor,angleLineWidth:this.options.angleShowLineOut?this.options.angleLineWidth:0,pointLabelFontColor:this.options.pointLabelFontColor,pointLabelFontSize:this.options.pointLabelFontSize,pointLabelFontFamily:this.options.pointLabelFontFamily,pointLabelFontStyle:this.options.pointLabelFontStyle,height:this.chart.height,width:this.chart.width,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,labels:t.labels,valuesCount:t.datasets[0].data.length}),this.scale.setScaleSize(),this.updateScaleRange(t.datasets),this.scale.buildYLabels()},updateScaleRange:function(t){var i=function(){var i=[];return e.each(t,function(t){t.data?i=i.concat(t.data):e.each(t.points,function(t){i.push(t.value)})}),i}(),s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s)},addData:function(t,i){this.scale.valuesCount++,e.each(t,function(t,e){var s=this.scale.getPointPosition(this.scale.valuesCount,this.scale.calculateCenterOffset(t));this.datasets[e].points.push(new this.PointClass({value:t,label:i,x:s.x,y:s.y,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.labels.push(i),this.reflow(),this.update()},removeData:function(){this.scale.valuesCount--,this.scale.labels.shift(),e.each(this.datasets,function(t){t.points.shift()},this),this.reflow(),this.update()},update:function(){this.eachPoints(function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.scale,{width:this.chart.width,height:this.chart.height,size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2}),this.updateScaleRange(this.datasets),this.scale.setScaleSize(),this.scale.buildYLabels()},draw:function(t){var i=t||1,s=this.chart.ctx;this.clear(),this.scale.draw(),e.each(this.datasets,function(t){e.each(t.points,function(t,e){t.hasValue()&&t.transition(this.scale.getPointPosition(e,this.scale.calculateCenterOffset(t.value)),i)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(t.points,function(t,i){0===i?s.moveTo(t.x,t.y):s.lineTo(t.x,t.y)},this),s.closePath(),s.stroke(),s.fillStyle=t.fillColor,s.fill(),e.each(t.points,function(t){t.hasValue()&&t.draw()})},this)}})}.call(this); \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/js/icagenda.js b/deployed/icagenda/media/com_icagenda/js/icagenda.js new file mode 100644 index 00000000..2315e9bb --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/icagenda.js @@ -0,0 +1,53 @@ +/** + *------------------------------------------------------------------------------ + * iCagenda v3 by Jooml!C - Events Management Extension for Joomla! 2.5 / 3.x + *------------------------------------------------------------------------------ + * @package com_icagenda + * @copyright Copyright (c)2012-2019 Cyril Rezé, Jooml!C - All rights reserved + * + * @license GNU General Public License version 3 or later; see LICENSE.txt + * @author Cyril Rezé (Lyr!C) + * @link http://www.joomlic.com + * + * @version 3.6.0 2016-05-31 + * @since 3.4.0 + *------------------------------------------------------------------------------ +*/ + +(function($) +{ + $(document).ready(function() + { +// $('*[rel=tooltip]').tooltip() + + // Turn radios into btn-group + $('.ic-radio.ic-btn-group label').addClass('ic-btn'); + $(".ic-btn-group label:not(.active)").click(function() + { + var label = $(this); + var input = $('#' + label.attr('for')); + + if (!input.prop('checked')) { + label.closest('.ic-btn-group').find("label").removeClass('active ic-btn-success ic-btn-danger ic-btn-primary'); + if (input.val() == '') { + label.addClass('active ic-btn-primary'); + } else if (input.val() == 0) { + label.addClass('active ic-btn-danger'); + } else { + label.addClass('active ic-btn-success'); + } + input.prop('checked', true); + } + }); + $(".ic-btn-group input[checked=checked]").each(function() + { + if ($(this).val() == '') { + $("label[for=" + $(this).attr('id') + "]").addClass('active ic-btn-primary'); + } else if ($(this).val() == 0) { + $("label[for=" + $(this).attr('id') + "]").addClass('active ic-btn-danger'); + } else { + $("label[for=" + $(this).attr('id') + "]").addClass('active ic-btn-success'); + } + }); + }) +})(jQuery); diff --git a/deployed/icagenda/media/com_icagenda/js/icdates.js b/deployed/icagenda/media/com_icagenda/js/icdates.js new file mode 100644 index 00000000..6b9e65c4 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/icdates.js @@ -0,0 +1,236 @@ +/* Language initialisation for the jQuery UI date picker plugin. */ +/* Written by Keith Wood (kbwood{at}iinet.com.au) and Stéphane Nahmani (sholby@sholby.net). + * Modified by Cyril Rezé (Lyr!C) for iCagenda, joomla! extension + */ + +/** + *------------------------------------------------------------------------------ + * iCagenda v3 by Jooml!C - Events Management Extension for Joomla! 2.5 / 3.x + *------------------------------------------------------------------------------ + * @package com_icagenda + * @copyright Copyright (c)2012-2019 Cyril Rezé, Jooml!C - All rights reserved + * + * @license GNU General Public License version 3 or later; see LICENSE.txt + * @author Cyril Rezé (Lyr!C) + * @link http://www.joomlic.com + * + * @version 3.6.9 2017-06-08 + * @since 1.0 + *------------------------------------------------------------------------------ +*/ + +jQuery(function($){ + $.datepicker.regional[''] = { + currentText: Joomla.JText._('COM_ICAGENDA_TP_CURRENT', 'Now'), + closeText: Joomla.JText._('COM_ICAGENDA_TP_CLOSE', 'Done'), + prevText: '<Prev', + nextText: 'Next>', + ampm: false, + amNames: ['AM', 'A'], + pmNames: ['PM', 'P'], + timeFormat: 'hh:mm tt', + timeSuffix: '', + monthNames: [Joomla.JText._('JANUARY', 'January'), + Joomla.JText._('FEBRUARY', 'February'), + Joomla.JText._('MARCH', 'March'), + Joomla.JText._('APRIL', 'April'), + Joomla.JText._('MAY', 'May'), + Joomla.JText._('JUNE', 'June'), + Joomla.JText._('JULY', 'July'), + Joomla.JText._('AUGUST', 'August'), + Joomla.JText._('SEPTEMBER', 'September'), + Joomla.JText._('OCTOBER', 'October'), + Joomla.JText._('NOVEMBER', 'November'), + Joomla.JText._('DECEMBER', 'December')], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: [Joomla.JText._('SU', 'Su'), + Joomla.JText._('MO', 'Mo'), + Joomla.JText._('TU', 'Tu'), + Joomla.JText._('WE', 'We'), + Joomla.JText._('TH', 'Th'), + Joomla.JText._('FR', 'Fr'), + Joomla.JText._('SA', 'Sa')], + weekHeader: 'Wk', + isRTL: false, + showMonthAfterYear: false, + timeOnlyTitle: Joomla.JText._('COM_ICAGENDA_TP_TITLE', 'Choose Time'), + timeText: [Joomla.JText._('COM_ICAGENDA_TP_TIME')], + hourText: Joomla.JText._('COM_ICAGENDA_TP_HOUR', 'Hour'), + minuteText: Joomla.JText._('COM_ICAGENDA_TP_MINUTE', 'Minute'), + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['']); + + $.timepicker.regional[''] = { + currentText: Joomla.JText._('COM_ICAGENDA_TP_CURRENT', 'Now'), + closeText: Joomla.JText._('COM_ICAGENDA_TP_CLOSE', 'Done'), + prevText: '<Prev', + nextText: 'Next>', + ampm: false, + amNames: ['AM', 'A'], + pmNames: ['PM', 'P'], + timeFormat: 'hh:mm tt', + timeSuffix: '', + monthNames: [Joomla.JText._('JANUARY', 'January'), + Joomla.JText._('FEBRUARY', 'February'), + Joomla.JText._('MARCH', 'March'), + Joomla.JText._('APRIL', 'April'), + Joomla.JText._('MAY', 'May'), + Joomla.JText._('JUNE', 'June'), + Joomla.JText._('JULY', 'July'), + Joomla.JText._('AUGUST', 'August'), + Joomla.JText._('SEPTEMBER', 'September'), + Joomla.JText._('OCTOBER', 'October'), + Joomla.JText._('NOVEMBER', 'November'), + Joomla.JText._('DECEMBER', 'December')], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: [Joomla.JText._('SU', 'Su'), + Joomla.JText._('MO', 'Mo'), + Joomla.JText._('TU', 'Tu'), + Joomla.JText._('WE', 'We'), + Joomla.JText._('TH', 'Th'), + Joomla.JText._('FR', 'Fr'), + Joomla.JText._('SA', 'Sa')], + weekHeader: 'Wk', + isRTL: false, + showMonthAfterYear: false, + timeOnlyTitle: Joomla.JText._('COM_ICAGENDA_TP_TITLE', 'Choose Time'), + timeText: [Joomla.JText._('COM_ICAGENDA_TP_TIME')], + hourText: Joomla.JText._('COM_ICAGENDA_TP_HOUR', 'Hour'), + minuteText: Joomla.JText._('COM_ICAGENDA_TP_MINUTE', 'Minute'), + yearSuffix: ''}; + $.timepicker.setDefaults($.timepicker.regional['']); +}); + +jQuery(function($){ + + var startDateTextBox = $('#startdate'), + endDateTextBox = $('#enddate'), + $add_counter = $('#dTable_jalali input').length; + + startDateTextBox.live('focus', function(){ + $(this).datetimepicker({ + dateFormat: "yy-mm-dd", + timeFormat: 'hh:mm', + hourGrid: 4, + minuteGrid: 10, + onClose: function(dateText, inst) { + if (endDateTextBox.val() != '') { + var testStartDate = startDateTextBox.datetimepicker('getDate'); + var testEndDate = endDateTextBox.datetimepicker('getDate'); + if (testStartDate > testEndDate) + { + endDateTextBox.datetimepicker('setDate', startDateTextBox.val()); + } + } + else { + endDateTextBox.val(dateText); + } + }, +// onSelect: function (selectedDateTime){ +// endDateTextBox.datetimepicker('option', 'minDate', startDateTextBox.datetimepicker('getDate') ); +// } + }); + }); + + endDateTextBox.live('focus', function(){ + $(this).datetimepicker({ + dateFormat: "yy-mm-dd", + timeFormat: 'hh:mm', + hourGrid: 4, + minuteGrid: 10, + onClose: function(dateText, inst) { + if (startDateTextBox.val() != '') { + var testStartDate = startDateTextBox.datetimepicker('getDate'); + var testEndDate = endDateTextBox.datetimepicker('getDate'); + if (testStartDate > testEndDate) + { + startDateTextBox.datetimepicker('setDate', endDateTextBox.val()); + } + } + else { + startDateTextBox.val(dateText); + } + }, +// onSelect: function (selectedDateTime){ +// startDateTextBox.datetimepicker('option', 'maxDate', endDateTextBox.datetimepicker('getDate') ); +// } + }); + }); + + $( ".ic-date-input" ).live('focus', function(){ + $(this).datetimepicker({ + dateFormat: 'yy-mm-dd', + timeFormat: 'hh:mm', + hourGrid: 4, + minuteGrid: 10, + addSliderAccess: true, + sliderAccessArgs: { touchonly: true } + }); + }); + + $('#add').live('click', function(e){ + e.preventDefault(); + $delete = Joomla.JText._('COM_ICAGENDA_DELETE_DATE', 'Delete'); + + if ($("#dTable_jalali").length) { + $add_counter = $add_counter+1; + $('#dTable_jalali').append('
    '+$delete+''); +// jQuery(document).ready(function($) { + Calendar.setup({ + // Id of the input field + inputField: 'date_jalali'+$add_counter, + // Format of the input field + ifFormat: "%Y-%m-%d %H:%M", + // Trigger for the calendar (button ID) + button: 'date_jalali'+$add_counter+'_img', + // Alignment (defaults to "Bl") + align: "Tl", + singleClick: true, + firstDay: 6 + }); +// }); + } else { + $('#dTable').append(''+$delete+''); + } + }); + +// $( ".ui-state-default" ).live('click', function(){ + if ($("#dTable_jalali").length) { + $( "#dates" ).on('mouseleave', function() { + $array = $('#dTable_jalali input').serialize(); + $suffix = '_jalali'; + $('input.date').attr('value', $array); + document.getElementById('startdate'+$suffix).removeClass("ic-date-invalid"); + document.getElementById('enddate'+$suffix).removeClass("ic-date-invalid"); + document.getElementById('dTable'+$suffix).removeClass("ic-date-invalid"); + }); + } else { + $( ".ui-state-default" ).live('mouseout', function() { + $array = $('#dTable input').serialize(); + $('input.date').attr('value', $array); + document.getElementById('startdate').removeClass("ic-date-invalid"); + document.getElementById('enddate').removeClass("ic-date-invalid"); + document.getElementById('dTable').removeClass("ic-date-invalid"); + }); + } + + $('.del').live('click', function(e) { + e.preventDefault(); + $(this).parent().parent('tr').remove(); + + if ($("#dTable_jalali").length) { + $add_counter = $add_counter-1; + $array = $('#dTable_jalali input').serialize(); + } else { + $array = $('#dTable input').serialize(); + } + $('input.date').attr('value', $array); + }); + +}); diff --git a/deployed/icagenda/media/com_icagenda/js/icform.js b/deployed/icagenda/media/com_icagenda/js/icform.js new file mode 100644 index 00000000..5b3ff014 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/icform.js @@ -0,0 +1,65 @@ +/** + *------------------------------------------------------------------------------ + * iCagenda v3 by Jooml!C - Events Management Extension for Joomla! 2.5 / 3.x + *------------------------------------------------------------------------------ + * @package com_icagenda + * @copyright Copyright (c)2012-2019 Cyril Rezé, Jooml!C - All rights reserved + * + * @license GNU General Public License version 3 or later; see LICENSE.txt + * @author Cyril Rezé (Lyr!C) + * @link http://www.joomlic.com + * + * @version 3.5.0 2015-02-14 + * @since 3.4.0 + *------------------------------------------------------------------------------ +*/ + +/** + * Function Text Counter + */ +function iCtextCounter( field, countfield, maxlimit ) +{ + if ( field.value.length > maxlimit ) + { + field.value = field.value.substring( 0, maxlimit ); + countfield.value = 0; + jQuery(field).addClass("ic-counter-limit"); + jQuery(countfield).addClass("ic-counter-limit"); + + return false; + } + else + { + countfield.value = maxlimit - field.value.length; + jQuery(field).removeClass("ic-counter-limit"); + jQuery(countfield).removeClass("ic-counter-limit"); + } +} + +/** + * fieldname, warningname, remainingname, maxchars // DEV. + */ +function CheckFieldLength(fn,wn,rn,maxlimit) { + var length = fn.value.length; + if (length > maxlimit) { + fn.value = fn.value.substring(0,maxlimit); + length = maxlimit; + + return false; + } + document.getElementById(wn).innerHTML = length; + document.getElementById(rn).innerHTML = maxlimit - length; +} + +/** + * Function in array + */ +function inArray(needle, haystack) +{ + var length = haystack.length; + for(var i = 0; i < length; i++) + { + if(haystack[i] == needle) return true; + } + return false; +} diff --git a/deployed/icagenda/media/com_icagenda/js/icmap-front.js b/deployed/icagenda/media/com_icagenda/js/icmap-front.js new file mode 100644 index 00000000..d72fcee1 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/icmap-front.js @@ -0,0 +1,42 @@ +/** + *---------------------------------------------------------------------------- + * iCagenda Events Management Extension for Joomla! + *---------------------------------------------------------------------------- + * @version 3.7.0 2018-05-15 + * + * @package iCagenda.Media + * @subpackage js + * @link https://icagenda.joomlic.com + * + * @author Cyril Rezé + * @copyright (c) 2012-2019 Jooml!C / Cyril Rezé. All rights reserved. + * @license GNU General Public License version 3 or later; see LICENSE.txt + * + * @since 1.0 + *---------------------------------------------------------------------------- +*/ + +var lat, + lng, + id; + +function icMapInitialize(lat, lng, id){ + function initialize(){ + var latlng = new google.maps.LatLng(lat, lng); + var mapOptions = { + zoom: 16, + center: latlng, + mapTypeId: google.maps.MapTypeId.ROADMAP + }; + + var mapid = new google.maps.Map(document.getElementById('map_canvas'+id), mapOptions); + + var newMarker = new google.maps.Marker({ + map: mapid, + draggable: false, + position: latlng + }); + } + + google.maps.event.addDomListener(window, 'load', initialize); +} diff --git a/deployed/icagenda/media/com_icagenda/js/icmap.js b/deployed/icagenda/media/com_icagenda/js/icmap.js new file mode 100644 index 00000000..8596e8b9 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/icmap.js @@ -0,0 +1,241 @@ +/* + * jQuery UI addresspicker @VERSION + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.autocomplete.js + */ +(function( $, undefined ) { + + $.widget( "ui.addresspicker", { + options: { + appendAddressString: "", + draggableMarker: true, + regionBias: null, + updateCallback: null, + reverseGeocode: false, + mapOptions: { + zoom: 13, + center: new google.maps.LatLng(46, 2), + scrollwheel: false, + mapTypeId: google.maps.MapTypeId.ROADMAP + }, + elements: { + map: false, + lat: false, + lng: false, + street_number: false, + route: false, + locality: false, + administrative_area_level_2: false, + administrative_area_level_1: false, + country: false, + postal_code: false, + type: false + + } + }, + + marker: function() { + return this.gmarker; + }, + + map: function() { + return this.gmap; + }, + + updatePosition: function() { + this._updatePosition(this.gmarker.getPosition()); + }, + + reloadPosition: function() { + this.gmarker.setVisible(true); + this.gmarker.setPosition(new google.maps.LatLng(this.lat.val(), this.lng.val())); + this.gmap.setCenter(this.gmarker.getPosition()); + }, + + selected: function() { + return this.selectedResult; + }, + + _create: function() { + this.geocoder = new google.maps.Geocoder(); + this.element.autocomplete({ + source: $.proxy(this._geocode, this), + focus: $.proxy(this._focusAddress, this), + select: $.proxy(this._selectAddress, this) + }); + + this.lat = $(this.options.elements.lat); + this.lng = $(this.options.elements.lng); + this.street_number = $(this.options.elements.street_number); + this.route = $(this.options.elements.route); + this.locality = $(this.options.elements.locality); + this.administrative_area_level_2 = $(this.options.elements.administrative_area_level_2); + this.administrative_area_level_1 = $(this.options.elements.administrative_area_level_1); + this.country = $(this.options.elements.country); + this.postal_code = $(this.options.elements.postal_code); + this.type = $(this.options.elements.type); + if (this.options.elements.map) { + this.mapElement = $(this.options.elements.map); + this._initMap(); + } + }, + + _initMap: function() { + if (this.lat && this.lat.val()) { + this.options.mapOptions.center = new google.maps.LatLng(this.lat.val(), this.lng.val()); + } + + this.gmap = new google.maps.Map(this.mapElement[0], this.options.mapOptions); + this.gmarker = new google.maps.Marker({ + position: this.options.mapOptions.center, + map:this.gmap, + draggable: this.options.draggableMarker}); + google.maps.event.addListener(this.gmarker, 'dragend', $.proxy(this._markerMoved, this)); + this.gmarker.setVisible(false); + }, + + _updatePosition: function(location) { + if (this.lat) { + this.lat.val(location.lat()); + } + if (this.lng) { + this.lng.val(location.lng()); + } + }, + + _addressParts: {street_number: null, route: null, locality: null, + administrative_area_level_2: null, administrative_area_level_1: null, + country: null, postal_code:null, type: null}, + + _updateAddressParts: function(geocodeResult){ + + parsedResult = this._parseGeocodeResult(geocodeResult); + + for (addressPart in this._addressParts){ + if (this[addressPart]){ + if (JSON.stringify(parsedResult[addressPart]) == 'false'){ + this[addressPart].val(''); + } else { + this[addressPart].val(parsedResult[addressPart]); + } + } + } + }, + + _updateAddressPartsViaReverseGeocode: function(location){ + var latLng = new google.maps.LatLng(location.lat(), location.lng()); + + this.geocoder.geocode({'latLng': latLng}, $.proxy(function(results, status){ + if (status == google.maps.GeocoderStatus.OK) + + this._updateAddressParts(results[0]); + this.element.val(results[0].formatted_address); + this.selectedResult = results[0]; + + if (this.options.updateCallback) { + this.options.updateCallback(this.selectedResult, this._parseGeocodeResult(this.selectedResult)); + } + }, this)); + }, + + _parseGeocodeResult: function(geocodeResult){ + + var parsed = {lat: geocodeResult.geometry.location.lat(), + lng: geocodeResult.geometry.location.lng()}; + + for (var addressPart in this._addressParts){ + parsed[addressPart] = this._findInfo(geocodeResult, addressPart); + } + + parsed.type = geocodeResult.types[0]; + + return parsed; + }, + + _markerMoved: function() { + this._updatePosition(this.gmarker.getPosition()); + + if (this.options.reverseGeocode){ + this._updateAddressPartsViaReverseGeocode(this.gmarker.getPosition()); + } + }, + + // Autocomplete source method: fill its suggests with google geocoder results + _geocode: function(request, response) { + var address = request.term, self = this; + this.geocoder.geocode({ + 'address': address + this.options.appendAddressString, + 'region': this.options.regionBias + }, function(results, status) { + if (status == google.maps.GeocoderStatus.OK) { + for (var i = 0; i < results.length; i++) { + results[i].label = results[i].formatted_address; + }; + } + response(results); + }) + }, + + _findInfo: function(result, type) { + for (var i = 0; i < result.address_components.length; i++) { + var component = result.address_components[i]; + if (component.types.indexOf(type) !=-1) { + return component.long_name; + } + } + return false; + }, + + _focusAddress: function(event, ui) { + var address = ui.item; + if (!address) { + return; + } + + if (this.gmarker) { + this.gmarker.setPosition(address.geometry.location); + this.gmarker.setVisible(true); + + this.gmap.fitBounds(address.geometry.viewport); + } + + this._updatePosition(address.geometry.location); + + this._updateAddressParts(address); + + }, + + _selectAddress: function(event, ui) { + this.selectedResult = ui.item; + if (this.options.updateCallback) { + this.options.updateCallback(this.selectedResult, this._parseGeocodeResult(this.selectedResult)); + } + } + }); + + $.extend( $.ui.addresspicker, { + version: "@VERSION" + }); + + // make IE think it doesn't suck + if(!Array.indexOf){ + Array.prototype.indexOf = function(obj){ + for(var i=0; i \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/js/jquery.noconflict.js b/deployed/icagenda/media/com_icagenda/js/jquery.noconflict.js new file mode 100644 index 00000000..aa32286f --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/jquery.noconflict.js @@ -0,0 +1 @@ +jQuery.noConflict(); \ No newline at end of file diff --git a/deployed/icagenda/media/com_icagenda/js/jquery.tipTip.js b/deployed/icagenda/media/com_icagenda/js/jquery.tipTip.js new file mode 100644 index 00000000..ac33d5d9 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/jquery.tipTip.js @@ -0,0 +1,202 @@ + /* + * TipTip + * Copyright 2010 Drew Wilson + * www.drewwilson.com + * code.drewwilson.com/entry/tiptip-jquery-plugin + * + * Version 1.3 - Updated: Mar. 23, 2010 + * + * This Plug-In will create a custom tooltip to replace the default + * browser tooltip. It is extremely lightweight and very smart in + * that it detects the edges of the browser window and will make sure + * the tooltip stays within the current window size. As a result the + * tooltip will adjust itself to be displayed above, below, to the left + * or to the right depending on what is necessary to stay within the + * browser window. It is completely customizable as well via CSS. + * + * This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Updated by Cyril Rezé (JoomliC) + * @version 3.5.5 2015-04-27 + */ + +(function($){ + $.fn.tipTip = function(options) { + var defaults = { + activation: "hover", + keepAlive: false, + maxWidth: "200px", + edgeOffset: 3, + defaultPosition: "bottom", + delay: 400, + fadeIn: 200, + fadeOut: 200, + attribute: "title", + content: false, // HTML or String to fill TipTIp with + enter: function(){}, + exit: function(){} + }; + var opts = $.extend(defaults, options); + + // Setup tip tip elements and render them to the DOM + if($("#tiptip_holder").length <= 0){ + var tiptip_holder = $('
    '); + var tiptip_content = $('
    '); + var tiptip_arrow = $('
    '); + $("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('
    '))); + } else { + var tiptip_holder = $("#tiptip_holder"); + var tiptip_content = $("#tiptip_content"); + var tiptip_arrow = $("#tiptip_arrow"); + } + + return this.each(function(){ + var org_elem = $(this); + if(opts.content){ + var org_title = opts.content; + } else { + var org_title = org_elem.attr(opts.attribute); + } + if(org_title != ""){ + if(!opts.content){ + org_elem.removeAttr(opts.attribute); //remove original Attribute + } + var timeout = false; + + if(opts.activation == "hover"){ + org_elem.hover(function(){ + active_tiptip(); + }, function(){ + if(!opts.keepAlive){ + deactive_tiptip(); + } + }); + if(opts.keepAlive){ + tiptip_holder.hover(function(){}, function(){ + deactive_tiptip(); + }); + } + } else if(opts.activation == "focus"){ + org_elem.focus(function(){ + active_tiptip(); + }).blur(function(){ + deactive_tiptip(); + }); + } else if(opts.activation == "click"){ + org_elem.click(function(){ + active_tiptip(); + return false; + }).hover(function(){},function(){ + if(!opts.keepAlive){ + deactive_tiptip(); + } + }); + if(opts.keepAlive){ + tiptip_holder.hover(function(){}, function(){ + deactive_tiptip(); + }); + } + } + + function active_tiptip(){ + opts.enter.call(this); + tiptip_content.html(org_title); + tiptip_holder.hide().removeAttr("class").css("margin","0"); + tiptip_arrow.removeAttr("style"); + + // Add body offset control + var body_offset = $('body').offset(), + offset = org_elem.offset(), + tip_top = offset.top, + tip_left = offset.left, + body_top = body_offset.top, + body_left = body_offset.left, + top = parseInt(tip_top - body_top), + left = parseInt(tip_left - body_left); + + var org_width = parseInt(org_elem.outerWidth()), + org_height = parseInt(org_elem.outerHeight()), + tip_w = tiptip_holder.outerWidth(), + tip_h = tiptip_holder.outerHeight(), + w_compare = Math.round((org_width - tip_w) / 2), + h_compare = Math.round((org_height - tip_h) / 2), + marg_left = Math.round(left + w_compare), + marg_top = Math.round(top + org_height + opts.edgeOffset), + t_class = "", + arrow_top = "", + arrow_left = Math.round(tip_w - 12) / 2; + + if(opts.defaultPosition == "bottom"){ + t_class = "_bottom"; + } else if(opts.defaultPosition == "top"){ + t_class = "_top"; + } else if(opts.defaultPosition == "left"){ + t_class = "_left"; + } else if(opts.defaultPosition == "right"){ + t_class = "_right"; + } + + var right_compare = (w_compare + left) < parseInt($(window).scrollLeft()); + var left_compare = (tip_w + left) > parseInt($(window).width()); + + if((right_compare && w_compare < 0) || (t_class == "_right" && !left_compare) || (t_class == "_left" && left < (tip_w + opts.edgeOffset + 5))){ + t_class = "_right"; + arrow_top = Math.round(tip_h - 13) / 2; + arrow_left = -12; + marg_left = Math.round(left + org_width + opts.edgeOffset); + marg_top = Math.round(top + h_compare); + } else if((left_compare && w_compare < 0) || (t_class == "_left" && !right_compare)){ + t_class = "_left"; + arrow_top = Math.round(tip_h - 13) / 2; + arrow_left = Math.round(tip_w); + marg_left = Math.round(left - (tip_w + opts.edgeOffset + 5)); + marg_top = Math.round(top + h_compare); + } + + var top_compare = (top + org_height + opts.edgeOffset + tip_h + 8) > parseInt($(window).height() + $(window).scrollTop()); + var bottom_compare = ((top + org_height) - (opts.edgeOffset + tip_h + 8)) < 0; + + if(top_compare || (t_class == "_bottom" && top_compare) || (t_class == "_top" && !bottom_compare)){ + if(t_class == "_top" || t_class == "_bottom"){ + t_class = "_top"; + } else { + t_class = t_class+"_top"; + } + arrow_top = tip_h; + marg_top = Math.round(top - (tip_h + 5 + opts.edgeOffset)); + } else if(bottom_compare | (t_class == "_top" && bottom_compare) || (t_class == "_bottom" && !top_compare)){ + if(t_class == "_top" || t_class == "_bottom"){ + t_class = "_bottom"; + } else { + t_class = t_class+"_bottom"; + } + arrow_top = -12; + marg_top = Math.round(top + org_height + opts.edgeOffset); + } + + if(t_class == "_right_top" || t_class == "_left_top"){ + marg_top = marg_top + 5; + } else if(t_class == "_right_bottom" || t_class == "_left_bottom"){ + marg_top = marg_top - 5; + } + if(t_class == "_left_top" || t_class == "_left_bottom"){ + marg_left = marg_left + 5; + } + tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"}); + tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class); + + if (timeout){ clearTimeout(timeout); } + timeout = setTimeout(function(){ tiptip_holder.stop(true,true).fadeIn(opts.fadeIn); }, opts.delay); + } + + function deactive_tiptip(){ + opts.exit.call(this); + if (timeout){ clearTimeout(timeout); } + tiptip_holder.fadeOut(opts.fadeOut); + } + } + }); + } +})(jQuery); diff --git a/deployed/icagenda/media/com_icagenda/js/template.js b/deployed/icagenda/media/com_icagenda/js/template.js new file mode 100644 index 00000000..76d83623 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/template.js @@ -0,0 +1,45 @@ +/** + * @package Joomla.Administrator + * @subpackage Templates.isis + * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved. + * @license GNU General Public License version 3 or later; see LICENSE.txt + * @since 3.0 + */ + +(function($) +{ + $(document).ready(function() + { + $('*[rel=tooltip]').tooltip() + + // Turn radios into btn-group + $('.radio.btn-group label').addClass('btn'); + $(".btn-group label:not(.active)").click(function() + { + var label = $(this); + var input = $('#' + label.attr('for')); + + if (!input.prop('checked')) { + label.closest('.btn-group').find("label").removeClass('active btn-success btn-danger btn-primary'); + if (input.val() == '') { + label.addClass('active btn-primary'); + } else if (input.val() == 0) { + label.addClass('active btn-danger'); + } else { + label.addClass('active btn-success'); + } + input.prop('checked', true); + } + }); + $(".btn-group input[checked=checked]").each(function() + { + if ($(this).val() == '') { + $("label[for=" + $(this).attr('id') + "]").addClass('active btn-primary'); + } else if ($(this).val() == 0) { + $("label[for=" + $(this).attr('id') + "]").addClass('active btn-danger'); + } else { + $("label[for=" + $(this).attr('id') + "]").addClass('active btn-success'); + } + }); + }) +})(jQuery); diff --git a/deployed/icagenda/media/com_icagenda/js/timepicker.js b/deployed/icagenda/media/com_icagenda/js/timepicker.js new file mode 100644 index 00000000..65f763f2 --- /dev/null +++ b/deployed/icagenda/media/com_icagenda/js/timepicker.js @@ -0,0 +1,1764 @@ +/* + * jQuery timepicker addon + * By: Trent Richardson [http://trentrichardson.com] + * Version 1.0.3 + * Last Modified: 09/15/2012 + * + * Copyright 2012 Trent Richardson + * You may use this project under MIT or GPL licenses. + * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt + * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt + * + * HERES THE CSS: + * .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } + * .ui-timepicker-div dl { text-align: left; } + * .ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; } + * .ui-timepicker-div dl dd { margin: 0 10px 10px 65px; } + * .ui-timepicker-div td { font-size: 90%; } + * .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } + */ + +/*jslint evil: true, white: false, undef: false, nomen: false */ + +(function($) { + + /* + * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded" + */ + $.ui.timepicker = $.ui.timepicker || {}; + if ($.ui.timepicker.version) { + return; + } + + /* + * Extend jQueryUI, get it started with our version number + */ + $.extend($.ui, { + timepicker: { + version: "1.0.3" + } + }); + + /* + * Timepicker manager. + * Use the singleton instance of this class, $.timepicker, to interact with the time picker. + * Settings for (groups of) time pickers are maintained in an instance object, + * allowing multiple different settings on the same page. + */ + function Timepicker() { + this.regional = []; // Available regional settings, indexed by language code + this.regional[''] = { // Default regional settings + currentText: Joomla.JText._('COM_ICAGENDA_TP_CURRENT', 'Now'), + closeText: Joomla.JText._('COM_ICAGENDA_TP_CLOSE', 'Done'), + ampm: false, + amNames: ['AM', 'A'], + pmNames: ['PM', 'P'], + timeFormat: 'hh:mm tt', + timeSuffix: '', + timeOnlyTitle: Joomla.JText._('COM_ICAGENDA_TP_TITLE', 'Choose Time'), + timeText: Joomla.JText._('COM_ICAGENDA_TP_TIME', 'Time'), + hourText: Joomla.JText._('COM_ICAGENDA_TP_HOUR', 'Hour'), + minuteText: Joomla.JText._('COM_ICAGENDA_TP_MINUTE', 'Minute'), + secondText: 'Second', + millisecText: 'Millisecond', + timezoneText: 'Time Zone' + }; + this._defaults = { // Global defaults for all the datetime picker instances + showButtonPanel: true, + timeOnly: false, + showHour: true, + showMinute: true, + showSecond: false, + showMillisec: false, + showTimezone: false, + showTime: true, + stepHour: 1, + stepMinute: 1, + stepSecond: 1, + stepMillisec: 1, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + timezone: null, + useLocalTimezone: false, + defaultTimezone: "+0000", + hourMin: 0, + minuteMin: 0, + secondMin: 0, + millisecMin: 0, + hourMax: 23, + minuteMax: 59, + secondMax: 59, + millisecMax: 999, + minDateTime: null, + maxDateTime: null, + onSelect: null, + hourGrid: 0, + minuteGrid: 0, + secondGrid: 0, + millisecGrid: 0, + alwaysSetTime: true, + separator: ' ', + altFieldTimeOnly: true, + altSeparator: null, + altTimeSuffix: null, + showTimepicker: true, + timezoneIso8601: false, + timezoneList: null, + addSliderAccess: false, + sliderAccessArgs: null, + defaultValue: null + }; + $.extend(this._defaults, this.regional['']); + } + + $.extend(Timepicker.prototype, { + $input: null, + $altInput: null, + $timeObj: null, + inst: null, + hour_slider: null, + minute_slider: null, + second_slider: null, + millisec_slider: null, + timezone_select: null, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + timezone: null, + defaultTimezone: "+0000", + hourMinOriginal: null, + minuteMinOriginal: null, + secondMinOriginal: null, + millisecMinOriginal: null, + hourMaxOriginal: null, + minuteMaxOriginal: null, + secondMaxOriginal: null, + millisecMaxOriginal: null, + ampm: '', + formattedDate: '', + formattedTime: '', + formattedDateTime: '', + timezoneList: null, + units: ['hour','minute','second','millisec'], + + /* + * Override the default settings for all instances of the time picker. + * @param settings object - the new settings to use as defaults (anonymous object) + * @return the manager object + */ + setDefaults: function(settings) { + extendRemove(this._defaults, settings || {}); + return this; + }, + + /* + * Create a new Timepicker instance + */ + _newInst: function($input, o) { + var tp_inst = new Timepicker(), + inlineSettings = {}; + + for (var attrName in this._defaults) { + if(this._defaults.hasOwnProperty(attrName)){ + var attrValue = $input.attr('time:' + attrName); + if (attrValue) { + try { + inlineSettings[attrName] = eval(attrValue); + } catch (err) { + inlineSettings[attrName] = attrValue; + } + } + } + } + tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, { + beforeShow: function(input, dp_inst) { + if ($.isFunction(o.beforeShow)) { + return o.beforeShow(input, dp_inst, tp_inst); + } + }, + onChangeMonthYear: function(year, month, dp_inst) { + // Update the time as well : this prevents the time from disappearing from the $input field. + tp_inst._updateDateTime(dp_inst); + if ($.isFunction(o.onChangeMonthYear)) { + o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); + } + }, + onClose: function(dateText, dp_inst) { + if (tp_inst.timeDefined === true && $input.val() !== '') { + tp_inst._updateDateTime(dp_inst); + } + if ($.isFunction(o.onClose)) { + o.onClose.call($input[0], dateText, dp_inst, tp_inst); + } + }, + timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); + }); + tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { + return val.toUpperCase(); + }); + tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { + return val.toUpperCase(); + }); + + if (tp_inst._defaults.timezoneList === null) { + var timezoneList = ['-1200', '-1100', '-1000', '-0930', '-0900', '-0800', '-0700', '-0600', '-0500', '-0430', '-0400', '-0330', '-0300', '-0200', '-0100', '+0000', + '+0100', '+0200', '+0300', '+0330', '+0400', '+0430', '+0500', '+0530', '+0545', '+0600', '+0630', '+0700', '+0800', '+0845', '+0900', '+0930', + '+1000', '+1030', '+1100', '+1130', '+1200', '+1245', '+1300', '+1400']; + + if (tp_inst._defaults.timezoneIso8601) { + timezoneList = $.map(timezoneList, function(val) { + return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3)); + }); + } + tp_inst._defaults.timezoneList = timezoneList; + } + + tp_inst.timezone = tp_inst._defaults.timezone; + tp_inst.hour = tp_inst._defaults.hour; + tp_inst.minute = tp_inst._defaults.minute; + tp_inst.second = tp_inst._defaults.second; + tp_inst.millisec = tp_inst._defaults.millisec; + tp_inst.ampm = ''; + tp_inst.$input = $input; + + if (o.altField) { + tp_inst.$altInput = $(o.altField).css({ + cursor: 'pointer' + }).focus(function() { + $input.trigger("focus"); + }); + } + + if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) { + tp_inst._defaults.minDate = new Date(); + } + if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) { + tp_inst._defaults.maxDate = new Date(); + } + + // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. + if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) { + tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); + } + if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) { + tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); + } + if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) { + tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); + } + if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) { + tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); + } + tp_inst.$input.bind('focus', function() { + tp_inst._onFocus(); + }); + + return tp_inst; + }, + + /* + * add our sliders to the calendar + */ + _addTimePicker: function(dp_inst) { + var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val(); + + this.timeDefined = this._parseTime(currDT); + this._limitMinMaxDateTime(dp_inst, false); + this._injectTimePicker(); + }, + + /* + * parse the time string from input value or _setTime + */ + _parseTime: function(timeString, withDate) { + if (!this.inst) { + this.inst = $.datepicker._getInst(this.$input[0]); + } + + if (withDate || !this._defaults.timeOnly) { + var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); + try { + var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults); + if (!parseRes.timeObj) { + return false; + } + $.extend(this, parseRes.timeObj); + } catch (err) { + return false; + } + return true; + } else { + var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults); + if (!timeObj) { + return false; + } + $.extend(this, timeObj); + return true; + } + }, + + /* + * generate and inject html for timepicker into ui datepicker + */ + _injectTimePicker: function() { + var $dp = this.inst.dpDiv, + o = this.inst.settings, + tp_inst = this, + litem = '', + uitem = '', + max = {}, + gridSize = {}, + size = null; + + // Prevent displaying twice + if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) { + var noDisplay = ' style="display:none;"', + html = '
    ' + '
    ' + o.timeText + '
    ' + + '
    '; + + // Create the markup + for(var i=0,l=this.units.length; i' + o[litem +'Text'] + '' + + '
    '; + + if (o['show'+uitem] && o[litem+'Grid'] > 0) { + html += '
    '; + + if(litem == 'hour'){ + for (var h = o[litem+'Min']; h <= max[litem]; h += parseInt(o[litem+'Grid'], 10)) { + gridSize[litem]++; + var tmph = (o.ampm && h > 12) ? h - 12 : h; + if (tmph < 10) { + tmph = '0' + tmph; + } + if (o.ampm) { + if (h === 0) { + tmph = 12 + 'a'; + } else { + if (h < 12) { + tmph += 'a'; + } else { + tmph += 'p'; + } + } + } + html += ''; + } + } + else{ + for (var m = o[litem+'Min']; m <= max[litem]; m += parseInt(o[litem+'Grid'], 10)) { + gridSize[litem]++; + html += ''; + } + } + + html += '
    ' + tmph + '' + ((m < 10) ? '0' : '') + m + '
    '; + } + html += '
    '; + } + + // Timezone + html += '
    ' + o.timezoneText + '
    '; + html += '
    '; + + // Create the elements from string + html += '
    '; + var $tp = $(html); + + // if we only want time picker... + if (o.timeOnly === true) { + $tp.prepend('
    ' + '
    ' + o.timeOnlyTitle + '
    ' + '
    '); + $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); + } + + // Updated by Peter Medeiros: + // - Pass in Event and UI instance into slide function + this.hour_slider = $tp.find('.ui_tpicker_hour_slider').prop('slide', null).slider({ + orientation: "horizontal", + value: this.hour, + min: o.hourMin, + max: max.hour, + step: o.stepHour, + slide: function(event, ui) { + tp_inst.hour_slider.slider("option", "value", ui.value); + tp_inst._onTimeChange(); + }, + stop: function(event, ui) { + tp_inst._onSelectHandler(); + } + }); + + this.minute_slider = $tp.find('.ui_tpicker_minute_slider').prop('slide', null).slider({ + orientation: "horizontal", + value: this.minute, + min: o.minuteMin, + max: max.minute, + step: o.stepMinute, + slide: function(event, ui) { + tp_inst.minute_slider.slider("option", "value", ui.value); + tp_inst._onTimeChange(); + }, + stop: function(event, ui) { + tp_inst._onSelectHandler(); + } + }); + + this.second_slider = $tp.find('.ui_tpicker_second_slider').prop('slide', null).slider({ + orientation: "horizontal", + value: this.second, + min: o.secondMin, + max: max.second, + step: o.stepSecond, + slide: function(event, ui) { + tp_inst.second_slider.slider("option", "value", ui.value); + tp_inst._onTimeChange(); + }, + stop: function(event, ui) { + tp_inst._onSelectHandler(); + } + }); + + this.millisec_slider = $tp.find('.ui_tpicker_millisec_slider').prop('slide', null).slider({ + orientation: "horizontal", + value: this.millisec, + min: o.millisecMin, + max: max.millisec, + step: o.stepMillisec, + slide: function(event, ui) { + tp_inst.millisec_slider.slider("option", "value", ui.value); + tp_inst._onTimeChange(); + }, + stop: function(event, ui) { + tp_inst._onSelectHandler(); + } + }); + + // add sliders, adjust grids, add events + for(var i=0,l=tp_inst.units.length; i 0) { + size = 100 * gridSize[litem] * o[litem+'Grid'] / (max[litem] - o[litem+'Min']); + $tp.find('.ui_tpicker_'+litem+' table').css({ + width: size + "%", + marginLeft: (size / (-2 * gridSize[litem])) + "%", + borderCollapse: 'collapse' + }).find("td").click(function(e){ + var $t = $(this), + h = $t.html() + f = $t.data('for'); // loses scope, so we use data-for + + if (f == 'hour' && o.ampm) { + var ap = h.substring(2).toLowerCase(), + aph = parseInt(h.substring(0, 2), 10); + if (ap == 'a') { + if (aph == 12) { + h = 0; + } else { + h = aph; + } + } else if (aph == 12) { + h = 12; + } else { + h = aph + 12; + } + } + tp_inst[f+'_slider'].slider("option", "value", parseInt(h,10)); + tp_inst._onTimeChange(); + tp_inst._onSelectHandler(); + }) + .css({ + cursor: 'pointer', + width: (100 / gridSize[litem]) + '%', + textAlign: 'center', + overflow: 'hidden' + }); + } // end if grid > 0 + } // end for loop + + // Add timezone options + this.timezone_select = $tp.find('.ui_tpicker_timezone').append('').find("select"); + $.fn.append.apply(this.timezone_select, + $.map(o.timezoneList, function(val, idx) { + return $("