Initial release vcc_0-1-0
authorNicole Cordes <cordes@cps-it.de>
Sat, 5 Jan 2013 00:27:16 +0000 (01:27 +0100)
committerNicole Cordes <cordes@cps-it.de>
Sat, 5 Jan 2013 00:27:16 +0000 (01:27 +0100)
14 files changed:
ChangeLog [new file with mode: 0644]
Classes/Hook/DocHeaderButtonsHook.php [new file with mode: 0644]
Classes/Service/CommunicationService.php [new file with mode: 0644]
Classes/Service/ExtensionSettingService.php [new file with mode: 0644]
Classes/Service/LoggingService.php [new file with mode: 0644]
Classes/Service/TsConfigService.php [new file with mode: 0644]
Resources/Public/Icons/CachePlugin.png [new file with mode: 0644]
ext_autoload.php [new file with mode: 0644]
ext_conf_template.txt [new file with mode: 0644]
ext_emconf.php [new file with mode: 0644]
ext_icon.gif [new file with mode: 0644]
ext_localconf.php [new file with mode: 0644]
ext_tables.php [new file with mode: 0644]
ext_tables.sql [new file with mode: 0644]

diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..e62df84
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,3 @@
+2013-01-05 Nicole Cordes <cordes@cps-it.de>
+
+       * Initial release
\ No newline at end of file
diff --git a/Classes/Hook/DocHeaderButtonsHook.php b/Classes/Hook/DocHeaderButtonsHook.php
new file mode 100644 (file)
index 0000000..34ebee1
--- /dev/null
@@ -0,0 +1,217 @@
+<?php
+       /***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2012 Nicole Cordes <cordes@cps-it.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Adds the cache clear button to the edit form
+ *
+ * @author Nicole Cordes <cordes@cps-it.de>
+ * @package TYPO3
+ * @subpackage vcc
+ */
+class tx_vcc_hook_docHeaderButtonsHook {
+
+       /**
+        * @var tx_vcc_service_communicationService|NULL
+        */
+       var $communicationService = NULL;
+
+       /**
+        * @var tx_vcc_service_tsConfigService|NULL
+        */
+       var $tsConfigService = NULL;
+
+       /**
+        * @var array
+        */
+       var $params = array();
+
+       /**
+        * @var template|NULL
+        */
+       var $pObj = NULL;
+
+       /**
+        * @var string
+        */
+       var $permsClause = '';
+
+       /**
+        * Initialize the object
+        *
+        * @return void
+        */
+       public function __construct() {
+               $communicationService = t3lib_div::makeInstance('tx_vcc_service_communicationService');
+               $this->injectCommunicationService($communicationService);
+
+               $tsConfigService = t3lib_div::makeInstance('tx_vcc_service_tsConfigService');
+               $this->injectTsConfigService($tsConfigService);
+
+               $this->permsClause = $GLOBALS['BE_USER']->getPagePermsClause(2);
+       }
+
+       /**
+        * Injects the communication service
+        *
+        * @param tx_vcc_service_communicationService $communicationService
+        *
+        * @return void
+        */
+       public function injectCommunicationService(tx_vcc_service_communicationService $communicationService) {
+               $this->communicationService = $communicationService;
+       }
+
+       /**
+        * Injects the TSConfig service
+        *
+        * @param tx_vcc_service_tsConfigService $tsConfigService
+        *
+        * @return void
+        */
+       public function injectTsConfigService(tx_vcc_service_tsConfigService $tsConfigService) {
+               $this->tsConfigService = $tsConfigService;
+       }
+
+       /**
+        * Checks access to the record and adds the clear cache button
+        *
+        * @param array $params
+        * @param template $pObj
+        *
+        * @return void
+        */
+       public function addButton($params, $pObj) {
+               $this->params = $params;
+               $this->pObj = $pObj;
+
+               $record = array();
+               $table = '';
+
+                       // For web -> page view or web -> list view
+               if ($this->pObj->scriptID === 'ext/cms/layout/db_layout.php' || $this->pObj->scriptID === 'ext/recordlist/mod1/index.php') {
+                       $id = t3lib_div::_GP('id');
+                       if (is_object($GLOBALS['SOBE']) && $GLOBALS['SOBE']->current_sys_language) {
+                               $table = 'pages_language_overlay';
+                               $record = t3lib_BEfunc::getRecordsByField($table, 'pid', $id, ' AND ' . $table . '.sys_language_uid=' . intval($GLOBALS['SOBE']->current_sys_language), '', '', '1');
+                               if (is_array($record) && !empty($record)) {
+                                       $record = $record[0];
+                               }
+                       } else {
+                               $table = 'pages';
+                               $record = array(
+                                       'uid' => $id,
+                                       'pid' => $id
+                               );
+                       }
+               } elseif ($this->pObj->scriptID === 'typo3/alt_doc.php') {      // For record edit
+                       $editConf = t3lib_div::_GP('edit');
+                       if (is_array($editConf) && !empty($editConf)) {
+                               // Finding the current table
+                               reset($editConf);
+                               $table = key($editConf);
+
+                               // Finding the first id and get the records pid
+                               reset($editConf[$table]);
+                               $recordUid = key($editConf[$table]);
+                               // If table is pages we need uid (as pid) to get TSconfig
+                               if ($table === 'pages') {
+                                       $record['uid'] = $recordUid;
+                                       $record['pid'] = $recordUid;
+                               } else {
+                                       $record = t3lib_BEfunc::getRecord($table, $recordUid, 'uid, pid');
+                               }
+                       }
+               }
+
+               if (isset($record['pid']) && $record['pid'] > 0) {
+                       if ($this->isModuleAccessible($record['pid'], $table)) {
+                               // Process last request
+                               $button = $this->process($table, $record['uid']);
+
+                               // Add icon
+                               $button .=
+                               $buttons['save_close'] = t3lib_iconWorks::getSpriteIcon(
+                                       'extensions-vcc-clearVarnishCache',
+                                       array(
+                                               'html' => '<input type="image" class="c-inputButton" name="_clearvarnishcache" src="clear.gif" title="Clear Varnish cache" />'
+                                       )
+                               );
+
+                                       //'<a href="#" onclick="' . htmlspecialchars('window.location.href += \'&_clear_varnish_cache=1\'') . '" title="Clear Varnish cache">' .
+                                       //t3lib_iconWorks::getSpriteIcon('extensions-vcc-clearVarnishCache') . '</a>';
+                               $this->params['buttons']['vcc'] = $button;
+                               $buttonWrap = t3lib_parsehtml::getSubpart($pObj->moduleTemplate, '###BUTTON_GROUP_WRAP###');
+                               $this->params['markers']['BUTTONLIST_LEFT'] .= t3lib_parsehtml::substituteMarker($buttonWrap, '###BUTTONS###', trim($button));
+                       }
+               }
+       }
+
+       /**
+        * Checks if the button could be inserted
+        *
+        * @param integer $pageId
+        * @param string $table
+        *
+        * @return boolean
+        */
+       protected function isModuleAccessible($pageId, $table) {
+               $access = FALSE;
+
+                       // Check edit rights for page as cache can be flushed then only
+               $pageinfo = t3lib_BEfunc::readPageAccess($pageId, $this->permsClause);
+               if ($pageinfo !== FALSE) {
+                               // Get TSconfig for extension
+                       $tsConfig = $this->tsConfigService->getConfiguration($pageId);
+                       if (isset($tsConfig[$table]) && !empty($tsConfig[$table])) {
+                               $access = TRUE;
+                       }
+               }
+
+               return $access;
+       }
+
+       /**
+        * Evaluate request and send clear cache commands
+        *
+        * @param string $table
+        * @param integer $uid
+        *
+        * @return string
+        */
+       protected function process($table, $uid) {
+               $string = '';
+               if (isset($_POST['_clearvarnishcache_x'])) {
+                       $resultArray = $this->communicationService->sendClearCacheCommandForTables($table, $uid);
+                       $string = $this->communicationService->generateBackendMessage($resultArray);
+               }
+
+               return $string;
+       }
+}
+
+if (defined('TYPO3_MODE') && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Hook/DocHeaderButtonsHook.php'])  {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Hooks/DocHeaderButtonsHook.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/Classes/Service/CommunicationService.php b/Classes/Service/CommunicationService.php
new file mode 100644 (file)
index 0000000..f523f71
--- /dev/null
@@ -0,0 +1,428 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2012 Nicole Cordes <cordes@cps-it.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Service to send the cache command to server
+ *
+ * @author Nicole Cordes <cordes@cps-it.de>
+ * @package TYPO3
+ * @subpackage vcc
+ */
+class tx_vcc_service_communicationService implements t3lib_Singleton {
+
+       /**
+        * @var tslib_cObj|NULL
+        */
+       var $contentObject = NULL;
+
+       /**
+        * @var tx_vcc_service_extensionSettingService|NULL
+        */
+       var $extensionSettingService = NULL;
+
+       /**
+        * @var tx_vcc_service_loggingService|NULL
+        */
+       var $loggingService = NULL;
+
+       /**
+        * @var tx_vcc_service_tsConfigService|NULL
+        */
+       var $tsConfigService = NULL;
+
+       /**
+        * @var string
+        */
+       var $httpMethod = '';
+
+       /**
+        * @var string
+        */
+       var $httpProtocol = '';
+
+       /**
+        * @var integer
+        */
+       var $stripSlash = 0;
+
+       /**
+        * @var array
+        */
+       var $serverArray = array();
+
+       /**
+        * Initialize the object
+        *
+        * @return void
+        */
+       public function __construct() {
+               $extensionSettingService = t3lib_div::makeInstance('tx_vcc_service_extensionSettingService');
+               $this->injectExtensionSettingService($extensionSettingService);
+
+               $loggingService = t3lib_div::makeInstance('tx_vcc_service_loggingService');
+               $this->injectLoggingService($loggingService);
+
+               $tsConfigService = t3lib_div::makeInstance('tx_vcc_service_tsConfigService');
+               $this->injectTsConfigService($tsConfigService);
+
+               $configuration = $this->extensionSettingService->getConfiguration();
+               $this->serverArray = t3lib_div::trimExplode(',', $configuration['server'], 1);
+               $this->httpMethod = trim($configuration['httpMethod']);
+               $this->httpProtocol = trim($configuration['httpProtocol']);
+               $this->stripSlash = $configuration['stripSlash'];
+
+               if (!is_object($GLOBALS['TSFE'])) {
+                       $this->createTSFE();
+               }
+
+               $this->contentObject = t3lib_div::makeInstance('tslib_cObj');
+       }
+
+       /**
+        * Injects the extension setting service
+        *
+        * @param tx_vcc_service_extensionSettingService $extensionSettingService
+        *
+        * @return void
+        */
+       public function injectExtensionSettingService(tx_vcc_service_extensionSettingService $extensionSettingService) {
+               $this->extensionSettingService = $extensionSettingService;
+       }
+
+       /**
+        * Injects the logging service
+        *
+        * @param tx_vcc_service_loggingService $loggingService
+        *
+        * @return void
+        */
+       public function injectLoggingService(tx_vcc_service_loggingService $loggingService) {
+               $this->loggingService = $loggingService;
+       }
+
+       /**
+        * Injects the TSConfig service
+        *
+        * @param tx_vcc_service_tsConfigService $tsConfigService
+        *
+        * @return void
+        */
+       public function injectTsConfigService(tx_vcc_service_tsConfigService $tsConfigService) {
+               $this->tsConfigService = $tsConfigService;
+       }
+
+       protected function createTSFE() {
+               if (!is_object($GLOBALS['TT'])) {
+                       $GLOBALS['TT'] = t3lib_div::makeInstance('t3lib_TimeTrackNull');
+               }
+
+               $GLOBALS['TSFE'] = t3lib_div::makeInstance('tslib_fe', $GLOBALS['TYPO3_CONF_VARS'], 1, '');
+               $GLOBALS['TSFE']->connectToDB();
+               $GLOBALS['TSFE']->initFEuser();
+               $GLOBALS['TSFE']->determineId();
+               $GLOBALS['TSFE']->getCompressedTCarray();
+               $GLOBALS['TSFE']->initTemplate();
+               $GLOBALS['TSFE']->getConfigArray();
+
+               TSpagegen::pagegenInit();
+       }
+
+       /**
+        * Send clear cache commands for pages to defined server
+        *
+        * @param string $table
+        * @param integer $id
+        * @param string $host
+        *
+        * @return array
+        */
+       public function sendClearCacheCommandForTables($table, $uid, $host = '') {
+                       // Get current record to process
+               $record = t3lib_BEfunc::getRecord($table, $uid);
+
+                       // Build request
+               if ($table === 'pages') {
+                       $pid = $record['uid'];
+               } else {
+                       $pid = $record['pid'];
+               }
+
+                       // Log debug information
+               $logData = array(
+                       'table' => $table,
+                       'uid' => $uid,
+                       'host' => $host,
+                       'pid' => $pid
+               );
+               $this->loggingService->debug('CommunicationService::sendClearCacheCommandForTables arguments', $logData, $pid);
+
+               $tsConfig = $this->tsConfigService->getConfiguration($pid);
+               $typolink = $tsConfig[$table . '.']['typolink.'];
+               $this->contentObject->data = $record;
+
+               $url = $this->contentObject->typoLink_URL($typolink);
+
+                       // Check for root site
+               if ($url === '' && $table === 'pages') {
+                       $rootline = t3lib_BEfunc::BEgetRootLine($uid);
+                       if (is_array($rootline) && count($rootline) > 1) {
+                                       // If uid equals the site root we have to process
+                               if ($uid == $rootline[1]['uid']) {
+                                       $url = '/';
+                               }
+                       }
+               }
+
+                       // Log debug information
+               $logData['url'] = $url;
+               $this->loggingService->debug('CommunicationService::sendClearCacheCommandForTables built url', $logData, $pid);
+
+                       // Process only for valid URLs
+               if ($url !== '') {
+
+                               // Remove any host if set
+                       if (strpos($url, '://') !== FALSE) {
+                               $urlArray = parse_url($url);
+                               $url = substr($url, strlen($urlArray['scheme'] . '://' . $urlArray['host']));
+                       }
+
+                       return $this->processClearCacheCommand($url, $pid, $host);
+               }
+
+               return array(
+                       array(
+                               'status' => t3lib_FlashMessage::ERROR,
+                               'message' => array('No valid URL was generated.', 'table: ' . $table, 'uid: ' . $uid, 'host: ' . $host),
+                               'requestHeader' => array($url)
+                       )
+               );
+       }
+
+       /**
+        * Send clear cache commands for pages to defined server
+        *
+        * @param string $fileName
+        * @param string $host
+        *
+        * @return array
+        */
+       public function sendClearCacheCommandForFiles($fileName, $host = '') {
+                       // Log debug information
+               $logData = array(
+                       'fileName' => $fileName,
+                       'host' => $host
+               );
+               $this->loggingService->debug('CommunicationService::sendClearCacheCommandForFiles arguments', $logData);
+
+                       // If no host was given get all
+               if ($host === '') {
+                       $hostArray = array();
+
+                               // Get all domain records and check page access
+                       $domainArray = t3lib_BEfunc::getRecordsByField('sys_domain', 'redirectTo', '', ' AND hidden=0');
+                       if (is_array($domainArray) && !empty($domainArray)) {
+                               $permsClause = $GLOBALS['BE_USER']->getPagePermsClause(2);
+                               foreach ($domainArray as $domain) {
+                                       $pageinfo = t3lib_BEfunc::readPageAccess($domain['pid'], $permsClause);
+                                       if ($pageinfo !== FALSE) {
+                                               $hostArray[] = $domain['domainName'];
+                                       }
+                               }
+                               unset($domain);
+                       }
+                       $host = implode(',', $hostArray);
+
+                               // Log debug information
+                       $logData['host'] = $host;
+                       $this->loggingService->debug('CommunicationService::sendClearCacheCommandForFiles built host', $logData);
+               }
+
+               return $this->processClearCacheCommand($fileName, 0, $host);
+       }
+
+       /**
+        * Processes the CURL request and sends action to Varnish server
+        *
+        * @param string $url
+        * @param integer $pid
+        * @param string $host
+        *
+        * @return array
+        */
+       protected function processClearCacheCommand($url, $pid, $host = '') {
+               $responseArray = array();
+
+               foreach ($this->serverArray as $server) {
+                       $response = array(
+                               'server' => $server
+                       );
+
+                               // Build request
+                       if ($this->stripSlash) {
+                               $url = rtrim($url, '/');
+                       }
+                       $request = $server . '/' . ltrim($url, '/');
+                       $response['request'] = $request;
+
+                               // Check for curl functions
+                       if (!function_exists('curl_init')) {
+                                       // TODO: Implement fallback to file_get_contents()
+                                       // TODO: Check TYPO3_CONF_VARS for curl
+                               $response['status'] = t3lib_FlashMessage::ERROR;
+                               $response['message'] = 'No curl_init available';
+                       } else {
+                                       // If no host was given we need to loop over all
+                               $hostArray = array();
+                               if ($host !== '') {
+                                       $hostArray = t3lib_div::trimExplode(',', $host, 1);
+                               } else {
+                                               // Get all (non-redirecting) domains from root
+                                       $rootLine = t3lib_BEfunc::BEgetRootLine($pid);
+                                       foreach ($rootLine as $row) {
+                                               $domainArray = t3lib_BEfunc::getRecordsByField('sys_domain', 'pid', $row['uid'], ' AND redirectTo="" AND hidden=0');
+                                               if (is_array($domainArray) && !empty($domainArray)) {
+                                                       foreach ($domainArray as $domain) {
+                                                               $hostArray[] = $domain['domainName'];
+                                                       }
+                                                       unset($domain);
+                                               }
+                                       }
+                                       unset($row);
+                               }
+
+                                       // Fallback to current server
+                               if (empty($hostArray)) {
+                                       $domain = rtrim(t3lib_div::getIndpEnv('TYPO3_SITE_URL'), '/');
+                                       $hostArray[] = substr($domain, strpos($domain, '://') + 3);
+                               }
+
+                                       // Loop over hosts
+                               foreach ($hostArray as $xHost) {
+                                       $response['host'] = $xHost;
+
+                                               // Curl initialization
+                                       $ch = curl_init();
+
+                                               // Disable direct output
+                                       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+
+                                               // Only get header response
+                                       curl_setopt($ch, CURLOPT_HEADER, 1);
+                                       curl_setopt($ch, CURLOPT_NOBODY, 1);
+
+                                               // Set url
+                                       curl_setopt($ch, CURLOPT_URL, $request);
+
+                                               // Set method and protocol
+                                       curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->httpMethod);
+                                       curl_setopt($ch, CURLOPT_HTTP_VERSION, ($this->httpProtocol === 'http_10') ? CURL_HTTP_VERSION_1_0 : CURL_HTTP_VERSION_1_1);
+
+                                               // Set X-Host header
+                                       curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Host: ' . $xHost));
+
+                                               // Store outgoing header
+                                       curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
+
+                                       $header = curl_exec($ch);
+                                       if (!curl_error($ch)) {
+                                               $response['status'] = (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) ? t3lib_FlashMessage::OK : t3lib_FlashMessage::ERROR;
+                                               $response['message'] = preg_split('/(\r|\n)+/m', trim($header));
+                                       } else {
+                                               $response['status'] = t3lib_FlashMessage::ERROR;
+                                               $response['message'] = curl_error($ch);
+                                       }
+                                       $response['requestHeader'] = preg_split('/(\r|\n)+/m', trim(curl_getinfo($ch, CURLINFO_HEADER_OUT)));
+
+                                       curl_close($ch);
+
+                                               // Log debug information
+                                       $logData = array(
+                                               'url' => $url,
+                                               'pid' => $pid,
+                                               'host' => $host,
+                                               'response' => $response
+                                       );
+                                       $logType = ($response['status'] == t3lib_FlashMessage::OK) ? tx_vcc_service_loggingService::OK : tx_vcc_service_loggingService::ERROR;
+                                       $this->loggingService->log('CommunicationService::processClearCacheCommand', $logData, $logType, $pid, 3);
+
+                                       $responseArray[] = $response;
+                               }
+                               unset($xHost);
+                       }
+               }
+               unset($server);
+
+               return $responseArray;
+       }
+
+       /**
+        * Generates the flash messages for the requests
+        *
+        * @param array $resultArray
+        *
+        * @return string
+        */
+       public function generateBackendMessage(array $resultArray) {
+               $content = '';
+
+               if (is_array($resultArray)) {
+                       foreach ($resultArray as $result) {
+                               switch ($result['status']) {
+                                       case t3lib_FlashMessage::OK:
+                                                       // Extend button marker with messages
+                                               $content .= '<script type="text/javascript">
+                                                       parent.TYPO3.Flashmessage.display(
+                                                               TYPO3.Severity.ok,
+                                                               "Server: ' . $result['server'] . ' // Host: ' . $result['host'] . '",
+                                                               "Request: ' . $result['request'] . '<br />Message: ' . $result['message'][0] . '",
+                                                               5
+                                                       );
+                                               </script>';
+                                               break;
+
+                                       default:
+                                                       // Extend button marker with messages
+                                               $content .= '<script type="text/javascript">
+                                                       parent.TYPO3.Flashmessage.display(
+                                                               TYPO3.Severity.error,
+                                                               "Server: ' . $result['server'] . ' // Host: ' . $result['host'] . '",
+                                                               "Request: ' . $result['request'] . '<br />Message: ' . implode('<br />', $result['message']) . '<br />Sent:<br />' . implode('<br />', $result['requestHeader']) . '",
+                                                               10
+                                                       );
+                                               </script>';
+                                               break;
+                               }
+                       }
+                       unset($result);
+               }
+
+               return $content;
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Service/CommunicationService.php'])  {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Service/CommunicationService.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/Classes/Service/ExtensionSettingService.php b/Classes/Service/ExtensionSettingService.php
new file mode 100644 (file)
index 0000000..41a7d7d
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2012 Nicole Cordes <cordes@cps-it.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Service to handle extension settings
+ *
+ * @author Nicole Cordes <cordes@cps-it.de>
+ * @package TYPO3
+ * @subpackage vcc
+ */
+class tx_vcc_service_extensionSettingService implements t3lib_Singleton {
+
+       const extensionKey = 'vcc';
+
+       /**
+        * @var array
+        */
+       var $configuration = array();
+
+       /**
+        * Initialize the object
+        *
+        * @return void
+        */
+       public function __construct() {
+               $this->configuration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::extensionKey]);
+       }
+
+       /**
+        * Injects the logging service
+        *
+        * @param tx_vcc_service_loggingService $loggingService
+        *
+        * @return void
+        */
+       public function injectLoggingService(tx_vcc_service_loggingService $loggingService) {
+               $this->loggingService = $loggingService;
+       }
+
+       /**
+        * Returns the configuration
+        *
+        * @return array
+        */
+       public function getConfiguration() {
+               return $this->configuration;
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Service/ExtensionSettingService.php'])  {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Service/ExtensionSettingService.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/Classes/Service/LoggingService.php b/Classes/Service/LoggingService.php
new file mode 100644 (file)
index 0000000..abfa15b
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2012 Nicole Cordes <cordes@cps-it.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Service to log requests and responses
+ *
+ * @author Nicole Cordes <cordes@cps-it.de>
+ * @package TYPO3
+ * @subpackage vcc
+ */
+class tx_vcc_service_loggingService implements t3lib_Singleton {
+
+       const OK      = 0;
+       const NOTICE  = 1;
+       const INFO    = 2;
+       const WARNING = 3;
+       const ERROR   = 4;
+       const DEBUG   = 99;
+
+       /**
+        * @var tx_vcc_service_extensionSettingService|NULL
+        */
+       var $extensionSettingService = NULL;
+
+       /**
+        * @var integer
+        */
+       var $debug = 0;
+
+       /**
+        * @var string
+        */
+       var $hash = '';
+
+       /**
+        * Initialize the object
+        *
+        * @return void
+        */
+       public function __construct() {
+               $extensionSettingService = t3lib_div::makeInstance('tx_vcc_service_extensionSettingService');
+               $this->injectExtensionSettingService($extensionSettingService);
+
+               $configuration = $this->extensionSettingService->getConfiguration();
+               $this->debug = $configuration['debug'];
+
+               $this->hash = md5(uniqid('LoggingService', TRUE));
+       }
+
+       /**
+        * Injects the extension setting service
+        *
+        * @param tx_vcc_service_extensionSettingService $extensionSettingService
+        *
+        * @return void
+        */
+       public function injectExtensionSettingService(tx_vcc_service_extensionSettingService $extensionSettingService) {
+               $this->extensionSettingService = $extensionSettingService;
+       }
+
+       /**
+        * @return void
+        */
+       public function log($message, $logData = array(), $type = self::INFO, $pid = 0, $callerDepth = 2, $caller = NULL) {
+                       // Get caller if not already set
+               if ($caller === NULL) {
+                       $caller = $this->getCallerFromBugtrace($callerDepth);
+               }
+
+               $insertArray = array(
+                       'pid' => $pid,
+                       'tstamp' => time(),
+                       'be_user' => $GLOBALS['BE_USER']->user['uid'],
+                       'type' => $type,
+                       'message' => $message,
+                       'log_data' => serialize($logData),
+                       'caller' => serialize($caller),
+                       'hash' => $this->hash
+               );
+               $GLOBALS['TYPO3_DB']->exec_INSERTquery('tx_vcc_log', $insertArray);
+       }
+
+       /**
+        * @return void
+        */
+       public function debug($message, $logData = array(), $pid = 0, $callerDepth = 2, $caller = NULL) {
+               if ($this->debug) {
+                               // Adjust callerDepth due to debug function
+                       $callerDepth++;
+                       $this->log($message, $logData, self::DEBUG, $pid, $callerDepth, $caller);
+               }
+       }
+
+       /**
+        * @param integer $callerDepth
+        *
+        * @return array
+        */
+       protected function getCallerFromBugtrace($callerDepth) {
+                       // Get trace array
+               $trace = debug_backtrace();
+
+                       // Adjust callerDepth due to separate function
+               $callerDepth++;
+               if (isset($trace[$callerDepth])) {
+                       return $trace[$callerDepth];
+               }
+
+               return array();
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Service/LoggingService.php'])  {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Service/LoggingService.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/Classes/Service/TsConfigService.php b/Classes/Service/TsConfigService.php
new file mode 100644 (file)
index 0000000..880335d
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2012 Nicole Cordes <cordes@cps-it.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Service to handle TSConfig settings
+ *
+ * @author Nicole Cordes <cordes@cps-it.de>
+ * @package TYPO3
+ * @subpackage vcc
+ */
+class tx_vcc_service_tsConfigService implements t3lib_Singleton {
+
+       /**
+        * @var tx_vcc_service_loggingService|NULL
+        */
+       var $loggingService = NULL;
+
+       /**
+        * @var array
+        */
+       var $configurationArray = array();
+
+       /**
+        * Initialize the object
+        *
+        * @return void
+        */
+       public function __construct() {
+               $loggingService = t3lib_div::makeInstance('tx_vcc_service_loggingService');
+               $this->injectLoggingService($loggingService);
+       }
+
+       /**
+        * Injects the logging service
+        *
+        * @param tx_vcc_service_loggingService $loggingService
+        *
+        * @return void
+        */
+       public function injectLoggingService(tx_vcc_service_loggingService $loggingService) {
+               $this->loggingService = $loggingService;
+       }
+
+       /**
+        * Returns the configuration
+        *
+        * @param integer $id
+        *
+        * @return array
+        */
+       public function getConfiguration($id) {
+               if (!isset($this->configurationArray[$id])) {
+                       $modTsConfig = t3lib_BEfunc::getModTSconfig($id, 'mod.vcc');
+                       $this->configurationArray[$id] = $modTsConfig['properties'];
+
+                               // Log debug information
+                       $logData = array(
+                               'id' => $id,
+                               'configuration' => $modTsConfig['properties']
+                       );
+                       $this->loggingService->debug('TsConfigService::getConfiguration id: ' . $id, $logData);
+               }
+
+               return $this->configurationArray[$id];
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Service/TsConfigService.php'])  {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/vcc/Classes/Service/TsConfigService.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/Resources/Public/Icons/CachePlugin.png b/Resources/Public/Icons/CachePlugin.png
new file mode 100644 (file)
index 0000000..29f32d7
Binary files /dev/null and b/Resources/Public/Icons/CachePlugin.png differ
diff --git a/ext_autoload.php b/ext_autoload.php
new file mode 100644 (file)
index 0000000..925a846
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+       $extensionPath = t3lib_extMgm::extPath('vcc') . 'Classes/';
+
+       return array(
+               'tx_vcc_service_communicationservice' => $extensionPath . 'Service/CommunicationService.php',
+               'tx_vcc_service_extensionsettingservice' => $extensionPath . 'Service/ExtensionSettingService.php',
+               'tx_vcc_service_loggingservice' => $extensionPath . 'Service/LoggingService.php',
+               'tx_vcc_service_tsconfigservice' => $extensionPath . 'Service/TsConfigService.php',
+       );
+?>
\ No newline at end of file
diff --git a/ext_conf_template.txt b/ext_conf_template.txt
new file mode 100644 (file)
index 0000000..f8d0829
--- /dev/null
@@ -0,0 +1,14 @@
+# cat=basic/enable/010; type=string; label=Varnish Server: Enter a comma separated list with IP addresses of your Varnish servers.\r
+server = 127.0.0.1\r
+\r
+# cat=basic/enable/020; type=string; label=HTTP ban method: HTTP method to send to the Varnish server to invalidate cache (ban).\r
+httpMethod = BAN\r
+\r
+# cat=basic/enable/030; type=options[HTTP/1.0=http_10,HTTP/1.1=http_11]; label=HTTP protocol: The HTTP protocol to use for the HTTP method.\r
+httpProtocol = http_11\r
+\r
+# cat=basic/enable/040; type=boolean; label=Strip slash: Strip appended slash in requested url to be able to adjust right behaviour in Varnish vcl configuration\r
+stripSlash = 0\r
+\r
+# cat=basic/enable/050; type=boolean; label=Debug mode: Enable debug mode to log additional information\r
+debug = 0
\ No newline at end of file
diff --git a/ext_emconf.php b/ext_emconf.php
new file mode 100644 (file)
index 0000000..0f89975
--- /dev/null
@@ -0,0 +1,49 @@
+<?php
+
+/***************************************************************
+ * Extension Manager/Repository config file for ext "vcc".
+ *
+ * Auto generated 03-01-2013 09:11
+ *
+ * Manual updates:
+ * Only the data in the array - everything else is removed by next
+ * writing. "version" and "dependencies" must not be touched!
+ ***************************************************************/
+
+$EM_CONF[$_EXTKEY] = array(
+       'title' => 'Varnish Cache Control',
+       'description' => 'Extension to clear Varnish cache on demand',
+       'author' => 'Nicole Cordes',
+       'author_email' => 'cordes@cps-it.de',
+       'author_company' => 'CPS-IT',
+       'category' => 'module',
+       'constraints' => array(
+               'depends' => array(
+                       'cms' => '',
+                       'php' => '5.2.0-0.0.0',
+                       'typo3' => '4.5.0-4.7.99',
+               ),
+               'conflicts' => array(
+               ),
+               'suggests' => array(
+               ),
+       ),
+       'dependencies' => 'cms',
+       'module' => '',
+       'state' => 'alpha',
+       'version' => '0.1.0',
+       'clearCacheOnLoad' => 0,
+       'createDirs' => '',
+       'internal' => '',
+       'lockType' => '',
+       'modify_tables' => '',
+       'priority' => '',
+       'shy' => '',
+       'uploadfolder' => 0,
+       '_md5_values_when_last_written' => 'a:54:{s:12:"ext_icon.gif";s:4:"402e";s:17:"ext_localconf.php";s:4:"c217";s:14:"ext_tables.php";s:4:"2cb5";s:14:"ext_tables.sql";s:4:"f285";s:21:"ExtensionBuilder.json";s:4:"ebfe";s:38:"Classes/Controller/ImageController.php";s:4:"7006";s:33:"Classes/Domain/Model/Category.php";s:4:"44eb";s:30:"Classes/Domain/Model/Image.php";s:4:"3af2";s:48:"Classes/Domain/Repository/CategoryRepository.php";s:4:"d78d";s:45:"Classes/Domain/Repository/ImageRepository.php";s:4:"2bc2";s:42:"Classes/ViewHelpers/VsprintfViewHelper.php";s:4:"f027";s:51:"Classes/ViewHelpers/Image/OrientationViewHelper.php";s:4:"c9b8";s:49:"Classes/ViewHelpers/Widget/PaginateViewHelper.php";s:4:"a508";s:60:"Classes/ViewHelpers/Widget/Controller/PaginateController.php";s:4:"756c";s:44:"Configuration/ExtensionBuilder/settings.yaml";s:4:"9825";s:41:"Configuration/FlexForms/ImageDatabase.xml";s:4:"03a8";s:30:"Configuration/TCA/Category.php";s:4:"6fac";s:27:"Configuration/TCA/Image.php";s:4:"3058";s:38:"Configuration/TypoScript/constants.txt";s:4:"e2ae";s:34:"Configuration/TypoScript/setup.txt";s:4:"459d";s:40:"Resources/Private/Language/locallang.xml";s:4:"a3b6";s:43:"Resources/Private/Language/locallang_be.xml";s:4:"3b39";s:80:"Resources/Private/Language/locallang_csh_tx_bmuimagedb_domain_model_category.xml";s:4:"a9ee";s:77:"Resources/Private/Language/locallang_csh_tx_bmuimagedb_domain_model_image.xml";s:4:"ba09";s:43:"Resources/Private/Language/locallang_db.xml";s:4:"b50d";s:50:"Resources/Private/Language/locallang_flexforms.xml";s:4:"037a";s:38:"Resources/Private/Layouts/Default.html";s:4:"9ca6";s:41:"Resources/Private/Partials/Links/Add.html";s:4:"8bf8";s:48:"Resources/Private/Partials/Links/Collection.html";s:4:"7c67";s:42:"Resources/Private/Partials/Links/List.html";s:4:"2853";s:47:"Resources/Private/Partials/Links/Icons/Add.html";s:4:"e71b";s:50:"Resources/Private/Partials/Links/Icons/Delete.html";s:4:"5a61";s:52:"Resources/Private/Partials/Links/Icons/Download.html";s:4:"c026";s:48:"Resources/Private/Partials/Links/Icons/Show.html";s:4:"7283";s:42:"Resources/Private/Partials/List/Image.html";s:4:"722b";s:42:"Resources/Private/Templates/Image/Add.html";s:4:"712d";s:49:"Resources/Private/Templates/Image/Collection.html";s:4:"a3fc";s:43:"Resources/Private/Templates/Image/List.html";s:4:"e87e";s:43:"Resources/Private/Templates/Image/Show.html";s:4:"5bc5";s:66:"Resources/Private/Templates/ViewHelpers/Widget/Paginate/Index.html";s:4:"aa05";s:42:"Resources/Public/Icons/2012_link_arrow.png";s:4:"4849";s:38:"Resources/Public/Icons/bdb_ansicht.gif";s:4:"14f8";s:39:"Resources/Public/Icons/bdb_bild_300.gif";s:4:"5806";s:38:"Resources/Public/Icons/bdb_bild_72.gif";s:4:"7a0b";s:39:"Resources/Public/Icons/bdb_loeschen.gif";s:4:"10d4";s:39:"Resources/Public/Icons/bdb_sammlung.gif";s:4:"a89a";s:41:"Resources/Public/Icons/bdb_uebersicht.gif";s:4:"4ad2";s:35:"Resources/Public/Icons/relation.gif";s:4:"e615";s:62:"Resources/Public/Icons/tx_bmuimagedb_domain_model_category.gif";s:4:"e117";s:59:"Resources/Public/Icons/tx_bmuimagedb_domain_model_image.gif";s:4:"d556";s:44:"Resources/Public/Stylesheets/bmu_imagedb.css";s:4:"7078";s:45:"Tests/Unit/Controller/ImageControllerTest.php";s:4:"79c5";s:37:"Tests/Unit/Domain/Model/ImageTest.php";s:4:"8c7c";s:14:"doc/manual.sxw";s:4:"8d2d";}',
+       'suggests' => array(
+       ),
+       'conflicts' => '',
+);
+
+?>
\ No newline at end of file
diff --git a/ext_icon.gif b/ext_icon.gif
new file mode 100644 (file)
index 0000000..8b9f000
Binary files /dev/null and b/ext_icon.gif differ
diff --git a/ext_localconf.php b/ext_localconf.php
new file mode 100644 (file)
index 0000000..8d1ca54
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+if (!defined('TYPO3_MODE')) {
+       die ('Access denied.');
+}
+
+if (TYPO3_MODE == 'BE') {
+               // Register hook to add the cache clear button to configured items in different views
+       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['docHeaderButtonsHook']['vcc'] =
+               'EXT:vcc/Classes/Hook/DocHeaderButtonsHook.php:tx_vcc_hook_docHeaderButtonsHook->addButton';
+}
+
+?>
\ No newline at end of file
diff --git a/ext_tables.php b/ext_tables.php
new file mode 100644 (file)
index 0000000..ed52731
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+if (!defined('TYPO3_MODE')) {
+       die ('Access denied.');
+}
+
+       // Register sprite icons
+$icons = array(
+       'clearVarnishCache' => t3lib_extMgm::extRelPath('vcc') . 'Resources/Public/Icons/CachePlugin.png',
+);
+t3lib_SpriteManager::addSingleIcons($icons, 'vcc');
+
+       // Add default module settings
+t3lib_extMgm::addPageTSConfig('
+mod.vcc {
+       pages = 1
+       pages {
+               typolink {
+                       parameter.field = uid
+               }
+       }
+
+       pages_language_overlay = 1
+       pages_language_overlay {
+               typolink {
+                       parameter.field = pid
+                       additionalParams = &L={field:sys_language_uid}
+                       additionalParams.insertData = 1
+               }
+       }
+
+       tt_content = 1
+       tt_content {
+               typolink {
+                       parameter.field = pid
+                       additionalParams = &L={field:sys_language_uid}
+                       additionalParams.insertData = 1
+               }
+       }
+}
+');
+
+?>
\ No newline at end of file
diff --git a/ext_tables.sql b/ext_tables.sql
new file mode 100644 (file)
index 0000000..9d57556
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Table structure for table 'tx_vcc_log'
+#
+CREATE TABLE tx_vcc_log (
+       uid int(11) NOT NULL auto_increment,
+       pid int(11) unsigned DEFAULT '0' NOT NULL,
+
+       tstamp int(11) unsigned DEFAULT '0' NOT NULL,
+       be_user int(11) unsigned DEFAULT '0' NOT NULL,
+
+       type tinyint(4) unsigned DEFAULT '0' NOT NULL,
+       message text NOT NULL,
+       log_data text NOT NULL,
+
+       caller varchar(255) DEFAULT '' NOT NULL,
+       hash varchar(255) DEFAULT '' NOT NULL,
+
+       PRIMARY KEY (uid),
+       KEY parent (pid),
+       KEY hash (hash)
+);
\ No newline at end of file