Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Version 1.6.6

This release contains the Last code update: 2012.07.25 – v2.0.2 of Add To Home Screen

Bug: correctly detects Chrome browser
Bug: Added support to disable balloon for Chrome iOS browsers
  • Loading branch information...
commit 30d197d47a665806dac32fba6ea08d08f6d76ae9 1 parent 2131a2e
@cedricwalter authored
Showing with 3,852 additions and 0 deletions.
  1. +32 −0 a_installer.xml
  2. +18 −0 install.css
  3. +3 −0  install.html
  4. +248 −0 install.script.php
  5. +13 −0 installer.php
  6. +357 −0 installer/RokInstaller.php
  7. +15 −0 installer/RokInstallerEvents.php
  8. +203 −0 installer/adapters/component.php
  9. +190 −0 installer/adapters/file.php
  10. +190 −0 installer/adapters/language.php
  11. +190 −0 installer/adapters/library.php
  12. +336 −0 installer/adapters/module.php
  13. +185 −0 installer/adapters/plugin.php
  14. +305 −0 installer/adapters/template.php
  15. +1 −0  installer/language/en-GB/en-GB.install_override.ini
  16. +152 −0 plg_add2home/add2home.css
  17. +341 −0 plg_add2home/add2home.js
  18. +286 −0 plg_add2home/add2home.php
  19. +281 −0 plg_add2home/add2home.xml
  20. +158 −0 plg_add2home/add2home_ipad.css
  21. +158 −0 plg_add2home/add2home_ipod.css
  22. +158 −0 plg_add2home/add2home_retina.css
  23. BIN  plg_add2home/icon_ipad.png
  24. BIN  plg_add2home/icon_ipod.png
  25. BIN  plg_add2home/icon_retina.png
  26. +1 −0  plg_add2home/index.html
  27. +1 −0  plg_add2home/language/en-GB/en-GB.plg_system_add2home.ini
  28. +1 −0  plg_add2home/language/en-GB/index.html
  29. +1 −0  plg_add2home/language/index.html
  30. +28 −0 plg_add2home/license.txt
  31. BIN  plg_add2home/startupIPhone.png
  32. BIN  plg_add2home/startupImageIpadLandscape.png
  33. BIN  plg_add2home/startupImageIpadPortrait.png
