PublicLink.class.php (7264B)
1 <?php 2 3 namespace cms\generator\link; 4 5 use cms\base\Configuration; 6 use cms\generator\PageContext; 7 use cms\model\BaseObject; 8 use cms\model\File; 9 use cms\model\Folder; 10 use cms\model\Language; 11 use cms\model\Link; 12 use cms\model\Page; 13 use cms\model\Project; 14 use cms\model\Template; 15 use cms\model\TemplateModel; 16 use cms\model\Url; 17 use cms\generator\target\Dav; 18 use cms\generator\target\Fax; 19 use cms\generator\target\Ftp; 20 use cms\generator\target\Ftps; 21 use cms\generator\target\Local; 22 use cms\generator\target\NoBaseTarget; 23 use cms\generator\target\Scp; 24 use cms\generator\target\SFtp; 25 use cms\generator\target\BaseTarget; 26 use util\exception\PublisherException; 27 use util\FileUtils; 28 use logger\Logger; 29 use util\exception\UIException; 30 use util\Session; 31 32 33 34 /** 35 * Linkformatter for public links. 36 * 37 * @author Jan Dankert 38 */ 39 40 class PublicLink implements LinkFormat 41 { 42 const SCHEMA_ABSOLUTE = 1; 43 const SCHEMA_RELATIVE = 2; 44 45 const MAX_RECURSIVE_COUNT = 10; 46 47 /** 48 * @var PageContext 49 */ 50 private $pageContext; 51 52 /** 53 * PublicLink constructor. 54 * @param $pageContext PageContext 55 */ 56 public function __construct($pageContext) 57 { 58 $this->pageContext = $pageContext; 59 } 60 61 62 /** 63 * Creates a link from an object to another object. 64 * 65 * @param $from \cms\model\BaseObject 66 * @param $to \cms\model\BaseObject 67 * 68 * @return string the url 69 */ 70 public function linkToObject( BaseObject $from, BaseObject $to ) { 71 72 $publishConfig = Configuration::subset('publish'); 73 74 $from->load(); 75 $fromProject = $from->getProject()->load(); 76 77 $schema = $fromProject->linkAbsolute?self::SCHEMA_ABSOLUTE:self::SCHEMA_RELATIVE; 78 79 $counter = 0; 80 while( $to->typeid == BaseObject::TYPEID_LINK ) 81 { 82 if ( $counter++ > self::MAX_RECURSIVE_COUNT) 83 throw new \LogicException("Too much redirects while following a link. Stopped at #".$to->objectid ); 84 85 $link = new Link( $to->objectid ); 86 $link->load(); 87 88 $to = new BaseObject( $link->linkedObjectId ); 89 $to->objectLoad(); 90 } 91 92 switch( $to->typeid ) { 93 case BaseObject::TYPEID_FILE: 94 case BaseObject::TYPEID_IMAGE: 95 case BaseObject::TYPEID_TEXT: 96 97 $f = new File($to->objectid); 98 99 $f->load(); 100 $filename = $f->filename(); 101 102 if ( $fromProject->publishFileExtension && ! $fromProject->content_negotiation ) 103 // Add file extension 104 $filename .= '.'.$f->extension; 105 106 break; 107 108 case BaseObject::TYPEID_PAGE: 109 110 if ($fromProject->cut_index && $to->filename == $publishConfig->get('default','index')) { 111 $filename = ''; // Link auf Index-Datei, der Dateiname bleibt leer. 112 } else { 113 114 $page = new Page($to->objectid); 115 $page->load(); 116 117 $template = new Template( $page->templateid ); 118 $template->load(); 119 120 if ( ! $template->publish ) { 121 // fixme: target page is not publishable - what to do here? 122 return ''; 123 } 124 125 $parentFolder = new Folder($page->parentid); 126 $parentFolder->load(); 127 128 $format = $publishConfig->get('format','{filename}{language_sep}{language}{type_sep}{type}'); 129 $format = str_replace('{filename}', $page->filename(), $format); 130 131 $allLanguages = $fromProject->getLanguageIds(); 132 $allModels = $fromProject->getModelIds(); 133 134 $withLanguage = 135 !$fromProject->content_negotiation && 136 $fromProject->publishPageExtension && 137 (count($allLanguages) > 1 || $publishConfig->get('filename_language','auto') == 'always'); 138 139 $withModel = 140 ! $fromProject->content_negotiation && 141 $fromProject->publishPageExtension && 142 (count($allModels) > 1 || $publishConfig->get('filename_type','always') == 'always'); 143 144 $languagePart = ''; 145 $typePart = ''; 146 147 if ($withLanguage ) { 148 $l = new Language($this->pageContext->languageId); 149 $l->load(); 150 $languagePart = $l->isoCode; 151 } 152 153 if ( $withModel ) { 154 $templateModel = new TemplateModel( $page->templateid, $this->pageContext->modelId ); 155 $templateModel->load(); 156 157 $typePart = $templateModel->extension; 158 } 159 160 $languageSep = $languagePart? $publishConfig->get('language_sep','.') :''; 161 $typeSep = $typePart ? $publishConfig->get('type_sep' ,'.') :''; 162 163 $format = str_replace('{language}' ,$languagePart ,$format ); 164 $format = str_replace('{language_sep}',$languageSep ,$format ); 165 $format = str_replace('{type}' ,$typePart ,$format ); 166 $format = str_replace('{type_sep}' ,$typeSep ,$format ); 167 168 $filename = $format; 169 } 170 171 break; 172 173 case BaseObject::TYPEID_URL: 174 $url = new Url( $to->objectid ); 175 $url->load(); 176 return $url->url; 177 178 default: 179 throw new \LogicException("Could not build a link to the unknown Type ".$to->typeid.':'.$to->getType() ); 180 } 181 182 183 if ( $from->projectid != $to->projectid ) 184 { 185 // BaseTarget object is in another project. 186 // we have to use absolute URLs. 187 $schema = self::SCHEMA_ABSOLUTE; 188 189 // BaseTarget is in another Project. So we have to create an absolute URL. 190 $targetProject = Project::create( $to->projectid )->load(); 191 $host = $targetProject->url; 192 193 if ( ! strpos($host,'//' ) === FALSE ) { 194 // No protocol in hostname. So we have to prepend the URL with '//'. 195 $host = '//'.$host; 196 } 197 } 198 else { 199 $host = ''; 200 } 201 202 203 204 205 if ( $schema == self::SCHEMA_RELATIVE ) 206 { 207 $folder = new Folder( $from->getParentFolderId() ); 208 $folder->load(); 209 $fromPathFolders = $folder->parentObjectFileNames(false,true); 210 211 $folder = new Folder($to->getParentFolderId() ); 212 213 $toPathFolders = $folder->parentObjectFileNames(false, true); 214 215 // Shorten the relative URL 216 // if the actual page is /path/folder1/page1 217 // and the target page is /path/folder2/page2 218 // we shorten the link from ../../path/folder2/page2 219 // to ../folder2/page2 220 foreach( $fromPathFolders as $folderId => $folderFileName ) { 221 if ( count($toPathFolders) >= 1 && array_keys($toPathFolders)[0] == $folderId ) { 222 unset( $fromPathFolders[$folderId] ); 223 unset( $toPathFolders [$folderId] ); 224 }else { 225 break; 226 } 227 228 } 229 230 if ( $fromPathFolders ) 231 $path = str_repeat( '../',count($fromPathFolders) ); 232 else 233 $path = './'; // Just to clarify- this could be blank too. 234 235 if ( $toPathFolders ) 236 $path .= implode('/',$toPathFolders).'/'; 237 } 238 else { 239 // Absolute Pfadangaben 240 $folder = new Folder( $to->getParentFolderId() ); 241 $toPathFolders = $folder->parentObjectFileNames(false, true); 242 243 $path = '/'; 244 245 if ( $toPathFolders ) 246 $path .= implode('/',$toPathFolders).'/'; 247 } 248 249 250 $uri = $host . $path . $filename; 251 252 if( !$uri ) 253 $uri = '.'; 254 255 return $uri; 256 } 257 258 }