├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── RoboFile.php
├── build.properties.dist
├── build.xml
├── cli
└── joomla.php
├── codeception.yml
├── component
├── admin
│ ├── Webservices
│ │ ├── Controller
│ │ │ ├── AddController.php
│ │ │ ├── AjaxController.php
│ │ │ ├── ApplyController.php
│ │ │ ├── CancelController.php
│ │ │ ├── DisplayController.php
│ │ │ ├── EditController.php
│ │ │ ├── InstallController.php
│ │ │ ├── PublishController.php
│ │ │ ├── SaveController.php
│ │ │ └── UnpublishController.php
│ │ ├── Helper.php
│ │ ├── Layout
│ │ │ ├── fields.php
│ │ │ ├── fields
│ │ │ │ └── field.php
│ │ │ ├── operation.php
│ │ │ ├── operation
│ │ │ │ └── attributes.php
│ │ │ ├── resources.php
│ │ │ ├── resources
│ │ │ │ └── resource.php
│ │ │ └── scopes.php
│ │ ├── Model
│ │ │ ├── Fields
│ │ │ │ ├── componentlist.php
│ │ │ │ ├── tablelist.php
│ │ │ │ ├── webservicelist.php
│ │ │ │ ├── webservicepaths.php
│ │ │ │ └── webservicescopes.php
│ │ │ ├── FormModel.php
│ │ │ ├── Forms
│ │ │ │ ├── filter_webservices.xml
│ │ │ │ ├── webservice.xml
│ │ │ │ ├── webservice_defaults.xml
│ │ │ │ └── webservice_operation.xml
│ │ │ ├── WebserviceModel.php
│ │ │ └── WebservicesModel.php
│ │ ├── Table
│ │ │ └── WebserviceTable.php
│ │ └── View
│ │ │ ├── DefaultHtmlView.php
│ │ │ ├── Webservice
│ │ │ ├── WebserviceHtmlView.php
│ │ │ └── tmpl
│ │ │ │ ├── default.php
│ │ │ │ ├── default_create.php
│ │ │ │ ├── default_delete.php
│ │ │ │ ├── default_documentation.php
│ │ │ │ ├── default_main.php
│ │ │ │ ├── default_read.php
│ │ │ │ ├── default_task.php
│ │ │ │ └── default_update.php
│ │ │ └── Webservices
│ │ │ ├── WebservicesHtmlView.php
│ │ │ └── tmpl
│ │ │ └── default.php
│ ├── access.xml
│ ├── config.xml
│ ├── language
│ │ └── en-GB
│ │ │ ├── en-GB.com_webservices.ini
│ │ │ └── en-GB.com_webservices.sys.ini
│ ├── sql
│ │ ├── install
│ │ │ └── mysql
│ │ │ │ ├── install.sql
│ │ │ │ └── uninstall.sql
│ │ └── updates
│ │ │ └── mysql
│ │ │ └── 1.0.0.sql
│ └── webservices.php
├── media
│ └── webservices
│ │ └── js
│ │ ├── component.js
│ │ └── component.min.js
└── webservices.xml
├── composer.json
├── composer.lock
├── config.dist.json
├── extension_packager.xml
├── layouts
└── webservice
│ ├── documentation.php
│ ├── documentationoperation.php
│ └── documentationoperation
│ └── example.php
├── plugins
└── authentication
│ └── redcore_oauth2
│ ├── language
│ └── en-GB
│ │ ├── en-GB.plg_authentication_redcore_oauth2.ini
│ │ └── en-GB.plg_authentication_redcore_oauth2.sys.ini
│ ├── redcore_oauth2.php
│ └── redcore_oauth2.xml
├── routes.json
├── src
├── Api
│ ├── ApiBase.php
│ ├── ApiInterface.php
│ ├── Rest
│ │ └── Rest.php
│ └── Soap
│ │ ├── Operation
│ │ └── Operation.php
│ │ ├── Soap.php
│ │ ├── SoapHelper.php
│ │ ├── Transform
│ │ ├── TransformArray.php
│ │ ├── TransformArrayDefined.php
│ │ ├── TransformArrayRequired.php
│ │ ├── TransformBase.php
│ │ ├── TransformBoolean.php
│ │ ├── TransformDatetime.php
│ │ ├── TransformFloat.php
│ │ ├── TransformInt.php
│ │ └── TransformInterface.php
│ │ └── Wsdl.php
├── CliApplication.php
├── Integrations
│ ├── AuthorisationInterface.php
│ ├── IntegrationInterface.php
│ └── Joomla
│ │ ├── Authorisation
│ │ └── Authorise.php
│ │ ├── Joomla.php
│ │ ├── Model
│ │ ├── Item.php
│ │ └── Jlist.php
│ │ ├── Strategy
│ │ └── Joomla.php
│ │ ├── Table
│ │ └── Table.php
│ │ └── defines.php
├── Layout
│ ├── Base.php
│ ├── File.php
│ ├── Layout.php
│ └── LayoutHelper.php
├── Renderer
│ ├── Application
│ │ ├── Haljson.php
│ │ ├── Halxml.php
│ │ ├── Json.php
│ │ ├── Soapxml.php
│ │ └── Xml.php
│ ├── Renderer.php
│ └── RendererInterface.php
├── Resource
│ ├── Resource.php
│ ├── ResourceHome.php
│ ├── ResourceItem.php
│ ├── ResourceLink.php
│ └── ResourceList.php
├── Service
│ ├── ConfigurationProvider.php
│ ├── DatabaseProvider.php
│ ├── EventProvider.php
│ └── RendererProvider.php
├── Type
│ ├── AbstractType.php
│ ├── TypeArray.php
│ ├── TypeBoolean.php
│ ├── TypeDatetime.php
│ ├── TypeFile.php
│ ├── TypeFloat.php
│ ├── TypeFloating.php
│ ├── TypeInteger.php
│ ├── TypeInterface.php
│ ├── TypeJson.php
│ ├── TypeNone.php
│ ├── TypePosition.php
│ ├── TypeState.php
│ ├── TypeString.php
│ ├── TypeTarget.php
│ ├── TypeUrn.php
│ └── TypeYnglobal.php
├── Uri
│ └── Uri.php
├── WebApplication.php
├── Webservices
│ ├── ConfigurationHelper.php
│ ├── Create.php
│ ├── Delete.php
│ ├── Exception
│ │ ├── ConfigurationException.php
│ │ └── KeyNotFoundException.php
│ ├── Factory.php
│ ├── Profile.php
│ ├── Read.php
│ ├── Update.php
│ ├── Webservice.php
│ ├── WebserviceBase.php
│ └── WebserviceHelper.php
├── Xml
│ └── XmlHelper.php
└── language
│ └── en-GB
│ └── en-GB.lib_webservices.ini
├── tests
├── _bootstrap.php
├── _data
│ └── dump.sql
├── _support
│ └── Helper
│ │ ├── Acceptance.php
│ │ ├── Api.php
│ │ ├── Functional.php
│ │ └── Unit.php
├── acceptance.suite.dist.yml
├── acceptance
│ ├── _bootstrap.php
│ ├── administrator
│ │ └── ActivateContactWebserviceCept.php
│ ├── install
│ │ ├── 01-InstallJoomlaCept.php
│ │ └── 02-InstallExtensionCept.php
│ └── uninstall
│ │ └── ZZ-UninstallExtensionCept.php
├── api.suite.dist.yml
├── api
│ ├── _bootstrap.php
│ └── administrator.contact.1.0.0.Cest.php
├── functional
│ └── _bootstrap.php
├── travis-ci-apache.conf
└── unit
│ └── _bootstrap.php
├── webservices_copy_mandatory.xml
└── www
├── htaccess.txt
├── index.php
└── media
└── webservices
└── webservices
├── index.html
├── joomla
├── administrator.contact.1.0.0.php
├── administrator.contact.1.0.0.xml
├── index.html
├── site.categories.1.0.0.php
├── site.categories.1.0.0.xml
├── site.contacts.1.0.0.php
├── site.contacts.1.0.0.xml
├── site.contents.1.0.0.xml
├── site.users.1.0.0.php
└── site.users.1.0.0.xml
└── upload
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | config.json
2 |
3 | # OSX
4 | .DS_Store
5 | ._*
6 | .Spotlight-V100
7 | .Trashes
8 |
9 | # Windows
10 | Thumbs.db
11 | Desktop.ini
12 |
13 | # PHPStorm
14 | .idea/
15 |
16 | # Sublime Text
17 | *.sublime*
18 |
19 | # Eclipse
20 | .buildpath
21 | .project
22 | .settings
23 |
24 | # Temp files
25 | *.tmp
26 | *.bak
27 | *.swp
28 | *~.nib
29 | *~
30 |
31 | # Phing
32 | build.properties
33 | phing-latest.phar
34 | .dist
35 |
36 | # composer
37 | composer.phar
38 | vendor/*
39 |
40 | # Robo
41 | robo.phar
42 |
43 | # Test related files
44 | tests/acceptance.suite.yml
45 | tests/functional.suite.yml
46 | tests/unit.suite.yml
47 | tests/api.suite.yml
48 | tests/*/*Tester.php
49 | tests/joomla-cms3*
50 | tests/_output
51 | selenium-server-standalone.jar
52 | codecept.phar
53 | selenium.log
54 | selenium-errors.log
55 | tests/_support/_generated/*
56 | tests/_output/*
57 |
58 | # Never ignore
59 | !.gitignore
60 | !index.html
61 | !index.php
62 |
63 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | env: TRAVIS_PUBLIC_REPOSITORY=true
3 | php:
4 | - 5.5
5 | - 5.6
6 | - 7.0
7 | matrix:
8 | allow_failures:
9 | - php: 5.6
10 | - php: 7.0
11 | before_script:
12 | - sudo apt-get update -qq
13 | - sudo apt-get install -y --force-yes apache2 libapache2-mod-fastcgi php5-curl php5-mysql php5-intl php5-gd > /dev/null
14 | - sudo mkdir $(pwd)/.run
15 | - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
16 | - sudo sed -e "s,listen = 127.0.0.1:9000,listen = /tmp/php5-fpm.sock,g" --in-place ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
17 | - sudo sed -e "s,;listen.owner = nobody,listen.owner = $USER,g" --in-place ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
18 | - sudo sed -e "s,;listen.group = nobody,listen.group = $USER,g" --in-place ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
19 | - sudo sed -e "s,;listen.mode = 0660,listen.mode = 0666,g" --in-place ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
20 | - sudo sed -e "s,user = nobody,;user = $USER,g" --in-place ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
21 | - sudo sed -e "s,group = nobody,;group = $USER,g" --in-place ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
22 | - cat ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
23 | - sudo a2enmod rewrite actions fastcgi alias
24 | - echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
25 | - ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm
26 | - sudo cp -f tests/travis-ci-apache.conf /etc/apache2/sites-available/default
27 | - sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/default
28 | - git submodule update --init --recursive
29 | - sudo service apache2 restart
30 | - "export DISPLAY=:99.0"
31 | - "sh -e /etc/init.d/xvfb start"
32 | - sleep 3 # give xvfb some time to start
33 | - sudo apt-get install fluxbox -y --force-yes
34 | - fluxbox &
35 | - sleep 3 # give fluxbox some time to start
36 | - composer install --prefer-dist
37 |
38 | script:
39 | - mv tests/acceptance.suite.dist.yml tests/acceptance.suite.yml
40 | - mv tests/api.suite.dist.yml tests/api.suite.yml
41 | - vendor/bin/robo run:tests 1
42 |
--------------------------------------------------------------------------------
/build.properties.dist:
--------------------------------------------------------------------------------
1 | # Properties files are configuration files used by PHING scripts containing:
2 | # key=value
3 | # more info at: https://redweb.atlassian.net/wiki/display/Devportal/Using+PHING+for+packaging+and+testing+an+extension
4 |
5 | # Extension details:
6 | comp.name=webservices
7 |
8 | # Folder to create the extension .zip build package used by extension_packager.xml
9 | package.dir=
10 |
11 | # Testing Joomla site at a localhost folder. Only needed when using build.xml
12 | www.dir=
13 |
14 | # For unit testing. Only needed when using build.xml
15 | www.dirtest=
16 |
--------------------------------------------------------------------------------
/cli/joomla.php:
--------------------------------------------------------------------------------
1 | registerServiceProvider(new Joomla\Webservices\Service\ConfigurationProvider)
31 | ->registerServiceProvider(new Joomla\Webservices\Service\DatabaseProvider)
32 | ->registerServiceProvider(new Joomla\Language\Service\LanguageFactoryProvider)
33 | ->registerServiceProvider(new Joomla\Webservices\Service\EventProvider);
34 |
35 | // Set error reporting based on config
36 | $errorReporting = (int) $container->get('config')->get('errorReporting', 0);
37 | error_reporting($errorReporting);
38 | }
39 | catch (\Exception $e)
40 | {
41 | echo 'An error occurred while booting the application: ' . $e->getMessage() . "\n";
42 |
43 | exit;
44 | }
45 |
46 | // Execute the application
47 | try
48 | {
49 | (new Joomla\Webservices\CliApplication($container))->execute();
50 | }
51 | catch (\Exception $e)
52 | {
53 | echo 'An error occurred while executing the application: ' . $e->getMessage() . "\n";
54 |
55 | exit;
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/codeception.yml:
--------------------------------------------------------------------------------
1 | actor: Tester
2 | paths:
3 | tests: tests
4 | log: tests/_output
5 | data: tests/_data
6 | support: tests/_support
7 | settings:
8 | bootstrap: _bootstrap.php
9 | colors: true
10 | memory_limit: 1024M
11 | extensions:
12 | enabled:
13 | - Codeception\Extension\RunFailed
14 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Controller/AddController.php:
--------------------------------------------------------------------------------
1 | context = \JApplicationHelper::getComponentName() . '.' . $this->getInput()->getCmd('view', $this->defaultView);
45 | }
46 |
47 | /**
48 | * Execute the controller.
49 | *
50 | * @return boolean True on success
51 | *
52 | * @since 2.0
53 | * @throws \RuntimeException
54 | */
55 | public function execute()
56 | {
57 | // Set up variables to build our classes
58 | $view = $this->defaultView;
59 | $format = $this->getInput()->getCmd('format', 'html');
60 |
61 | // Register the layout paths for the view
62 | $paths = new \SplPriorityQueue;
63 |
64 | // Add the path for template overrides
65 | $paths->insert(JPATH_THEMES . '/' . $this->getApplication()->getTemplate() . '/html/' . \JApplicationHelper::getComponentName() . '/' . $view, 2);
66 |
67 | // Add the path for the default layouts
68 | $paths->insert(JPATH_BASE . '/components/' . \JApplicationHelper::getComponentName() . '/Webservices/View/' . ucfirst($view) . '/tmpl', 1);
69 |
70 | // Build the class names for the model and view
71 | $viewClass = '\\Webservices\\View\\' . ucfirst($view) . '\\' . ucfirst($view) . ucfirst($format) . 'View';
72 | $modelClass = '\\Webservices\\Model\\' . ucfirst($view) . 'Model';
73 |
74 | // Sanity check - Ensure our classes exist
75 | if (!class_exists($viewClass))
76 | {
77 | // Try to use a default view
78 | $viewClass = '\\Webservices\\View\\Default' . ucfirst($format) . 'View';
79 |
80 | if (!class_exists($viewClass))
81 | {
82 | throw new \RuntimeException(
83 | sprintf('The view class for the %1$s view in the %2$s format was not found.', $view, $format), 500
84 | );
85 | }
86 | }
87 |
88 | if (!class_exists($modelClass))
89 | {
90 | throw new \RuntimeException(sprintf('The model class for the %s view was not found.', $view), 500);
91 | }
92 |
93 | // Initialize the model class now; need to do it before setting the state to get required data from it
94 | $model = new $modelClass($this->context, null, Helper::createDbo());
95 |
96 | // Initialize the state for the model
97 | //$model->setState($this->initializeState($model));
98 |
99 | // Initialize the view class now
100 | $view = new $viewClass($model, $paths);
101 |
102 | // Echo the rendered view for the application
103 | echo $view->render();
104 |
105 | // Finished!
106 | return true;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Controller/ApplyController.php:
--------------------------------------------------------------------------------
1 | setState($this->initializeState($model));
38 |
39 | $id = $this->getInput()->getUint('id');
40 |
41 | $data = $this->getInput()->getArray()['jform'];
42 |
43 | if ($model->save($data))
44 | {
45 | $msg = \JText::_('COM_WEBSERVICES_APPLY_OK');
46 | }
47 | else
48 | {
49 | $msg = \JText::_('COM_WEBSERVICES_APPLY_ERROR');
50 | }
51 |
52 | $type = 'message';
53 | $url = 'index.php?option=com_webservices&task=edit&id=' . $id;
54 | }
55 | catch (\Exception $e)
56 | {
57 | $msg = $e->getMessage();
58 | $type = 'error';
59 | }
60 |
61 | $url = isset($this->returnurl) ? $this->returnurl : $url;
62 |
63 | $this->getApplication()->enqueueMessage($msg, $type);
64 | $this->getApplication()->redirect(\JRoute::_($url, false));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Controller/CancelController.php:
--------------------------------------------------------------------------------
1 | getApplication()->enqueueMessage($msg, $type);
33 | $this->getApplication()->redirect(\JRoute::_('index.php?option=com_webservices', false));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Controller/EditController.php:
--------------------------------------------------------------------------------
1 | returnurl = 'index.php?option=com_webservices&view=webservices';
33 | parent::execute();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Controller/InstallController.php:
--------------------------------------------------------------------------------
1 | returnurl = 'index.php?option=com_webservices';
37 |
38 | // Initialize the state for the model
39 | $model->setState($this->initializeState($model));
40 |
41 | $input = $this->getInput();
42 |
43 | $webservice = $input->getString('webservice');
44 | $version = $input->getString('version');
45 | $folder = $input->getString('folder');
46 | $client = $input->getString('client');
47 |
48 | $msg = \JText::_('COM_WEBSERVICES_WEBSERVICES_INSTALLED_WEBSERVICES');
49 | $type = 'message';
50 |
51 | try
52 | {
53 | if ($webservice == 'all')
54 | {
55 | // @@ TODO: Fix this
56 | //$this->batchWebservices('install');
57 | throw new \Exception('Batch installation not implemented yet. Install services one at a time.');
58 | }
59 | else
60 | {
61 | if ($model->installWebservice($client, $webservice, $version, $folder))
62 | {
63 | $msg = \JText::_('COM_WEBSERVICES_WEBSERVICES_WEBSERVICE_INSTALLED');
64 | }
65 | }
66 | }
67 | catch (\Exception $e)
68 | {
69 | $msg = $e->getMessage();
70 | $type = 'error';
71 | }
72 |
73 | $this->getApplication()->enqueueMessage($msg, $type);
74 | $this->getApplication()->redirect(\JRoute::_($this->returnurl, false));
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Controller/PublishController.php:
--------------------------------------------------------------------------------
1 | input;
37 |
38 | // Get the values
39 | $cid = $input->get('cid', array(), 'array');
40 | $data = array('publish' => 1, 'unpublish' => 0, 'archive' => 2, 'trash' => -2, 'report' => -3);
41 | $task = $input->get('task');
42 | $value = \JArrayHelper::getValue($data, $task, 0, 'int');
43 |
44 | if (empty($cid))
45 | {
46 | \JLog::add(\JText::_('COM_WEBSERVICES_NO_ITEM_SELECTED'), \JLog::WARNING, 'jerror');
47 | }
48 | else
49 | {
50 | // Get and initialize the state for the model
51 | $model = new WebserviceModel;
52 | $model->setState($this->initializeState($model));
53 |
54 | $table = $model->getTable();
55 |
56 | // Make sure the item ids are integers
57 | \JArrayHelper::toInteger($cid);
58 |
59 | // Publish the items.
60 | try
61 | {
62 | $table->publish($cid, $value, \JFactory::getUser()->id);
63 |
64 | if ($value == 1)
65 | {
66 | $ntext = \JText::plural('COM_WEBSERVICES_N_ITEMS_PUBLISHED', count($cid));
67 | }
68 | elseif ($value == 0)
69 | {
70 | $ntext = \JText::plural('COM_WEBSERVICES_N_ITEMS_UNPUBLISHED', count($cid));
71 | }
72 | elseif ($value == 2)
73 | {
74 | $ntext = \JText::plural('COM_WEBSERVICES_N_ITEMS_ARCHIVED', count($cid));
75 | }
76 | else
77 | {
78 | $ntext = \JText::plural('COM_WEBSERVICES_N_ITEMS_TRASHED', count($cid));
79 | }
80 |
81 | $type = 'message';
82 | }
83 | catch (\Exception $e)
84 | {
85 | $type = 'error';
86 | }
87 | }
88 |
89 | $this->getApplication()->enqueueMessage($ntext, $type);
90 |
91 | $this->returnurl = 'index.php?option=com_webservices&view=webservices';
92 | parent::execute();
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Controller/SaveController.php:
--------------------------------------------------------------------------------
1 | returnurl = 'index.php?option=com_webservices&view=webservices';
33 | parent::execute();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Controller/UnpublishController.php:
--------------------------------------------------------------------------------
1 | returnurl = 'index.php?option=com_webservices&view=webservices';
33 | parent::execute();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Layout/operation.php:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 | sublayout('attributes', $displayData); ?>
22 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Layout/scopes.php:
--------------------------------------------------------------------------------
1 |
25 |
26 |
50 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Model/Fields/componentlist.php:
--------------------------------------------------------------------------------
1 | element);
50 |
51 | if (!isset(static::$cache[$hash]))
52 | {
53 | static::$cache[$hash] = parent::getOptions();
54 | $lang = JFactory::getLanguage();
55 |
56 | $options = array();
57 | $db = JFactory::getDbo();
58 | $query = $db->getQuery(true)
59 | ->select('*')
60 | ->from('#__extensions')
61 | ->where('type=' . $db->quote('component'));
62 |
63 | // Setup the query
64 | $db->setQuery($query);
65 |
66 | // Return the result
67 | $components = $db->loadObjectList();
68 |
69 | if (!empty($components))
70 | {
71 | foreach ($components as $value)
72 | {
73 | $extension = $value->element;
74 | $source = JPATH_ADMINISTRATOR . '/components/' . $extension;
75 | $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, true)
76 | || $lang->load($extension . '.sys', $source, null, false, true);
77 | $contentElements = '';
78 |
79 | if ($this->getAttribute('loadContentElements', 'false') == 'true')
80 | {
81 | $contentElementsArray = RTranslationHelper::getContentElements($value->name);
82 |
83 | if (!empty($contentElementsArray))
84 | {
85 | $contentElements = ' (' . count($contentElementsArray) . ')';
86 | }
87 | }
88 |
89 | if ($this->getAttribute('showFullName', 'false') == 'true')
90 | {
91 | $title = JText::_($value->name);
92 | }
93 | else
94 | {
95 | $title = $value->name;
96 | }
97 |
98 | $options[] = JHtml::_('select.option', $value->element, $title . $contentElements);
99 | }
100 |
101 | static::$cache[$hash] = array_merge(static::$cache[$hash], $options);
102 | }
103 | }
104 |
105 | $component = JFactory::getApplication()->input->get->getString('component', '');
106 |
107 | if (!empty($component))
108 | {
109 | $this->value = $component;
110 | }
111 |
112 | return static::$cache[$hash];
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Model/Fields/tablelist.php:
--------------------------------------------------------------------------------
1 | element);
50 |
51 | if (!isset(static::$cache[$hash]))
52 | {
53 | static::$cache[$hash] = parent::getOptions();
54 |
55 | $db = JFactory::getDbo();
56 | $tables = $db->getTableList();
57 | $tablePrefix = $db->getPrefix();
58 |
59 | if (!empty($tables))
60 | {
61 | foreach ($tables as $i => $table)
62 | {
63 | // Make sure we get the right tables based on prefix
64 | if (stripos($table, $tablePrefix) !== 0)
65 | {
66 | continue;
67 | }
68 |
69 | $table = substr($table, strlen($tablePrefix));
70 | $options[] = JHtml::_('select.option', $table, $table);
71 | }
72 |
73 | static::$cache[$hash] = array_merge(static::$cache[$hash], $options);
74 | }
75 | }
76 |
77 | return static::$cache[$hash];
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Model/Fields/webservicelist.php:
--------------------------------------------------------------------------------
1 | getWebservices();
49 |
50 | // Build the field options.
51 | if (!empty($items))
52 | {
53 | foreach ($items as $item)
54 | {
55 | $options[] = JHtml::_('select.option', $item->identifier, $item->displayName);
56 | }
57 | }
58 |
59 | return array_merge(parent::getOptions(), $options);
60 | }
61 |
62 | /**
63 | * Method to get the list of paths.
64 | *
65 | * @return array An array of path names.
66 | */
67 | protected function getWebservices()
68 | {
69 | if (empty($this->cache))
70 | {
71 | try
72 | {
73 | $container = (new Joomla\DI\Container)
74 | ->registerServiceProvider(new Joomla\Webservices\Service\ConfigurationProvider)
75 | ->registerServiceProvider(new Joomla\Webservices\Service\DatabaseProvider);
76 | }
77 | catch (\Exception $e)
78 | {
79 | throw new RuntimeException(JText::sprintf('COM_WEBSERVICES_WEBSERVICE_ERROR_DATABASE_CONNECTION', $e->getMessage()), 500, $e);
80 | }
81 |
82 | $db = $container->get('db');
83 |
84 | $query = $db->getQuery(true)
85 | ->select('CONCAT_WS(" ", ' . $db->qn('client') . ', ' . $db->qn('name') . ', ' . $db->qn('version') . ') as displayName')
86 | ->select('id as identifier')
87 | ->from('#__webservices')
88 | ->order('client')
89 | ->order('name')
90 | ->order('version');
91 |
92 | $db->setQuery($query);
93 |
94 | $result = $db->loadObjectList();
95 |
96 | if (is_array($result))
97 | {
98 | $this->cache = $result;
99 | }
100 | }
101 |
102 | return $this->cache;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Model/Fields/webservicepaths.php:
--------------------------------------------------------------------------------
1 | getPaths();
48 |
49 | // Build the field options.
50 | if (!empty($items))
51 | {
52 | foreach ($items as $item)
53 | {
54 | $options[] = JHtml::_('select.option', $item->path, $item->path);
55 | }
56 | }
57 |
58 | return array_merge(parent::getOptions(), $options);
59 | }
60 |
61 | /**
62 | * Method to get the list of paths.
63 | *
64 | * @return array An array of path names.
65 | */
66 | protected function getPaths()
67 | {
68 | if (empty($this->cache))
69 | {
70 | try
71 | {
72 | $container = (new Joomla\DI\Container)
73 | ->registerServiceProvider(new Joomla\Webservices\Service\ConfigurationProvider)
74 | ->registerServiceProvider(new Joomla\Webservices\Service\DatabaseProvider);
75 | }
76 | catch (\Exception $e)
77 | {
78 | throw new RuntimeException(JText::sprintf('COM_WEBSERVICES_WEBSERVICE_ERROR_DATABASE_CONNECTION', $e->getMessage()), 500, $e);
79 | }
80 |
81 | $db = $container->get('db');
82 |
83 | $query = $db->getQuery(true)
84 | ->select('path')
85 | ->from('#__webservices')
86 | ->order('path')
87 | ->group('path');
88 |
89 | $db->setQuery($query);
90 |
91 | $result = $db->loadObjectList();
92 |
93 | if (is_array($result))
94 | {
95 | $this->cache = $result;
96 | }
97 | }
98 |
99 | return $this->cache;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Model/Fields/webservicescopes.php:
--------------------------------------------------------------------------------
1 | element);
50 |
51 | try
52 | {
53 | $container = (new Joomla\DI\Container)
54 | ->registerServiceProvider(new Joomla\Webservices\Service\ConfigurationProvider)
55 | ->registerServiceProvider(new Joomla\Language\Service\LanguageFactoryProvider)
56 | ->registerServiceProvider(new Joomla\Webservices\Service\DatabaseProvider);
57 | }
58 | catch (\Exception $e)
59 | {
60 | throw new RuntimeException(JText::sprintf('COM_WEBSERVICES_WEBSERVICE_ERROR_DATABASE_CONNECTION', $e->getMessage()), 500, $e);
61 | }
62 |
63 | /** @var \Joomla\Database\DatabaseDriver $db */
64 | $db = $container->get('db');
65 |
66 | /** @var \Joomla\Language\LanguageFactory $languageFactory */
67 | $languageFactory = $container->get('Joomla\\Language\\LanguageFactory');
68 | $languageFactory->getLanguage()->load('lib_webservices');
69 | $text = $languageFactory->getText();
70 |
71 | if (!isset(static::$cache[$hash]))
72 | {
73 | static::$cache[$hash] = parent::getOptions();
74 |
75 | $options = \Joomla\Webservices\Webservices\ConfigurationHelper::getWebserviceScopes($text, array(), $db);
76 |
77 | static::$cache[$hash] = array_merge(static::$cache[$hash], $options);
78 | }
79 |
80 | return static::$cache[$hash];
81 | }
82 |
83 | /**
84 | * Method to get the field input markup for OAuth2 Scope Lists.
85 | *
86 | * @return string The field input markup.
87 | */
88 | protected function getInput()
89 | {
90 | return JLayoutHelper::render(
91 | 'webservice.scopes',
92 | array(
93 | 'view' => $this,
94 | 'options' => array (
95 | 'scopes' => $this->getOptions(),
96 | 'id' => $this->id,
97 | 'name' => $this->name,
98 | 'label' => $this->label,
99 | 'value' => $this->value,
100 | )
101 | )
102 | );
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Model/Forms/filter_webservices.xml:
--------------------------------------------------------------------------------
1 |
2 |
58 |
--------------------------------------------------------------------------------
/component/admin/Webservices/Table/WebserviceTable.php:
--------------------------------------------------------------------------------
1 | _tableName = '#__webservices';
42 | $this->_tbl_key = 'id';
43 |
44 | parent::__construct($this->_tableName, $this->_tbl_key, $db);
45 | }
46 |
47 | /**
48 | * Checks that the object is valid and able to be stored.
49 | *
50 | * This method checks that the parent_id is non-zero and exists in the database.
51 | * Note that the root node (parent_id = 0) cannot be manipulated with this class.
52 | *
53 | * @return boolean True if all checks pass.
54 | */
55 | public function check()
56 | {
57 | // Check if client is not already created with this id.
58 | $client = clone $this;
59 |
60 | $this->client = trim($this->client);
61 | $this->name = trim($this->name);
62 | $this->version = trim($this->version);
63 |
64 | if (empty($this->version))
65 | {
66 | $this->version = '1.0.0';
67 | }
68 | else
69 | {
70 | $matches = array();
71 |
72 | // Major
73 | $versionPattern = '/^(?[0-9]+\.[0-9]+\.[0-9]+)$/';
74 |
75 | // Match the possible parts of a SemVer
76 | $matched = preg_match(
77 | $versionPattern,
78 | $this->version,
79 | $matches
80 | );
81 |
82 | // No match, invalid
83 | if (!$matched)
84 | {
85 | $this->setError(\JText::_('COM_WEBSERVICES_WEBSERVICE_VERSION_WRONG_FORMAT'));
86 |
87 | return false;
88 | }
89 |
90 | $this->version = $matches['version'];
91 | }
92 |
93 | if (empty($this->name))
94 | {
95 | $this->setError(\JText::_('COM_WEBSERVICES_WEBSERVICE_NAME_FIELD_CANNOT_BE_EMPTY'));
96 |
97 | return false;
98 | }
99 |
100 | if (empty($this->client))
101 | {
102 | $this->setError(\JText::_('COM_WEBSERVICES_WEBSERVICE_CLIENT_FIELD_CANNOT_BE_EMPTY'));
103 |
104 | return false;
105 | }
106 |
107 | if ($client->load(array('client' => $this->client, 'name' => $this->name, 'version' => $this->version)) && $client->id != $this->id)
108 | {
109 | $this->setError(\JText::_('COM_WEBSERVICES_WEBSERVICE_ALREADY_EXISTS'));
110 |
111 | return false;
112 | }
113 |
114 | return true;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/component/admin/Webservices/View/DefaultHtmlView.php:
--------------------------------------------------------------------------------
1 | _output = null;
32 |
33 | $template = \JFactory::getApplication()->getTemplate();
34 | $layout = $this->getLayout();
35 | $layoutTemplate = $this->getLayoutTemplate();
36 |
37 | // Create the template file name based on the layout
38 | $file = isset($tpl) ? $layout . '_' . $tpl : $layout;
39 |
40 | // Clean the file name
41 | $file = preg_replace('/[^A-Z0-9_\.-]/i', '', $file);
42 | $tpl = isset($tpl) ? preg_replace('/[^A-Z0-9_\.-]/i', '', $tpl) : $tpl;
43 |
44 | // Load the language file for the template
45 | $lang = \JFactory::getLanguage();
46 | $lang->load('tpl_' . $template, JPATH_BASE, null, false, true)
47 | || $lang->load('tpl_' . $template, JPATH_THEMES . "/$template", null, false, true);
48 |
49 | // Change the template folder if alternative layout is in different template
50 | if (isset($layoutTemplate) && $layoutTemplate != '_' && $layoutTemplate != $template)
51 | {
52 | $this->_path['template'] = str_replace($template, $layoutTemplate, $this->_path['template']);
53 | }
54 |
55 | // Load the template script
56 | jimport('joomla.filesystem.path');
57 | $filetofind = $this->_createFileName('template', array('name' => $file));
58 |
59 | if (empty($this->paths_arr))
60 | {
61 | $paths = $this->paths;
62 |
63 | $this->paths_arr = array();
64 | while($paths->valid()){
65 |
66 | $this->paths_arr[] = $paths->current();
67 |
68 | $paths->next();
69 | }
70 | }
71 |
72 | $this->_template = \JPath::find($this->paths_arr, $filetofind);
73 |
74 | // If alternate layout can't be found, fall back to default layout
75 | if ($this->_template == false)
76 | {
77 | $filetofind = $this->_createFileName('', array('name' => 'default' . (isset($tpl) ? '_' . $tpl : $tpl)));
78 |
79 | $this->_template = \JPath::find($this->paths_arr, $filetofind);
80 | }
81 |
82 | if ($this->_template != false)
83 | {
84 | // Unset so as not to introduce into template scope
85 | unset($tpl);
86 | unset($file);
87 |
88 | // Never allow a 'this' property
89 | if (isset($this->this))
90 | {
91 | unset($this->this);
92 | }
93 |
94 | // Start capturing output into a buffer
95 | ob_start();
96 |
97 | // Include the requested template filename in the local scope
98 | // (this will execute the view logic).
99 | include $this->_template;
100 |
101 | // Done with the requested template; get the buffer and
102 | // clear it.
103 | $this->_output = ob_get_contents();
104 | ob_end_clean();
105 |
106 | return $this->_output;
107 | }
108 | else
109 | {
110 | throw new \Exception(\JText::sprintf('JLIB_APPLICATION_ERROR_LAYOUTFILE_NOT_FOUND', $file), 500);
111 | }
112 | }
113 |
114 | /**
115 | * Get the layout template.
116 | *
117 | * @return string The layout template name
118 | */
119 | public function getLayoutTemplate()
120 | {
121 | return $this->_layoutTemplate;
122 | }
123 |
124 | /**
125 | * Create the filename for a resource
126 | *
127 | * @param string $type The resource type to create the filename for
128 | * @param array $parts An associative array of filename information
129 | *
130 | * @return string The filename
131 | *
132 | * @since 12.2
133 | */
134 | protected function _createFileName($type, $parts = array())
135 | {
136 | switch ($type)
137 | {
138 | case 'template':
139 | $filename = strtolower($parts['name']) . '.' . $this->_layoutExt;
140 | break;
141 |
142 | default:
143 | $filename = strtolower($parts['name']) . '.php';
144 | break;
145 | }
146 |
147 | return $filename;
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/component/admin/Webservices/View/Webservice/WebserviceHtmlView.php:
--------------------------------------------------------------------------------
1 | model;
83 |
84 | $this->form = $model->getForm();
85 | $this->state = $model->getState();
86 | $this->fields = $model->fields;
87 | $this->resources = $model->resources;
88 | $this->formData = $model->formData;
89 |
90 | // Check if option is enabled
91 | try
92 | {
93 | $container = (new \Joomla\DI\Container)
94 | ->registerServiceProvider(new \Joomla\Webservices\Service\ConfigurationProvider);
95 | }
96 | catch (\Exception $e)
97 | {
98 | throw new RuntimeException(JText::sprintf('COM_WEBSERVICES_WEBSERVICE_ERROR_CONFIGURATION', $e->getMessage()), 500, $e);
99 | }
100 |
101 | $config = $container->get("config");
102 |
103 | if ($config->get('webservices.enable_webservices', 0) == 0)
104 | {
105 | \JFactory::getApplication()->enqueueMessage(
106 | \JText::sprintf(
107 | 'COM_WEBSERVICES_WEBSERVICES_PLUGIN_LABEL_WARNING',
108 | '' . JText::_('COM_WEBSERVICES_CONFIGURE') . ''
109 | ),
110 | 'error');
111 | }
112 |
113 | $this->canDo = \JHelperContent::getActions('com_webservices');
114 | $input = \JFactory::getApplication()->input;
115 | $input->set('hidemainmenu', true);
116 |
117 | $this->addToolbar();
118 |
119 | return parent::render();
120 | }
121 |
122 | /**
123 | * Get the view title.
124 | *
125 | * @return string The view title.
126 | */
127 | public function getTitle()
128 | {
129 | return \JText::_('COM_WEBSERVICES_WEBSERVICE_TITLE');
130 | }
131 |
132 | /**
133 | * Add the page title and toolbar.
134 | *
135 | * @return void
136 | *
137 | * @since 1.0
138 | */
139 | protected function addToolbar()
140 | {
141 | $user = \JFactory::getUser();
142 | $isNew = isset($this->item->id) ? ($this->item->id == 0) : true;
143 |
144 | // Prepare the toolbar.
145 | \JToolbarHelper::title(
146 | $this->getTitle(),
147 | 'folder ' . ($isNew ? 'add' : 'edit')
148 | );
149 |
150 | // For new records, check the create permission.
151 | if ($user->authorise('core.admin', 'com_webservices'))
152 | {
153 | \JToolbarHelper::apply('apply');
154 | \JToolbarHelper::save('save');
155 | \JToolbarHelper::save2new('save2new');
156 | }
157 |
158 | if (empty($this->item->id))
159 | {
160 | \JToolbarHelper::cancel('cancel');
161 | }
162 | else
163 | {
164 | \JToolbarHelper::cancel('cancel', 'JTOOLBAR_CLOSE');
165 | }
166 |
167 | \JToolbarHelper::divider();
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/component/admin/Webservices/View/Webservice/tmpl/default_create.php:
--------------------------------------------------------------------------------
1 | $this,
15 | 'options' => array(
16 | 'operation' => 'create',
17 | 'form' => $this->form,
18 | 'tabActive' => ' active in ',
19 | 'fieldList' => array('defaultValue', 'isRequiredField', 'isPrimaryField'),
20 | )
21 | ),
22 | JPATH_COMPONENT_ADMINISTRATOR.'/Webservices/Layout'
23 | );
24 |
--------------------------------------------------------------------------------
/component/admin/Webservices/View/Webservice/tmpl/default_delete.php:
--------------------------------------------------------------------------------
1 | $this,
15 | 'options' => array(
16 | 'operation' => 'delete',
17 | 'form' => $this->form,
18 | 'tabActive' => ' active in ',
19 | 'fieldList' => array('defaultValue', 'isRequiredField', 'isPrimaryField'),
20 | )
21 | ),
22 | JPATH_COMPONENT_ADMINISTRATOR.'/Webservices/Layout'
23 | );
24 |
--------------------------------------------------------------------------------
/component/admin/Webservices/View/Webservice/tmpl/default_documentation.php:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 | form->getLabel('authorizationNeeded', 'documentation'); ?>
17 |
18 |
19 | form->getInput('authorizationNeeded', 'documentation'); ?>
20 |
21 |
22 |
23 |
24 | form->getLabel('source', 'documentation'); ?>
25 |
26 |
27 | form->getInput('source', 'documentation'); ?>
28 |
29 |
30 |
31 |
32 | form->getLabel('url', 'documentation'); ?>
33 |
34 |
35 | form->getInput('url', 'documentation'); ?>
36 |
37 |
38 |
39 |
40 | form->getLabel('description', 'documentation'); ?>
41 |
42 |
43 | form->getInput('description', 'documentation'); ?>
44 |
45 |
46 |
47 | form->getInput('isEnabled', 'documentation'); ?>
48 |
49 |
--------------------------------------------------------------------------------
/component/admin/Webservices/View/Webservice/tmpl/default_main.php:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 | form->getLabel('client', 'main'); ?>
17 |
18 |
19 | form->getInput('client', 'main'); ?>
20 |
21 |
22 |
23 |
24 | form->getLabel('name', 'main'); ?>
25 |
26 |
27 | form->getInput('name', 'main'); ?>
28 |
29 |
30 |
31 |
32 | form->getLabel('version', 'main'); ?>
33 |
34 |
35 | form->getInput('version', 'main'); ?>
36 |
37 |
38 |
39 |
40 | form->getLabel('path', 'main'); ?>
41 |
42 |
43 |
44 | //
45 |
46 | form->getInput('path', 'main'); ?>
47 |
48 | /form->getValue('xmlFile', 'main'); ?>
49 |
50 |
51 |
52 |
53 |
54 |
55 | form->getLabel('authorizationAssetName', 'main'); ?>
56 |
57 |
58 | form->getInput('authorizationAssetName', 'main'); ?>
59 |
60 |
61 |
62 |
63 | form->getLabel('title', 'main'); ?>
64 |
65 |
66 | form->getInput('title', 'main'); ?>
67 |
68 |
69 |
70 |
71 | form->getLabel('author', 'main'); ?>
72 |
73 |
74 | form->getInput('author', 'main'); ?>
75 |
76 |
77 |
78 |
79 | form->getLabel('copyright', 'main'); ?>
80 |
81 |
82 | form->getInput('copyright', 'main'); ?>
83 |
84 |
85 |
86 |
87 | form->getLabel('state', 'main'); ?>
88 |
89 |
90 | form->getInput('state', 'main'); ?>
91 |
92 |
93 |
94 |
95 | form->getLabel('description', 'main'); ?>
96 |
97 |
98 | form->getInput('description', 'main'); ?>
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/component/admin/Webservices/View/Webservice/tmpl/default_read.php:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 | formData as $operation => $operationData): ?>
16 |
17 | - >
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | formData as $operation => $operationData): ?>
29 | $this,
42 | 'options' => array(
43 | 'operation' => $operation,
44 | 'form' => $this->form,
45 | 'tabActive' => $firstContentActive ? ' active in ' : '',
46 | 'fieldList' => $fieldList,
47 | )
48 | ),
49 | JPATH_COMPONENT_ADMINISTRATOR.'/Webservices/Layout'
50 | );
51 |
52 | $firstContentActive = false;
53 | endif;
54 | ?>
55 |
56 |
57 |
--------------------------------------------------------------------------------
/component/admin/Webservices/View/Webservice/tmpl/default_task.php:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | formData as $operation => $operationData): ?>
32 |
33 | - >
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | formData as $operation => $operationData): ?>
45 | $this,
51 | 'options' => array(
52 | 'operation' => $operation,
53 | 'form' => $this->form,
54 | 'tabActive' => $firstContentActive ? ' active in ' : '',
55 | 'fieldList' => array('defaultValue', 'isRequiredField', 'isPrimaryField'),
56 | )
57 | ),
58 | JPATH_COMPONENT_ADMINISTRATOR.'/Webservices/Layout'
59 | );
60 |
61 | $firstContentActive = false;
62 | endif;
63 | ?>
64 |
65 |
66 |
--------------------------------------------------------------------------------
/component/admin/Webservices/View/Webservice/tmpl/default_update.php:
--------------------------------------------------------------------------------
1 | $this,
15 | 'options' => array(
16 | 'operation' => 'update',
17 | 'form' => $this->form,
18 | 'tabActive' => ' active in ',
19 | 'fieldList' => array('defaultValue', 'isRequiredField', 'isPrimaryField'),
20 | )
21 | ),
22 | JPATH_COMPONENT_ADMINISTRATOR.'/Webservices/Layout'
23 | );
24 |
--------------------------------------------------------------------------------
/component/admin/access.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/component/admin/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/component/admin/language/en-GB/en-GB.com_webservices.sys.ini:
--------------------------------------------------------------------------------
1 | ; WEBSERVICES
2 | ; Copyright (C) 2008 - 2015 redCOMPONENT.com. All rights reserved.
3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE.php
4 | ; Note : All ini files need to be saved as UTF-8
5 |
6 | COM_WEBSERVICES="Webservices"
7 | COM_WEBSERVICES_DESC="Webservices for Joomla"
8 |
9 | COM_WEBSERVICES_WEBSERVICES="Webservices"
10 |
--------------------------------------------------------------------------------
/component/admin/sql/install/mysql/install.sql:
--------------------------------------------------------------------------------
1 | SET FOREIGN_KEY_CHECKS = 0;
2 |
3 | -- -----------------------------------------------------
4 | -- Table `#__webservices`
5 | -- -----------------------------------------------------
6 | CREATE TABLE IF NOT EXISTS `#__webservices` (
7 | `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
8 | `name` VARCHAR(255) NOT NULL DEFAULT '',
9 | `version` VARCHAR(5) NOT NULL DEFAULT '1.0.0',
10 | `title` VARCHAR(255) NOT NULL DEFAULT '',
11 | `path` VARCHAR(255) NOT NULL DEFAULT '',
12 | `xmlFile` VARCHAR(255) NOT NULL DEFAULT '',
13 | `xmlHashed` VARCHAR(32) NOT NULL DEFAULT '',
14 | `operations` TEXT NULL,
15 | `scopes` TEXT NULL,
16 | `client` VARCHAR(15) NOT NULL DEFAULT 'site',
17 | `published` TINYINT(1) NOT NULL DEFAULT '1',
18 | `checked_out` INT(11) NULL DEFAULT NULL,
19 | `checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
20 | `created_by` INT(11) NULL DEFAULT NULL,
21 | `created_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
22 | `modified_by` INT(11) NULL DEFAULT NULL,
23 | `modified_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
24 | PRIMARY KEY (`id`),
25 | KEY `idx_webservice_keys` (`client`, `name`, `version`)
26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
27 |
28 | SET FOREIGN_KEY_CHECKS = 1;
29 |
--------------------------------------------------------------------------------
/component/admin/sql/install/mysql/uninstall.sql:
--------------------------------------------------------------------------------
1 | SET FOREIGN_KEY_CHECKS = 0;
2 |
3 | DROP TABLE IF EXISTS `#__webservices`;
4 |
5 | SET FOREIGN_KEY_CHECKS = 1;
6 |
--------------------------------------------------------------------------------
/component/admin/sql/updates/mysql/1.0.0.sql:
--------------------------------------------------------------------------------
1 | -- Register initial version
2 |
--------------------------------------------------------------------------------
/component/admin/webservices.php:
--------------------------------------------------------------------------------
1 | authorise('core.manage', 'com_webservices'))
13 | {
14 | return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));
15 | }
16 |
17 | $applicationPath = realpath(JPATH_ROOT);
18 | $composerPath = $applicationPath . '/vendor/autoload.php';
19 | define ('JPATH_API', $applicationPath);
20 | require_once($composerPath);
21 |
22 | // Application reference
23 | $app = JFactory::getApplication();
24 |
25 | // Register the component namespace to the autoloader
26 | JLoader::registerNamespace('Webservices', __DIR__);
27 |
28 | // Build the controller class name based on task
29 | $task = $app->input->getCmd('task', 'display');
30 |
31 | // If $task is an empty string, apply our default since JInput might not
32 | if ($task === '')
33 | {
34 | $task = 'display';
35 | }
36 | $class = '\\Webservices\\Controller\\' . ucfirst(strtolower($task)) . 'Controller';
37 |
38 | // Instantiate and execute the controller
39 | $controller = new $class($app->input, $app);
40 | $controller->execute();
41 |
--------------------------------------------------------------------------------
/component/media/webservices/js/component.min.js:
--------------------------------------------------------------------------------
1 | (function(a){a.fn.extend({enterSubmits:function(){var b=a(this);b.keydown(function(c){if(c.which===13){b.closest("form").submit()}});return a(this)}});a(document).ready(function(){a(".js-enter-submits").enterSubmits();a("*[rel=tooltip]").tooltip({animation:true,html:true});rRadioGroupButtonsSet();rRadioGroupButtonsEvent();if(typeof Joomla=="object"){Joomla.submitform=function(b,c){if(typeof(c)==="undefined"){c=document.getElementById("adminForm")}if(typeof(b)!=="undefined"&&b!==""){c.task.value=b}if(typeof c.onsubmit=="function"){c.onsubmit()}if(typeof c.fireEvent=="function"){c.fireEvent("submit")}c.submit()}}});a('select[class^="chzn-color"], select[class*=" chzn-color"]').on("liszt:ready",function(){var b=a(this);var d=this.className.replace(/^.(chzn-color[a-z0-9-_]*)$.*/,"\1");var c=b.next(".chzn-container").find(".chzn-single");c.addClass(d).attr("rel","value_"+b.val());b.on("change click",function(){c.attr("rel","value_"+b.val())})})})(jQuery);function rRadioGroupButtonsSet(a){a=typeof(a)!="undefined"?a:"";jQuery(a+" .radio.btn-group label").removeClass("btn").removeClass("btn-default").addClass("btn").addClass("btn-default");jQuery(a+" .btn-group label:not(.active)").click(function(){var c=jQuery(this);var b=jQuery("#"+c.attr("for"));if(!b.prop("checked")){c.closest(".btn-group").find("label").removeClass("active btn-success btn-danger btn-primary");if(b.val()==""){c.addClass("active btn-primary")}else{if(b.val()==0){c.addClass("active btn-danger")}else{c.addClass("active btn-success")}}b.prop("checked",true)}})}function rRadioGroupButtonsEvent(a){a=typeof(a)!="undefined"?a:"";jQuery(a+" .btn-group input[checked=checked]").each(function(){if(jQuery(this).val()==""){jQuery("label[for="+jQuery(this).attr("id")+"]").addClass("active btn-primary")}else{if(jQuery(this).val()==0){jQuery("label[for="+jQuery(this).attr("id")+"]").addClass("active btn-danger")}else{jQuery("label[for="+jQuery(this).attr("id")+"]").addClass("active btn-success")}}})}function listItemTaskForm(g,b,d){d=document.getElementById(d);if(typeof(d)==="undefined"){d=document.getElementById("adminForm")}var a=d[g];if(a){for(var c=0;true;c++){var e=d["cb"+c];if(!e){break}e.checked=false}a.checked=true;d.boxchecked.value=1;Joomla.submitform(b,d)}return false};
--------------------------------------------------------------------------------
/component/webservices.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | COM_WEBSERVICES
4 | April 2015
5 | redCOMPONENT
6 | email@redcomponent.com
7 | www.redcomponent.com
8 | Copyright (C) 2008 - 2015 redCOMPONENT.com. All rights reserved.
9 | GNU General Public License version 2 or later, see LICENSE.
10 | 1.0.0
11 | COM_WEBSERVICES_DESC
12 |
13 |
14 |
15 | sql/install/mysql/install.sql
16 |
17 |
18 |
19 |
20 | sql/install/mysql/uninstall.sql
21 |
22 |
23 |
24 |
25 | sql/updates/mysql
26 |
27 |
28 |
29 |
30 |
31 | language
32 | sql
33 | Webservices
34 | access.xml
35 | webservices.php
36 |
37 |
38 | en-GB/en-GB.com_webservices.ini
39 | en-GB/en-GB.com_webservices.sys.ini
40 |
41 |
42 |
43 |
44 |
45 |
46 | js
47 |
48 |
49 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "joomla-projects/webservices",
3 | "type": "joomla-package",
4 | "description": "Joomla Webservices Application",
5 | "keywords": ["joomla", "cms", "webservices"],
6 | "homepage": "https://github.com/joomla-projects/webservices",
7 | "license": "GPL-2.0+",
8 | "require": {
9 | "php": ">=5.3.10",
10 | "joomla/application": "~1.4",
11 | "joomla/database": "~1.2",
12 | "joomla/input": "~1.2",
13 | "joomla/filter": "~1.1",
14 | "joomla/event": "2.*@dev",
15 | "joomla/uri": "~1.1",
16 | "joomla/filesystem": "~1.2",
17 | "joomla/authentication": "^1.1.1",
18 | "joomla/registry": "~1.4",
19 | "joomla/di": "~1.3",
20 | "joomla/utilities": "~1.3",
21 | "joomla/date": "2.*@dev",
22 | "joomla/language": "2.*@dev",
23 | "psr/log": "~1.0",
24 | "willdurand/Negotiation": "^2.0",
25 | "joomla/router": "dev-2.0-dev"
26 | },
27 | "require-dev": {
28 | "codeception/codeception": "~2.1",
29 | "joomla-projects/joomla-browser": "dev-develop",
30 | "codegyre/robo": "dev-master",
31 | "flow/jsonpath": "dev-master",
32 | "phing/phing": "~2",
33 | "joomla-projects/robo": "dev-master",
34 | "joomla-projects/selenium-server-standalone": "v2.47.1",
35 | "cloudinary/cloudinary_php": "1.1.1"
36 | },
37 | "autoload": {
38 | "psr-4": {
39 | "Joomla\\Webservices\\": "src/"
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/config.dist.json:
--------------------------------------------------------------------------------
1 | {
2 | "database": {
3 | "driver" : "mysqli",
4 | "host" : "localhost",
5 | "user" : "root",
6 | "password" : "",
7 | "database" : "test_webservices",
8 | "prefix" : "jos_",
9 | "debug" : false
10 | },
11 | "webservices": {
12 | "enable_webservices" : 1,
13 | "webservices_default_page_authorization": 0,
14 | "webservices_permission_check" : 1,
15 | "debug_webservices" : 0,
16 | "enable_soap" : 1,
17 | "content_types": [
18 | "application/hal+json",
19 | "application/hal+xml",
20 | "application/json",
21 | "application/soap+xml",
22 | "application/xml"
23 | ],
24 | "routes": "/routes.json"
25 | },
26 | "language" : {
27 | "basedir" : "",
28 | "default" : "en-GB"
29 | },
30 | "errorReporting": -1
31 | }
32 |
--------------------------------------------------------------------------------
/extension_packager.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
109 |
110 |
111 |
112 |
113 |
114 |
118 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/plugins/authentication/redcore_oauth2/language/en-GB/en-GB.plg_authentication_redcore_oauth2.ini:
--------------------------------------------------------------------------------
1 | ; webservices
2 | ; Copyright (C) 2008 - 2015 redCOMPONENT.com. All rights reserved.
3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE.php
4 | ; Note : All ini files need to be saved as UTF-8
5 |
6 | PLG_AUTHENTICATION_REDCORE_OAUTH2="Webservices - Redcore OAuth2 plugin"
7 | PLG_AUTHENTICATION_REDCORE_OAUTH2_XML_DESCRIPTION="Plugin for authorization over redCORE OAuth2 server"
8 |
9 | PLG_AUTHENTICATION_REDCORE_OAUTH2_OAUTH2_SERVER_IS_NOT_ACTIVE="OAuth2 Server is not active. Cannot perform authorization."
10 | PLG_AUTHENTICATION_REDCORE_OAUTH2_OAUTH2_SERVER_ERROR="Error ir OAuth2 check: %s"
11 |
--------------------------------------------------------------------------------
/plugins/authentication/redcore_oauth2/language/en-GB/en-GB.plg_authentication_redcore_oauth2.sys.ini:
--------------------------------------------------------------------------------
1 | ; Webservices
2 | ; Copyright (C) 2008 - 2015 redCOMPONENT.com. All rights reserved.
3 | ; License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE.php
4 | ; Note : All ini files need to be saved as UTF-8
5 |
6 | PLG_AUTHENTICATION_REDCORE_OAUTH2="Webservices - Redcore OAuth2 plugin"
7 | PLG_AUTHENTICATION_REDCORE_OAUTH2_XML_DESCRIPTION="Plugin for authorization over redCORE OAuth2 server"
8 |
--------------------------------------------------------------------------------
/plugins/authentication/redcore_oauth2/redcore_oauth2.php:
--------------------------------------------------------------------------------
1 | type = 'redcore_oauth2';
33 | $scopes = !empty($options['scopes']) ? $options['scopes'] : array();
34 | $format = !empty($options['format']) ? $options['format'] : 'json';
35 |
36 | // Check if redCORE OAuth2 server is installed
37 | if (class_exists('RApiOauth2Helper'))
38 | {
39 | /** @var $oauth2Response OAuth2\Response */
40 | $oauth2Response = RApiOauth2Helper::verifyResourceRequest($scopes);
41 |
42 | if ($oauth2Response instanceof OAuth2\Response)
43 | {
44 | if (!$oauth2Response->isSuccessful())
45 | {
46 | $response->status = JAuthentication::STATUS_FAILURE;
47 | $response->error_message = JText::sprintf('PLG_AUTHENTICATION_REDCORE_OAUTH2_OAUTH2_SERVER_ERROR', $oauth2Response->getResponseBody($format));
48 |
49 | return false;
50 | }
51 | }
52 | elseif ($oauth2Response === false)
53 | {
54 | $response->status = JAuthentication::STATUS_FAILURE;
55 | $response->error_message = JText::_('PLG_AUTHENTICATION_REDCORE_OAUTH2_OAUTH2_SERVER_IS_NOT_ACTIVE');
56 |
57 | return false;
58 | }
59 | else
60 | {
61 | $oauth2Response = json_decode($oauth2Response);
62 |
63 | if (!empty($oauth2Response->user_id))
64 | {
65 | $user = JFactory::getUser($oauth2Response->user_id);
66 |
67 | // Load the JUser class on application for this client
68 | JFactory::getApplication()->loadIdentity($user);
69 | JFactory::getSession()->set('user', $user);
70 |
71 | // Bring this in line with the rest of the system
72 | $response->email = $user->email;
73 | $response->fullname = $user->name;
74 |
75 | if (JFactory::getApplication()->isAdmin())
76 | {
77 | $response->language = $user->getParam('admin_language');
78 | }
79 | else
80 | {
81 | $response->language = $user->getParam('language');
82 | }
83 |
84 | $response->status = JAuthentication::STATUS_SUCCESS;
85 | $response->error_message = '';
86 |
87 | return true;
88 | }
89 | }
90 | }
91 |
92 | return false;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/plugins/authentication/redcore_oauth2/redcore_oauth2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PLG_AUTHENTICATION_REDCORE_OAUTH2
4 | redCOMPONENT
5 | April 2015
6 | Copyright (C) 2008 - 2015 redCOMPONENT.com. All rights reserved.
7 | GNU General Public License version 2 or later; see LICENSE.txt
8 | email@redcomponent.com
9 | www.redcomponent.com
10 | 1.0.0
11 | PLG_AUTHENTICATION_REDCORE_OAUTH2_XML_DESCRIPTION
12 |
13 |
14 | redcore_oauth2.php
15 |
16 |
17 |
18 | en-GB/en-GB.plg_authentication_redcore_oauth2.ini
19 | en-GB/en-GB.plg_authentication_redcore_oauth2.sys.ini
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/routes.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "contents",
4 | "description": "API contents (home) page",
5 | "style": "rest",
6 | "routes": {
7 | "/": ["GET"]
8 | }
9 | },
10 | {
11 | "name": "categories",
12 | "description": "Categories collection and individual categories",
13 | "style": "rest",
14 | "routes": {
15 | "/categories": ["GET","POST"],
16 | "/categories/:id/:resource": ["GET"],
17 | "/categories/:id": ["GET","PUT","PATCH","DELETE"]
18 | },
19 | "regex": {
20 | "id": "\\d+",
21 | "resource": "contacts"
22 | }
23 | },
24 | {
25 | "name": "contacts",
26 | "description": "Contacts collection and individual contacts",
27 | "style": "rest",
28 | "routes": {
29 | "/contacts": ["GET","POST"],
30 | "/contacts/:id/:resource": ["GET"],
31 | "/contacts/:id": ["GET","PUT","PATCH","DELETE"]
32 | },
33 | "regex": {
34 | "id": "\\d+",
35 | "resource": "categories|users"
36 | }
37 | },
38 | {
39 | "name": "users",
40 | "description": "Users collection and individual users",
41 | "style": "rest",
42 | "routes": {
43 | "/users": ["GET","POST"],
44 | "/users/:id": ["GET","PUT","PATCH","DELETE"]
45 | },
46 | "regex": {
47 | "id": "\\d+"
48 | }
49 | }
50 | ]
51 |
--------------------------------------------------------------------------------
/src/Api/ApiInterface.php:
--------------------------------------------------------------------------------
1 | element->addAttribute('type', 'tns:' . $elementName . '_' . $field['name']);
48 |
49 | if (!empty($extraFields))
50 | {
51 | SoapHelper::addElementFields($extraFields, $typeSchema, $elementName . '_' . $field['name'], true);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Api/Soap/Transform/TransformArrayRequired.php:
--------------------------------------------------------------------------------
1 | element->addAttribute('type', 'tns:' . $elementName . '_' . $field['name']);
48 |
49 | if (!empty($extraFields))
50 | {
51 | SoapHelper::addElementFields($extraFields, $typeSchema, $elementName . '_' . $field['name']);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Api/Soap/Transform/TransformBase.php:
--------------------------------------------------------------------------------
1 | element))
71 | {
72 | $this->element = $sequence->addChild('element', null, 'http://www.w3.org/2001/XMLSchema');
73 | }
74 |
75 | if (!isset($this->element['minOccurs']))
76 | {
77 | $this->element->addAttribute(
78 | 'minOccurs',
79 | (($validateOptional && XmlHelper::isAttributeTrue($field, 'isRequiredField') || !$validateOptional) ? '1' : '0')
80 | );
81 | }
82 |
83 | if (!isset($this->element['maxOccurs']))
84 | {
85 | $this->element->addAttribute('maxOccurs', XmlHelper::attributeToString($field, 'maxOccurs', 1));
86 | }
87 |
88 | if (!isset($this->element['name']) && isset($field['name']))
89 | {
90 | $this->element->addAttribute('name', $field['name']);
91 | }
92 |
93 | if ($this->type != '')
94 | {
95 | $this->element->addAttribute('type', $this->type);
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/Api/Soap/Transform/TransformBoolean.php:
--------------------------------------------------------------------------------
1 | defaultValue = date('Y-m-d h:i:s');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Api/Soap/Transform/TransformFloat.php:
--------------------------------------------------------------------------------
1 | user = \JUser::getInstance($id);
36 | }
37 |
38 | /**
39 | * Authorise the user in the class to perform the action
40 | *
41 | * @param string $action The action to check the user has permission to do
42 | * @param mixed $asset The asset the action is to performed on (either a string or an integer)
43 | *
44 | * @return mixed
45 | */
46 | public function authorise($action, $asset)
47 | {
48 | return $this->user->authorise($action, $asset);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Integrations/Joomla/Table/Table.php:
--------------------------------------------------------------------------------
1 | _tableName = $table;
38 |
39 | if (is_array($key))
40 | {
41 | $this->_tbl_keys = $key;
42 | $this->_tbl_key = $key;
43 | $this->_tableKey = $key[key($key)];
44 | }
45 | else
46 | {
47 | $this->_tbl_key = $key;
48 | $this->_tableKey = $key;
49 | }
50 |
51 | // Set all columns from table as properties
52 | $columns = array();
53 | $dbColumns = $db->getTableColumns('#__' . $table, false);
54 |
55 | if (count($dbColumns) > 0)
56 | {
57 | foreach ($dbColumns as $columnKey => $columnValue)
58 | {
59 | $columns[$columnValue->Field] = $columnValue->Default;
60 | }
61 |
62 | $this->setProperties($columns);
63 | }
64 |
65 | $table = '#__' . str_replace('#__', '', $table);
66 |
67 | parent::__construct($table, $key, $db);
68 | }
69 |
70 | /**
71 | * Method to get the primary key field name for the table.
72 | *
73 | * @param boolean $multiple True to return all primary keys (as an array) or false to return just the first one (as a string).
74 | *
75 | * @return mixed Array of primary key field names or string containing the first primary key field.
76 | *
77 | * @link https://docs.joomla.org/JTable/getKeyName
78 | * @since 11.1
79 | */
80 | public function getKeyName($multiple = false)
81 | {
82 | // Count the number of keys
83 | if (count($this->_tbl_keys))
84 | {
85 | if (count($this->_tbl_keys) > 1)
86 | {
87 | // If we want multiple keys, return the raw array.
88 | return $this->_tbl_keys;
89 | }
90 | else
91 | {
92 | // If we want the standard method, just return the first key.
93 | return $this->_tbl_keys[0];
94 | }
95 | }
96 |
97 | return '';
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/Integrations/Joomla/defines.php:
--------------------------------------------------------------------------------
1 | options = $options;
53 | }
54 | // Received array
55 | elseif (is_array($options))
56 | {
57 | $this->options = new Registry($options);
58 | }
59 | else
60 | {
61 | $this->options = new Registry;
62 | }
63 |
64 | return $this;
65 | }
66 |
67 | /**
68 | * Get the options
69 | *
70 | * @return Registry Object with the options
71 | *
72 | * @since 3.2
73 | */
74 | public function getOptions()
75 | {
76 | // Always return a Registry instance
77 | if (!($this->options instanceof Registry))
78 | {
79 | $this->resetOptions();
80 | }
81 |
82 | return $this->options;
83 | }
84 |
85 | /**
86 | * Function to empty all the options
87 | *
88 | * @return JLayoutBase Instance of $this to allow chaining.
89 | *
90 | * @since 3.2
91 | */
92 | public function resetOptions()
93 | {
94 | return $this->setOptions(null);
95 | }
96 |
97 | /**
98 | * Method to escape output.
99 | *
100 | * @param string $output The output to escape.
101 | *
102 | * @return string The escaped output.
103 | *
104 | * @since 3.0
105 | */
106 | public function escape($output)
107 | {
108 | return htmlspecialchars($output, ENT_COMPAT, 'UTF-8');
109 | }
110 |
111 | /**
112 | * Get the debug messages array
113 | *
114 | * @return array
115 | *
116 | * @since 3.2
117 | */
118 | public function getDebugMessages()
119 | {
120 | return $this->debugMessages;
121 | }
122 |
123 | /**
124 | * Method to render the layout.
125 | *
126 | * @param object $displayData Object which properties are used inside the layout file to build displayed output
127 | *
128 | * @return string The necessary HTML to display the layout
129 | *
130 | * @since 3.0
131 | */
132 | public function render($displayData)
133 | {
134 | return '';
135 | }
136 |
137 | /**
138 | * Render the list of debug messages
139 | *
140 | * @return string Output text/HTML code
141 | *
142 | * @since 3.2
143 | */
144 | public function renderDebugMessages()
145 | {
146 | return implode($this->debugMessages, "\n");
147 | }
148 |
149 | /**
150 | * Add a debug message to the debug messages array
151 | *
152 | * @param string $message Message to save
153 | *
154 | * @return void
155 | *
156 | * @since 3.2
157 | */
158 | public function addDebugMessage($message)
159 | {
160 | $this->debugMessages[] = $message;
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/src/Layout/Layout.php:
--------------------------------------------------------------------------------
1 | render($displayData);
49 |
50 | return $renderedLayout;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Renderer/Application/Json.php:
--------------------------------------------------------------------------------
1 | setMimeEncoding('application/json', false);
44 |
45 | // Set document type.
46 | $this->setType('json');
47 | }
48 |
49 | /**
50 | * Render a representation of a ResourceLink object.
51 | *
52 | * Adds an HTTP Link header to the application header buffer.
53 | *
54 | * @param Resource $resource A resource item object.
55 | *
56 | * @return void
57 | *
58 | * @see https://tools.ietf.org/html/rfc5988
59 | */
60 | public function renderResourceLink(Resource $resource)
61 | {
62 | $linkText = '<' . $resource->getHref() . '>;'
63 | . ' rel="' . $resource->getRel() . '"'
64 | . ($resource->getTitle() != '' ? ' title="' . $resource->getTitle() . '"' : '')
65 | . ($resource->getTemplated() ? ' templated="true"' : '');
66 |
67 | $this->app->setHeader('Link', $linkText, false);
68 | }
69 |
70 | /**
71 | * Render a representation of a ResourceList object.
72 | *
73 | * @param Resource $resource A resource list object.
74 | *
75 | * @return A representation of the object.
76 | */
77 | public function renderResourceList(Resource $resource)
78 | {
79 | $properties = array();
80 | $data = $resource->getData();
81 |
82 | // Iterate through the links and add them as headers.
83 | foreach ($resource->getLinks() as $rel => $link)
84 | {
85 | // Drop first and previous page links on first page.
86 | if ($data['page'] == 1)
87 | {
88 | if ($rel == 'first' || $rel == 'previous')
89 | {
90 | continue;
91 | }
92 | }
93 |
94 | // Drop last and next page links on last page.
95 | if ($data['page'] == $data['totalPages'])
96 | {
97 | if ($rel == 'last' || $rel == 'next')
98 | {
99 | continue;
100 | }
101 | }
102 |
103 | // Add link to _links element.
104 | if ($link instanceof Resource)
105 | {
106 | $this->renderResourceLink($link);
107 |
108 | continue;
109 | }
110 |
111 | // An array of Link resources.
112 | foreach ($link as $linkResource)
113 | {
114 | $this->renderResourceLink($linkResource);
115 | }
116 | }
117 |
118 | // Iterate through the data properties and add them to the top-level array.
119 | foreach ($resource->getData() as $name => $property)
120 | {
121 | $properties[$name] = $property;
122 | }
123 |
124 | // Iterate through the embedded resources and add them to the _embedded element.
125 | foreach ($resource->getEmbedded() as $rel => $embedded)
126 | {
127 | foreach ($embedded as $item)
128 | {
129 | if ($item instanceof ResourceItem)
130 | {
131 | $properties['_embedded'][$rel][] = json_decode($this->render($item));
132 | }
133 | }
134 | }
135 |
136 | return json_encode($properties);
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/Renderer/Application/Soapxml.php:
--------------------------------------------------------------------------------
1 | documentFormat = $options['documentFormat'];
70 |
71 | // Sanity check - fall back to XML format
72 | if (!in_array($this->documentFormat, array('xml', 'json')))
73 | {
74 | $this->documentFormat = 'xml';
75 | }
76 |
77 | // Set default mime type.
78 | $this->setMimeEncoding('application/' . $mimeType, false);
79 |
80 | // Set document type.
81 | $this->setType('xml');
82 |
83 | // Set absolute/relative hrefs.
84 | $this->absoluteHrefs = isset($options['absoluteHrefs']) ? $options['absoluteHrefs'] : true;
85 |
86 | // Set token if needed
87 | $this->uriParams = isset($options['uriParams']) ? $options['uriParams'] : array();
88 | }
89 |
90 | /**
91 | * Render the document.
92 | *
93 | * @param boolean $cache If true, cache the output
94 | * @param array $params Associative array of attributes
95 | *
96 | * @return string The rendered data
97 | *
98 | * @since 1.4
99 | */
100 | public function render($cache = false, $params = array())
101 | {
102 | parent::render($cache, $params);
103 | $runtime = microtime(true) - $this->app->startTime;
104 |
105 | $this->app->setHeader('Status', $this->soap->statusCode . ' ' . $this->soap->statusText, true);
106 | $this->app->setHeader('Server', '', true);
107 | $this->app->setHeader('X-Runtime', $runtime, true);
108 | $this->app->setHeader('Access-Control-Allow-Origin', '*', true);
109 | $this->app->setHeader('Pragma', 'public', true);
110 | $this->app->setHeader('Expires', '0', true);
111 | $this->app->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true);
112 | $this->app->setHeader('Cache-Control', 'private', false);
113 | $this->app->setHeader('Content-type', $this->getMimeEncoding() . '; charset=' . $this->getCharset(), true);
114 |
115 | // $this->app->sendHeaders();
116 |
117 | // Get the Soap string from the buffer.
118 | $content = $this->getBuffer();
119 |
120 | return (string) $content;
121 | }
122 |
123 | /**
124 | * Sets Soap object to the document
125 | *
126 | * @param Api $soap Soap object
127 | *
128 | * @return $this
129 | *
130 | * @since 1.4
131 | */
132 | public function setApiObject(Api $soap)
133 | {
134 | $this->soap = $soap;
135 |
136 | return $this;
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/Renderer/Application/Xml.php:
--------------------------------------------------------------------------------
1 | setMimeEncoding('application/xml', false);
36 |
37 | // Set document type.
38 | $this->setType('xml');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Renderer/RendererInterface.php:
--------------------------------------------------------------------------------
1 | data;
45 | }
46 |
47 | /**
48 | * Gets all Embedded elements
49 | *
50 | * @return array
51 | */
52 | public function getEmbedded()
53 | {
54 | return $this->embedded;
55 | }
56 |
57 | /**
58 | * Gets all links
59 | *
60 | * @return array
61 | */
62 | public function getLinks()
63 | {
64 | return $this->links;
65 | }
66 |
67 | /**
68 | * Gets self link
69 | *
70 | * @return Link
71 | */
72 | public function getSelf()
73 | {
74 | return $this->links['self'];
75 | }
76 |
77 | /**
78 | * Sets data to the resource
79 | *
80 | * @param string $rel Rel element
81 | * @param mixed $data Data for the resource
82 | *
83 | * @return $this
84 | */
85 | public function setData($rel, $data = null)
86 | {
87 | if (is_array($rel) && null === $data)
88 | {
89 | foreach ($rel as $k => $v)
90 | {
91 | $this->data[$k] = $v;
92 | }
93 | }
94 | else
95 | {
96 | $this->data[$rel] = $data;
97 | }
98 |
99 | return $this;
100 | }
101 |
102 | /**
103 | * Sets Embedded resource
104 | *
105 | * @param string $rel Relation of the resource
106 | * @param Resource $resource Resource
107 | * @param bool $singular Force overwrite of the existing embedded element
108 | *
109 | * @return $this
110 | */
111 | public function setEmbedded($rel, Resource $resource = null, $singular = false)
112 | {
113 | if ($singular)
114 | {
115 | $this->embedded[$rel] = $resource;
116 | }
117 | else
118 | {
119 | $this->embedded[$rel][] = $resource;
120 | }
121 |
122 | return $this;
123 | }
124 |
125 | /**
126 | * Add a link to the resource.
127 | *
128 | * Per the JSON-HAL specification, a link relation can reference a
129 | * single link or an array of links. By default, two or more links with
130 | * the same relation will be treated as an array of links. The $singular
131 | * flag will force links with the same relation to be overwritten. The
132 | * $plural flag will force links with only one relation to be treated
133 | * as an array of links. The $plural flag has no effect if $singular
134 | * is set to true.
135 | *
136 | * @param ResourceLink $link Link
137 | * @param boolean $singular Force overwrite of the existing link
138 | * @param boolean $plural Force plural mode even if only one link is present
139 | *
140 | * @return $this
141 | */
142 | public function setLink(ResourceLink $link, $singular = false, $plural = false)
143 | {
144 | $rel = $link->getRel();
145 |
146 | if ($singular || (!isset($this->links[$rel]) && !$plural))
147 | {
148 | $this->links[$rel] = $link;
149 | }
150 | else
151 | {
152 | if (isset($this->links[$rel]) && !is_array($this->links[$rel]))
153 | {
154 | $orig_link = $this->links[$rel];
155 | $this->links[$rel] = array($orig_link);
156 | }
157 |
158 | $this->links[$rel][] = $link;
159 | }
160 |
161 | return $this;
162 | }
163 |
164 | /**
165 | * Set multiple links at once.
166 | *
167 | * @param array $links List of links
168 | * @param bool $singular Force overwrite of the existing link
169 | * @param bool $plural Force plural mode even if only one link is present
170 | *
171 | * @return $this
172 | */
173 | public function setLinks(array $links, $singular = false, $plural = false)
174 | {
175 | foreach ($links as $link)
176 | {
177 | $this->setLink($link, $singular, $plural);
178 | }
179 |
180 | return $this;
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/src/Resource/ResourceHome.php:
--------------------------------------------------------------------------------
1 | profile = $profile;
34 | }
35 |
36 | /**
37 | * Replace existing link to the resource.
38 | *
39 | * @param ResourceLink $link Link
40 | * @param mixed $group Groupped link container
41 | *
42 | * @return $this
43 | */
44 | public function setReplacedLink(ResourceLink $link, $group = '')
45 | {
46 | $rel = $link->getRel();
47 |
48 | if ($group !== '')
49 | {
50 | $this->links[$rel][$group] = $link;
51 | }
52 | else
53 | {
54 | $this->links[$rel] = $link;
55 | }
56 |
57 | return $this;
58 | }
59 |
60 | /**
61 | * Converts current Resource object to Array
62 | *
63 | * @return array
64 | */
65 | public function toArray()
66 | {
67 | $data = array();
68 |
69 | foreach ($this->links as $rel => $link)
70 | {
71 | $links = $this->_recourseLinks($link);
72 |
73 | if (!empty($links))
74 | {
75 | $data['_links'][$rel] = $links;
76 | }
77 | }
78 |
79 | foreach ($this->data as $key => $value)
80 | {
81 | $data[$key] = $value;
82 | }
83 |
84 | foreach ($this->embedded as $rel => $embed)
85 | {
86 | $data['_embedded'][$rel] = $this->_recourseEmbedded($embed);
87 | }
88 |
89 | return $data;
90 | }
91 |
92 | /**
93 | * Recourse function for Embedded objects
94 | *
95 | * @param Resource|null|array $embedded Embedded object
96 | *
97 | * @return array
98 | */
99 | protected function _recourseEmbedded($embedded)
100 | {
101 | if (is_null($embedded))
102 | {
103 | return null;
104 | }
105 |
106 | $result = array();
107 |
108 | if ($embedded instanceof self)
109 | {
110 | $result = $embedded->toArray();
111 | }
112 | else
113 | {
114 | foreach ($embedded as $embed)
115 | {
116 | if ($embed instanceof self)
117 | {
118 | $result[] = $embed->toArray();
119 | }
120 | }
121 | }
122 |
123 | return $result;
124 | }
125 |
126 | /**
127 | * Recourse function for Link objects
128 | *
129 | * @param array|Link $links Link object
130 | *
131 | * @return array
132 | */
133 | protected function _recourseLinks($links)
134 | {
135 | $result = array();
136 |
137 | if (!is_array($links))
138 | {
139 | $result = $links->toArray();
140 | }
141 | else
142 | {
143 | /** @var \Joomla\Webservices\Resource\Link $link */
144 | foreach ($links as $link)
145 | {
146 | $result[] = $link->toArray();
147 | }
148 | }
149 |
150 | return $result;
151 | }
152 |
153 | /**
154 | * Method to load an object or an array into this HAL object.
155 | *
156 | * @param object $object Object whose properties are to be loaded.
157 | *
158 | * @return object This method may be chained.
159 | */
160 | public function load($object)
161 | {
162 | foreach ($object as $name => $value)
163 | {
164 | // For _links and _embedded, we merge rather than replace.
165 | if ($name == '_links')
166 | {
167 | $this->links = array_merge((array) $this->links, (array) $value);
168 | }
169 | elseif ($name == '_embedded')
170 | {
171 | $this->embedded = array_merge((array) $this->embedded, (array) $value);
172 | }
173 | else
174 | {
175 | $this->data[$name] = $value;
176 | }
177 | }
178 |
179 | return $this;
180 | }
181 |
182 | /**
183 | * Merges two resource fields
184 | *
185 | * @param array $resourceMain Resource array main
186 | * @param array $resourceChild Resource array child
187 | *
188 | * @return array
189 | */
190 | public static function mergeResourceFields($resourceMain = array(), $resourceChild = array())
191 | {
192 | foreach ($resourceMain as $key => $value)
193 | {
194 | $resourceMain[$key] = !empty($resourceChild[$key]) ? $resourceChild[$key] : $resourceMain[$key];
195 | }
196 |
197 | return $resourceMain;
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/src/Service/ConfigurationProvider.php:
--------------------------------------------------------------------------------
1 | config = (new Registry)->loadObject($configObject);
57 | $this->config->set('language.basedir', JPATH_API . '/src');
58 | }
59 |
60 | /**
61 | * Registers the service provider with a DI container.
62 | *
63 | * @param Container $container The DI container.
64 | *
65 | * @return void
66 | *
67 | * @since 1.0
68 | */
69 | public function register(Container $container)
70 | {
71 | $container->set('config',
72 | function ()
73 | {
74 | return $this->config;
75 | },
76 | true, true
77 | );
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Service/DatabaseProvider.php:
--------------------------------------------------------------------------------
1 | alias("db", "Joomla\\Database\\DatabaseDriver")
33 | ->share(
34 | "Joomla\\Database\\DatabaseDriver",
35 | function () use ($container)
36 | {
37 | $config = $container->get("config");
38 |
39 | return DatabaseDriver::getInstance((array) $config["database"]);
40 | },
41 | true
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Service/EventProvider.php:
--------------------------------------------------------------------------------
1 | share(
33 | "Joomla\\Event\\Dispatcher",
34 | function ()
35 | {
36 | return new Dispatcher;
37 | },
38 | true
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Service/RendererProvider.php:
--------------------------------------------------------------------------------
1 | application = $application;
59 | $this->contentType = $contentType;
60 | $this->options = $options;
61 | }
62 |
63 | /**
64 | * Return a Renderer for the content type.
65 | *
66 | * @param Container $container Dependency injection container.
67 | *
68 | * @return Renderer object.
69 | */
70 | public function register(Container $container)
71 | {
72 | $application = $this->application;
73 | $contentType = $this->contentType;
74 | $options = $this->options;
75 |
76 | $container->share('renderer',
77 | function () use ($container, $application, $contentType, $options)
78 | {
79 | // Split type and subtype strings from content type.
80 | $parts = explode('/', strtolower($contentType));
81 | $typeName = ucfirst($parts[0]);
82 | $subtypeName = ucfirst(str_replace(['+', '-', '.'], '', $parts[1]));
83 |
84 | // Construct the class name.
85 | $rendererClass = 'Joomla\\Webservices\\Renderer\\' . $typeName . '\\' . $subtypeName;
86 |
87 | if (!class_exists($rendererClass))
88 | {
89 | throw new \RuntimeException($container->get('text')->sprintf('LIB_WEBSERVICES_API_UNABLE_TO_LOAD_RENDERER', $rendererClass));
90 | }
91 |
92 | try
93 | {
94 | $renderer = new $rendererClass($application, $options);
95 | }
96 | catch (\RuntimeException $e)
97 | {
98 | throw new \RuntimeException($container->get('text')->sprintf('LIB_WEBSERVICES_API_UNABLE_TO_INSTANTIATE_RENDERER', $e->getMessage()));
99 | }
100 |
101 | return $renderer;
102 | },
103 | true
104 | );
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/Type/AbstractType.php:
--------------------------------------------------------------------------------
1 | constructed === true)
54 | {
55 | throw new \BadMethodCallException('This is an immutable object');
56 | }
57 |
58 | $this->constructed = true;
59 | }
60 |
61 | /**
62 | * Prevent setting undeclared properties.
63 | *
64 | * @param string $name This is an immutable object, setting $name is not allowed.
65 | * @param mixed $value This is an immutable object, setting $value is not allowed.
66 | *
67 | * @return null This method always throws an exception.
68 | *
69 | * @throws \BadMethodCallException
70 | */
71 | public function __set($name, $value)
72 | {
73 | throw new \BadMethodCallException('This is an immutable object');
74 | }
75 |
76 | /**
77 | * Get the external value of the type.
78 | *
79 | * @return mixed
80 | */
81 | public function getExternal()
82 | {
83 | return $this->external;
84 | }
85 |
86 | /**
87 | * Get the internal value of the type.
88 | *
89 | * @return mixed
90 | */
91 | public function getInternal()
92 | {
93 | return $this->internal;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/Type/TypeArray.php:
--------------------------------------------------------------------------------
1 | internal = true;
40 | $boolean->external = 'true';
41 | break;
42 |
43 | case 'false':
44 | case '0':
45 | case false:
46 | $boolean->internal = false;
47 | $boolean->external = 'false';
48 | break;
49 |
50 | default:
51 | throw new \BadMethodCallException('Internal value must be "true", "1", "false" or "0", ' . $internalValue . ' given');
52 | }
53 |
54 | return $boolean;
55 | }
56 |
57 | /**
58 | * Public named constructor to create a new object from an external value.
59 | *
60 | * @param mixed $externalValue External value.
61 | *
62 | * @return TypeBoolean object.
63 | *
64 | * @throws \BadMethodCallException
65 | */
66 | public static function fromExternal($externalValue)
67 | {
68 | $boolean = new TypeBoolean;
69 |
70 | switch ($externalValue)
71 | {
72 | case 'true':
73 | case '1':
74 | case true:
75 | $boolean->internal = true;
76 | $boolean->external = 'true';
77 | break;
78 |
79 | case 'false':
80 | case '0':
81 | case false:
82 | $boolean->internal = false;
83 | $boolean->external = 'false';
84 | break;
85 |
86 | default:
87 | throw new \BadMethodCallException('External value must be "true", "1", "false" or "0", ' . $externalValue . ' given');
88 | }
89 |
90 | return $boolean;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/Type/TypeDatetime.php:
--------------------------------------------------------------------------------
1 | internal = \DateTime::createFromFormat('Y-m-d H:i:s', $internalValue);
43 |
44 | if ($datetime->internal instanceof \DateTime)
45 | {
46 | $datetime->external = $datetime->internal->format(\DateTime::ISO8601);
47 | }
48 | }
49 | catch (\Exception $e)
50 | {
51 | $errors = \DateTime::getLastErrors();
52 | $errorMessage = 'Date/time parse error(s): ';
53 | $errorMessage .= implode(', ', array_merge($errors['warnings'], $errors['errors']));
54 |
55 | throw new \BadMethodCallException($errorMessage);
56 | }
57 |
58 | return $datetime;
59 | }
60 |
61 | /**
62 | * Public named constructor to create a new object from an external value.
63 | *
64 | * @param string $externalValue External value (must be ISO8601 format).
65 | *
66 | * @return TypeDatetime object.
67 | *
68 | * @throws \BadMethodCallException
69 | */
70 | public static function fromExternal($externalValue)
71 | {
72 | $datetime = new TypeDatetime;
73 |
74 | try
75 | {
76 | $datetime->external = \DateTime::createFromFormat('Y-m-d H:i:s', $externalValue);
77 |
78 | if ($datetime->external instanceof \DateTime)
79 | {
80 | $datetime->internal = $datetime->external->format('Y-m-d H:i:s');
81 | }
82 | }
83 | catch (\Exception $e)
84 | {
85 | $errors = \DateTime::getLastErrors();
86 | $errorMessage = 'Date/time parse error(s): ';
87 | $errorMessage .= implode(', ', array_merge($errors['warnings'], $errors['errors']));
88 |
89 | throw new \BadMethodCallException($errorMessage);
90 | }
91 |
92 | return $datetime;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/Type/TypeFile.php:
--------------------------------------------------------------------------------
1 | internal = $internalValue;
34 | $integer->external = $internalValue;
35 |
36 | return $integer;
37 | }
38 |
39 | /**
40 | * Public named constructor to create a new object from an external value.
41 | *
42 | * @param integer $externalValue External value.
43 | *
44 | * @return TypeInteger object.
45 | *
46 | * @throws \BadMethodCallException
47 | */
48 | public static function fromExternal($externalValue)
49 | {
50 | $integer = new TypeInteger;
51 | $integer->internal = $externalValue;
52 | $integer->external = $externalValue;
53 |
54 | return $integer;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Type/TypeInterface.php:
--------------------------------------------------------------------------------
1 | internal = $internalValue;
38 | $json->external = json_encode($internalValue);
39 |
40 | return $json;
41 | }
42 |
43 | /**
44 | * Public named constructor to create a new object from an external value.
45 | *
46 | * @param string $externalValue External value.
47 | *
48 | * @return TypeState object.
49 | *
50 | * @throws \BadMethodCallException
51 | */
52 | public static function fromExternal($externalValue)
53 | {
54 | $json = new TypeJson;
55 | $json->external = $externalValue;
56 | $json->internal = json_decode($externalValue);
57 |
58 | return $json;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Type/TypeNone.php:
--------------------------------------------------------------------------------
1 | internal = $internalValue;
35 | $none->external = $internalValue;
36 |
37 | return $none;
38 | }
39 |
40 | /**
41 | * Public named constructor to create a new object from an external value.
42 | *
43 | * @param string $externalValue External value.
44 | *
45 | * @return TypeState object.
46 | *
47 | * @throws \BadMethodCallException
48 | */
49 | public static function fromExternal($externalValue)
50 | {
51 | $none = new TypeNone;
52 | $none->internal = $externalValue;
53 | $none->external = $externalValue;
54 |
55 | return $none;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Type/TypePosition.php:
--------------------------------------------------------------------------------
1 | internal = $internalValue;
34 | $state->external = '';
35 |
36 | switch ($internalValue)
37 | {
38 | case '0':
39 | $state->external = 'unpublished';
40 | break;
41 |
42 | case '1':
43 | $state->external = 'published';
44 | break;
45 |
46 | case '2':
47 | $state->external = 'archived';
48 | break;
49 |
50 | case '-2':
51 | $state->external = 'trashed';
52 | break;
53 |
54 | default:
55 | throw new \UnexpectedValueException('Internal value must be "0", "1", "2" or "-2"; ' . $internalValue . ' given');
56 | }
57 |
58 | return $state;
59 | }
60 |
61 | /**
62 | * Public named constructor to create a new object from an external value.
63 | *
64 | * @param string $externalValue External value.
65 | *
66 | * @return TypeState object.
67 | *
68 | * @throws \BadMethodCallException
69 | */
70 | public static function fromExternal($externalValue)
71 | {
72 | $state = new TypeState;
73 | $state->external = $externalValue;
74 | $state->internal = '';
75 |
76 | switch ($externalValue)
77 | {
78 | case 'unpublished':
79 | $state->internal = '0';
80 | break;
81 |
82 | case 'published':
83 | $state->internal = '1';
84 | break;
85 |
86 | case 'archived':
87 | $state->internal = '2';
88 | break;
89 |
90 | case 'trashed':
91 | $state->internal = '-2';
92 | break;
93 |
94 | default:
95 | $message = 'External value must be "unpublished", "published", "archived" or "trashed"; ' . $externalValue . ' given';
96 | throw new \UnexpectedValueException($message);
97 | }
98 |
99 | return $state;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/Type/TypeString.php:
--------------------------------------------------------------------------------
1 | internal = (string) $internalValue;
39 | $string->external = (string) $internalValue;
40 |
41 | return $string;
42 | }
43 |
44 | /**
45 | * Public named constructor to create a new object from an external value.
46 | *
47 | * @param string $externalValue External value.
48 | *
49 | * @return TypeString object.
50 | *
51 | * @throws \BadMethodCallException
52 | */
53 | public static function fromExternal($externalValue)
54 | {
55 | if (!is_string($externalValue))
56 | {
57 | throw new \BadMethodCallException('String expected');
58 | }
59 |
60 | $string = new TypeString;
61 | $string->internal = (string) $externalValue;
62 | $string->external = (string) $externalValue;
63 |
64 | return $string;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Type/TypeTarget.php:
--------------------------------------------------------------------------------
1 | internal = $internalValue;
41 | $state->external = $internalValue;
42 |
43 | $parts = explode(':', $internalValue);
44 |
45 | if ($parts[0] != 'urn')
46 | {
47 | throw new \UnexpectedValueException('Internal value is not a URN: ' . $internalValue);
48 | }
49 |
50 | if ($parts[1] != 'joomla')
51 | {
52 | throw new \UnexpectedValueException('Internal value must be a URN in the "joomla" namespace, ' . $parts[1] . ' given');
53 | }
54 |
55 | if (count($parts) != 4)
56 | {
57 | throw new \UnexpectedValueException('Internal value must be a URN with exactly 4 parts');
58 | }
59 |
60 | return $state;
61 | }
62 |
63 | /**
64 | * Public named constructor to create a new object from an external value.
65 | *
66 | * @param string $externalValue External value.
67 | *
68 | * @return TypeUrn object.
69 | *
70 | * @throws \BadMethodCallException
71 | */
72 | public static function fromExternal($externalValue)
73 | {
74 | $state = new TypeUrn;
75 | $state->external = $externalValue;
76 | $state->internal = $externalValue;
77 |
78 | $parts = explode(':', $externalValue);
79 |
80 | if ($parts[0] != 'urn')
81 | {
82 | throw new \UnexpectedValueException('External value is not a URN: ' . $externalValue);
83 | }
84 |
85 | if ($parts[1] != 'joomla')
86 | {
87 | throw new \UnexpectedValueException('External value must be a URN in the "joomla" namespace, ' . $parts[1] . ' given');
88 | }
89 |
90 | if (count($parts) != 4)
91 | {
92 | throw new \UnexpectedValueException('External value must be a URN with exactly 4 parts');
93 | }
94 |
95 | return $state;
96 | }
97 |
98 | /**
99 | * Return the raw id without the namespace and type stuff.
100 | *
101 | * @return integer
102 | */
103 | public function getId()
104 | {
105 | $parts = explode(':', $this->internal);
106 |
107 | return $parts[3];
108 | }
109 |
110 | /**
111 | * Return the type of the URN.
112 | *
113 | * @return string
114 | */
115 | public function getType()
116 | {
117 | $parts = explode(':', $this->internal);
118 |
119 | return $parts[2];
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/Type/TypeYnglobal.php:
--------------------------------------------------------------------------------
1 | profile = $profile;
35 |
36 | // Check we have permission to perform this operation.
37 | if (!$this->triggerFunction('isOperationAllowed'))
38 | {
39 | return false;
40 | }
41 |
42 | // Get name for integration model/table. Could be different from the webserviceName.
43 | $this->elementName = ucfirst(strtolower((string) $this->getConfig('config.name')));
44 |
45 | $this->operationConfiguration = $this->getConfig('operations.' . strtolower($this->operation));
46 |
47 | $this->triggerFunction('apiCreate');
48 |
49 | $this->resource = new ResourceItem($this->profile);
50 |
51 | // Set links from resources to the main document.
52 | $this->setDataValueToResource($this->resource, $this->resources, $this->data);
53 |
54 | return $this->resource;
55 | }
56 |
57 | /**
58 | * Execute the Api Create operation.
59 | *
60 | * @return mixed JApi object with information on success, boolean false on failure.
61 | *
62 | * @since 1.2
63 | */
64 | public function apiCreate()
65 | {
66 | // Get resource profile from configuration.
67 | $profile = $this->profile->getResources($this->getOptions());
68 |
69 | $model = $this->triggerFunction('loadModel', $this->elementName, $this->operationConfiguration);
70 | $functionName = XmlHelper::attributeToString($this->operationConfiguration, 'functionName', 'save');
71 |
72 | $data = $this->profile->bindData((array) $this->getOptions()->get('data', array()));
73 |
74 | $data = $this->triggerFunction('validatePostData', $model, $data, $this->operationConfiguration);
75 |
76 | if ($data === false)
77 | {
78 | // Data failed validation.
79 | $this->setStatusCode(406);
80 | $this->triggerFunction('displayErrors', $model);
81 | $this->setData('result', $data);
82 |
83 | return;
84 | }
85 |
86 | // Prepare parameters for the function.
87 | $args = $this->profile->buildFunctionArgs($data);
88 | $result = null;
89 | $id = 0;
90 |
91 | // Checks if that method exists in model class file and executes it.
92 | if (method_exists($model, $functionName))
93 | {
94 | $result = $this->triggerCallFunction($model, $functionName, $args);
95 | }
96 | else
97 | {
98 | $this->setStatusCode(400);
99 | }
100 |
101 | if (method_exists($model, 'getState'))
102 | {
103 | $id = $model->getState($model->getName() . '.id');
104 | $this->setData('id', $id);
105 | }
106 |
107 | $this->setData('result', $result);
108 | $this->triggerFunction('displayErrors', $model);
109 |
110 | if ($this->statusCode < 400)
111 | {
112 | if ($result === false)
113 | {
114 | $this->setStatusCode(404);
115 | }
116 | else
117 | {
118 | $this->setStatusCode(201);
119 | $this->app->setHeader('Location', $this->webserviceName . '/' . $id, true);
120 | }
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/Webservices/Delete.php:
--------------------------------------------------------------------------------
1 | profile = $profile;
35 |
36 | // Check we have permission to perform this operation.
37 | if (!$this->triggerFunction('isOperationAllowed'))
38 | {
39 | return false;
40 | }
41 |
42 | // Get name for integration model/table. Could be different from the webserviceName.
43 | $this->elementName = ucfirst(strtolower((string) $this->getConfig('config.name')));
44 |
45 | $this->operationConfiguration = $this->getConfig('operations.' . strtolower($this->operation));
46 |
47 | $this->triggerFunction('apiDelete');
48 |
49 | $this->resource = new ResourceItem($this->profile);
50 |
51 | // Set links from resources to the main document
52 | $this->setDataValueToResource($this->resource, $this->resources, $this->data);
53 |
54 | return $this->resource;
55 | }
56 |
57 | /**
58 | * Execute the Api Delete operation.
59 | *
60 | * @return mixed JApi object with information on success, boolean false on failure.
61 | *
62 | * @since 1.2
63 | */
64 | public function apiDelete()
65 | {
66 | // Get resource list from configuration.
67 | $this->profile->getResources($this->getOptions());
68 |
69 | // Delete function requires references and not values like we use in call_user_func_array so we use List delete function
70 | $model = $this->triggerFunction('loadModel', $this->elementName, $this->operationConfiguration);
71 | $functionName = XmlHelper::attributeToString($this->operationConfiguration, 'functionName', 'delete');
72 |
73 | // Get data from request and validate it.
74 | // Note that we actually get the data from the request URI, but we process/validate it as if the data came from the request body.
75 | $data = $this->profile->bindData((array) $this->getOptions()->get('dataGet', array()));
76 | $data = $this->triggerFunction('validatePostData', $model, $data, $this->operationConfiguration);
77 |
78 | if ($data === false)
79 | {
80 | // 406 = Not acceptable.
81 | $this->setStatusCode(406);
82 | $this->triggerFunction('displayErrors', $model);
83 | $this->setData('result', $data);
84 |
85 | return;
86 | }
87 |
88 | $result = null;
89 | $args = $this->profile->buildFunctionArgs($data);
90 |
91 | // Prepare parameters for the function
92 | if (strtolower(XmlHelper::attributeToString($this->operationConfiguration, 'dataMode', 'model')) == 'table')
93 | {
94 | $primaryKeys = $this->profile->bindDataToPrimaryKeys($data, $this->operationConfiguration->getName());
95 |
96 | if (!empty($primaryKeys))
97 | {
98 | $result = $model->{$functionName}($primaryKeys);
99 | }
100 | else
101 | {
102 | $result = $model->{$functionName}($args);
103 | }
104 | }
105 | else
106 | {
107 | // Checks if that method exists in model class file and executes it
108 | if (method_exists($model, $functionName))
109 | {
110 | $result = $this->triggerCallFunction($model, $functionName, $args);
111 | }
112 | else
113 | {
114 | $this->setStatusCode(400);
115 | }
116 | }
117 |
118 | $this->setData('result', $result);
119 |
120 | $this->triggerFunction('displayErrors', $model);
121 |
122 | if ($this->statusCode < 400)
123 | {
124 | if ($result === false)
125 | {
126 | // If delete failed then we set it to Internal Server Error status code
127 | $this->setStatusCode(500);
128 | }
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/Webservices/Exception/ConfigurationException.php:
--------------------------------------------------------------------------------
1 | resource = $resource;
35 |
36 | // Check we have permission to perform this operation.
37 | if (!$this->triggerFunction('isOperationAllowed'))
38 | {
39 | return false;
40 | }
41 |
42 | $this->elementName = ucfirst(strtolower((string) $this->getConfig('config.name')));
43 | $this->operationConfiguration = $this->getConfig('operations.' . strtolower($this->operation));
44 | $this->triggerFunction('apiUpdate');
45 |
46 | // Set links from resources to the main document
47 | $this->setDataValueToResource($this->resource, $this->resources, $this->data);
48 |
49 | return $this->resource;
50 | }
51 |
52 | /**
53 | * Execute the Api Update operation.
54 | *
55 | * @return mixed JApi object with information on success, boolean false on failure.
56 | *
57 | * @since 1.2
58 | */
59 | public function apiUpdate()
60 | {
61 | // Get resource list from configuration.
62 | $this->profile->getResources($this->getOptions());
63 |
64 | $model = $this->triggerFunction('loadModel', $this->elementName, $this->operationConfiguration);
65 | $functionName = XmlHelper::attributeToString($this->operationConfiguration, 'functionName', 'save');
66 | $data = $this->profile->bindData((array) $this->getOptions()->get('data', array()));
67 |
68 | $data = $this->triggerFunction('validatePostData', $model, $data, $this->operationConfiguration);
69 |
70 | if ($data === false)
71 | {
72 | // Not Acceptable
73 | $this->setStatusCode(406);
74 | $this->triggerFunction('displayErrors', $model);
75 | $this->setData('result', $data);
76 |
77 | return;
78 | }
79 |
80 | // Prepare parameters for the function
81 | $args = $this->profile->buildFunctionArgs($data);
82 | $result = null;
83 |
84 | // Checks if that method exists in model class and executes it
85 | if (method_exists($model, $functionName))
86 | {
87 | $result = $this->triggerCallFunction($model, $functionName, $args);
88 | }
89 | else
90 | {
91 | $this->setStatusCode(400);
92 | }
93 |
94 | if (method_exists($model, 'getState'))
95 | {
96 | $this->setData('id', $model->getState(strtolower($this->elementName) . '.id'));
97 | }
98 |
99 | $this->setData('result', $result);
100 | $this->triggerFunction('displayErrors', $model);
101 |
102 | if ($this->statusCode < 400)
103 | {
104 | if ($result === false)
105 | {
106 | // If update failed then we set it to Internal Server Error status code
107 | $this->setStatusCode(500);
108 | }
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/Webservices/WebserviceHelper.php:
--------------------------------------------------------------------------------
1 |
24 | * $key is "displayGroup"
25 | * Then this method will return "something".
26 | *
27 | * @param \SimpleXMLElement|Array $element XML object or array
28 | * @param string $key Key to check
29 | * @param string $default Default value to return
30 | *
31 | * @return boolean
32 | *
33 | * @since __DEPLOY_VERSION__
34 | */
35 | public static function attributeToString($element, $key, $default = '')
36 | {
37 | if (!isset($element[$key]))
38 | {
39 | return $default;
40 | }
41 |
42 | $value = (string) $element[$key];
43 |
44 | return !empty($value) ? $value : $default;
45 | }
46 |
47 | /**
48 | * Method to transform XML to array and get XML attributes
49 | *
50 | * @param \SimpleXMLElement|Array $element XML object or array
51 | * @param string $key Key to check
52 | * @param boolean $default Default value to return
53 | *
54 | * @return boolean
55 | *
56 | * @since __DEPLOY_VERSION__
57 | */
58 | public static function isAttributeTrue($element, $key, $default = false)
59 | {
60 | if (!isset($element[$key]))
61 | {
62 | return $default;
63 | }
64 |
65 | return strtolower($element[$key]) == "true" ? true : false;
66 | }
67 |
68 | /**
69 | * Method to transform XML to array and get XML attributes
70 | *
71 | * @param \SimpleXMLElement $xmlElement XML object to transform
72 | * @param boolean $onlyAttributes return only attributes or all elements
73 | *
74 | * @return array
75 | *
76 | * @since __DEPLOY_VERSION__
77 | */
78 | public static function getXMLElementAttributes($xmlElement, $onlyAttributes = true)
79 | {
80 | $transformedXML = json_decode(json_encode((array) $xmlElement), true);
81 |
82 | return $onlyAttributes ? $transformedXML['@attributes'] : $transformedXML;
83 | }
84 | }
--------------------------------------------------------------------------------
/tests/_bootstrap.php:
--------------------------------------------------------------------------------
1 | config[$element];
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/_support/Helper/Api.php:
--------------------------------------------------------------------------------
1 | am('Administrator');
12 | $I->wantToTest('Activate the default webservices');
13 | $I->doAdministratorLogin();
14 | $I->comment('I enable basic authentication');
15 | $I->amOnPage('administrator/index.php?option=com_webservices');
16 | $I->waitForText('Webservice Manager', 30, ['class' => 'page-title']);
17 | $I->click(['class' => 'lc-not_installed_webservices']);
18 | $I->click(['class' => 'lc-install_webservice_administrator_contact']);
19 | $I->waitForElement(['id' => 'mainComponentWebservices'], 30);
20 | $I->see('administrator.contact.1.0.0.xml',['class' => 'lc-webservice_file']);
21 |
22 |
--------------------------------------------------------------------------------
/tests/acceptance/install/01-InstallJoomlaCept.php:
--------------------------------------------------------------------------------
1 | wantToTest('Joomla 3 Installation');
14 | $I->installJoomlaRemovingInstallationFolder();
15 | $I->doAdministratorLogin();
16 | $I->setErrorReportingToDevelopment();
17 |
--------------------------------------------------------------------------------
/tests/acceptance/install/02-InstallExtensionCept.php:
--------------------------------------------------------------------------------
1 | am('Administrator');
14 | $I->wantToTest('Webservices installation in Joomla 3');
15 | $I->doAdministratorLogin();
16 | $path = $I->getConfiguration('repo_folder');
17 | $I->installExtensionFromFolder($path . '/component');
--------------------------------------------------------------------------------
/tests/acceptance/uninstall/ZZ-UninstallExtensionCept.php:
--------------------------------------------------------------------------------
1 | wantTo('Uninstall Webservices Extension');
13 | $I->doAdministratorLogin();
14 | $I->amOnPage('/administrator/index.php?option=com_installer&view=manage');
15 | $I->waitForText('Extensions: Manage',30, ['css' => 'H1']);
16 | $I->searchForItem('Webservices');
17 | $I->waitForElement(['id' => 'manageList']);
18 | $I->checkAllResults();
19 | $I->click(['xpath' => "//div[@id='toolbar-delete']/button"]);
20 | $I->waitForElement(['id' => 'system-message-container'],30);
21 | $I->see('Uninstalling the component was successful.', ['id' => 'system-message-container']);
22 | $I->searchForItem('Webservices package');
23 | $I->waitForElement(['class' => 'alert-no-items'],30);
24 | $I->see('There are no extensions installed matching your query.', ['class' => 'alert-no-items']);
25 |
--------------------------------------------------------------------------------
/tests/api.suite.dist.yml:
--------------------------------------------------------------------------------
1 | class_name: ApiTester
2 | modules:
3 | enabled:
4 | - \Helper\Api
5 | - REST:
6 | depends: PhpBrowser
7 | url: http://localhost/tests/joomla-cms3/www/
8 |
--------------------------------------------------------------------------------
/tests/api/_bootstrap.php:
--------------------------------------------------------------------------------
1 | name = 'contact' . rand(0,1000);
18 | $this->id = 0;
19 | }
20 |
21 | public function WebserviceIsAvailable(ApiTester $I)
22 | {
23 | $I->wantTo("check the availability of the webservice");
24 | $I->amHttpAuthenticated('admin', 'admin');
25 | $I->sendGET('index.php'
26 | . '?option=contact'
27 | . '&api=Hal'
28 | . '&webserviceClient=administrator'
29 | . '&webserviceVersion=1.0.0'
30 | );
31 |
32 | $I->seeResponseCodeIs(200);
33 | $I->seeResponseIsJson();
34 | $I->seeHttpHeader('Webservice-Name', 'contact');
35 | $I->seeHttpHeader('Webservice-Version', '1.0.0');
36 | }
37 |
38 |
39 | /**
40 | * @todo
41 | * @depends WebserviceIsAvailable
42 | *
43 | public function create(ApiTester $I)
44 | {
45 | $I->wantTo('POST a new Contact in com_contacts');
46 | $I->amHttpAuthenticated('admin', 'admin');
47 | $I->sendPOST('index.php'
48 | . '?option=contact'
49 | . '&api=Hal'
50 | . '&webserviceClient=administrator'
51 | . '&webserviceVersion=1.0.0'
52 | . "&name=$this->name"
53 | // Uncategorised default category
54 | . '&catid=4'
55 | );
56 |
57 | $I->seeResponseCodeIs(201);
58 | $I->seeResponseIsJson();
59 |
60 | $links = $I->grabDataFromResponseByJsonPath('$._links');
61 | $I->sendGET($links[0]['contact:self']['href']);
62 | $I->seeResponseCodeIs(200);
63 | $I->seeResponseIsJson();
64 | $ids = $I->grabDataFromResponseByJsonPath('$.id');
65 | $this->id = $ids[0];
66 | $I->comment("The id of the new created contact with name '$this->name' is: $this->id");
67 | }
68 | */
69 |
70 | /**
71 | * @todo
72 | * @depends create
73 | *
74 | public function readItem(ApiTester $I)
75 | {
76 | $I->wantTo("GET an existing Contact");
77 | $I->amHttpAuthenticated('admin', 'admin');
78 | $I->sendGET('index.php'
79 | . '?option=contact'
80 | . '&api=Hal'
81 | . '&webserviceClient=administrator'
82 | . '&webserviceVersion=1.0.0'
83 | . "&id=$this->id"
84 | );
85 |
86 | $I->seeResponseCodeIs(200);
87 | $I->seeResponseIsJson();
88 | $I->seeResponseContains('"name":"'. $this->name.'"');
89 | }
90 | */
91 |
92 | /**
93 | * @todo
94 | * @depends readItem
95 | *
96 | public function update(ApiTester $I)
97 | {
98 | $I->wantTo('Update a new Contact in com_contacts using PUT');
99 | $I->amHttpAuthenticated('admin', 'admin');
100 |
101 | $this->name = 'new_' . $this->name;
102 | $I->sendPUT('index.php'
103 | . '?option=contact'
104 | . '&api=Hal'
105 | . '&webserviceClient=administrator'
106 | . '&webserviceVersion=1.0.0'
107 | . "&id=$this->id"
108 | . "&name=$this->name"
109 | // Uncategorised default category
110 | . '&catid=4'
111 | );
112 |
113 | $I->seeResponseCodeIs(200);
114 |
115 | $I->sendGET('index.php'
116 | . '?option=contact'
117 | . '&api=Hal'
118 | . '&webserviceClient=administrator'
119 | . '&webserviceVersion=1.0.0'
120 | . "&id=$this->id"
121 | );
122 |
123 | $I->seeResponseCodeIs(200);
124 | $I->seeResponseIsJson();
125 | $I->seeResponseContains('"name":"' . $this->name . '"');
126 | $I->comment("The contact name has been modified to: $this->name");
127 | }
128 | */
129 |
130 | /**
131 | * @todo delete depends on https://github.com/joomla-projects/webservices/issues/16
132 | */
133 | }
--------------------------------------------------------------------------------
/tests/functional/_bootstrap.php:
--------------------------------------------------------------------------------
1 |
2 | ServerAdmin webmaster@localhost
3 | DocumentRoot %TRAVIS_BUILD_DIR%
4 |
5 |
6 | Options FollowSymLinks
7 | AllowOverride All
8 |
9 |
10 |
11 | Options FollowSymLinks MultiViews ExecCGI
12 | AllowOverride All
13 | Order deny,allow
14 | Allow from all
15 |
16 |
17 | # Wire up Apache to use Travis CI's php-fpm.
18 |
19 | AddHandler php5-fcgi .php
20 | Action php5-fcgi /php5-fcgi
21 | Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
22 | FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /tmp/php5-fpm.sock -pass-header Authorization
23 |
24 |
25 | ErrorLog ${APACHE_LOG_DIR}/error.log
26 |
27 |
--------------------------------------------------------------------------------
/tests/unit/_bootstrap.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/www/htaccess.txt:
--------------------------------------------------------------------------------
1 | ##
2 | # @package Joomla
3 | # @copyright Copyright (C) 2005 - 2015 Open Source Matters. All rights reserved.
4 | # @license GNU General Public License version 2 or later; see LICENSE.txt
5 | ##
6 |
7 | ##
8 | # READ THIS COMPLETELY IF YOU CHOOSE TO USE THIS FILE!
9 | #
10 | # The line just below this section: 'Options +FollowSymLinks' may cause problems
11 | # with some server configurations. It is required for use of mod_rewrite, but may already
12 | # be set by your server administrator in a way that disallows changing it in
13 | # your .htaccess file. If using it causes your server to error out, comment it out (add # to
14 | # beginning of line), reload your site in your browser and test your sef url's. If they work,
15 | # it has been set by your server administrator and you do not need it set here.
16 | ##
17 |
18 | ## No directory listings
19 | IndexIgnore *
20 |
21 | ## Can be commented out if causes errors, see notes above.
22 | Options +FollowSymlinks
23 | Options -Indexes
24 |
25 | ## Mod_rewrite in use.
26 |
27 | RewriteEngine On
28 |
29 | ## Begin - Rewrite rules to block out some common exploits.
30 | # If you experience problems on your site block out the operations listed below
31 | # This attempts to block the most common type of exploit `attempts` to Joomla!
32 | #
33 | # Block out any script trying to base64_encode data within the URL.
34 | RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
35 | # Block out any script that includes a