View
32 a_installer.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<extension version="1.6" type="plugin" group="system" method="upgrade">
+ <name>add2home</name>
+
+ <packagename>add2home</packagename>
+ <packager>Cedric Walter</packager>
+ <packagerurl>http://www.waltercedric.com</packagerurl>
+
+ <author>Cedric Walter</author>
+ <authorEmail>cedric.walter@gmail.com</authorEmail>
+ <authorUrl>www.waltercedric.com</authorUrl>
+
+ <creationDate>14.05.2011</creationDate>
+ <copyright>Copyright (C) 2011 waltercedric.com All rights reserved.</copyright>
+ <license>GNU/GPL 3.0 for Joomla! + MIT license for add2home</license>
+ <version>1.6.6</version>
+ <description>The script places a floating balloon inviting the user to add your application to the home screen.</description>
+ <scriptfile>install.script.php</scriptfile>
+
+ <files>
+ <filename plugin="installer">installer.php</filename>
+ </files>
+ <cogs>
+
+ <cog type="plugin" client="site" ordering="1" access="1" enabled="true" protected="false">
+ plg_add2home
+ <name>Plugin add2home</name>
+ <description>The script places a floating balloon inviting the user to add your application to the home screen.</description>
+ </cog>
+
+ </cogs>
+</extension>
View
18 install.css
@@ -0,0 +1,18 @@
+#rokinstall-logo {background-image: url(data:image/png;base64,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%3D);}
+
+#rokinstall-status .rokinstall-success .rokinstall-icon {background-image: url(data:image/png;base64,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);}
+
+#rokinstall-status .rokinstall-failure .rokinstall-icon {background-image: url(data:image/png;base64,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);}
+
+#rokinstall-status .rokinstall-update .rokinstall-icon {background-image: url(data:image/png;base64,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);}
+
+#rokinstall-logo {background-repeat:no-repeat;min-height:125px;padding-top:15px;padding-right:100px;background-position:50px 0;}
+#rokinstall-status {font-family:Helvetica,Arial,sans-serif;font-size:14px;font-weight:normal;color:#fff;text-shadow:1px 1px 0 #333;margin: 0 0 0 260px;padding:0;}
+#rokinstall-status li {;margin:0 0 12px 0;text-indent:10px;padding:0;}
+#rokinstall-status .rokinstall-row {display:block;height:28px;margin-left:15px;line-height:28px;border-radius: 9px;white-space:nowrap;padding-right:25px;}
+#rokinstall-status .rokinstall-success .rokinstall-row {background: #99D100;}
+#rokinstall-status .rokinstall-failure .rokinstall-row {background: #ED573E;}
+#rokinstall-status .rokinstall-update .rokinstall-row {background: #0094DF;}
+#rokinstall-status .rokinstall-icon {display:block;background-repeat:no-repeat;height:38px;width:38px;margin:-5px 0 -5px -15px;float:left;}
+#rokinstall-status {list-style:none;}
+#rokinstall-status .rokinstall-errormsg {text-indent:0;display:block;margin:-1px 10px 10px 35px;padding:10px 15px 15px 15px;border: 1px solid #ED573E; background: #FDE0DC;color:#772013;font-size:13px;text-shadow:0 0;border-bottom-left-radius: 9px;border-bottom-right-radius: 9px;}
View
3  install.html
@@ -0,0 +1,3 @@
+<style>
+ @import "../tmp/install.css";
+</style>
View
248 install.script.php
@@ -0,0 +1,248 @@
+<?php
+/**
+ * @package gantry
+ * @subpackage core
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Gantry uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ *
+ */
+class PlgSystemInstallerInstallerScript
+{
+ protected $packages = array();
+ protected $sourcedir;
+ protected $installerdir;
+ protected $manifest;
+
+ protected function setup($parent)
+ {
+ $this->sourcedir = $parent->getParent()->getPath('source');
+ $this->manifest = $parent->getParent()->getManifest();
+ $this->installerdir = $this->sourcedir . DS . 'installer';
+ }
+
+ public function install($parent)
+ {
+
+ $this->cleanBogusError();
+
+ jimport('joomla.filesystem.file');
+ jimport('joomla.filesystem.folder');
+
+
+ $retval = true;
+ $buffer = '';
+ $install_html_file = dirname(__FILE__) . '/install.html';
+ $install_css_file = dirname(__FILE__) . '/install.css';
+ $tmp_path = JPATH_ROOT . '/tmp';
+
+ // Drop out Style
+ if (file_exists($install_css_file)) {
+ $buffer .= JFile::read($install_html_file);
+ }
+
+ if (JFolder::exists($tmp_path)) {
+ // Copy install.css to tmp dir for inclusion
+ JFile::copy($install_css_file, $tmp_path . '/install.css');
+ }
+
+ // Opening HTML
+ ob_start();
+ ?>
+ <div id="rokinstall-logo">
+ <ul id="rokinstall-status">
+ <?php
+ $buffer .= ob_get_clean();
+
+ $run_installer = true;
+ if (is_file(dirname(__FILE__) . '/requirements.php')) {
+ // check to see if requierments are met
+ if (($loaderrors = require_once(dirname(__FILE__) . '/requirements.php')) !== true) {
+
+ $package['name'] = '';
+ $msg = "Requirements check failed.<br />".implode('<br />',$loaderrors);
+ $buffer .= $this->printerror($package, $msg);
+ $run_installer = false;
+ }
+ }
+
+ // Cycle through cogs and install each
+
+ if ($run_installer) {
+ if (count($this->manifest->cogs->children())) {
+ require_once($this->installerdir . DS . 'RokInstaller.php');
+
+ foreach ($this->manifest->cogs->children() as $cog)
+ {
+ $folder = $this->sourcedir . DS . trim($cog);
+
+ jimport('joomla.installer.helper');
+ if (is_dir($folder)) {
+ // if its actually a directory then fill it up
+ $package = Array();
+ $package['dir'] = $folder;
+ $package['type'] = JInstallerHelper::detectType($folder);
+ $package['installer'] = new RokInstaller();
+ $package['name'] = (string)$cog->name;
+ $package['state'] = 'Success';
+ $package['description'] = (string)$cog->description;
+ $package['msg'] = '';
+ $package['type'] = ucfirst((string)$cog['type']);
+
+ $package['installer']->setCogInfo($cog);
+ // add installer to static for possible rollback
+ $this->packages[] = $package;
+ if (!$package['installer']->install($package['dir'])) {
+ while ($error = JError::getError(true)) {
+ $package['msg'] .= $error;
+ }
+ $buffer .= $this->printerror($package, $package['msg']);
+ //$this->abort();
+ break;
+ }
+ if ($package['installer']->getInstallType() == 'install') {
+ $buffer .= $this->printInstall($package);
+ }
+ else {
+ $buffer .= $this->printUpdate($package);
+ }
+ }
+ else {
+ $package = Array();
+ $package['dir'] = $folder;
+ $package['name'] = (string)$cog->name;
+ $package['state'] = 'Failed';
+ $package['description'] = (string)$cog->description;
+ $package['msg'] = '';
+ $package['type'] = ucfirst((string)$cog['type']);
+ $buffer .= $this->printerror($package, JText::_('JLIB_INSTALLER_ABORT_NOINSTALLPATH'));
+ //$this->abort();
+ break;
+ }
+ }
+ }
+ else
+ {
+ $parent->getParent()->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PACK_INSTALL_NO_FILES', JText::_('JLIB_INSTALLER_' . strtoupper($this->route))));
+ }
+ }
+
+
+ // Closing HTML
+ ob_start();
+ ?>
+ </ul>
+ </div>
+ <?php
+ $buffer .= ob_get_clean();
+
+
+ // Return stuff
+ echo $buffer;
+ return $retval;
+ }
+
+ public function uninstall($parent)
+ {
+
+ }
+
+ public function update($parent)
+ {
+ return $this->install($parent);
+ }
+
+ public function preflight($type, $parent)
+ {
+ $this->setup($parent);
+ //Load Event Handler
+ $event_handler_file = $this->installerdir . '/RokInstallerEvents.php';
+ require_once($event_handler_file);
+ $dispatcher =& JDispatcher::getInstance();
+ new RokInstallerEvents($dispatcher);
+ }
+
+ public function postflight($type, $parent)
+ {
+ $parent->getParent()->abort();
+ }
+
+ public function abort($msg = null, $type = null)
+ {
+ if ($msg) {
+ JError::raiseWarning(100, $msg);
+ }
+ foreach ($this->packages as $package) {
+ $package['installer']->abort(null, $type);
+ }
+ }
+
+ public function printerror($package, $msg)
+ {
+ ob_start();
+ ?>
+ <li class="rokinstall-failure"><span class="rokinstall-row"><span
+ class="rokinstall-icon"></span><?php echo $package['name'];?> installation failed</span>
+ <span class="rokinstall-errormsg">
+ <?php echo $msg; ?>
+ </span>
+ </li>
+ <?php
+ $out = ob_get_clean();
+ return $out;
+ }
+
+ public function printInstall($package)
+ {
+ ob_start();
+ ?>
+ <li class="rokinstall-success"><span class="rokinstall-row"><span
+ class="rokinstall-icon"></span><?php echo $package['name'];?> installation was successful</span></li>
+ <?php
+ $out = ob_get_clean();
+ return $out;
+ }
+
+ public function printUpdate($package)
+ {
+ ob_start();
+ ?>
+ <li class="rokinstall-update"><span class="rokinstall-row"><span
+ class="rokinstall-icon"></span><?php echo $package['name'];?> update was successful</span></li>
+ <?php
+ $out = ob_get_clean();
+ return $out;
+ }
+
+ protected function cleanBogusError(){
+ $errors = array();
+ while(($error = JError::getError(true)) !== false)
+ {
+ if (!($error->get('code') == 1 && $error->get('level') == 2 && $error->get('message') == JText::_('JLIB_INSTALLER_ERROR_NOTFINDXMLSETUPFILE')))
+ {
+ $errors[] = $error;
+ }
+ }
+ foreach($errors as $error)
+ {
+ JError::addToStack($error);
+ }
+
+ $app =& JFactory::getApplication();
+ $enqueued_messages = $app->get('_messageQueue');
+ $other_messages = array();
+ if (!empty($enqueued_messages) && is_array($enqueued_messages))
+ {
+ foreach($enqueued_messages as $enqueued_message)
+ {
+ if (!($enqueued_message['message'] == JText::_('JLIB_INSTALLER_ERROR_NOTFINDXMLSETUPFILE') && $enqueued_message['type']) == 'error'){
+ $other_messages[] = $enqueued_message;
+ }
+ }
+ }
+ $app->set('_messageQueue', $other_messages);
+ }
+}
View
13 installer.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * @package gantry
+ * @subpackage core
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Gantry uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ *
+ */
+die();
View
357 installer/RokInstaller.php
@@ -0,0 +1,357 @@
+<?php
+/**
+ * @package Installer Bundle Framework - RocketTheme
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Installer uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ */
+// Check to ensure this file is within the rest of the framework
+defined('JPATH_BASE') or die();
+
+jimport('joomla.installer.installer');
+jimport('joomla.filesystem.file');
+jimport('joomla.filesystem.folder');
+jimport('joomla.filesystem.archive');
+jimport('joomla.filesystem.path');
+
+/**
+ * Joomla base installer class
+ *
+ * @package Joomla.Framework
+ * @subpackage Installer
+ * @since 1.5
+ */
+class RokInstaller extends JInstaller
+{
+ const EXCEPTION_NO_REPLACE = 'noreplace';
+
+ var $no_overwrite = array();
+ var $backup_dir;
+ var $upgrade = false;
+
+ protected $installtype;
+
+ protected $cogInfo;
+
+
+
+ /**
+ * Returns a reference to the global Installer object, only creating it
+ * if it doesn't already exist.
+ *
+ * @static
+ * @return object An installer object
+ * @since 1.5
+ */
+ public static function getInstance()
+ {
+ static $instance;
+
+ if (!isset ($instance)) {
+ $instance = new RokInstaller();
+ }
+ return $instance;
+ }
+
+ /**
+ * Constructor
+ *
+ * @access protected
+ */
+ function __construct()
+ {
+ parent::__construct();
+ }
+
+
+ /**
+ * Set an installer adapter by name
+ *
+ * @access public
+ * @param string $name Adapter name
+ * @param object $adapter Installer adapter object
+ * @return boolean True if successful
+ * @since 1.5
+ */
+ public function setAdapter($name, &$adapter = null, $options = Array())
+ {
+ if (!is_object($adapter))
+ {
+ // Try to load the adapter object
+ $fullpath= dirname(__FILE__).DS.'adapters'.DS.strtolower($name).'.php';
+
+ if (!file_exists($fullpath)) {
+ return false;
+ }
+
+ // Try to load the adapter object
+ require_once $fullpath;
+
+ $class = "RokInstaller".ucfirst($name);
+ if (!class_exists($class)) {
+ return false;
+ }
+
+ $adapter = new $class($this, $this->_db, $options);
+ }
+ if (!is_object($adapter))
+ {
+ $ret = parent::setAdapter($name, $adapter);
+ if (!$ret){
+ return $ret;
+ }
+ }
+ $this->_adapters[$name] = &$adapter;
+ return true;
+ }
+
+ public function install($path=null)
+ {
+ if ($path && JFolder::exists($path)) {
+ $this->setPath('source', $path);
+ }
+ else
+ {
+ $this->abort(JText::_('JLIB_INSTALLER_ABORT_NOINSTALLPATH'));
+ return false;
+ }
+
+ if (!$this->setupInstall())
+ {
+ $this->abort(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST'));
+ return false;
+ }
+
+ $type = (string)$this->manifest->attributes()->type;
+
+ if (is_object($this->_adapters[$type]))
+ {
+ // Add the languages from the package itself
+ if (method_exists($this->_adapters[$type], 'loadLanguage'))
+ {
+ $this->_adapters[$type]->loadLanguage($path);
+ }
+
+ // Fire the onExtensionBeforeInstall event.
+ JPluginHelper::importPlugin('extension');
+ $dispatcher = JDispatcher::getInstance();
+ $dispatcher->trigger('onExtensionBeforeInstall', array('method'=>'install', 'type'=>$type, 'manifest'=>$this->manifest, 'extension'=>0));
+
+ // Run the install
+ $result = $this->_adapters[$type]->install();
+ $this->installtype = $this->_adapters[$type]->getInstallType();
+ if ($result !== false && method_exists($this->_adapters[$type], 'postInstall'))
+ {
+ $this->_adapters[$type]->postInstall($result);
+ }
+ // Fire the onExtensionAfterInstall
+ $dispatcher->trigger('onExtensionAfterInstall', array('installer'=>clone $this, 'eid'=> $result));
+ if ($result !== false) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ return false;
+ }
+
+
+
+ /**
+ * Method to parse through a files element of the installation manifest and take appropriate
+ * action.
+ *
+ * @access public
+ * @param object $element The xml node to process
+ * @param int $cid Application ID of application to install to
+ * @return boolean True on success
+ * @since 1.5
+ */
+ function prepExceptions($element, $cid=0)
+ {
+
+ $config =& JFactory::getConfig();
+ $this->backup_dir = $config->getValue('config.tmp_path') . DS.uniqid('backup_');
+ if (!JFolder::create($this->backup_dir)) {
+ JError::raiseWarning(1, 'JInstaller::install: '.JText::_('Failed to create directory').' "'.$this->backup_dir.'"');
+ return false;
+ }
+
+ // Initialize variables
+ $exceptionFiles = array ();
+
+ // Get the client info
+ jimport('joomla.application.helper');
+ $client =& JApplicationHelper::getClientInfo($cid);
+
+ if (!is_a($element, 'JSimpleXMLElement') || !count($element->children())) {
+ // Either the tag does not exist or has no children therefore we return zero files processed.
+ return 0;
+ }
+
+ // Get the array of file nodes to process
+ $files = $element->children();
+ if (count($files) == 0) {
+ // No files to process
+ return 0;
+ }
+
+ /*
+ * Here we set the folder we are going to remove the files from.
+ */
+ if ($client) {
+ $pathname = 'extension_'.$client->name;
+ $destination = $this->getPath($pathname);
+ } else {
+ $pathname = 'extension_root';
+ $destination = $this->getPath($pathname);
+ }
+
+ /*
+ * Here we set the folder we are going to copy the files from.
+ *
+ * Does the element have a folder attribute?
+ *
+ * If so this indicates that the files are in a subdirectory of the source
+ * folder and we should append the folder attribute to the source path when
+ * copying files.
+ */
+ if ($folder = $element->attributes('folder')) {
+ $source = $this->getPath('source').DS.$folder;
+ } else {
+ $source = $this->getPath('source');
+ }
+
+ // Process each file in the $files array (children of $tagName).
+ foreach ($files as $file)
+ {
+ $exception_type = $file->attributes('type');
+ $current_file =$destination.DS.$file->data();
+ if ($exception_type == self::EXCEPTION_NO_REPLACE && file_exists($current_file))
+ {
+ $type = ( $file->name() == 'folder') ? 'folder' : 'file';
+
+ $backuppath['src'] = $current_file;
+ $backuppath['dest'] = $this->backup_dir.DS.$file->data();
+ $backuppath['type'] = $type;
+
+ $replacepath['src'] = $backuppath['dest'];
+ $replacepath['dest'] = $backuppath['src'];
+ $replacepath['type'] = $type;
+
+ $this->no_overwrite[] = $replacepath;
+ if (!$this->copyFiles(array($backuppath))){
+ JError::raiseWarning(1, 'JInstaller::install: '.JText::_('Failed to copy backup to ').' "'.$backuppath['dest'].'"');
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ function finishExceptions(){
+ if (($this->upgrade && !empty($this->no_overwrite)) || !$this->upgrade ){
+ foreach ($this->no_overwrite as $restore){
+ if (JPath::canChmod($restore['dest'])){
+ JPath::setPermissions($restore['dest']);
+ }
+ }
+
+ if ($this->copyFiles($this->no_overwrite)){
+ JFolder::delete($this->backup_dir);
+ }
+ }
+ }
+
+ function copyFiles($files, $overwrite=null){
+ $ftp = JClientHelper::getCredentials('ftp');
+
+ // try to make writeable
+ if ($overwrite || $this->getOverwrite()){
+ foreach($files as $file){
+ $type = array_key_exists('type', $file) ? $file['type'] : 'file';
+ switch($type){
+ case 'file':
+ if (!$ftp['enabled'] && JFile::exists($file['dest']) && JPath::isOwner($file['dest'])){
+ JPath::setPermissions($file['dest']);
+ }
+ break;
+ case 'folder':
+ if (!$ftp['enabled'] && JFolder::exists($file['dest']) && JPath::isOwner($file['dest'])){
+ JPath::setPermissions($file['dest']);
+ }
+ break;
+ }
+ }
+ }
+ return parent::copyFiles($files, $overwrite);
+ }
+
+
+ public function postInstall($cogInfo)
+ {
+ if ($path && JFolder::exists($path)) {
+ $this->setPath('source', $path);
+ }
+ else
+ {
+ $this->abort(JText::_('JLIB_INSTALLER_ABORT_NOINSTALLPATH'));
+ return false;
+ }
+
+ if (!$this->setupInstall())
+ {
+ $this->abort(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST'));
+ return false;
+ }
+
+ $type = (string)$this->manifest->attributes()->type;
+
+ if (is_object($this->_adapters[$type]))
+ {
+ // Add the languages from the package itself
+ if (method_exists($this->_adapters[$type], 'loadLanguage'))
+ {
+ $this->_adapters[$type]->loadLanguage($path);
+ }
+
+ // Fire the onExtensionBeforeInstall event.
+ JPluginHelper::importPlugin('extension');
+ $dispatcher = JDispatcher::getInstance();
+ $dispatcher->trigger('onExtensionBeforeInstall', array('method'=>'install', 'type'=>$type, 'manifest'=>$this->manifest, 'extension'=>0));
+
+ // Run the install
+ $result = $this->_adapters[$type]->install();
+
+ // Fire the onExtensionAfterInstall
+ $dispatcher->trigger('onExtensionAfterInstall', array('installer'=>clone $this, 'eid'=> $result));
+ if ($result !== false) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ public function setCogInfo($cogInfo)
+ {
+ $this->cogInfo = $cogInfo;
+ }
+
+ public function getCogInfo()
+ {
+ return $this->cogInfo;
+ }
+
+
+ public function getInstallType(){
+ return $this->installtype;
+ }
+
+}
View
15 installer/RokInstallerEvents.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ */
+
+class RokInstallerEvents extends JPlugin {
+ public function onExtensionAfterInstall($installer, $eid)
+ {
+ $lang = JFactory::getLanguage();
+ $lang->load('install_override',dirname(__FILE__), $lang->getTag(), true);
+ }
+}
View
203 installer/adapters/component.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * @package Installer Bundle Framework - RocketTheme
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Installer uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ */
+
+// Check to ensure this file is within the rest of the framework
+defined('JPATH_BASE') or die();
+
+if (!class_exists("JInstallerComponent"))
+{
+ @include_once(JPATH_LIBRARIES . '/joomla/installer/adapters/component.php');
+}
+/**
+ * Component installer
+ *
+ * @package Joomla.Framework
+ * @subpackage Installer
+ * @since 1.5
+ */
+class RokInstallerComponent extends JInstallerComponent
+{
+
+ protected $installtype = 'install';
+
+ protected $access;
+ protected $enabled;
+ protected $client;
+ protected $ordering = 0;
+ protected $protected;
+ protected $params;
+ protected $remove_admin_menu;
+
+ const DEFAULT_ACCESS = 1;
+ const DEFAULT_ENABLED = 'true';
+ const DEFAULT_PROTECTED = 'false';
+ const DEFAULT_CLIENT = 'site';
+ const DEFAULT_ORDERING = 0;
+ const DEFAULT_PARAMS = null;
+ const DEFAULT_REMOVE_ADMIN_MENU = 'false';
+
+
+ public function setAccess($access)
+ {
+ $this->access = $access;
+ }
+
+ public function getAccess()
+ {
+ return $this->access;
+ }
+
+ public function setClient($client)
+ {
+ switch ($client)
+ {
+ case 'site':
+ $client = 0;
+ break;
+ case 'administrator':
+ $client = 1;
+ break;
+ default:
+ $client = (int)$client;
+ break;
+ }
+ $this->client = $client;
+ }
+
+ public function getClient()
+ {
+ return $this->client;
+ }
+
+ public function setEnabled($enabled)
+ {
+ switch (strtolower($enabled))
+ {
+ case 'true':
+ $enabled = 1;
+ break;
+ case 'false':
+ $enabled = 0;
+ break;
+ default:
+ $enabled = (int)$enabled;
+ break;
+ }
+ $this->enabled = $enabled;
+ }
+
+ public function getEnabled()
+ {
+ return $this->enabled;
+ }
+
+ public function setOrdering($ordering)
+ {
+ $this->ordering = $ordering;
+ }
+
+ public function getOrdering()
+ {
+ return $this->ordering;
+ }
+
+ public function setProtected($protected)
+ {
+ switch (strtolower($protected))
+ {
+ case 'true':
+ $protected = 1;
+ break;
+ case 'false':
+ $protected = 0;
+ break;
+ default:
+ $protected = (int)$protected;
+ break;
+ }
+ $this->protected = $protected;
+ }
+
+ public function getProtected()
+ {
+ return $this->protected;
+ }
+
+ public function setParams($params)
+ {
+ $this->params = $params;
+ }
+
+ public function getParams()
+ {
+ return $this->params;
+ }
+
+ protected function updateExtension(&$extension)
+ {
+ if ($extension)
+ {
+ $extension->access = $this->access;
+ $extension->enabled = $this->enabled;
+ $extension->protected = $this->protected;
+ $extension->client_id = $this->client;
+ $extension->ordering = $this->ordering;
+ $extension->params = $this->params;
+ $extension->store();
+ }
+ }
+
+ public function postInstall($extensionId)
+ {
+
+ $coginfo = $this->parent->getCogInfo();
+
+ $this->setAccess(($coginfo['access']) ? (int)$coginfo['access'] : self::DEFAULT_ACCESS);
+ $this->setEnabled(($coginfo['enabled']) ? (string)$coginfo['enabled'] : self::DEFAULT_ENABLED);
+ $this->setProtected(($coginfo['protected']) ? (string)$coginfo['protected'] : self::DEFAULT_PROTECTED);
+ $this->setClient(($coginfo['client']) ? (string)$coginfo['client'] : self::DEFAULT_CLIENT);
+ $this->setParams(($coginfo->params) ? (string)$coginfo->params : self::DEFAULT_PARAMS);
+ $this->setOrdering(($coginfo['ordering']) ? (int)$coginfo['ordering'] : self::DEFAULT_ORDERING);
+
+
+
+ $extention = $this->loadExtension($extensionId);
+
+ // update the extension info
+ $this->updateExtension($extention);
+
+ $remove_admin_menu = ($coginfo['remove_admin_menu']) ? strtolower((string)$coginfo['remove_admin_menu']) : self::DEFAULT_REMOVE_ADMIN_MENU;
+ if ($remove_admin_menu === 'true')
+ {
+ $this->_removeAdminMenus($extention);
+ }
+ }
+
+ protected function &loadExtension($eid)
+ {
+ $row = JTable::getInstance('extension');
+ $row->load($eid);
+ return $row;
+ }
+
+ public function getInstallType()
+ {
+ return $this->installtype;
+ }
+
+ public function update()
+ {
+ $this->installtype = 'update';
+ return parent::update();
+ }
+
+
+}
View
190 installer/adapters/file.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * @package Installer Bundle Framework - RocketTheme
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Installer uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ */
+
+// Check to ensure this file is within the rest of the framework
+defined('JPATH_BASE') or die();
+
+if (!class_exists("JInstallerFile"))
+{
+ @include_once(JPATH_LIBRARIES . '/joomla/installer/adapters/file.php');
+}
+/**
+ * Component installer
+ *
+ * @package Joomla.Framework
+ * @subpackage Installer
+ * @since 1.5
+ */
+class RokInstallerFile extends JInstallerFile
+{
+ protected $access;
+ protected $enabled;
+ protected $client;
+ protected $ordering;
+ protected $protected;
+ protected $params;
+
+ const DEFAULT_ACCESS = 1;
+ const DEFAULT_ENABLED = 'true';
+ const DEFAULT_PROTECTED = 'false';
+ const DEFAULT_CLIENT = 'site';
+ const DEFAULT_ORDERING = 0;
+ const DEFAULT_PARAMS = null;
+
+
+ public function setAccess($access)
+ {
+ $this->access = $access;
+ }
+
+ public function getAccess()
+ {
+ return $this->access;
+ }
+
+ public function setClient($client)
+ {
+ switch ($client)
+ {
+ case 'site':
+ $client = 0;
+ break;
+ case 'administrator':
+ $client = 1;
+ break;
+ default:
+ $client = (int)$client;
+ break;
+ }
+ $this->client = $client;
+ }
+
+ public function getClient()
+ {
+ return $this->client;
+ }
+
+ public function setEnabled($enabled)
+ {
+ switch (strtolower($enabled))
+ {
+ case 'true':
+ $enabled = 1;
+ break;
+ case 'false':
+ $enabled = 0;
+ break;
+ default:
+ $enabled = (int)$enabled;
+ break;
+ }
+ $this->enabled = $enabled;
+ }
+
+ public function getEnabled()
+ {
+ return $this->enabled;
+ }
+
+ public function setOrdering($ordering)
+ {
+ $this->ordering = $ordering;
+ }
+
+ public function getOrdering()
+ {
+ return $this->ordering;
+ }
+
+ public function setProtected($protected)
+ {
+ switch (strtolower($protected))
+ {
+ case 'true':
+ $protected = 1;
+ break;
+ case 'false':
+ $protected = 0;
+ break;
+ default:
+ $protected = (int)$protected;
+ break;
+ }
+ $this->protected = $protected;
+ }
+
+ public function getProtected()
+ {
+ return $this->protected;
+ }
+
+ public function setParams($params)
+ {
+ $this->params = $params;
+ }
+
+ public function getParams()
+ {
+ return $this->params;
+ }
+
+ protected function updateExtension(&$extension)
+ {
+ if ($extension)
+ {
+ $extension->access = $this->access;
+ $extension->enabled = $this->enabled;
+ $extension->protected = $this->protected;
+ $extension->client_id = $this->client;
+ $extension->ordering = $this->ordering;
+ $extension->params = $this->params;
+ $extension->store();
+ }
+ }
+
+ public function postInstall($extensionId)
+ {
+
+ $coginfo = $this->parent->getCogInfo();
+
+ $this->setAccess(($coginfo['access']) ? (int)$coginfo['access'] : self::DEFAULT_ACCESS);
+ $this->setEnabled(($coginfo['enabled']) ? (string)$coginfo['enabled'] : self::DEFAULT_ENABLED);
+ $this->setProtected(($coginfo['protected']) ? (string)$coginfo['protected'] : self::DEFAULT_PROTECTED);
+ $this->setClient(($coginfo['client']) ? (string)$coginfo['client'] : self::DEFAULT_CLIENT);
+ $this->setParams(($coginfo->params) ? (string)$coginfo->params : self::DEFAULT_PARAMS);
+ $this->setOrdering(($coginfo['ordering']) ? (int)$coginfo['ordering'] : self::DEFAULT_ORDERING);
+
+ $extention = $this->loadExtension($extensionId);
+
+ // update the extension info
+ $this->updateExtension($extention);
+ }
+
+ protected function &loadExtension($eid)
+ {
+ $row = JTable::getInstance('extension');
+ $row->load($eid);
+ return $row;
+ }
+
+ protected $installtype = 'install';
+
+ public function getInstallType()
+ {
+ return $this->installtype;
+ }
+
+ public function update()
+ {
+ $this->installtype = 'update';
+ return parent::update();
+ }
+}
View
190 installer/adapters/language.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * @package Installer Bundle Framework - RocketTheme
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Installer uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ */
+
+// Check to ensure this file is within the rest of the framework
+defined('JPATH_BASE') or die();
+
+if (!class_exists("JInstallerLanguage"))
+{
+ @include_once(JPATH_LIBRARIES . '/joomla/installer/adapters/language.php');
+}
+/**
+ * Component installer
+ *
+ * @package Joomla.Framework
+ * @subpackage Installer
+ * @since 1.5
+ */
+class RokInstallerLanguage extends JInstallerLanguage
+{
+ protected $access;
+ protected $enabled;
+ protected $client;
+ protected $ordering;
+ protected $protected;
+ protected $params;
+
+ const DEFAULT_ACCESS = 1;
+ const DEFAULT_ENABLED = 'true';
+ const DEFAULT_PROTECTED = 'false';
+ const DEFAULT_CLIENT = 'site';
+ const DEFAULT_ORDERING = 0;
+ const DEFAULT_PARAMS = null;
+
+
+ public function setAccess($access)
+ {
+ $this->access = $access;
+ }
+
+ public function getAccess()
+ {
+ return $this->access;
+ }
+
+ public function setClient($client)
+ {
+ switch ($client)
+ {
+ case 'site':
+ $client = 0;
+ break;
+ case 'administrator':
+ $client = 1;
+ break;
+ default:
+ $client = (int)$client;
+ break;
+ }
+ $this->client = $client;
+ }
+
+ public function getClient()
+ {
+ return $this->client;
+ }
+
+ public function setEnabled($enabled)
+ {
+ switch (strtolower($enabled))
+ {
+ case 'true':
+ $enabled = 1;
+ break;
+ case 'false':
+ $enabled = 0;
+ break;
+ default:
+ $enabled = (int)$enabled;
+ break;
+ }
+ $this->enabled = $enabled;
+ }
+
+ public function getEnabled()
+ {
+ return $this->enabled;
+ }
+
+ public function setOrdering($ordering)
+ {
+ $this->ordering = $ordering;
+ }
+
+ public function getOrdering()
+ {
+ return $this->ordering;
+ }
+
+ public function setProtected($protected)
+ {
+ switch (strtolower($protected))
+ {
+ case 'true':
+ $protected = 1;
+ break;
+ case 'false':
+ $protected = 0;
+ break;
+ default:
+ $protected = (int)$protected;
+ break;
+ }
+ $this->protected = $protected;
+ }
+
+ public function getProtected()
+ {
+ return $this->protected;
+ }
+
+ public function setParams($params)
+ {
+ $this->params = $params;
+ }
+
+ public function getParams()
+ {
+ return $this->params;
+ }
+
+ protected function updateExtension(&$extension)
+ {
+ if ($extension)
+ {
+ $extension->access = $this->access;
+ $extension->enabled = $this->enabled;
+ $extension->protected = $this->protected;
+ $extension->client_id = $this->client;
+ $extension->ordering = $this->ordering;
+ $extension->params = $this->params;
+ $extension->store();
+ }
+ }
+
+ public function postInstall($extensionId)
+ {
+
+ $coginfo = $this->parent->getCogInfo();
+
+ $this->setAccess(($coginfo['access']) ? (int)$coginfo['access'] : self::DEFAULT_ACCESS);
+ $this->setEnabled(($coginfo['enabled']) ? (string)$coginfo['enabled'] : self::DEFAULT_ENABLED);
+ $this->setProtected(($coginfo['protected']) ? (string)$coginfo['protected'] : self::DEFAULT_PROTECTED);
+ $this->setClient(($coginfo['client']) ? (string)$coginfo['client'] : self::DEFAULT_CLIENT);
+ $this->setParams(($coginfo->params) ? (string)$coginfo->params : self::DEFAULT_PARAMS);
+ $this->setOrdering(($coginfo['ordering']) ? (int)$coginfo['ordering'] : self::DEFAULT_ORDERING);
+
+ $extention = $this->loadExtension($extensionId);
+
+ // update the extension info
+ $this->updateExtension($extention);
+ }
+
+ protected function &loadExtension($eid)
+ {
+ $row = JTable::getInstance('extension');
+ $row->load($eid);
+ return $row;
+ }
+
+ protected $installtype = 'install';
+
+ public function getInstallType()
+ {
+ return $this->installtype;
+ }
+
+ public function update()
+ {
+ $this->installtype = 'update';
+ return parent::update();
+ }
+}
View
190 installer/adapters/library.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * @package Installer Bundle Framework - RocketTheme
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Installer uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ */
+
+// Check to ensure this file is within the rest of the framework
+defined('JPATH_BASE') or die();
+
+if (!class_exists("JInstallerLibrary"))
+{
+ @include_once(JPATH_LIBRARIES . '/joomla/installer/adapters/library.php');
+}
+/**
+ * Component installer
+ *
+ * @package Joomla.Framework
+ * @subpackage Installer
+ * @since 1.5
+ */
+class RokInstallerLibrary extends JInstallerLibrary
+{
+ protected $access;
+ protected $enabled;
+ protected $client;
+ protected $ordering;
+ protected $protected;
+ protected $params;
+
+ const DEFAULT_ACCESS = 1;
+ const DEFAULT_ENABLED = 'true';
+ const DEFAULT_PROTECTED = 'false';
+ const DEFAULT_CLIENT = 'site';
+ const DEFAULT_ORDERING = 0;
+ const DEFAULT_PARAMS = null;
+
+
+ public function setAccess($access)
+ {
+ $this->access = $access;
+ }
+
+ public function getAccess()
+ {
+ return $this->access;
+ }
+
+ public function setClient($client)
+ {
+ switch ($client)
+ {
+ case 'site':
+ $client = 0;
+ break;
+ case 'administrator':
+ $client = 1;
+ break;
+ default:
+ $client = (int)$client;
+ break;
+ }
+ $this->client = $client;
+ }
+
+ public function getClient()
+ {
+ return $this->client;
+ }
+
+ public function setEnabled($enabled)
+ {
+ switch (strtolower($enabled))
+ {
+ case 'true':
+ $enabled = 1;
+ break;
+ case 'false':
+ $enabled = 0;
+ break;
+ default:
+ $enabled = (int)$enabled;
+ break;
+ }
+ $this->enabled = $enabled;
+ }
+
+ public function getEnabled()
+ {
+ return $this->enabled;
+ }
+
+ public function setOrdering($ordering)
+ {
+ $this->ordering = $ordering;
+ }
+
+ public function getOrdering()
+ {
+ return $this->ordering;
+ }
+
+ public function setProtected($protected)
+ {
+ switch (strtolower($protected))
+ {
+ case 'true':
+ $protected = 1;
+ break;
+ case 'false':
+ $protected = 0;
+ break;
+ default:
+ $protected = (int)$protected;
+ break;
+ }
+ $this->protected = $protected;
+ }
+
+ public function getProtected()
+ {
+ return $this->protected;
+ }
+
+ public function setParams($params)
+ {
+ $this->params = $params;
+ }
+
+ public function getParams()
+ {
+ return $this->params;
+ }
+
+ protected function updateExtension(&$extension)
+ {
+ if ($extension)
+ {
+ $extension->access = $this->access;
+ $extension->enabled = $this->enabled;
+ $extension->protected = $this->protected;
+ $extension->client_id = $this->client;
+ $extension->ordering = $this->ordering;
+ $extension->params = $this->params;
+ $extension->store();
+ }
+ }
+
+ public function postInstall($extensionId)
+ {
+
+ $coginfo = $this->parent->getCogInfo();
+
+ $this->setAccess(($coginfo['access']) ? (int)$coginfo['access'] : self::DEFAULT_ACCESS);
+ $this->setEnabled(($coginfo['enabled']) ? (string)$coginfo['enabled'] : self::DEFAULT_ENABLED);
+ $this->setProtected(($coginfo['protected']) ? (string)$coginfo['protected'] : self::DEFAULT_PROTECTED);
+ $this->setClient(($coginfo['client']) ? (string)$coginfo['client'] : self::DEFAULT_CLIENT);
+ $this->setParams(($coginfo->params) ? (string)$coginfo->params : self::DEFAULT_PARAMS);
+ $this->setOrdering(($coginfo['ordering']) ? (int)$coginfo['ordering'] : self::DEFAULT_ORDERING);
+
+ $extention = $this->loadExtension($extensionId);
+
+ // update the extension info
+ $this->updateExtension($extention);
+ }
+
+ protected function &loadExtension($eid)
+ {
+ $row = JTable::getInstance('extension');
+ $row->load($eid);
+ return $row;
+ }
+
+ protected $installtype = 'install';
+
+ public function getInstallType()
+ {
+ return $this->installtype;
+ }
+
+ public function update()
+ {
+ $this->installtype = 'update';
+ return parent::update();
+ }
+}
View
336 installer/adapters/module.php
@@ -0,0 +1,336 @@
+<?php
+/**
+ * @package Installer Bundle Framework - RocketTheme
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Installer uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ */
+
+// Check to ensure this file is within the rest of the framework
+defined('JPATH_BASE') or die();
+
+if (!class_exists("JInstallerModule")) {
+ @include_once(JPATH_LIBRARIES . '/joomla/installer/adapters/module.php');
+}
+/**
+ * Component installer
+ *
+ * @package Joomla.Framework
+ * @subpackage Installer
+ * @since 1.5
+ */
+class RokInstallerModule extends JInstallerModule
+{
+ protected $access;
+ protected $enabled;
+ protected $client;
+ protected $ordering = 0;
+ protected $protected;
+ protected $params;
+
+ const DEFAULT_ACCESS = 1;
+ const DEFAULT_ENABLED = 'true';
+ const DEFAULT_PROTECTED = 'false';
+ const DEFAULT_CLIENT = 'site';
+ const DEFAULT_ORDERING = 0;
+ const DEFAULT_PARAMS = null;
+
+
+ public function setAccess($access)
+ {
+ $this->access = $access;
+ }
+
+ public function getAccess()
+ {
+ return $this->access;
+ }
+
+ public function setClient($client)
+ {
+ switch ($client)
+ {
+ case 'site':
+ $client = 0;
+ break;
+ case 'administrator':
+ $client = 1;
+ break;
+ default:
+ $client = (int)$client;
+ break;
+ }
+ $this->client = $client;
+ }
+
+ public function getClient()
+ {
+ return $this->client;
+ }
+
+ public function setEnabled($enabled)
+ {
+ switch (strtolower($enabled))
+ {
+ case 'true':
+ $enabled = 1;
+ break;
+ case 'false':
+ $enabled = 0;
+ break;
+ default:
+ $enabled = (int)$enabled;
+ break;
+ }
+ $this->enabled = $enabled;
+ }
+
+ public function getEnabled()
+ {
+ return $this->enabled;
+ }
+
+ public function setOrdering($ordering)
+ {
+ $this->ordering = $ordering;
+ }
+
+ public function getOrdering()
+ {
+ return $this->ordering;
+ }
+
+ public function setProtected($protected)
+ {
+ switch (strtolower($protected))
+ {
+ case 'true':
+ $protected = 1;
+ break;
+ case 'false':
+ $protected = 0;
+ break;
+ default:
+ $protected = (int)$protected;
+ break;
+ }
+ $this->protected = $protected;
+ }
+
+ public function getProtected()
+ {
+ return $this->protected;
+ }
+
+ public function setParams($params)
+ {
+ $this->params = $params;
+ }
+
+ public function getParams()
+ {
+ return $this->params;
+ }
+
+ protected function updateExtension(&$extension)
+ {
+ if ($extension) {
+ $extension->access = $this->access;
+ $extension->enabled = $this->enabled;
+ $extension->protected = $this->protected;
+ $extension->client_id = $this->client;
+ $extension->ordering = $this->ordering;
+ $extension->params = $this->params;
+ $extension->store();
+ }
+ }
+
+ public function postInstall($extensionId)
+ {
+
+ $coginfo = $this->parent->getCogInfo();
+
+ $this->setAccess(($coginfo['access']) ? (int)$coginfo['access'] : self::DEFAULT_ACCESS);
+ $this->setEnabled(($coginfo['enabled']) ? (string)$coginfo['enabled'] : self::DEFAULT_ENABLED);
+ $this->setProtected(($coginfo['protected']) ? (string)$coginfo['protected'] : self::DEFAULT_PROTECTED);
+ $this->setClient(($coginfo['client']) ? (string)$coginfo['client'] : self::DEFAULT_CLIENT);
+ $this->setParams(($coginfo->params) ? (string)$coginfo->params : self::DEFAULT_PARAMS);
+ $this->setOrdering(($coginfo['ordering']) ? (int)$coginfo['ordering'] : self::DEFAULT_ORDERING);
+
+ $extention = $this->loadExtension($extensionId);
+
+ // update the extension info
+ $this->updateExtension($extention);
+
+ if ($this->getInstallType() != 'update') {
+ if (strtolower($this->route) == 'install') {
+ // remove the auto installed module instance
+ $this->removeInstances($extention->element);
+ }
+
+ foreach ($coginfo->module as $moduleinfo)
+ {
+ $this->addInstance($extention->element, $moduleinfo);
+ }
+ }
+
+ }
+
+ protected function &loadExtension($eid)
+ {
+ $row = JTable::getInstance('extension');
+ $row->load($eid);
+ return $row;
+ }
+
+ protected function removeInstances($module_name)
+ {
+ $db = $this->parent->getDbo();
+ // Lets delete all the module copies for the type we are uninstalling
+ $query = 'SELECT `id`' .
+ ' FROM `#__modules`' .
+ ' WHERE module = ' . $db->Quote($module_name);
+ $db->setQuery($query);
+
+ try
+ {
+ $modules = $db->loadResultArray();
+ }
+ catch (JException $e)
+ {
+ $modules = array();
+ }
+
+ // Do we have any module copies?
+ if (count($modules)) {
+ // Ensure the list is sane
+ JArrayHelper::toInteger($modules);
+ $modID = implode(',', $modules);
+
+ // Wipe out any items assigned to menus
+ $query = 'DELETE' .
+ ' FROM #__modules_menu' .
+ ' WHERE moduleid IN (' . $modID . ')';
+ $db->setQuery($query);
+ try
+ {
+ $db->query();
+ }
+ catch (JException $e)
+ {
+ JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_MOD_UNINSTALL_EXCEPTION', $db->stderr(true)));
+ $retval = false;
+ }
+
+ // Wipe out any instances in the modules table
+ $query = 'DELETE' .
+ ' FROM #__modules' .
+ ' WHERE id IN (' . $modID . ')';
+ $db->setQuery($query);
+
+ try
+ {
+ $db->query();
+ }
+ catch (JException $e)
+ {
+ JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_MOD_UNINSTALL_EXCEPTION', $db->stderr(true)));
+ $retval = false;
+ }
+ }
+ }
+
+ protected function addInstance($module_name, &$moduleInfo)
+ {
+
+ $db = $this->parent->getDbo();
+
+ $module = JTable::getInstance('module');
+
+ $module->set('module', $module_name);
+ if ($moduleInfo['title']) $module->set('title', (string)$moduleInfo['title']);
+ if ($moduleInfo['position']) $module->set('position', (string)$moduleInfo['position']);
+ if ($moduleInfo['access']) $module->set('access', (int)$moduleInfo['access']);
+ if ($moduleInfo['ordering']) $module->set('ordering', (int)$moduleInfo['ordering']);
+ $module->set('language', ($moduleInfo['language']) ? (string)$moduleInfo['language'] : '*');
+ if ($moduleInfo['published']) {
+ $published = (string)$moduleInfo['published'];
+ switch (strtolower($published))
+ {
+ case 'true':
+ $published = 1;
+ break;
+ case 'false':
+ $published = 0;
+ break;
+ default:
+ $published = (int)$published;
+ break;
+ }
+ $module->set('published', $published);
+ }
+ if ($moduleInfo['showtitle']) {
+ $showtitle = (string)$moduleInfo['showtitle'];
+ switch (strtolower($showtitle))
+ {
+ case 'true':
+ $showtitle = 1;
+ break;
+ case 'false':
+ $showtitle = 0;
+ break;
+ default:
+ $showtitle = (int)$showtitle;
+ break;
+ }
+ $module->set('showtitle', $showtitle);
+ }
+ if ($moduleInfo['client']) {
+ $client = (string)$moduleInfo['client'];
+ switch ($client)
+ {
+ case 'site':
+ $client_id = 0;
+ break;
+ case 'administrator':
+ $client_id = 1;
+ break;
+ default:
+ $client_id = (int)$client;
+ break;
+ }
+ $module->set('client_id', $client_id);
+ }
+ if ($moduleInfo->params) {
+ $module->set('params', (string)$moduleInfo->params);
+ }
+ if ($moduleInfo->content) {
+ $module->set('content', (string)$moduleInfo->content);
+ }
+ if ($moduleInfo->note) {
+ $module->set('note', (string)$moduleInfo->note);
+ }
+ $module->store();
+
+ $module_id = $db->insertid();
+
+ $query = $db->getQuery(true);
+ if ($moduleInfo['assigned'] && strtolower((string)$moduleInfo['assigned']) == 'all') {
+ $query->clear();
+ $query->insert('#__modules_menu');
+ $query->set('moduleid=' . (int)$module_id);
+ $query->set('menuid=0');
+ $db->setQuery((string)$query);
+ $db->query();
+ }
+ }
+
+
+ public function getInstallType()
+ {
+ return strtolower($this->route);
+ }
+}
View
185 installer/adapters/plugin.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * @package Installer Bundle Framework - RocketTheme
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Installer uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ */
+
+// Check to ensure this file is within the rest of the framework
+defined('JPATH_BASE') or die();
+
+if (!class_exists("JInstallerPlugin"))
+{
+ @include_once(JPATH_LIBRARIES . '/joomla/installer/adapters/plugin.php');
+}
+/**
+ * Component installer
+ *
+ * @package Joomla.Framework
+ * @subpackage Installer
+ * @since 1.5
+ */
+class RokInstallerPlugin extends JInstallerPlugin
+{
+ protected $access;
+ protected $enabled;
+ protected $client;
+ protected $ordering = 0;
+ protected $protected;
+ protected $params;
+
+ const DEFAULT_ACCESS = 1;
+ const DEFAULT_ENABLED = 'true';
+ const DEFAULT_PROTECTED = 'false';
+ const DEFAULT_CLIENT = 'site';
+ const DEFAULT_ORDERING = 0;
+ const DEFAULT_PARAMS = null;
+
+
+ public function setAccess($access)
+ {
+ $this->access = $access;
+ }
+
+ public function getAccess()
+ {
+ return $this->access;
+ }
+
+ public function setClient($client)
+ {
+ switch ($client)
+ {
+ case 'site':
+ $client = 0;
+ break;
+ case 'administrator':
+ $client = 1;
+ break;
+ default:
+ $client = (int)$client;
+ break;
+ }
+ $this->client = $client;
+ }
+
+ public function getClient()
+ {
+ return $this->client;
+ }
+
+ public function setEnabled($enabled)
+ {
+ switch (strtolower($enabled))
+ {
+ case 'true':
+ $enabled = 1;
+ break;
+ case 'false':
+ $enabled = 0;
+ break;
+ default:
+ $enabled = (int)$enabled;
+ break;
+ }
+ $this->enabled = $enabled;
+ }
+
+ public function getEnabled()
+ {
+ return $this->enabled;
+ }
+
+ public function setOrdering($ordering)
+ {
+ $this->ordering = $ordering;
+ }
+
+ public function getOrdering()
+ {
+ return $this->ordering;
+ }
+
+ public function setProtected($protected)
+ {
+ switch (strtolower($protected))
+ {
+ case 'true':
+ $protected = 1;
+ break;
+ case 'false':
+ $protected = 0;
+ break;
+ default:
+ $protected = (int)$protected;
+ break;
+ }
+ $this->protected = $protected;
+ }
+
+ public function getProtected()
+ {
+ return $this->protected;
+ }
+
+ public function setParams($params)
+ {
+ $this->params = $params;
+ }
+
+ public function getParams()
+ {
+ return $this->params;
+ }
+
+ protected function updateExtension(&$extension)
+ {
+ if ($extension)
+ {
+ $extension->access = $this->access;
+ $extension->enabled = $this->enabled;
+ $extension->protected = $this->protected;
+ $extension->client_id = $this->client;
+ $extension->ordering = $this->ordering;
+ $extension->params = $this->params;
+ $extension->store();
+ }
+ }
+
+ public function postInstall($extensionId)
+ {
+
+ $coginfo = $this->parent->getCogInfo();
+
+ $this->setAccess(($coginfo['access']) ? (int)$coginfo['access'] : self::DEFAULT_ACCESS);
+ $this->setEnabled(($coginfo['enabled']) ? (string)$coginfo['enabled'] : self::DEFAULT_ENABLED);
+ $this->setProtected(($coginfo['protected']) ? (string)$coginfo['protected'] : self::DEFAULT_PROTECTED);
+ $this->setClient(($coginfo['client']) ? (string)$coginfo['client'] : self::DEFAULT_CLIENT);
+ $this->setParams(($coginfo->params) ? (string)$coginfo->params : self::DEFAULT_PARAMS);
+ $this->setOrdering(($coginfo['ordering']) ? (int)$coginfo['ordering'] : self::DEFAULT_ORDERING);
+
+ $params = null;
+ if ($coginfo->params) $params = (string)$coginfo->params;
+
+ $extention = $this->loadExtension($extensionId);
+
+ // update the extension info
+ $this->updateExtension($extention);
+ }
+
+ protected function &loadExtension($eid)
+ {
+ $row = JTable::getInstance('extension');
+ $row->load($eid);
+ return $row;
+ }
+
+ public function getInstallType()
+ {
+ return $this->route;
+ }
+}
View
305 installer/adapters/template.php
@@ -0,0 +1,305 @@
+<?php
+/**
+ * @package Installer Bundle Framework - RocketTheme
+ * @version 1.8 November 2, 2011
+ * @author RocketTheme http://www.rockettheme.com
+ * @copyright Copyright (C) 2007 - 2011 RocketTheme, LLC
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
+ *
+ * Installer uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
+ */
+
+// Check to ensure this file is within the rest of the framework
+defined('JPATH_BASE') or die();
+
+if (!class_exists("JInstallerTemplate")) {
+ @include_once(JPATH_LIBRARIES . '/joomla/installer/adapters/template.php');
+}
+/**
+ * Component installer
+ *
+ * @package Joomla.Framework
+ * @subpackage Installer
+ * @since 1.5
+ */
+class RokInstallerTemplate extends JInstallerTemplate
+{
+
+ protected $master_id = 0;
+
+ const DEFAULT_ACCESS = 1;
+ const DEFAULT_ENABLED = 'true';
+ const DEFAULT_PROTECTED = 'false';
+ const DEFAULT_CLIENT = 'site';
+ const DEFAULT_ORDERING = 0;
+ const DEFAULT_PARAMS = null;
+
+ protected $access;
+ protected $enabled;
+ protected $client;
+ protected $ordering;
+ protected $protected;
+ protected $params;
+
+
+ public function setAccess($access)
+ {
+ $this->access = $access;
+ }
+
+ public function getAccess()
+ {
+ return $this->access;
+ }
+
+ public function setClient($client)
+ {
+ switch ($client)
+ {
+ case 'site':
+ $client = 0;
+ break;
+ case 'administrator':
+ $client = 1;
+ break;
+ default:
+ $client = (int)$client;
+ break;
+ }
+ $this->client = $client;
+ }
+
+ public function getClient()
+