File modules/cms/action/page/PageAllAction.class.php
Last commit: Thu Oct 15 01:39:59 2026 +0200 Jan Dankert New: A much better generation of the OpenAPI Interface documents, supports now the UI API Objects.
1 <?php 2 namespace cms\action\page; 3 4 use cms\action\Method; 5 use cms\action\PageAction; 6 use cms\action\UiInClass; 7 use cms\action\ValueMapping; 8 use cms\api\Values; 9 use cms\base\Language as L; 10 use cms\generator\PageContext; 11 use cms\generator\PageGenerator; 12 use cms\generator\Producer; 13 use cms\generator\Publisher; 14 use cms\generator\PublishOrder; 15 use cms\model\BaseObject; 16 use cms\model\Content; 17 use cms\model\Element; 18 use cms\model\Language; 19 use cms\model\PageContent; 20 use cms\model\Permission; 21 use cms\model\Project; 22 use cms\model\Value; 23 use language\Messages; 24 use logger\Logger; 25 use util\exception\ClientException; 26 use util\exception\PublisherException; 27 use util\exception\SecurityException; 28 use util\exception\ValidationException; 29 use util\Hydrator; 30 use util\Session; 31 use util\Text; 32 use function logger\Logger; 33 34 class PageAllAction extends PageAction implements Method { 35 36 use ValueMapping; 37 38 public function view() 39 { 40 $languageid = $this->request->getRequiredNumber('languageid'); 41 $language = new Language($languageid); 42 $language->load(); 43 44 $this->setTemplateVar('language_name', $language->getName()); 45 $this->setTemplateVar('languageid' , $language->languageid ); 46 47 $this->setTemplateVar('value_time',time() ); 48 $this->setTemplateVar('writable' ,$this->page->hasRight( Permission::ACL_WRITE ) ); 49 50 $elements = []; 51 52 /** @var Element $element */ 53 foreach ($this->getElements() as $element) { 54 55 $pageContent = new PageContent(); 56 $pageContent->elementId = $element->elementid; 57 $pageContent->pageId = $this->page->pageid; 58 $pageContent->languageid = $languageid; 59 $pageContent->load(); 60 61 if ( $pageContent->isPersistent() ) { 62 $value = new Value(); 63 $value->contentid = $pageContent->contentId; 64 $value->load(); 65 } 66 else { 67 // There is no content yet, so creating an empty value. 68 $value = new Value(); 69 } 70 71 $output = []; 72 $output['element' ] = $element->getProperties(); 73 $output['elementid'] = $element->getId(); 74 $output['type' ] = $element->getTypeName(); 75 $output['decimals'] = $element->decimals; 76 $output['name' ] = $element->name; 77 $output['label' ] = $element->label; 78 $output['desc' ] = $element->desc; 79 80 //$output['value' ] = $value->getProperties(); 81 $output += $this->outputValue($element,$value); 82 83 //$this->setTemplateVar( $element->name, $output['value'] ); 84 85 $elements[ $element->name ] = $output; 86 } 87 88 if ($this->page->hasRight(Permission::ACL_RELEASE)) 89 $this->setTemplateVar('release', true); 90 if ($this->page->hasRight(Permission::ACL_PUBLISH)) 91 $this->setTemplateVar('publish', false); 92 93 $this->setTemplateVar('elements', $elements ); 94 } 95 96 97 98 #[UiInClass(Values::class)] 99 public function post( ) 100 { 101 /** @var Values $values */ 102 $values = $this->request->toObject( Values::class ); 103 104 $project = $this->page->getProject(); 105 $languageIds = $project->getLanguageIds(); 106 107 $log = []; 108 109 /** @var Element $element */ 110 foreach ($this->getElements() as $element) { 111 112 /** @var \cms\api\Value $uiValue */ 113 $uiValue = array_find( $values->values, function ($uiValue) use ($element) { 114 return ($uiValue->elementId == $element->elementid ); 115 } ); 116 if ( !$uiValue ) 117 continue; // Element not found in Request. 118 119 $pageContent = new PageContent(); 120 $pageContent->elementId = $element->elementid; 121 $pageContent->pageId = $this->page->pageid; 122 123 if ( !array_any($languageIds, function($languageId) use ($uiValue) { 124 return $uiValue->languageId == $languageId; 125 })) 126 throw new ClientException("Invalid language id ".$uiValue->languageId." not found for this project."); 127 128 $pageContent->languageid = $uiValue->languageId; 129 $pageContent->load(); 130 $pageContent->persist(); // Create if it does not exist yet. 131 132 $value = new Value(); 133 $value->contentid = $pageContent->contentId; 134 $oldValue = clone $value; 135 $oldValue->load(); 136 $value->format = $oldValue->format; 137 138 try { 139 $this->parseToValue($element, $value, $uiValue->value); 140 } catch(\InvalidArgumentException ) { 141 throw new ValidationException( $element->getName() ); 142 } 143 144 // Inhalt sofort freigegeben, wenn 145 // - Recht vorhanden 146 // - Freigabe gewuenscht 147 $value->publish = $this->page->hasRight(Permission::ACL_RELEASE) && $this->request->isTrue('release'); 148 149 // Up-To-Date-Check 150 $content = new Content( $pageContent->contentId ); 151 $lastChangeTime = $content->getLastChangeSinceByAnotherUser($this->request->getNumber('value_time'), $this->getCurrentUserId()); 152 if ($lastChangeTime) 153 $this->addWarningFor($value, Messages::CONCURRENT_VALUE_CHANGE, array('last_change_time' => date(L::lang('DATE_FORMAT'), $lastChangeTime))); 154 155 // Check if anything has changed 156 if ( $oldValue->text == $value->text && 157 $oldValue->linkToObjectId == $value->linkToObjectId && 158 $oldValue->format == $value->format && 159 $oldValue->number == $value->number && 160 $oldValue->date == $value->date && 161 !(!$oldValue->publish && $value->publish) 162 ) { 163 $log[] = str_pad($element->label,20).': Unchanged'; 164 continue; // nothing has changed. 165 } 166 167 // Inhalt speichern 168 $value->persist(); 169 $log[] = str_pad($element->label,20).': '."Saved \u{2713}"; 170 171 // Wenn Inhalt in allen Sprachen gleich ist, dann wird der Inhalt 172 // fuer jede Sprache einzeln gespeichert. 173 if ($element->allLanguages) { 174 $project = new Project($this->page->projectid); 175 foreach ($project->getLanguageIds() as $languageid) { 176 if ($languageid != $pageContent->languageid) { 177 $otherPageContent = clone $pageContent; 178 $otherPageContent->languageid = $languageid; 179 $otherPageContent->contentId = null; 180 $otherPageContent->load(); 181 if (!$otherPageContent->contentId) 182 $otherPageContent->persist(); // create pagecontent if it does not exist. 183 184 $otherValue = clone $value; 185 $otherValue->contentid = $otherPageContent->contentId; 186 $otherValue->persist(); 187 } 188 } 189 } 190 } 191 192 // Falls ausgewaehlt die Seite sofort veroeffentlichen 193 if ($this->page->hasRight(Permission::ACL_PUBLISH) && $this->request->isTrue('publish')) { 194 $this->publishPage( $languageid ); 195 $log[] = 'Published page "'.$this->page->getName().'"'; 196 } 197 198 $this->page->setTimestamp(); // "Letzte Aenderung" setzen 199 200 $this->addNoticeFor($this->page, Messages::SAVED,[],$log); 201 } 202 203 204 /** 205 * Gets all elements of the current page. 206 * 207 * @return array 208 */ 209 protected function getElements() { 210 211 return $this->page->getTemplate()->getWritableElements(); 212 } 213 214 215 protected function linkifyOIDs( $text ) 216 { 217 $pageContext = $this->createPageContext( Producer::SCHEME_PREVIEW ); 218 219 $linkFormat = $pageContext->getLinkScheme(); 220 221 foreach( Text::parseOID($text) as $oid=>$t ) 222 { 223 $url = $linkFormat->linkToObject($this->page, (new BaseObject($oid))->load() ); 224 foreach( $t as $match) 225 $text = str_replace($match,$url,$text); 226 } 227 228 return $text; 229 } 230 231 232 233 234 protected function compactOIDs( $text ) 235 { 236 foreach( Text::parseOID($text) as $oid=>$t ) 237 { 238 foreach( $t as $match) 239 $text = str_replace($match,'?__OID__'.$oid.'__',$text); 240 } 241 242 return $text; 243 } 244 245 246 247 protected function publishPage( $languageid ) { 248 249 $project = $this->page->getProject(); 250 251 // Nothing is written to the session from this point. so we should free the session. 252 Session::close(); 253 254 $publisher = new Publisher( $project->projectid ); 255 256 foreach( $project->getModelIds() as $modelId ) { 257 258 $pageContext = new PageContext( $this->page->objectid, Producer::SCHEME_PUBLIC ); 259 $pageContext->modelId = $modelId; 260 $pageContext->languageId = $languageid; 261 262 $pageGenerator = new PageGenerator( $pageContext ); 263 264 $publisher->addOrderForPublishing( new PublishOrder( $pageGenerator->getCache()->load()->getFilename(),$pageGenerator->getPublicFilename(), $this->page->lastchangeDate ) ); 265 } 266 267 try { 268 $publisher->publish(); 269 } catch( PublisherException $e ) { 270 $this->addErrorFor( $this->page,Messages::PUBLISHED_ERROR,[],$e->getMessage() ); 271 } 272 273 $this->page->setPublishedTimestamp(); 274 275 $this->addNoticeFor( $this->page,Messages::PUBLISHED,[], 276 implode("\n",$publisher->getDestinationFilenames() ) ); 277 278 } 279 }
Downloadmodules/cms/action/page/PageAllAction.class.php
History Thu, 15 Oct 2026 01:39:59 +0200 Jan Dankert New: A much better generation of the OpenAPI Interface documents, supports now the UI API Objects. Tue, 13 Oct 2026 22:52:59 +0200 Jan Dankert New: The UI is now able to send hierarchical form data and the server is converting it into an object. This is a very nice feature, because this enables a better OpenAPI interface. Tue, 13 Oct 2026 18:49:59 +0200 Jan Dankert New: Another action which returns an object instead of single output values. This should be the future, but it's a long way to refactore all old action methods... Tue, 14 Jan 2025 01:57:22 +0100 Jan Dankert New: Some new template element types like 'url','email','range','password','date','time', ...; New: datalists for input fields; Refactoring: Cleaner templates and actions for editing values; Wed, 17 Apr 2024 00:34:07 +0200 Jan Dankert New: Inputfields for coordinates; coordinates are stored in the now 64bit-number-field of the value. Wed, 15 Feb 2023 00:22:28 +0100 Jan Dankert Fix: Changing the Longtext format was not possible. Mon, 27 Jun 2022 02:54:38 +0200 Jan Dankert Fix: Editing of dates was broken, do not know why the code was missing up to now... Mon, 27 Jun 2022 02:22:50 +0200 Jan Dankert Fix: Saving links in PageallAction and PageelementAllAction. Thu, 2 Jun 2022 01:04:54 +0200 Jan Dankert New: Element type "checkbox" Wed, 1 Jun 2022 01:05:34 +0200 Jan Dankert New: Element types for "coordinates" and "data" Wed, 1 Jun 2022 00:11:40 +0200 Jan Dankert New: DSL as a filter for number values Sun, 10 Apr 2022 12:10:24 +0200 dankert Fix: Pagecontent must be created if the value of a pageelement is stored for the first time. Fri, 11 Mar 2022 12:26:33 +0100 dankert Fix: Catch error if something happens while publishing. Wed, 9 Mar 2022 13:28:52 +0100 dankert Refactoring: Checkbox values are always sent to the server. In the actions we must test the value with 'isTrue()' Mon, 6 Dec 2021 02:22:45 +0100 dankert Fix for: Do not store value is nothing has changed. Mon, 6 Dec 2021 02:11:33 +0100 dankert New: Do not store value is nothing has changed. Sun, 5 Dec 2021 20:33:24 +0100 dankert Cleanup: Removed unusable properties from class 'Value' and 'BaseObject'. Sat, 4 Dec 2021 01:03:54 +0100 dankert Fix: Editing all values of the page is now able to save with the new pagecontent. Sat, 4 Dec 2021 00:18:39 +0100 dankert Some security enhancements. Wed, 10 Mar 2021 23:51:22 +0100 Jan Dankert Refactoring: Cleaned the Request params. Sat, 6 Mar 2021 03:42:38 +0100 Jan Dankert New: Better permission checks. Sat, 27 Feb 2021 01:07:14 +0100 Jan Dankert Fix: Request-Id may contain '_'. Sat, 27 Feb 2021 00:29:39 +0100 Jan Dankert New: Set publishing date on publishing. Fri, 26 Feb 2021 01:06:01 +0100 Jan Dankert Refactoring accessing the request parameter values. Thu, 25 Feb 2021 01:22:10 +0100 Jan Dankert New: Edit all page elements in 1 view.