/** * Test whether singleton, session singleton, and application singleton caches * are not interfering. See issue ID#286 for details. */ public function testCacheBoundaries() { $singletonCache = new ReflectionProperty(Singleton::class, 'CACHE'); $singletonCache->setAccessible(true); $singletonCache->setValue(null, []); $sessionSingletonCache = new ReflectionProperty(SessionSingleton::class, 'CACHE'); $sessionSingletonCache->setAccessible(true); $sessionSingletonCache->setValue(null, []); $applicationSingletonCache = new ReflectionProperty(ApplicationSingleton::class, 'CACHE'); $applicationSingletonCache->setAccessible(true); $applicationSingletonCache->setValue(null, []); // test singleton instance is created in singleton cache only Singleton::getInstance(TagModel::class); $this->assertCount(1, $singletonCache->getValue(null)); $this->assertCount(0, $sessionSingletonCache->getValue(null), 'Session singleton cache should be empty!'); $this->assertCount(0, $applicationSingletonCache->getValue(null), 'Application singleton cache should be empty!'); // test session singleton instance is created in singleton cache only SessionSingleton::getInstance(TagModel::class); $value = $singletonCache->getValue(null); $this->assertCount(2, $value); // 1=TagModel, 2=HttpRequestImpl (session singleton uses request -> session!) $this->assertEquals(TagModel::class, get_class($value[array_keys($value)[0]])); $this->assertEquals(RequestImpl::class, get_class($value[array_keys($value)[1]])); $this->assertCount(1, $sessionSingletonCache->getValue(null)); $this->assertCount(0, $applicationSingletonCache->getValue(null), 'Application singleton cache should be empty!'); // test application instance is created in singleton cache only ApplicationSingleton::getInstance(TagModel::class); $this->assertCount(2, $singletonCache->getValue(null)); $this->assertCount(1, $sessionSingletonCache->getValue(null)); $this->assertCount(1, $applicationSingletonCache->getValue(null)); }
/** * Loads a paged entry list. * * @return Entry[] The paged entry list. * * @author Christian Achatz * @version * Version 0.1, 21.05.2009<br /> */ public function loadPagedEntryList() { /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); $t->start('loadPagedEntryList'); $pager = $this->getPager(); $entryIds = $pager->loadEntries(['GuestbookID' => $this->getModel()->getGuestbookId()]); $entries = []; $mapper = $this->getMapper(); foreach ($entryIds as $entryId) { $entries[] = $mapper->loadEntry($entryId); } $t->stop('loadPagedEntryList'); return $entries; }
public function testMixedInstanceIdCreation() { Singleton::deleteInstance(self::SERVICE_CLASS, self::INSTANCE_ID); $paramOne = 'one'; $paramTwo = 'two'; /* @var $service DummyService */ $service = ServiceManager::getServiceObject(self::SERVICE_CLASS, self::CONTEXT, self::LANGUAGE, [$paramOne, $paramTwo], APFService::SERVICE_TYPE_SINGLETON, self::INSTANCE_ID); $this->assertEquals(self::CONTEXT, $service->getContext()); $this->assertEquals(self::LANGUAGE, $service->getLanguage()); $this->assertEquals(APFService::SERVICE_TYPE_SINGLETON, $service->getServiceType()); $this->assertEquals($paramOne, $service->getParamOne()); $this->assertEquals($paramTwo, $service->getParamTwo()); $service = ServiceManager::getServiceObject(self::SERVICE_CLASS, self::CONTEXT, self::LANGUAGE); $this->assertNotEquals($paramOne, $service->getParamOne()); $this->assertNotEquals($paramTwo, $service->getParamTwo()); /* @var $service DummyService */ $service = ServiceManager::getServiceObject(self::SERVICE_CLASS, self::CONTEXT, self::LANGUAGE, [], APFService::SERVICE_TYPE_SINGLETON, self::INSTANCE_ID); $this->assertEquals($paramOne, $service->getParamOne()); $this->assertEquals($paramTwo, $service->getParamTwo()); }
/** * Returns a service object according to the current application context. * * @param string $class Fully qualified class name of the service object. * @param string $context The application context, the service object belongs to. * @param string $language The language, the service object has. * @param array $arguments A list of constructor arguments to create the service instance with. * @param string $type The initializing type (see service manager for details). * @param string $instanceId The id of the instance to return. * * @return APFService The desired service object. * @throws InvalidArgumentException In case of invalid ServiceType or if requested service does not implement the APFService interface. * * @author Christian Schäfer * @version * Version 0.1, 07.03.2007<br /> * Version 0.2, 17.03.2007 (Adjusted error messages)<br /> * Version 0.3, 22.04.2007 (Language is now injected)<br /> * Version 0.4, 24.02.2008 (Added SessionSingleton service type)<br /> * Version 0.5, 25.02.2008 (Added performance optimization for the SessionSingleton objects)<br /> * Version 0.6, 10.08.2009 (Added lazy import, so that the developer must not care about the inclusion of the component.)<br /> * Version 0.7, 04.03.2011 (Refactored to static method; enhanced code)<br /> * Version 0.8, 07.07.2012 Jan Wiese <*****@*****.**> (Corrected service retrieval to respect context and language each time.)<br /> * Version 0.9, 23.07.2013 (Added "APPLICATIONSINGLETON" object creation mechanism.)<br /> */ public static function &getServiceObject($class, $context, $language, array $arguments = [], $type = APFService::SERVICE_TYPE_SINGLETON, $instanceId = null) { // Introduce generated instance key to create services with respect to the context. // In 1.15, creating instances of the same service implementation within different contexts // resulted in equal instances instead of different ones. // In 2.0 language has been removed from the instance id since within multi-language applications // you want to re-use the instance throughout different languages! if ($instanceId === null) { $instanceId = $class . '|' . $context; } $service = null; switch ($type) { case APFService::SERVICE_TYPE_SINGLETON: $service = Singleton::getInstance($class, $arguments, $instanceId); break; case APFService::SERVICE_TYPE_SESSION_SINGLETON: $service = SessionSingleton::getInstance($class, $arguments, $instanceId); break; case APFService::SERVICE_TYPE_APPLICATION_SINGLETON: $service = ApplicationSingleton::getInstance($class, $arguments, $instanceId); break; case APFService::SERVICE_TYPE_NORMAL: if (count($arguments) > 0) { $service = (new ReflectionClass($class))->newInstanceArgs($arguments); } else { $service = new $class(); } break; default: throw new InvalidArgumentException('[ServiceManager::getServiceObject()] The given type (' . $type . ') is not supported. Please provide one out of "' . APFService::SERVICE_TYPE_SINGLETON . '", "' . APFService::SERVICE_TYPE_SESSION_SINGLETON . '" or "' . APFService::SERVICE_TYPE_NORMAL . '"', E_USER_WARNING); } // inject the basic set of information to the APF style service if ($service instanceof APFService) { $service->setContext($context); $service->setLanguage($language); $service->setServiceType($type); } else { throw new InvalidArgumentException('[ServiceManager::getServiceObject()] The precisely ' . 'now created object (' . $class . ') does not implement the APFService interface! ' . 'So context, language and service type cannot be set correctly!', E_USER_WARNING); } return $service; }
/** * Creates a list of pager pages and returns it. * * @param string[] $addStmtParams list of additional statement params * * @return Page[] List of pages. * * @author Christian Achatz * @version * Version 0.1, 05.08.2006<br /> * Version 0.2, 06.08.2006<br /> * Version 0.3, 14.08.2006 (Added a global configuration for url rewriting)<br /> * Version 0.4, 16.11.2007 (Switched to the FrontcontrollerLinkHandler)<br /> * Version 0.5, 26.04.2008 (Avoid division by zero)<br /> * Version 0.6, 19.01.2009 (Changed the implementation due to refactoring)<br /> * Version 0.7, 10.04.2011 (Switched to LinkGenerator due to new link generation concept in 1.14)<br /> */ private function createPages4PagerDisplay($addStmtParams = []) { /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); $t->start('PagerManager::createPages4PagerDisplay()'); // initialize start params $start = (int) 1; $countPerPage = $this->getCountPerPage(); $currentStart = (int) $this->getRequest()->getParameter($this->pageUrlParameterName, 1) * $countPerPage; // initialize page delimiter params $m = $this->getMapper(); $entriesCount = $m->getEntriesCount($this->statementNamespace, $this->countStatementFile, $this->getStatementParams($addStmtParams), $this->cacheInSession === 'true'); $pageCount = ceil($entriesCount / $countPerPage); // create the page representation objects /* @var $pages PageItem[] */ $pages = []; for ($i = 0; $i < $pageCount; $i++) { // create a new pager page object $pages[$i] = new PageItem(); // generate the link $link = LinkGenerator::generateUrl(Url::fromCurrent()->mergeQuery([$this->pageUrlParameterName => $start])); $pages[$i]->setLink($link); // set the number of the page $pages[$i]->setPage($i + 1); // mark as selected if ($start === $currentStart / $countPerPage) { $pages[$i]->setSelected(true); } // add the entries count $pages[$i]->setEntriesCount($entriesCount); // add the page count $pages[$i]->setPageCount($pageCount); $start++; } $t->stop('PagerManager::createPages4PagerDisplay()'); return $pages; }
/** * @return ResponseImpl The response implementation. */ protected static function &getResponseStatic() { return Singleton::getInstance(Frontcontroller::$responseImplClass); }
/** * Returns a list of the object ids, that should be loaded for the current page. * * @param string $namespace the namespace of the statement * @param string $statement the name of the statement file * @param array $params additional params for the statement * @param bool $cache decides if caching is active or not (true = yes, false = no) * * @return array $entries a list of entry ids * * @author Christian Achatz * @version * Version 0.1, 05.08.2006<br /> * Version 0.2, 19.01.2009 (Added the connection key handling)<br /> * Version 0.3, 24.01.2009 (Added session caching)<br /> * Version 0.4, 25.01.2009 (Removed null pointer bug due to session object definition)<br /> * Version 0.5, 27.12.2010 (Bug-fix: In case of empty results, no empty objects are returned any more.)<br /> */ public function loadEntries($namespace, $statement, array $params = [], $cache = true) { $t = Singleton::getInstance(BenchmarkTimer::class); /* @var $t BenchmarkTimer */ $t->start('PagerMapper::loadEntries()'); $params = $this->sanitizeParameters($params); // try to load the entries count from the session $session = null; $sessionKey = null; if ($cache === true) { $session = $this->getSession(); $sessionKey = $this->getSessionKey($namespace, $statement, $params) . '_EntryIDs'; $entryIds = $session->load($sessionKey); } else { $entryIds = null; } // load from database if not in session if ($entryIds === null) { $conn = $this->getConnection(); $result = $conn->executeStatement($namespace, $statement, $params); // map empty results to empty array if ($result === false) { return []; } $entryIds = []; while ($data = $conn->fetchData($result)) { $entryIds[] = $data['DB_ID']; } // only save to session, when cache is enabled if ($cache === true) { $session->save($sessionKey, serialize($entryIds)); } } else { $entryIds = unserialize($entryIds); } $t->stop('PagerMapper::loadEntries()'); return $entryIds; }
/** * Executes a statement provided using mysqli's bind feature. * * @param string $statement The statement to execute. * @param array $params A list of statement parameters. * @param boolean $logStatement Indicates, if the statement is logged for debug purposes. * * @return resource The execution result. * @throws DatabaseHandlerException In case the bind param mapping is wrong. * * @author Christian Achatz * @version * Version 0.1, 08.03.2010<br /> */ public function executeTextBindStatement($statement, array $params = [], $logStatement = false) { /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); $statementId = md5($statement); // prepare statement $id = $statementId . ' prepare statement'; $t->start($id); $query = $this->createQuery($statement); $t->stop($id); // bind params $id = $statementId . ' bind params'; $t->start($id); // additional check, because bind param count errors do not result in an exception! $paramStatementCount = substr_count($statement, '?'); $paramCount = count($params); if ($paramStatementCount != $paramCount) { throw new DatabaseHandlerException('[MySQLiHandler->executeTextBindStatement()] Number ' . 'of given params (' . $paramCount . ') does not match number of bind params ' . 'within the statement (' . $paramStatementCount . ')! Current statement: ' . $statement, E_USER_ERROR); } $this->bindParams($query, $params); $t->stop($id); // log statements in debug mode or when requested explicitly if ($this->dbDebug === true || $logStatement === true) { $this->dbLog->logEntry($this->dbLogTarget, '[MySQLiHandler::executeTextBindStatement()] Current statement: ' . $statement, LogEntry::SEVERITY_DEBUG); } // execute statement $id = $statementId . ' execute'; $t->start($id); $query->execute(); // track $lastInsertId fur further usage $this->lastInsertId = $query->insert_id; $t->stop($id); // fetch the result set using the meta data returned by the query $id = $statementId . ' fetch'; $t->start($id); $statementResult = $this->fetchBindResult($query); $t->stop($id); // remember affected rows $this->bindNumRows = $query->num_rows; $query->free_result(); $query->close(); return $statementResult; }
* The APF 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the APF. If not, see http://www.gnu.org/licenses/lgpl-3.0.txt. * --> */ namespace APF\modules\usermanagement\pres; use APF\core\benchmark\BenchmarkTimer; use APF\core\frontcontroller\Frontcontroller; use APF\core\singleton\Singleton; /** * @file umgt.php * This file represents a bootstrap file to operate the usermanagement module. */ // include the pagecontroller (change the path to what ever you want) include_once './APF/core/bootstrap.php'; // create the front controller instance /* @var $fC Frontcontroller */ $fC = Singleton::getInstance(Frontcontroller::class); // set the current context (change the context to what ever you want) $fC->setContext('...'); // start the front controller $fC->start('APF\\modules\\usermanagement\\pres\\templates', 'main'); // create the benchmark report /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); echo $t->createReport();
/** * Implements an initializer method to setup derived classes using the * DIServiceManager. * * @author Christian Achatz * @version * Version 0.1, 07.05.2012<br /> */ public function setup() { $this->dbLog = Singleton::getInstance(Logger::class); $this->connect(); }
/** * Creates a log entry containing the exception occurred. * * @author Christian Achatz * @version * Version 0.1, 21.02.2009<br /> */ protected function logException() { $message = '[' . $this->generateExceptionID() . '] ' . $this->exceptionMessage . ' (Number: ' . $this->exceptionNumber . ', File: ' . $this->exceptionFile . ', Line: ' . $this->exceptionLine . ')'; $log = Singleton::getInstance(Logger::class); /* @var $log Logger */ $log->addEntry(new SimpleLogEntry(Registry::retrieve('APF\\core', 'InternalLogTarget'), $message, LogEntry::SEVERITY_ERROR)); }
error_reporting(E_ALL); ini_set('display_errors', '1'); ini_set('html_errors', 'off'); // register the APF error handler to be able to easily configure the error handling mechanism GlobalErrorHandler::registerErrorHandler(new DefaultErrorHandler()); GlobalErrorHandler::enable(); // Define base parameters of the framework's core and tools layer Registry::register('APF\\core', 'Environment', 'DEFAULT'); Registry::register('APF\\core', 'InternalLogTarget', 'apf'); Registry::register('APF\\core', 'Charset', 'UTF-8'); // set up configuration provider to let the developer customize it later on ConfigurationManager::registerProvider('ini', new IniConfigurationProvider()); // configure logger (outside namespace'd file! otherwise initialization will not work) register_shutdown_function(function () { /* @var $logger Logger */ $logger = Singleton::getInstance(Logger::class); $logger->flushLogBuffer(); }); // Set up default link scheme configuration. In case url rewriting is required, please // specify another link scheme within your application bootstrap file. LinkGenerator::setLinkScheme(new DefaultLinkScheme()); // Add the front controller filter that is a wrapper on the front controller's input // filters concerning thr url rewriting configuration. In case rewriting is required, // please specify another input filter within your application bootstrap file according // to your url mapping requirements (e.g. use the ChainedUrlRewritingInputFilter included // within the APF). // As shipped, the APF does not define an output filter since "normal" url handling // does not require rewriting. In case rewriting is required, please specify another output // filter according to your url mapping requirements (e.g. use the ChainedUrlRewritingOutputFilter // included within the APF). InputFilterChain::getInstance()->appendFilter(new ChainedStandardInputFilter());
public function filter(FilterChain &$chain, $input = null) { /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); $id = get_class($this); $t->start($id); $input = preg_replace_callback('/<form (.*?)action="(.*?)"(.*?)>(.*?)<\\/form>/ims', [ChainedUrlRewritingOutputFilter::class, 'replaceForm'], preg_replace_callback('/<a (.*?)href="(.*?)"(.*?)>(.*?)<\\/a>/ims', [ChainedUrlRewritingOutputFilter::class, 'replaceLink'], $input)); $t->stop($id); // delegate filtering to the applied chain return $chain->filter($input); }
public function testInstanceWithIdDeletion() { /* @var $model TagModel */ Singleton::getInstance(self::MODEL_CLASS, [self::TEST_TAG], self::INSTANCE_ID); $model = Singleton::getInstance(self::MODEL_CLASS, [], self::INSTANCE_ID); $this->assertNotNull($model->getTag()); Singleton::deleteInstance(self::MODEL_CLASS, self::INSTANCE_ID); $model = Singleton::getInstance(self::MODEL_CLASS, [], self::INSTANCE_ID); $this->assertNull($model->getTag()); }
/** * Generates the bookmark bar HTML code. * * @return string HTML code of the configured bookmarks. * * @author Christian W. Schäfer * @version * Version 0.1, 02.06.2007<br /> * Version 0.2, 07.09.2007<br /> * Version 0.3, 08.09.2007 (Added profiling)<br /> */ public function getBookmarkCode() { /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); $id = 'SocialBookmarkBarManager::getBookmarkCode()'; $t->start($id); // generate the current page's url, if no url was set if (empty($this->url)) { $this->url = LinkGenerator::generateUrl(Url::fromCurrent(true)); } // get services from config file $services = $this->getConfiguration('APF\\modules\\socialbookmark', 'bookmarkservices.ini'); foreach ($services->getSectionNames() as $serviceName) { $service = $services->getSection($serviceName)->getSection('BookmarkService'); $this->bookmarkServices[] = new SocialBookmarkItem($service->getValue('BaseURL'), $service->getSection('Param')->getValue('URL'), $service->getSection('Param')->getValue('Title'), $service->getSection('Display')->getValue('Title'), $service->getSection('Display')->getValue('Image'), $service->getSection('Display')->getValue('ImageExt')); } $output = (string) ''; for ($i = 0; $i < count($this->bookmarkServices); $i++) { $output .= $this->generateBookmarkEntry($this->bookmarkServices[$i]); $output .= PHP_EOL; } $t->stop($id); return $output; }
public function transformContent() { $form = $this->getForm('register'); if ($form->isSent() && $form->isValid()) { $uM = $this->getManager(); $user = new UmgtUser(); $firstName = $form->getFormElementByName('firstname'); $firstNameValue = $firstName->getValue(); $user->setFirstName($firstNameValue); $lastName = $form->getFormElementByName('lastname'); $lastNameValue = $lastName->getValue(); $user->setLastName($lastNameValue); $street = $form->getFormElementByName('street'); $user->setStreetName($street->getValue()); $number = $form->getFormElementByName('number'); $user->setStreetNumber($number->getValue()); $zip = $form->getFormElementByName('zip'); $user->setZIPCode($zip->getValue()); $city = $form->getFormElementByName('city'); $user->setCity($city->getValue()); $email = $form->getFormElementByName('email'); $user->setEMail($email->getValue()); $userName = $form->getFormElementByName('username'); $userNameValue = $userName->getValue(); $user->setUsername($userNameValue); $password = $form->getFormElementByName('password'); $user->setPassword($password->getValue()); // assemble display name to have a more readable user within the umgt mgmt UI if (empty($firstNameValue) && empty($lastNameValue)) { $user->setDisplayName($userNameValue); } else { $user->setDisplayName($lastNameValue . ', ' . $firstNameValue); } // add initial groups and roles if applicable try { foreach ($this->getInitialGroups() as $initialGroup) { $user->addGroup($initialGroup); } foreach ($this->getInitialRoles() as $initialRole) { $user->addRole($initialRole); } } catch (ConfigurationException $e) { $l = Singleton::getInstance(Logger::class); /* @var $l Logger */ $l->logEntry('registration', 'Registration cannot add initial groups or roles due to the following ' . 'exception: ' . $e . ' This may be ok, in case you have no initial groups and/or roles specified.', LogEntry::SEVERITY_INFO); } try { // Lets have a look if the username/email is always in use and show an error message try { $config = $this->getConfiguration('APF\\modules\\usermanagement\\pres', 'login.ini'); $loginType = $config->getSection('Default')->getValue('login.type', 'username'); } catch (ConfigurationException $e) { $loginType = 'username'; } if ($loginType === 'username') { $regUser = $uM->loadUserByUserName($userNameValue); } else { $regUser = $uM->loadUserByEMail($email->getValue()); } if ($regUser === null) { $uM->saveUser($user); $this->getTemplate('register-ok')->transformOnPlace(); } else { $form->setPlaceHolder('register-error', $this->getTemplate('register-error-user-already-exists')->transformTemplate()); $form->transformOnPlace(); } } catch (Exception $e) { $this->getTemplate('system-error')->transformOnPlace(); $l = Singleton::getInstance(Logger::class); /* @var $l Logger */ $l->logEntry('registration', 'Registration is not possible due to ' . $e, LogEntry::SEVERITY_ERROR); } } elseif ($form->isSent() && !$form->isValid()) { $form->setPlaceHolder('register-error', $this->getTemplate('register-error')->transformTemplate()); $form->transformOnPlace(); } else { $form->transformOnPlace(); } }
/** * Returns the initialized service object. * * @param string $configNamespace The namespace of the service object. * @param string $sectionName The name of the desired service object. * @param string $context The context of the current application. * @param string $language The language of the current application. * * @return APFDIService The pre-configured service object. * @throws ConfigurationException In case the requested service is not existent. * @throws InvalidArgumentException In case of injection issues. * * @author Christian Achatz * @version * Version 0.1, 19.04.2009<br /> * Version 0.2, 24.08.2011 (Added "setupmethod" functionality)<br/> * Version 0.3, 07.07.2012 Jan Wiese (Corrected service retrieval to respect context and language each time.<br /> * Introduced CACHED service type to retrieve a NORMAL instance from the cache and thus gain performance for none-singletons.)<br /> * Version 0.4, 10.07.2012 Jan Wiese (Introduced configuration cache to gain performance)<br /> * Version 0.5, 10.07.2012 Jan Wiese (Improvements in code quality and removed bugs from v0.3/v0.4)<br /> */ public static function &getServiceObject($configNamespace, $sectionName, $context, $language) { // build cache key. because configuration-file path includes context, include context (and language) in cache key // In 2.0 language has been removed from the instance id since within multi-language applications // you want to re-use the instance throughout different languages! $cacheKey = $configNamespace . '|' . $sectionName . '|' . $context; // Check, whether service object was created before. If yes, deliver it from cache for all services types except NORMAL. // Do not cache ServiceType 'NORMAL' because we want to have different instances! if (isset(self::$SERVICE_OBJECT_CACHE[$cacheKey]) && self::$SERVICE_TYPE_CACHE[$cacheKey] != APFService::SERVICE_TYPE_NORMAL) { return self::$SERVICE_OBJECT_CACHE[$cacheKey]; } // Invoke benchmarker. Suppress warning for already started timers with circular calls! // Suppressing is here done by a dirty '@', because we will run into an error anyway. $t = Singleton::getInstance(BenchmarkTimer::class); /* @var $t BenchmarkTimer */ $benchId = 'DIServiceManager::getServiceObject(' . $configNamespace . ',' . $sectionName . ',' . $context . ',' . $language . ')'; @$t->start($benchId); // Get config to determine, which object to create. $config = self::getServiceConfiguration($configNamespace, $context, $language, $cacheKey); if (!$config->hasSection($sectionName)) { throw new ConfigurationException('[DIServiceManager::getServiceObject()] Service object configuration with ' . 'name "' . $sectionName . '" cannot be found within namespace "' . $configNamespace . '"! Please double-check your setup.', E_USER_ERROR); } $section = $config->getSection($sectionName); // check, whether the section contains the basic directives and read/write service type cache if (isset(self::$SERVICE_TYPE_CACHE[$cacheKey])) { $serviceType = self::$SERVICE_TYPE_CACHE[$cacheKey]; } else { $serviceType = $section->getValue('servicetype'); self::$SERVICE_TYPE_CACHE[$cacheKey] = $serviceType; } $class = $section->getValue('class'); // The behaviour of service types CACHED and NORMAL is equal in the following, thus remapping it. if ($serviceType == APFService::SERVICE_TYPE_CACHED) { $serviceType = APFService::SERVICE_TYPE_NORMAL; } // Check if configuration section was complete. If not throw an exception to fail fast. if ($serviceType === null || $class === null) { throw new InvalidArgumentException('[DIServiceManager::getServiceObject()] Initialization of the service object "' . $sectionName . '" from namespace "' . $configNamespace . '" cannot be accomplished, due to missing or incorrect configuration! Please revise the configuration file and consult the manual!', E_USER_ERROR); } // Create the service object with use of the "normal" service manager. Perhaps, this // may run into problems, because we have to ensure, that the singleton objects are // only treated once by the injection mechanism! // But: if we constitute, that the injected service objects are often also singletons // and the DIServiceManager caches the created service objects within a singleton cache, // this is no problem. Hence, the injected instance is then only one time constructed. // ID#249: as of 3.0 you are also able to inject dependent configuration and services via constructor. // This replaces the former getAndInitServiceObject() method of the ServiceManager with a more elegant // way. Configuration allows any number of constructor arguments as string, array, or other services. $arguments = []; if ($section->hasSection('construct')) { $constructorArguments = $section->getSection('construct'); foreach ($constructorArguments->getSectionNames() as $argumentKey) { $directive = $constructorArguments->getSection($argumentKey); // be aware of the params needed for injection $value = $directive->getValue('value'); $namespace = $directive->getValue('namespace'); $name = $directive->getValue('name'); if ($value === null && ($namespace === null || $name === null)) { throw new InvalidArgumentException('[DIServiceManager::getServiceObject()] Construction of the' . ' service object "' . $sectionName . '" cannot be accomplished, due to' . ' incorrect constructor injection configuration! Please revise the "' . $argumentKey . '" sub section and consult the manual!', E_USER_ERROR); } // Simple value argument (string) if ($directive->hasValue('value')) { $arguments[] = $value; } else { // complex injection with another service $arguments[] =& self::getServiceObject($namespace, $name, $context, $language); } } } /* @var $serviceObject APFDIService */ $serviceObject =& ServiceManager::getServiceObject($class, $context, $language, $arguments, $serviceType, $cacheKey); // do param injection (static configuration) if ($section->hasSection('conf')) { $cfTasks = $section->getSection('conf'); foreach ($cfTasks->getSectionNames() as $initKey) { $directive = $cfTasks->getSection($initKey); // be aware of the params needed for injection $method = $directive->getValue('method'); if ($method === null) { throw new InvalidArgumentException('[DIServiceManager::getServiceObject()] Initialization of the' . ' service object "' . $sectionName . '" cannot be accomplished, due to' . ' incorrect configuration! Please revise the "' . $initKey . '" sub section and' . ' consult the manual!', E_USER_ERROR); } // check, if method exists to avoid fatal errors if (!method_exists($serviceObject, $method)) { throw new InvalidArgumentException('[DIServiceManager::getServiceObject()] Injection of' . ' configuration value "' . $directive->getValue('value') . '" cannot be accomplished' . ' to service object "' . $class . '"! Method ' . $method . '() is not implemented!', E_USER_ERROR); } if (($value = $directive->getValue('value')) !== null) { $serviceObject->{$method}($value); } else { if (!$directive->hasSection('value')) { throw new InvalidArgumentException('[DIServiceManager::getServiceObject()] Initialization of the' . ' service object "' . $sectionName . '" cannot be accomplished, due to' . ' missing value(s) for method ' . $method . '()! Please revise the "' . $initKey . '" sub section and' . ' consult the manual!', E_USER_ERROR); } $cfSubSection = $directive->getSection('value'); $values = []; foreach ($cfSubSection->getValueNames() as $valueName) { $values[] = $cfSubSection->getValue($valueName); } call_user_func_array([$serviceObject, $method], $values); } } } // do service object injection if ($section->hasSection('init')) { $miTasks = $section->getSection('init'); foreach ($miTasks->getSectionNames() as $initKey) { $directive = $miTasks->getSection($initKey); // be aware of the params needed for injection $method = $directive->getValue('method'); $namespace = $directive->getValue('namespace'); $name = $directive->getValue('name'); if ($method === null || $namespace === null || $name === null) { throw new InvalidArgumentException('[DIServiceManager::getServiceObject()] Initialization of the service object "' . $sectionName . '" cannot be accomplished, due to incorrect configuration! Please revise the "' . $initKey . '" sub section and consult the manual!', E_USER_ERROR); } // check for circular injection $injectionKey = $namespace . '::' . $class . '[' . $serviceType . ']' . ' injected with ' . $method . '(' . $namespace . '::' . $name . ')'; // TODO why do we accept loops for normal services? if (isset(self::$INJECTION_CALL_CACHE[$injectionKey]) && $serviceType != APFService::SERVICE_TYPE_NORMAL) { // append error to log to provide debugging information $log = Singleton::getInstance(Logger::class); /* @var $log Logger */ $instructions = ''; foreach (self::$INJECTION_CALL_CACHE as $injectionInstruction => $DUMMY) { $instructions .= PHP_EOL . $injectionInstruction; } $log->addEntry(new SimpleLogEntry(Registry::retrieve('APF\\core', 'InternalLogTarget'), '[DIServiceManager::getServiceObject()] Injection stack trace: ' . $instructions, LogEntry::SEVERITY_TRACE)); // print note with shorted information throw new InvalidArgumentException('[DIServiceManager::getServiceObject()] Detected circular injection! ' . 'Class "' . $class . '" from namespace "' . $namespace . '" with service type "' . $serviceType . '" was already configured with service object "' . $name . '" from namespace "' . $namespace . '"! Full stack trace can be taken from the logfile!', E_USER_ERROR); } else { // add the current run to the recursion detection array self::$INJECTION_CALL_CACHE[$injectionKey] = true; // get the dependent service object $miObject =& self::getServiceObject($namespace, $name, $context, $language); // inject the current service object with the created one if (method_exists($serviceObject, $method)) { $serviceObject->{$method}($miObject); } else { throw new InvalidArgumentException('[DIServiceManager::getServiceObject()] Injection of service object "' . $name . '" from namespace "' . $namespace . '" cannot be accomplished to service object "' . $class . '" from namespace "' . $namespace . '"! Method ' . $method . '() is not implemented!', E_USER_ERROR); } } } } // Often, there you have a services that depends on several other services (e.g. database connection). Thus, // you are forced to initialize your service using these components. To ease such cases, you may specify a // generic method within the "setupmethod" attribute. The DIServiceManager calls this method at the end of // the initialization process and you can initialize your service without being dependent on the user's // order of configuration parameters. // in order to not execute the setup method on every request, check the initialization status of the service // object before. this mechanism can be used for re-initialization on __wakeup() in case the property is // set to false (=reinitialization after session wake-up). $setupMethod = $section->getValue('setupmethod'); if (!empty($setupMethod)) { if (!$serviceObject->isInitialized()) { if (method_exists($serviceObject, $setupMethod)) { $serviceObject->{$setupMethod}(); } else { throw new InvalidArgumentException('[DIServiceManager::getServiceObject()] Custom service object setup ' . 'method "' . $setupMethod . '()" is not implemented for given type "' . get_class($serviceObject) . '"! Please double-check your configuration ' . 'for service "' . $sectionName . '" from namespace "' . $configNamespace . '."', E_USER_ERROR); } } } $t->stop($benchId); // add service object to cache and return it self::$SERVICE_OBJECT_CACHE[$cacheKey] = $serviceObject; return self::$SERVICE_OBJECT_CACHE[$cacheKey]; }
public function transform() { $t = Singleton::getInstance(BenchmarkTimer::class); /* @var $t BenchmarkTimer */ $t->start('(' . get_class($this) . ') ' . $this->getObjectId() . '::transform()'); // create copy, to preserve it! $content = $this->content; // execute the document controller if applicable if ($this->documentController instanceof DocumentController) { // start benchmark timer $id = '(' . get_class($this->documentController) . ') ' . XmlParser::generateUniqID() . '::transformContent()'; $t->start($id); // execute the document controller by using a standard method $this->documentController->transformContent(); $t->stop($id); } // transform child nodes and replace XML marker to place the output at the right position if (count($this->children) > 0) { foreach ($this->children as &$child) { $content = str_replace('<' . $child->getObjectId() . ' />', $child->transform(), $content); } } $t->stop('(' . get_class($this) . ') ' . $this->getObjectId() . '::transform()'); return $content; }
/** * Returns the desired instance of the GenericORMapper configured for this application case. * * @param GenericDomainObject[] A list of generic entries. * @param boolean $addEditor Indicates, if the editor should be mapped to the entry object. * * @return Entry[] A list of guestbook domain objects. * * @author Christian Achatz * @version * Version 0.1, 06.05.2009<br /> */ private function mapGenericEntries2DomainObjects(array $entries = [], $addEditor = true) { // return empty array, because having no entries means nothing to do! if (count($entries) == 0) { return []; } // invoke benchmarker to be able to monitor the performance /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); $t->start('mapGenericEntries2DomainObjects()'); // load the language object for the current language to enable // language dependent mapping! $lang = $this->getCurrentLanguage(); // define the criterion $critEntries = new GenericCriterionObject(); $critEntries->addRelationIndicator('Attribute2Language', $lang); $gbEntries = []; /* @var $current GenericDomainObject */ foreach ($entries as $current) { // Check, whether there are attributes related in the current language. // If not, do NOT add an entry, because it will be empty! $attributes = $this->orm->loadRelatedObjects($current, 'Entry2LangDepValues', $critEntries); if (count($attributes) > 0) { // load the entry itself $entry = new Entry(); $entry->setCreationTimestamp($current->getProperty('CreationTimestamp')); foreach ($attributes as $attribute) { if ($attribute->getProperty('Name') == 'title') { $entry->setTitle($attribute->getProperty('Value')); } if ($attribute->getProperty('Name') == 'text') { $entry->setText($attribute->getProperty('Value')); } } // add the editor's data if ($addEditor === true) { $editor = new User(); $user = $this->orm->loadRelatedObjects($current, 'Editor2Entry'); $editor->setName($user[0]->getProperty('Name')); $editor->setEmail($user[0]->getProperty('Email')); $editor->setWebsite($user[0]->getProperty('Website')); $editor->setId($user[0]->getProperty('UserID')); $entry->setEditor($editor); } $entry->setId($current->getProperty('EntryID')); $gbEntries[] = $entry; } } $t->stop('mapGenericEntries2DomainObjects()'); return $gbEntries; }
public static function deleteInstance($class, $instanceId = null) { parent::deleteInstance($class, $instanceId); // remove from APC store to not restore instance after in subsequent request by accident apc_delete(self::getCacheKey($class, $instanceId)); }
/** * Imports additional domain object mapping information. * * @param string $configNamespace the desired configuration namespace * @param string $configNameAffix the configuration affix of the desired configuration * * @author Ralf Schubert * @version * Version 0.1, 15.01.2011<br /> */ public function addDomainObjectsConfiguration($configNamespace, $configNameAffix) { $t = Singleton::getInstance(BenchmarkTimer::class); /* @var $t BenchmarkTimer */ $t->start('BaseMapper::addDomainObjectsConfiguration()'); // add config, if not already included $cacheKey = md5($configNamespace . $configNameAffix . '_domainobjects'); if (!isset($this->importedConfigCache[$cacheKey])) { try { // import and merge config $addConfig = $this->getConfiguration($configNamespace, $configNameAffix . '_domainobjects.' . $this->getConfigFileExtension()); // extract configuration to support pre 1.13 GORM config foreach ($addConfig->getSectionNames() as $sectionName) { $section = $addConfig->getSection($sectionName); $this->domainObjectsTable[$sectionName] = []; foreach ($section->getValueNames() as $valueName) { $this->domainObjectsTable[$sectionName][$valueName] = $section->getValue($valueName); } if ($section->hasSection('Base')) { $this->domainObjectsTable[$sectionName]['Base'] = ['Class' => $section->getSection('Base')->getValue('Class')]; } } } catch (ConfigurationException $e) { // do nothing, because we accept that (domain objects are optional)! } // mark object config as cached $this->importedConfigCache[$cacheKey] = true; } $t->stop('BaseMapper::addDomainObjectsConfiguration()'); }
public function transformContent() { /* @var $sessionStore UmgtUserSessionStore */ $sessionStore = $this->getServiceObject(UmgtUserSessionStore::class, [], APFService::SERVICE_TYPE_SESSION_SINGLETON); $appIdent = $this->getContext(); $user = $sessionStore->getUser($appIdent); if ($user === null) { $form = $this->getForm('login'); // generate url ourselves to not include the logout action instruction $form->setAction(LinkGenerator::generateUrl(Url::fromCurrent())); if ($form->isSent() && $form->isValid()) { $username = $form->getFormElementByName('username')->getAttribute('value'); $password = $form->getFormElementByName('password')->getAttribute('value'); try { $user = $this->loadUser($username, $password); if ($user === null) { $form->getFormElementByName('username')->markAsInvalid(); $form->getFormElementByName('username')->appendCssClass(AbstractFormValidator::$DEFAULT_MARKER_CLASS); $form->getFormElementByName('password')->markAsInvalid(); $form->getFormElementByName('password')->appendCssClass(AbstractFormValidator::$DEFAULT_MARKER_CLASS); $form->setPlaceHolder('login-error', $this->getTemplate('login-error')->transformTemplate()); $form->transformOnPlace(); } else { // store user $sessionStore->setUser($appIdent, $user); // create auto-login cookie $rememberMe = $form->getFormElementByName('remember-me'); if ($rememberMe->isChecked()) { $this->createAutoLogin($user); } // redirect to target page $urlProvider = $this->getDIServiceObject('APF\\modules\\usermanagement\\biz', 'LoginRedirectUrlProvider'); /* @var $urlProvider UmgtRedirectUrlProvider */ $this->getResponse()->forward(LinkGenerator::generateUrl(Url::fromString($urlProvider->getRedirectUrl()))); } } catch (Exception $e) { $this->getTemplate('system-error')->transformOnPlace(); $l = Singleton::getInstance(Logger::class); /* @var $l Logger */ $l->logEntry('login', 'Login is not possible due to ' . $e, LogEntry::SEVERITY_ERROR); } } elseif ($form->isSent() && !$form->isValid()) { $form->setPlaceHolder('login-error', $this->getTemplate('login-error')->transformTemplate()); $form->transformOnPlace(); } else { $form->transformOnPlace(); } } else { $this->getTemplate('login-ok')->transformOnPlace(); } }
public function transformContent() { // fill document attributes to local variable $document = $this->getDocument(); /* @var $config array */ $config = $document->getAttribute('Config'); $dataCount = $document->getAttribute('DataCount'); $anchorName = $document->getAttribute('AnchorName'); $request = $this->getRequest(); $urlParams = [$config['ParameterEntries'] => $config['Entries']]; if ($config['EntriesChangeable'] === true) { $urlParams = [$config['ParameterEntries'] => $request->getParameter($config['Entries'])]; } // Pager leer zurückgeben, falls keine Seiten vorhanden sind. if ($dataCount == 0) { return; } /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); $t->start('ArrayPager'); $content = $this->getTemplate('pager'); // Anzahl der Einträge $integerEntriesCount = $config['Entries']; // Anzahl der Seiten generieren $integerPageCount = ceil($dataCount / $integerEntriesCount); // Aktuelle Seite generieren $integerCurrentPage = intval($request->getParameter($config['ParameterPage'], 1)); // Puffer initialisieren $stringBuffer = ''; for ($integerPage = 1; $integerPage <= $integerPageCount; $integerPage++) { if ($integerPage == $integerCurrentPage) { // Referenz auf Template holen $objectTemplate = $this->getTemplate('Page_Selected'); } else { // Referenz auf Template holen $objectTemplate = $this->getTemplate('Page'); } $stringURL = LinkGenerator::generateUrl(Url::fromCurrent()->mergeQuery([$config['ParameterPage'] => $integerPage])); // Pager zusammenbauen if (!empty($anchorName)) { $objectTemplate->setPlaceHolder('URL', $stringURL . '#' . $anchorName); } else { $objectTemplate->setPlaceHolder('URL', $stringURL); } $objectTemplate->setPlaceHolder('Page', $integerPage); // Template transformieren $stringBuffer .= $objectTemplate->transformTemplate(); unset($objectTemplate, $stringURL); } unset($integerPage); // Puffer in Inhalt einsetzen $content->setPlaceHolder('Pager', $stringBuffer); unset($stringBuffer); // VorherigeSeite if ($integerCurrentPage > 1) { // Template vorherige Seite ausgeben $objectTemplatePreviousPage = $this->getTemplate('PreviousPage_Active'); $stringURL = LinkGenerator::generateUrl(Url::fromCurrent()->mergeQuery([$config['ParameterPage'] => $integerCurrentPage - 1])); if (!empty($anchorName)) { $objectTemplatePreviousPage->setPlaceHolder('URL', $stringURL . '#' . $anchorName); } else { $objectTemplatePreviousPage->setPlaceHolder('URL', $stringURL); } unset($stringURL); } else { // Template vorherige Seite (inaktiv) ausgeben $objectTemplatePreviousPage = $this->getTemplate('PreviousPage_Inactive'); } $content->setPlaceHolder('PreviousPage', $objectTemplatePreviousPage->transformTemplate()); unset($objectTemplatePreviousPage); // NaechsteSeite if ($integerCurrentPage < $integerPageCount) { $stringURL = LinkGenerator::generateUrl(Url::fromCurrent()->mergeQuery([$config['ParameterPage'] => $integerCurrentPage + 1])); $objectTemplateNextPage = $this->getTemplate('NextPage_Active'); if (isset($anchorName) === true) { $objectTemplateNextPage->setPlaceHolder('URL', $stringURL . '#' . $anchorName); } else { $objectTemplateNextPage->setPlaceHolder('URL', $stringURL); } unset($stringURL); } else { $objectTemplateNextPage = $this->getTemplate('NextPage_Inactive'); } $content->setPlaceHolder('NextPage', $objectTemplateNextPage->transformTemplate()); unset($objectTemplateNextPage); if ($config['EntriesChangeable'] === true) { // Einträge / Seite $arrayEntries = explode('|', $config['EntriesPossible']); $stringBuffer = ''; foreach ($arrayEntries as &$integerEntries) { if ($urlParams[$config['ParameterEntries']] == $integerEntries) { $objectTemplateEntries = $this->getTemplate('Entries_Active'); } else { $objectTemplateEntries = $this->getTemplate('Entries_Inactive'); } $stringURL = LinkGenerator::generateUrl(Url::fromCurrent()->mergeQuery([$config['ParameterPage'] => 1, $config['ParameterEntries'] => $integerEntries])); if (isset($anchorName) === true) { $objectTemplateEntries->setPlaceHolder('URL', $stringURL . '#' . $anchorName); } else { $objectTemplateEntries->setPlaceHolder('URL', $stringURL); } unset($stringURL); // Anzahl einsetzen $objectTemplateEntries->setPlaceHolder('Entries', $integerEntries); // Template in Puffer einsetzen $stringBuffer .= $objectTemplateEntries->transformTemplate(); unset($objectTemplateEntries); } $objectTemplateEntries = $this->getTemplate('Entries'); $objectTemplateEntries->setPlaceHolder('Entries', $stringBuffer); unset($stringBuffer); $content->setPlaceHolder('Entries', $objectTemplateEntries->transformTemplate()); unset($objectTemplateEntries); } $content->transformOnPlace(); $t->stop('ArrayPager'); }
/** * Executes all actions with the given type. Possible types are * <ul> * <li>prepagecreate</li> * <li>pretransform</li> * <li>posttransform</li> * </ul> * * @param string $type Type of the actions to execute. * * @author Christian Achatz * @version * Version 0.1, 27.01.2007<br /> * Version 0.2, 31.01.2007<br /> * Version 0.3, 03.02.2007 (Added benchmarker)<br /> * Version 0.4, 01.07.2007 (Removed debug output)<br /> * Version 0.5, 08.11.2007<br /> * Version 0.6, 28.03.2008 (Optimized benchmarker call)<br /> * Version 0.7, 07.08.2010 (Added action activation indicator to disable actions on demand)<br /> */ protected function runActions($type = Action::TYPE_PRE_PAGE_CREATE) { /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); foreach ($this->actionStack as $offset => $DUMMY) { // only execute, when the current action has a suitable type if ($this->actionStack[$offset]->getType() == $type && $this->actionStack[$offset]->isActive()) { $id = get_class($this->actionStack[$offset]) . '::run()'; $t->start($id); $this->actionStack[$offset]->run(); $t->stop($id); } } }
/** * @return Frontcontroller The current front controller instance. */ protected function &getFrontcontroller() { return Singleton::getInstance(Frontcontroller::class); }
/** * Sets up the provider to be ready for use. Converts each BBCodeParserDefinition into * it's real implementation. If a provider was added / removed the converter is going to * notice this fact. * * @author Christian Achatz * @version * Version 0.1, 28.10.2008 */ private function setUpProvider() { $t = Singleton::getInstance(BenchmarkTimer::class); /* @var $t BenchmarkTimer */ $t->start('AdvancedBBCodeParser::setUpProvider()'); foreach ($this->provider as $providerName => $providerDefinition) { if ($providerDefinition instanceof BBCodeParserDefinition) { /* @var $providerDefinition BBCodeParserDefinition */ $class = $providerDefinition->getClass(); // convert definition and initialize provider $this->provider[$providerName] = $this->getServiceObject($class, [], APFService::SERVICE_TYPE_NORMAL); } } $t->stop('AdvancedBBCodeParser::setUpProvider()'); }
/** * Handles the tag's attributes (ses class documentation) and includes the desired template. * * @author Christian Achatz * @version * Version 0.1, 30.10.2008<br /> * Version 0.2, 01.11.2008 (Added the modelmode and getmethode params)<br /> * Version 0.3, 29.12.2208 (Added the dependent action options)<br /> */ public function onParseTime() { // model-class="" $modelClass = $this->getRequiredAttribute('model-class'); // model-mode="NORMAL|SINGLETON|SESSIONSINGLETON" $modelMode = $this->getRequiredAttribute('model-mode'); // namespace-param="" $namespaceParam = $this->getRequiredAttribute('namespace-param'); // template-param="" $templateParam = $this->getRequiredAttribute('template-param'); // get-method="" (e.g. "getAttribute" or "get") $getMethod = $this->getAttribute('get-method'); if ($getMethod === null) { $getMethod = 'getAttribute'; } // register dependent action (needed, if the action is used for navigation purposes) $dependentActionNamespace = $this->getAttribute('dependent-action-namespace'); $dependentActionName = $this->getAttribute('dependent-action-name'); $dependentActionParams = $this->getAttribute('dependent-action-params'); if ($dependentActionNamespace !== null && $dependentActionName !== null) { // create param list $actionParamList = []; if ($dependentActionParams !== null) { $paramPieces = explode('|', $dependentActionParams); foreach ($paramPieces as $piece) { $temp = explode(':', $piece); if (isset($temp[1])) { $actionParamList[trim($temp[0])] = trim($temp[1]); } } } // register action with the front controller /* @var $fC Frontcontroller */ $fC = Singleton::getInstance(Frontcontroller::class); $action = $fC->getActionByName($dependentActionName); if ($action === null) { $fC->addAction($dependentActionNamespace, $dependentActionName, $actionParamList); } } // get model $model = $this->getServiceObject($modelClass, [], $modelMode); // check for the get method if (!method_exists($model, $getMethod)) { throw new InvalidArgumentException('[GenericImportTemplateTag::onParseTime()] ' . 'The model class ("' . $modelClass . '") does not support the method "' . $getMethod . '" provided within the "getmethod" attribute. Please provide the correct ' . 'function name!'); } // read the params from the model $templateNamespace = $model->{$getMethod}($namespaceParam); if (empty($templateNamespace)) { throw new InvalidArgumentException('[GenericImportTemplateTag::onParseTime()] ' . 'The model ("' . $modelClass . '") returned an empty value when trying to get ' . 'the template namespace using the "' . $getMethod . '" method! Please specify ' . 'another getter or check the model class implementation!'); } $templateName = $model->{$getMethod}($templateParam); if (empty($templateName)) { throw new InvalidArgumentException('[GenericImportTemplateTag::onParseTime()] ' . 'The model ("' . $modelClass . '") returned an empty value when trying to get ' . 'the template name using the "' . $getMethod . '" method! Please specify another ' . 'getter or check the model class implementation!'); } // import desired template $this->loadContentFromFile($templateNamespace, $templateName); $this->extractDocumentController(); $this->extractTagLibTags(); }
public function transformForm() { $t = Singleton::getInstance(BenchmarkTimer::class); /* @var $t BenchmarkTimer */ $id = '(HtmlFormTag) ' . $this->getObjectId() . '::transformForm()'; $t->start($id); // add action attribute if not set $action = $this->getAttribute(self::ACTION_ATTRIBUTE_NAME); if ($action === null) { $this->setAttribute(self::ACTION_ATTRIBUTE_NAME, $this->getRequest()->getRequestUri()); } // ID#239: always encode action attribute when present to secure custom actions as well as auto-generated ones $this->setAttribute(self::ACTION_ATTRIBUTE_NAME, htmlspecialchars($this->getAttribute(self::ACTION_ATTRIBUTE_NAME), ENT_QUOTES, Registry::retrieve('APF\\core', 'Charset'), false)); // transform the form including all child tags $htmlCode = (string) '<form '; $htmlCode .= $this->getAttributesAsString($this->attributes, $this->attributeWhiteList); $htmlCode .= '>'; // ID#281: add hidden form fields with URL get parameters for GET forms for convenience reasons if ($this->getAttribute(self::METHOD_ATTRIBUTE_NAME) === self::METHOD_GET_VALUE_NAME && $this->getAttribute(self::SUBMIT_ACTION_URL_PARAMS_ATTRIBUTE_NAME) === 'true') { $url = Url::fromString($this->getAttribute(self::ACTION_ATTRIBUTE_NAME)); $queryParams = $url->getQuery(); if (count($queryParams) > 0) { $hiddenFieldMarker = ''; foreach ($queryParams as $name => $value) { $control = $this->createFormElement($this, 'form:hidden', ['name' => $name, 'value' => $value]); $hiddenFieldMarker .= '<' . $control->getObjectId() . ' />'; } // prepend fields to preserve parameter order $this->content = $hiddenFieldMarker . $this->content; } } if (count($this->children) > 0) { foreach ($this->children as &$child) { $childId = '(' . get_class($child) . ') ' . $child->getObjectId() . '::transform()'; $t->start($childId); $this->content = str_replace('<' . $child->getObjectId() . ' />', $child->transform(), $this->content); $t->stop($childId); } } $htmlCode .= $this->content; $htmlCode .= '</form>'; $t->stop($id); return $htmlCode; }
/** * Send an email to the recipients configured. The return array contains two associative * offsets including the following information: * <ul> * <li>recipientcount (new!): the number of recipients.</li> * <li>successcount (new!): the number of emails sent successfully.</li> * </ul> * * @deprecated This implementation is deprecated. Please use any available PHP solution instead (e.g. PHPMailer). * * @return string[] The sending status. * * @author Christian Schäfer * @version * Version 0.1, 09.06.2004<br /> * Version 0.2, 03.01.2005<br /> * Version 0.3, 17.01.2005<br /> * Version 0.4, 14.01.2006<br /> */ public function sendMail() { $header = $this->generateHeader(); /* @var $log Logger */ $log = Singleton::getInstance(Logger::class); $sentEmails = []; for ($i = 0; $i < count($this->recipients); $i++) { $result = @mail($this->recipients[$i]['EMail'], $this->subject, $this->content, $header); if ($result == 1 || $result == true) { $log->logEntry('mail', 'Sending mail to ' . $this->recipients[$i]['EMail'] . '.', LogEntry::SEVERITY_INFO); $sentEmails[] = '1'; } else { $log->logEntry('mail', 'Sending mail to ' . $this->recipients[$i]['EMail'] . '.', LogEntry::SEVERITY_ERROR); } } $status['recipientcount'] = count($this->recipients); $status['successcount'] = count($sentEmails); return $status; }
public function filter(FilterChain &$chain, $input = null) { /* @var $t BenchmarkTimer */ $t = Singleton::getInstance(BenchmarkTimer::class); $id = get_class($this); $t->start($id); $request = $this->getRequest(); // extract the session id from $_REQUEST if existent to re-add it after filtering $sessionId = $request->getSessionId(); // initialize param to analyze $query = $request->getParameter(self::$REWRITE_QUERY_PARAM, ''); // delete the rewrite param indicator $request->deleteParameter(self::$REWRITE_QUERY_PARAM); // reset request but save POST data $postData = $request->getPostParameters(); $request->resetParameters(); // ID#63: re-map action instructions according to registered aliases $fC = $this->getFrontcontroller(); $tokens = $fC->getActionUrlMappingTokens(); // re-map action urls foreach ($tokens as $token) { if (strpos($query, '/' . $token . '/') !== false) { $mapping = $fC->getActionUrlMapping($token); $query = str_replace('/' . $token . '/', '/' . str_replace('\\', '_', $mapping->getNamespace()) . '-action/' . $mapping->getName() . '/', $query); } else { if (substr($query, -(strlen($token) + 1)) == '/' . $token) { // URL mapping appears at the end of the query and/or is the only part of it $mapping = $fC->getActionUrlMapping($token); $query = str_replace('/' . $token, '/' . str_replace('\\', '_', $mapping->getNamespace()) . '-action/' . $mapping->getName(), $query); } } } // extract actions from the request url, in case the action keyword or the action // delimiter is present in url. if (substr_count($query, self::$ACTION_TO_PARAM_DELIMITER) > 0 || substr_count($query, self::$FC_ACTION_KEYWORD . '/') > 0) { // split url by delimiter $requestURLParts = explode(self::$ACTION_TO_PARAM_DELIMITER, $query); $count = count($requestURLParts); for ($i = 0; $i < $count; $i++) { // remove leading slash $requestURLParts[$i] = $this->deleteTrailingSlash($requestURLParts[$i]); if (substr_count($requestURLParts[$i], self::$FC_ACTION_KEYWORD) > 0) { $requestArray = explode(self::$REWRITE_URL_DELIMITER, $requestURLParts[$i]); if (isset($requestArray[1])) { // create action params $actionNamespace = str_replace(self::$FC_ACTION_KEYWORD, '', $requestArray[0]); $actionName = $requestArray[1]; $actionParams = array_slice($requestArray, 2); $actionParamsArray = []; $actionParamCount = count($actionParams); if ($actionParamCount > 0) { $x = 0; while ($x <= $actionParamCount - 1) { if (isset($actionParams[$x + 1])) { $actionParamsArray[$actionParams[$x]] = $actionParams[$x + 1]; } $x = $x + 2; // increase by two, because next offset is the value! } } $fC->addAction($actionNamespace, $actionName, $actionParamsArray); } } else { $paramArray = $this->createRequestArray($requestURLParts[$i]); $request->setParameters(array_merge($request->getParameters(), $paramArray)); } } } else { // do page controller-style rewriting! $paramArray = $this->createRequestArray($query); $request->setParameters(array_merge($request->getParameters(), $paramArray)); } // re-initialize GET params to support e.g. form submission $request->setGetParameters($request->getParameters()); // re-add POST params $request->setParameters(array_merge($request->getParameters(), $postData)); $request->setPostParameters($postData); // add session id to the request again if (!empty($sessionId)) { $request->setParameter($request->getSessionName(), $sessionId); } $t->stop($id); // delegate further filtering to the applied chain $chain->filter($input); }