protected function getcapabilities() { $result = parent::getcapabilities(); if ($result->cached) { return $result; } $data = $result->data; if (empty($data) or floor($result->code / 100) >= 4) { jMessage::add('Server Error !', 'Error'); return $this->serviceException(); } if (preg_match('#ServiceExceptionReport#i', $data)) { return $result; } // Replace qgis server url in the XML (hide real location) $sUrl = jUrl::getFull("lizmap~service:index", array("repository" => $this->repository->getKey(), "project" => $this->project->getKey())); $sUrl = str_replace('&', '&', $sUrl); preg_match('/<get>.*\\n*.+xlink\\:href="(.+)"/i', $data, $matches); if (count($matches) < 2) { preg_match('/get onlineresource="(.+)"/i', $data, $matches); } if (count($matches) > 1) { $data = str_replace($matches[1], $sUrl, $data); } $data = str_replace('&&', '&', $data); // Add response to cache $cacheId = $this->repository->getKey() . '_' . $this->project->getKey() . '_' . $this->param('service'); $newhash = md5_file(realpath($this->repository->getPath()) . '/' . $this->project->getKey() . ".qgs"); jCache::set($cacheId . '_hash', $newhash); jCache::set($cacheId . '_mime', $result->mime); jCache::set($cacheId . '_data', $data); return (object) array('code' => 200, 'mime' => $result->mime, 'data' => $data, 'cached' => False); }
protected function getcapabilities() { $result = parent::getcapabilities(); if ($result->cached) { return $result; } $data = $result->data; if (empty($data) or floor($result->code / 100) >= 4) { jMessage::add('Server Error !', 'Error'); return $this->serviceException(); } if (preg_match('#ServiceExceptionReport#i', $data)) { return $result; } // Remove no interoparable elements $data = preg_replace('@<GetPrint[^>]*?>.*?</GetPrint>@si', '', $data); $data = preg_replace('@<ComposerTemplates[^>]*?>.*?</ComposerTemplates>@si', '', $data); // Replace qgis server url in the XML (hide real location) $sUrl = jUrl::getFull("lizmap~service:index", array("repository" => $this->repository->getKey(), "project" => $this->project->getKey())); $sUrl = str_replace('&', '&', $sUrl); preg_match('/<get>.*\\n*.+xlink\\:href="(.+)"/i', $data, $matches); if (count($matches) < 2) { preg_match('/get onlineresource="(.+)"/i', $data, $matches); } if (count($matches) > 1) { $data = str_replace($matches[1], $sUrl, $data); } $data = str_replace('&&', '&', $data); if (preg_match('@WMS_Capabilities@i', $data)) { // Update namespace $schemaLocation = "http://www.opengis.net/wms"; $schemaLocation .= " http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd"; $schemaLocation .= " http://www.opengis.net/sld"; $schemaLocation .= " http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd"; $schemaLocation .= " http://www.qgis.org/wms"; $schemaLocation .= " " . $sUrl . "SERVICE=WMS&REQUEST=GetSchemaExtension"; $data = preg_replace('@xsi:schemaLocation=".*?"@si', 'xsi:schemaLocation="' . $schemaLocation . '"', $data); if (!preg_match('@xmlns:qgs@i', $data)) { $data = preg_replace('@xmlns="http://www.opengis.net/wms"@', 'xmlns="http://www.opengis.net/wms" xmlns:qgs="http://www.qgis.org/wms"', $data); $data = preg_replace('@GetStyles@', 'qgs:GetStyles', $data); } if (!preg_match('@xmlns:sld@i', $data)) { $data = preg_replace('@xmlns="http://www.opengis.net/wms"@', 'xmlns="http://www.opengis.net/wms" xmlns:sld="http://www.opengis.net/sld"', $data); $data = preg_replace('@GetLegendGraphic@', 'sld:GetLegendGraphic', $data); } } // Add response to cache $cacheId = $this->repository->getKey() . '_' . $this->project->getKey() . '_' . $this->param('service'); $newhash = md5_file(realpath($this->repository->getPath()) . '/' . $this->project->getKey() . ".qgs"); jCache::set($cacheId . '_hash', $newhash); jCache::set($cacheId . '_mime', $result->mime); jCache::set($cacheId . '_data', $data); return (object) array('code' => 200, 'mime' => $result->mime, 'data' => $data, 'cached' => False); }
protected function getcapabilities() { //Get Cache $cacheId = $this->repository->getKey() . '_' . $this->project->getKey() . '_WMTS'; $hash = jCache::get($cacheId . '_hash'); $newhash = md5_file(realpath($this->repository->getPath()) . '/' . $this->project->getKey() . ".qgs"); $tileMatrixSetList = jCache::get($cacheId . '_tilematrixsetlist'); $layers = jCache::get($cacheId . '_layers'); if (!$tileMatrixSetList || !$layers || $hash != $newhash) { $wmsRequest = new lizmapWMSRequest($this->project, array('service' => 'WMS', 'request' => 'GetCapabilities')); $wmsResult = $wmsRequest->process(); $wms = $wmsResult->data; $wms_xml = simplexml_load_string($wms); $wms_xml->registerXPathNamespace("wms", "http://www.opengis.net/wms"); $wms_xml->registerXPathNamespace("xlink", "http://www.w3.org/1999/xlink"); $tileMatrixSetList = lizmapTiler::getTileMatrixSetList($this->project, $wms_xml); $cfgLayers = $this->project->getLayers(); $layers = array(); foreach ($cfgLayers as $n => $l) { if ($l->cached == 'True' && $l->singleTile != 'True' && strtolower($l->name) != 'overview') { $layer = lizmapTiler::getLayerTileInfo($l->name, $this->project, $wms_xml, $tileMatrixSetList); if ($layer) { $layers[] = $layer; } } } jCache::set($cacheId . '_hash', $newhash, 3600); jCache::set($cacheId . '_tilematrixsetlist', $tileMatrixSetList, 3600); jCache::set($cacheId . '_layers', $layers, 3600); } $sUrl = jUrl::getFull("lizmap~service:index", array("repository" => $this->repository->getKey(), "project" => $this->project->getKey())); $tpl = new jTpl(); $tpl->assign('url', $sUrl); $tpl->assign('repository', $this->param('repository')); $tpl->assign('project', $this->param('project')); $tpl->assign('tileMatrixSetList', $tileMatrixSetList); $tpl->assign('layers', $layers); return (object) array('code' => 200, 'mime' => 'text/xml', 'data' => $tpl->fetch('lizmap~wmts_capabilities'), 'cached' => False); }
public function testGarbage() { $this->assertFalse(jCache::garbage()); jCache::set('remainingDataKey', 'remaining data', 0, $this->profile); jCache::set('garbage1DataKey', 'data send to the garbage', 1, $this->profile); jCache::set('garbage2DataKey', 'other data send to the garbage', strtotime("-1 day"), $this->profile); sleep(2); $this->assertTrue(jCache::garbage($this->profile)); }
public function save() { foreach ($this->containers as $key => $container) { jCache::set($key, serialize($container), null, 'jforms'); } }
protected function getAnonymousRight($subject, $resource = '-') { if (empty($resource)) { $resource = '-'; } if ($this->anonacl === null) { $rights = jCache::get('acl2dbanon/rights', 'acl2db'); if ($rights === false) { // let's load rights for anonymous group $dao = jDao::get('jacl2db~jacl2rights', 'jacl2_profile'); $this->anonacl = array(); foreach ($dao->getAllAnonymousRights() as $rec) { if (isset($this->anonacl[$rec->id_aclsbj])) { if ($rec->canceled) { $this->anonacl[$rec->id_aclsbj] = false; } } else { $this->anonacl[$rec->id_aclsbj] = $rec->canceled ? false : true; } } jCache::set('acl2dbanon/rights', $this->anonacl, null, 'acl2db'); } else { $this->anonacl = $rights; } } if (!isset($this->anonacl[$subject])) { $this->anonacl[$subject] = false; jCache::set('acl2dbanon/rights', $this->anonacl, null, 'acl2db'); } // no resource given, just return the global right for the given subject if ($resource === '-') { return $this->anonacl[$subject]; } if (!isset($this->anonaclres[$subject])) { $rights = jCache::get('acl2dbanon/rightsres/' . $subject, 'acl2db'); if ($rights !== false) { $this->anonaclres[$subject] = $rights; } } // if we already have loaded the corresponding right, returns it if (isset($this->anonaclres[$subject][$resource])) { return $this->anonaclres[$subject][$resource]; } // default right for the resource is the global right $this->anonaclres[$subject][$resource] = $this->anonacl[$subject]; // if the general right is not given, check the specific right for the resource if (!$this->anonacl[$subject]) { $dao = jDao::get('jacl2db~jacl2rights', 'jacl2_profile'); $right = $dao->getAnonymousRightWithRes($subject, $resource); $this->anonaclres[$subject][$resource] = $right != false ? $right->canceled ? false : true : false; jCache::set('acl2dbanon/rightsres/' . $subject, $this->anonaclres[$subject], null, 'acl2db'); return $this->anonaclres[$subject][$resource]; } else { jCache::set('acl2dbanon/rightsres/' . $subject, $this->anonaclres[$subject], null, 'acl2db'); return true; } }
/** * Get data from map service or from the cache. * @param lizmapProject $project The project. * @param array $params Array of parameters. * @return array $data Normalized and filtered array. */ public static function getMap($project, $params, $forced = False) { // Get cache if exists $keyParams = array(); foreach ($params as $pk => $value) { if (in_array($pk, array("bbox", "format", "height", "layers", "transparent"))) { $keyParams[$pk] = $value; } } ksort($keyParams); $layers = str_replace(',', '_', $params['layers']); $crs = preg_replace('#[^a-zA-Z0-9_]#', '_', $params['crs']); // Get repository data $ser = lizmap::getServices(); $lrep = $project->getRepository(); $lproj = $project; $project = $lproj->getKey(); $repository = $lrep->getKey(); // Change to true to put some information in debug files $debug = $ser->debugMode; // Read config file for the current project $layername = $params["layers"]; $configLayers = $lproj->getLayers(); $configLayer = null; if (property_exists($configLayers, $layername)) { $configLayer = $configLayers->{$layername}; } // Set or get tile from the parent project in case of embedded layers if ($configLayer and property_exists($configLayer, 'sourceRepository') and property_exists($configLayer, 'sourceProject')) { $newRepository = (string) $configLayer->sourceRepository; $newProject = (string) $configLayer->sourceProject; $repository = $newRepository; $project = $newProject; $lrep = lizmap::getRepository($repository); if (!$lrep) { jMessage::add('The repository ' . strtoupper($repository) . ' does not exist !', 'RepositoryNotDefined'); return array('error', 'text/plain', '404'); } try { $lproj = lizmap::getProject($repository . '~' . $project); if (!$lproj) { jMessage::add('The lizmapProject ' . strtoupper($project) . ' does not exist !', 'ProjectNotDefined'); return array('error', 'text/plain', '404'); } } catch (UnknownLizmapProjectException $e) { jLog::logEx($e, 'error'); jMessage::add('The lizmapProject ' . strtoupper($project) . ' does not exist !', 'ProjectNotDefined'); return array('error', 'text/plain', '404'); } } $key = md5(serialize($keyParams)); // Get tile cache virtual profile (tile storage) // And get tile if already in cache // --> must be done after checking that parent project is involved $profile = lizmapProxy::createVirtualProfile($repository, $project, $layers, $crs); if ($debug) { lizmap::logMetric('LIZMAP_PROXY_READ_LAYER_CONFIG'); } // Has the user asked for cache for this layer ? $useCache = False; if ($configLayer) { $useCache = strtolower($configLayer->cached) == 'true'; } // Avoid using cache for requests concerning not square tiles or too big // Focus on real web square tiles $wmsClient = 'web'; if ($useCache and $params['width'] != $params['height'] and ($params['width'] > 300 or $params['height'] > 300)) { $wmsClient = 'gis'; $useCache = False; } if ($useCache and !$forced) { $tile = jCache::get($key, $profile); if ($tile) { $_SESSION['LIZMAP_GETMAP_CACHE_STATUS'] = 'read'; $mime = 'image/jpeg'; if (preg_match('#png#', $params['format'])) { $mime = 'image/png'; } if ($debug) { lizmap::logMetric('LIZMAP_PROXY_HIT_CACHE'); } return array($tile, $mime, 200); } } // *************************** // No cache hit : need to ask the tile from QGIS Server // *************************** // Construction of the WMS url : base url + parameters $url = $ser->wmsServerURL . '?'; // Add project path into map parameter $params["map"] = realpath($lproj->getQgisPath()); // Metatile : if needed, change the bbox // Avoid metatiling when the cache is not active for the layer $metatileSize = '1,1'; if ($configLayer and property_exists($configLayer, 'metatileSize')) { if (preg_match('#^[3579],[3579]$#', $configLayer->metatileSize)) { $metatileSize = $configLayer->metatileSize; } } # Metatile buffer $metatileBuffer = 5; // Also checks if gd is installed if ($metatileSize and $useCache and $wmsClient == 'web' and extension_loaded('gd') && function_exists('gd_info')) { # Metatile Size $metatileSizeExp = explode(',', $metatileSize); $metatileSizeX = (int) $metatileSizeExp[0]; $metatileSizeY = (int) $metatileSizeExp[1]; # Get requested bbox $bboxExp = explode(',', $params['bbox']); $width = $bboxExp[2] - $bboxExp[0]; $height = $bboxExp[3] - $bboxExp[1]; # Calculate factors $xFactor = (int) ($metatileSizeX / 2); $yFactor = (int) ($metatileSizeY / 2); # Calculate the new bbox $xmin = $bboxExp[0] - $xFactor * $width - $metatileBuffer * $width / $params["width"]; $ymin = $bboxExp[1] - $yFactor * $height - $metatileBuffer * $height / $params["height"]; $xmax = $bboxExp[2] + $xFactor * $width + $metatileBuffer * $width / $params["width"]; $ymax = $bboxExp[3] + $yFactor * $height + $metatileBuffer * $height / $params["height"]; # Replace request bbox by metatile bbox $params["bbox"] = "{$xmin},{$ymin},{$xmax},{$ymax}"; # Keep original param value $originalParams = array("width" => $params["width"], "height" => $params["height"]); # Replace width and height before requesting the image from qgis $params["width"] = $metatileSizeX * $params["width"] + 2 * $metatileBuffer; $params["height"] = $metatileSizeY * $params["height"] + 2 * $metatileBuffer; } // Build params before send the request to Qgis $builtParams = http_build_query($params); // Replace needed characters (not needed for php >= 5.4, just use the 4th parameter of the method http_build_query) $a = array('+', '_', '.', '-'); $b = array('%20', '%5F', '%2E', '%2D'); $builtParams = str_replace($a, $b, $builtParams); // Get data from the map server $proxyMethod = $ser->proxyMethod; $getRemoteData = lizmapProxy::getRemoteData($url . $builtParams, $proxyMethod, $debug); $data = $getRemoteData[0]; $mime = $getRemoteData[1]; $code = $getRemoteData[2]; if ($debug) { lizmap::logMetric('LIZMAP_PROXY_REQUEST_QGIS_MAP'); } if ($useCache && !preg_match('/^image/', $mime)) { $useCache = False; } // Metatile : if needed, crop the metatile into a single tile // Also checks if gd is installed if ($metatileSize and $useCache and $wmsClient == 'web' and extension_loaded('gd') && function_exists('gd_info')) { # Save original content into an image var $original = imagecreatefromstring($data); # crop parameters $newWidth = (int) $originalParams["width"]; // px $newHeight = (int) $originalParams["height"]; // px $positionX = (int) ($xFactor * $originalParams["width"]) + $metatileBuffer; // left translation of 30px $positionY = (int) ($yFactor * $originalParams["height"]) + $metatileBuffer; // top translation of 20px # create new gd image $image = imageCreateTrueColor($newWidth, $newHeight); # save transparency if needed if (preg_match('#png#', $params['format'])) { imagesavealpha($original, true); imagealphablending($image, false); $color = imagecolortransparent($image, imagecolorallocatealpha($image, 0, 0, 0, 127)); imagefill($image, 0, 0, $color); imagesavealpha($image, true); } # crop image imagecopyresampled($image, $original, 0, 0, $positionX, $positionY, $newWidth, $newHeight, $newWidth, $newHeight); # Output the image as a string (use PHP buffering) ob_start(); if (preg_match('#png#', $params['format'])) { imagepng($image, null, 9); } else { imagejpeg($image, null, 90); } $data = ob_get_contents(); // read from buffer ob_end_clean(); // delete buffer // Destroy image handlers imagedestroy($original); imagedestroy($image); if ($debug) { lizmap::logMetric('LIZMAP_PROXY_CROP_METATILE'); } } $_SESSION['LIZMAP_GETMAP_CACHE_STATUS'] = 'off'; // Store into cache if needed if ($useCache) { //~ jLog::log( ' Store into cache'); $cacheExpiration = (int) $ser->cacheExpiration; if (property_exists($configLayer, 'cacheExpiration')) { $cacheExpiration = (int) $configLayer->cacheExpiration; } jCache::set($key, $data, $cacheExpiration, $profile); $_SESSION['LIZMAP_GETMAP_CACHE_STATUS'] = 'write'; if ($debug) { lizmap::logMetric('LIZMAP_PROXY_WRITE_CACHE'); } } return array($data, $mime, $code); }
/** * Get data from map service or from the cache. * @param string $repository The repository. * @param string $project The project. * @param array $params Array of parameters. * @return array $data Normalized and filtered array. */ public static function getServiceData($repository, $project, $params) { // Get cache if exists $keyParams = $params; if (array_key_exists('map', $keyParams)) { unset($keyParams['map']); } ksort($keyParams); $key = md5(serialize($keyParams)); $layers = str_replace(',', '_', $params['layers']); $crs = preg_replace('#[^a-zA-Z0-9_]#', '_', $params['crs']); // Get repository data $ser = lizmap::getServices(); $lrep = lizmap::getRepository($repository); $lproj = lizmap::getProject($repository . '~' . $project); // Change to true to put some information in debug files $debug = $ser->debugMode; // Read config file for the current project $layername = $params["layers"]; $configLayers = $lproj->getLayers(); $configLayer = null; if (property_exists($configLayers, $layername)) { $configLayers->{$layername}; } // Set or get tile from the parent project in case of embedded layers if ($configLayer and property_exists($configLayer, 'sourceRepository') and property_exists($configLayer, 'sourceProject')) { $newRepository = (string) $configLayer->sourceRepository; $newProject = (string) $configLayer->sourceProject; $repository = $newRepository; $project = $newProject; $lrep = lizmap::getRepository($repository); $lproj = lizmap::getProject($repository . '~' . $project); } // Get tile cache virtual profile (tile storage) // And get tile if already in cache // --> must be done after checking that parent project is involved $profile = 'lizmapCache_' . $repository . '_' . $project . '_' . $layers . '_' . $crs; lizmapCache::createVirtualProfile($repository, $project, $layers, $crs); $tile = jCache::get($key, $profile); // Return tile if cache hit ! if ($tile) { //~ jLog::log( 'cache hit !'); return $tile; } // Has the user asked for cache for this layer ? $string2bool = array('false' => False, 'False' => False, 'True' => True, 'true' => True); $useCache = False; if ($configLayer) { $string2bool[$configLayer->cached]; } // Avoid using cache for requests concerning not square tiles or too big // Focus on real web square tiles $wmsClient = 'web'; if ($useCache and $params['width'] != $params['height'] and ($params['width'] > 300 or $params['height'] > 300)) { $wmsClient = 'gis'; $useCache = False; } // *************************** // No cache hit : need to ask the tile from QGIS Server // *************************** // Construction of the WMS url : base url + parameters $url = $ser->wmsServerURL . '?'; // Add project path into map parameter $params["map"] = realpath($lrep->getPath()) . '/' . $lproj->getKey() . ".qgs"; // Metatile : if needed, change the bbox // Avoid metatiling when the cache is not active for the layer $metatileSize = '1,1'; if ($configLayer and property_exists($configLayer, 'metatileSize')) { if (preg_match('#^[3579],[3579]$#', $configLayer->metatileSize)) { $metatileSize = $configLayer->metatileSize; } } # Metatile buffer $metatileBuffer = 5; // Also checks if gd is installed if ($metatileSize and $useCache and $wmsClient == 'web' and extension_loaded('gd') && function_exists('gd_info')) { # Metatile Size $metatileSizeExp = explode(',', $metatileSize); $metatileSizeX = (int) $metatileSizeExp[0]; $metatileSizeY = (int) $metatileSizeExp[1]; # Get requested bbox $bboxExp = explode(',', $params['bbox']); $width = $bboxExp[2] - $bboxExp[0]; $height = $bboxExp[3] - $bboxExp[1]; # Calculate factors $xFactor = (int) ($metatileSizeX / 2); $yFactor = (int) ($metatileSizeY / 2); # Calculate the new bbox $xmin = $bboxExp[0] - $xFactor * $width - $metatileBuffer * $width / $params["width"]; $ymin = $bboxExp[1] - $yFactor * $height - $metatileBuffer * $height / $params["height"]; $xmax = $bboxExp[2] + $xFactor * $width + $metatileBuffer * $width / $params["width"]; $ymax = $bboxExp[3] + $yFactor * $height + $metatileBuffer * $height / $params["height"]; # Replace request bbox by metatile bbox $params["bbox"] = "{$xmin},{$ymin},{$xmax},{$ymax}"; # Keep original param value $originalParams = array("width" => $params["width"], "height" => $params["height"]); # Replace width and height before requesting the image from qgis $params["width"] = $metatileSizeX * $params["width"] + 2 * $metatileBuffer; $params["height"] = $metatileSizeY * $params["height"] + 2 * $metatileBuffer; } // Build params before send the request to Qgis $builtParams = http_build_query($params); // Replace needed characters (not needed for php >= 5.4, just use the 4th parameter of the method http_build_query) $a = array('+', '_', '.', '-'); $b = array('%20', '%5F', '%2E', '%2D'); $builtParams = str_replace($a, $b, $builtParams); // Get data from the map server $proxyMethod = $ser->proxyMethod; $getRemoteData = lizmapCache::getRemoteData($url . $builtParams, $proxyMethod, $debug); $data = $getRemoteData[0]; $mime = $getRemoteData[1]; if ($useCache && !preg_match('/^image/', $mime)) { $useCache = False; } // Metatile : if needed, crop the metatile into a single tile // Also checks if gd is installed if ($metatileSize and $useCache and $wmsClient == 'web' and extension_loaded('gd') && function_exists('gd_info')) { # Save original content into an image var $original = imagecreatefromstring($data); # crop parameters $newWidth = (int) $originalParams["width"]; // px $newHeight = (int) $originalParams["height"]; // px $positionX = (int) ($xFactor * $originalParams["width"]) + $metatileBuffer; // left translation of 30px $positionY = (int) ($yFactor * $originalParams["height"]) + $metatileBuffer; // top translation of 20px # create new gd image $image = imageCreateTrueColor($newWidth, $newHeight); # save transparency if needed if (preg_match('#png#', $params['format'])) { imagesavealpha($original, true); imagealphablending($image, false); $color = imagecolortransparent($image, imagecolorallocatealpha($image, 0, 0, 0, 127)); imagefill($image, 0, 0, $color); imagesavealpha($image, true); } # crop image imagecopyresampled($image, $original, 0, 0, $positionX, $positionY, $newWidth, $newHeight, $newWidth, $newHeight); # Output the image as a string (use PHP buffering) ob_start(); if (preg_match('#png#', $params['format'])) { imagepng($image, null); } else { imagejpeg($image, null, 80); } $data = ob_get_contents(); // read from buffer ob_end_clean(); // delete buffer // Destroy image handlers imagedestroy($original); imagedestroy($image); } // Store into cache if needed if ($useCache) { //~ jLog::log( ' Store into cache'); $cacheExpiration = (int) $ser->cacheExpiration; if (property_exists($configLayer, 'cacheExpiration')) { $cacheExpiration = (int) $configLayer->cacheExpiration; } jCache::set($key, $data, $cacheExpiration, $profile); } return $data; }
/** * constructor * @param string $key : the project name * @param lizmapRepository $ rep : the repository */ public function __construct($key, $rep) { $this->key = $key; $this->repository = $rep; $file = $rep->getPath() . $key . '.qgs'; // Verifying if the files exist if (!file_exists($file)) { throw new UnknownLizmapProjectException('The QGIS project ' . $file . ' does not exist!'); } if (!file_exists($file . '.cfg')) { throw new UnknownLizmapProjectException('The lizmap config ' . $file . '.cfg does not exist!'); } // For the cache key, we use the full path of the project file // to avoid collision in the cache engine $data = false; try { $data = jCache::get($file, 'qgisprojects'); } catch (Exception $e) { // if qgisprojects profile does not exist, or if there is an // other error about the cache, let's log it jLog::log($e->getMessage(), 'error'); } if ($data === false || $data['qgsmtime'] < filemtime($file) || $data['qgscfgmtime'] < filemtime($file . '.cfg')) { // FIXME reading XML could take time, so many process could // read it and construct the cache at the same time. We should // have a kind of lock to avoid this issue. $this->readXml($key, $rep); $data['qgsmtime'] = filemtime($file); $data['qgscfgmtime'] = filemtime($file . '.cfg'); foreach ($this->cachedProperties as $prop) { $data[$prop] = $this->{$prop}; } try { jCache::set($file, $data, null, 'qgisprojects'); } catch (Exception $e) { jLog::log($e->getMessage(), 'error'); } } else { foreach ($this->cachedProperties as $prop) { $this->{$prop} = $data[$prop]; } } }