Webylon 3.2 API Docs
  • Package
  • Class
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • 1c
    • exchange
      • catalog
  • auth
  • Booking
  • building
    • company
  • cart
    • shipping
    • steppedcheckout
  • Catalog
    • monument
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • Address
  • AddSubsiteTask
  • Announcement
  • AnnouncementDecorator
  • AnnouncementHolder
  • AssociatedFolderDecorator
  • AttachedFiles
  • AudioPhpCaptcha
  • AutoCompleteField
  • Base1CExchanger
  • BookingOrder_StatusLog
  • CalendarUtil
  • CalendarWidgetExtention
  • CatalogCatalogLinkedDecorator
  • CatalogOldFieldsDecorator
  • CatalogProductLinkedDecorator
  • CheckoutStep_ShippingMethod
  • ChequePayment
  • ClearHistoryTask
  • ClientEmailOrderNotification_SiteConfig
  • ClientVKOrderNotification_SiteConfig
  • CommentsSiteConfig
  • ContactsPage
  • CookieExtention
  • CostTableShippingRate
  • CustomMenu
  • CustomMenuAdmin
  • CustomMenuDecorator
  • CustomMenuHolder
  • CustomMenuItem
  • CustomPayment
  • DataObjectLoggerExtension
  • DataObjectSubsites
  • DefaultCMSActionDecorator
  • DocPage
  • DocumentDirection
  • DocumentHaving
  • DocumentSearchForm
  • DocumentSiteConfig
  • DocumentsPage
  • DocumentType
  • DOMUtil
  • ExtendPageAnnouncement
  • ExtendPagePoll
  • FavoriteExtention
  • FavoritePage
  • FavoriteProductMemberExtention
  • FavoriteProducts
  • FileOversizeDecorator
  • FindCyrillicSiteConfig
  • FolderRenameTask
  • GDMergeAlpha
  • HomePage
  • ImageAutoResize
  • ImageResizeTask
  • ImportCatalog1C_Importer
  • ImportCatalogSiteConfig
  • ImportSiteConfig
  • LoggerAdmin
  • LogItem
  • ManagerEmailOrderNotification_SiteConfig
  • MapObject
  • MapObjectGroup
  • MapPage
  • MediawebForm
  • MemberLoggerExtension
  • MonumentsSiteConfig
  • MultiUploadConfig
  • NearestEventExtention
  • NewDocumentsAdmin
  • NewsArchive
  • NewsEntry
  • NewsHolder
  • NewsSiteConfig
  • Order_StatusLog
  • Orders1CExchange_Exporter
  • PageHideFieldsExtension
  • PageInformerRates
  • PageInformerWeather
  • Payment_Failure
  • Payment_Processing
  • Payment_Result
  • Payment_Success
  • PaymentMethod
  • PaymentSiteConfig
  • PayPalPayment
  • PayPalPayment_Handler
  • PhoneField
  • PhotoAlbumExtentions
  • PhpCaptcha
  • PhpCaptchaColour
  • PhpCaptchaField
  • phpMorphy
  • phpMorphy_AncodesResolver_AsIs
  • phpMorphy_AncodesResolver_Proxy
  • phpMorphy_AncodesResolver_ToDialingAncodes
  • phpMorphy_AncodesResolver_ToText
  • phpMorphy_AnnotDecoder_Base
  • phpMorphy_AnnotDecoder_Common
  • phpMorphy_AnnotDecoder_Factory
  • phpMorphy_AnnotDecoder_Predict
  • phpMorphy_FilesBundle
  • phpMorphy_Fsa
  • phpMorphy_Fsa_Decorator
  • phpMorphy_Fsa_Proxy
  • phpMorphy_Fsa_Sparse_File
  • phpMorphy_Fsa_Sparse_Mem
  • phpMorphy_Fsa_Sparse_Shm
  • phpMorphy_Fsa_Tree_File
  • phpMorphy_Fsa_Tree_Mem
  • phpMorphy_Fsa_Tree_Shm
  • phpMorphy_Fsa_WordsCollector
  • phpMorphy_GramInfo
  • phpMorphy_GramInfo_AncodeCache
  • phpMorphy_GramInfo_Decorator
  • phpMorphy_Graminfo_File
  • phpMorphy_Graminfo_Mem
  • phpMorphy_GramInfo_Proxy
  • phpMorphy_GramInfo_Proxy_WithHeader
  • phpMorphy_GramInfo_RuntimeCaching
  • phpMorphy_Graminfo_Shm
  • phpMorphy_GrammemsProvider_Base
  • phpMorphy_GrammemsProvider_Decorator
  • phpMorphy_GrammemsProvider_Empty
  • phpMorphy_GrammemsProvider_Factory
  • phpMorphy_GrammemsProvider_ForFactory
  • phpMorphy_GrammemsProvider_ru_RU
  • phpMorphy_GramTab
  • phpMorphy_GramTab_Empty
  • phpMorphy_GramTab_Proxy
  • phpMorphy_Link
  • phpMorphy_Link_Annot
  • phpMorphy_Link_Base
  • phpMorphy_Morphier_Base
  • phpMorphy_Morphier_Bulk
  • phpMorphy_Morphier_Common
  • phpMorphy_Morphier_Empty
  • phpMorphy_Morphier_Finder_Base
  • phpMorphy_Morphier_Finder_Common
  • phpMorphy_Morphier_Finder_Predict_Databse
  • phpMorphy_Morphier_Finder_Predict_Suffix
  • phpMorphy_Morphier_Helper
  • phpMorphy_Morphier_Predict_Database
  • phpMorphy_Morphier_Predict_Suffix
  • phpMorphy_Morphier_PredictCollector
  • phpMorphy_Semaphore
  • phpMorphy_Semaphore_Empty
  • phpMorphy_Semaphore_Nix
  • phpMorphy_Semaphore_Win
  • phpMorphy_Shm_Cache
  • phpMorphy_Shm_Cache_FileDescriptor
  • phpMorphy_Shm_Header
  • phpMorphy_Source_Dba
  • phpMorphy_Source_Fsa
  • phpMorphy_State
  • phpMorphy_Storage
  • phpMorphy_Storage_Factory
  • phpMorphy_Storage_File
  • phpMorphy_Storage_Mem
  • phpMorphy_Storage_Proxy
  • phpMorphy_Storage_Shm
  • phpMorphy_UnicodeHelper
  • phpMorphy_UnicodeHelper_Base
  • phpMorphy_UnicodeHelper_MultiByteFixed
  • phpMorphy_UnicodeHelper_singlebyte
  • phpMorphy_UnicodeHelper_ucs_2be
  • phpMorphy_UnicodeHelper_ucs_2le
  • phpMorphy_UnicodeHelper_ucs_4be
  • phpMorphy_UnicodeHelper_ucs_4le
  • phpMorphy_UnicodeHelper_utf_16_Base
  • phpMorphy_UnicodeHelper_utf_16be
  • phpMorphy_UnicodeHelper_utf_16le
  • phpMorphy_UnicodeHelper_utf_32_Base
  • phpMorphy_UnicodeHelper_utf_32be
  • phpMorphy_UnicodeHelper_utf_32le
  • phpMorphy_UnicodeHelper_utf_8
  • phpMorphy_WordDescriptor
  • phpMorphy_WordDescriptor_Collection
  • phpMorphy_WordDescriptor_Collection_Serializer
  • phpMorphy_WordForm
  • ProductCatalogImportTask
  • ProductOldFieldsDecorator
  • ProductParamValue_BoolValueField
  • ProductParamValue_MultiValueField
  • ProductParamValue_MultiValueSetField
  • ProductParamValue_ValueField
  • ProductProductLinkedDecorator
  • PublHolder
  • Publication
  • PublicationSiteTree
  • RatingDataObject
  • RatingExtension
  • RealtySiteConfigDecorator
  • RecentComments
  • RecentFiles
  • RecentPages
  • RelatedPageLink
  • RoomRate_PriceField
  • RussianUpLower
  • SberbankPayment
  • SberbankPayment_Handler
  • SetMainSiteHomePageTypeTask
  • ShippingEstimator
  • ShippingPackage
  • ShowUserFromExtension
  • ShowViewedProductExtention
  • SiteConfigDecorator
  • SiteConfigSubsites
  • SiteTreeSubsites
  • SMSCOrderNotification_SiteConfig
  • SMSOrderNotification_SiteConfig
  • Socle
  • SocleSize
  • SortCMSActionDecorator
  • SS_Report_FakeQuery
  • SSMorphy
  • SSNController
  • SteppedCheckout_PageMessages
  • SubpageListField
  • SubscribeFormAllPagesExtension
  • SubsiteDropdownField
  • SubsiteReportWrapper
  • TableShippingRate
  • UnitellerPayment
  • UnitellerPayment_Handler
  • UnmoderatedComments
  • VAT
  • VideoManager
  • VideoSiteConfig
  • ViewedProductExtention
  • WatermarkImage
  • WatermarkSiteConfig
  • WeightTableShippingRate
  • XMLValidate
  • YaMoneyPayment
  • YaMoneyPayment_Handler
  • YMLExporter
  • YMLSiteConfig

Interfaces

  • PaymentObjectInterface
  • phpMorphy_AncodesResolver_Interface
  • phpMorphy_AnnotDecoder_Interface
  • phpMorphy_Fsa_Interface
  • phpMorphy_GramInfo_Interace
  • phpMorphy_GrammemsProvider_Interface
  • phpMorphy_GramTab_Interface
  • phpMorphy_Morphier_Finder_Interface
  • phpMorphy_Morphier_Interface
  • phpMorphy_Shm_Cache_Interface
  • phpMorphy_Source_Interface

Exceptions

  • phpMorphy_Exception

Functions

  • column_sort
  • column_sort_callback_basic
  • encodeFileForEmail
  • encodeMultipart
  • getMimeType
  • htmlEmail
  • loadMimeTypes
  • phpmorphy_overload_mb_funcs
  • plaintextEmail
  • processHeaders
  • QuotedPrintable_encode
  • supressOutput
  • validEmailAddr
  • wrapImagesInline
  • wrapImagesInline_rewriter
  1 <?php
  2  /**
  3  * This file is part of phpMorphy library
  4  *
  5  * Copyright c 2007-2008 Kamaev Vladimir <heromantor@users.sourceforge.net>
  6  *
  7  * This library is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU Lesser General Public
  9  * License as published by the Free Software Foundation; either
 10  * version 2 of the License, or (at your option) any later version.
 11  *
 12  * This library is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  * Lesser General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU Lesser General Public
 18  * License along with this library; if not, write to the
 19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 20  * Boston, MA 02111-1307, USA.
 21  */
 22 
 23 if(!defined('PHPMORPHY_SHM_SEGMENT_SIZE')) {
 24     define('PHPMORPHY_SHM_SEGMENT_SIZE', 1024 * 1024 * 24);
 25 }
 26 
 27 if(!defined('PHPMORPHY_SHM_SEGMENT_ID')) {
 28     define('PHPMORPHY_SHM_SEGMENT_ID', 0x54358308);
 29 }
 30 
 31 if(!defined('PHPMORPHY_SEMAPHORE_KEY')) {
 32     define('PHPMORPHY_SEMAPHORE_KEY', PHPMORPHY_SHM_SEGMENT_ID + 1);
 33 }
 34 
 35 if(!defined('PHPMORPHY_SHM_HEADER_MAX_SIZE')) {
 36     define('PHPMORPHY_SHM_HEADER_MAX_SIZE', 1024 * 32);
 37 }
 38 
 39 interface phpMorphy_Shm_Cache_Interface {
 40     function close();
 41     function get($filePath);
 42     function clear();
 43     function delete($filePath);
 44     function reload($filePath);
 45     function reloadIfExists($filePath);
 46     function free();
 47 }
 48 
 49 class phpMorphy_Shm_Cache_FileDescriptor {
 50     private
 51         $shm_id,
 52         $file_size,
 53         $offset;
 54     
 55     function __construct($shmId, $fileSize, $offset) {
 56         $this->shm_id = $shmId;
 57         $this->file_size = $fileSize;
 58         $this->offset = $offset;
 59     }
 60     
 61     function getShmId() { return $this->shm_id; }
 62     function getFileSize() { return $this->file_size; }
 63     function getOffset() { return $this->offset; }
 64 }
 65 
 66 abstract class phpMorphy_Semaphore {
 67     abstract function lock();
 68     abstract function unlock();
 69     
 70     static function create($key, $empty = false) {
 71         if(!$empty) {
 72             if (0 == strcasecmp($GLOBALS['__phpmorphy_substr'](PHP_OS, 0, 3), 'WIN')) {
 73                 $clazz = 'phpMorphy_Semaphore_Win';
 74             } else {
 75                 $clazz = 'phpMorphy_Semaphore_Nix';
 76             }
 77         } else {
 78             $clazz = 'phpMorphy_Semaphore_Empty';
 79         }
 80         
 81         return new $clazz($key);
 82     }
 83 };
 84 
 85 class phpMorphy_Semaphore_Empty extends phpMorphy_Semaphore {
 86     function lock() { }
 87     function unlock() { }
 88     function remove() { }
 89 };
 90 
 91 // TODO: implement this
 92 class phpMorphy_Semaphore_Win extends phpMorphy_Semaphore {
 93     const DIR_NAME = 'phpmorphy_semaphore';
 94     const USLEEP_TIME = 100000; // 0.1s
 95     const MAX_SLEEP_TIME = 5000000; // 5sec
 96     
 97     protected $dir_path;
 98     
 99     protected function __construct($key) {
100         $this->dir_path = $this->getTempDir() . DIRECTORY_SEPARATOR . self::DIR_NAME . "_$key";
101         
102         register_shutdown_function(array($this, 'unlock'));
103     }
104     
105     protected function getTempDir() {
106         if(false === ($result = getenv('TEMP'))) {
107             if(false === ($result = getenv('TMP'))) {
108                 throw new phpMorphy_Exception("Can`t get temporary directory");
109             }
110         }
111         
112         return $result;
113     }
114     
115     function lock() {
116         for($i = 0; $i < self::MAX_SLEEP_TIME; $i += self::USLEEP_TIME) {
117             if(!file_exists($this->dir_path)) {
118                 if(false !== @mkdir($this->dir_path, 0644)) {
119                     return true;
120                 }
121             }
122             
123             usleep(self::USLEEP_TIME);
124         }
125         
126         throw new phpMorphy_Exception("Can`t acquire semaphore");
127     }
128     
129     function unlock() {
130         @rmdir($this->dir_path);
131     }
132     
133     function remove() {
134     }
135 }
136 
137 class phpMorphy_Semaphore_Nix extends phpMorphy_Semaphore {
138     const DEFAULT_PERM = 0644;
139     
140     private $sem_id = false;
141     
142     protected function __construct($key) {
143         if(false === ($this->sem_id = sem_get($key, 1, self::DEFAULT_PERM, true))) {
144             throw new phpMorphy_Exception("Can`t get semaphore for '$key' key");
145         }
146     }
147     
148     function lock() {
149         if(false === sem_acquire($this->sem_id)) {
150             throw new phpMorphy_Exception("Can`t acquire semaphore");
151         }
152     }
153     
154     function unlock() {
155         if(false === sem_release($this->sem_id)) {
156             throw new phpMorphy_Exception("Can`t release semaphore");
157         }
158     }
159     
160     function remove() {
161         sem_remove($this->sem_id);
162     }
163 }
164 
165 class phpMorphy_Shm_Header {
166     protected
167         $max_size,
168         $segment_id,
169         $files_map = array(),
170         $free_map = array();
171     
172     function __construct($segmentId, $maxSize) {
173         $this->max_size = (int)$maxSize;
174         $this->segment_id = $segmentId;
175         
176         $this->clear();
177     }
178         
179     function lookup($filePath) {
180         if(!$this->exists($filePath)) {
181             throw new phpMorphy_Exception("'$filePath' not found in shm");
182         }
183         
184         return $this->files_map[$this->normalizePath($filePath)];
185     }
186     
187     function exists($filePath) {
188         return isset($this->files_map[$this->normalizePath($filePath)]);
189     }
190     
191     function register($filePath, $fh) {
192         if($this->exists($filePath)) {
193             throw new phpMorphy_Exception("Can`t register, '$filePath' already exists");
194         }
195         
196         if(false === ($stat = fstat($fh))) {
197             throw new phpMorphy_Exception("Can`t fstat '$filePath' file");
198         }
199         
200         $file_size = $stat['size'];
201         
202         $offset = $this->getBlock($file_size);
203         
204         $entry = array(
205             'offset' => $offset,
206             'mtime' => $stat['mtime'],
207             'size' => $file_size,
208             'shm_id' => $this->segment_id
209         );
210         
211         $this->files_map[$this->normalizePath($filePath)] = $entry;
212         
213         return $entry;
214     }
215     
216     function delete($filePath) {
217         $data = $this->lookup($filePath);
218         
219         unset($this->files_map[$this->normalizePath($filePath)]);
220         
221         $this->freeBlock($data['offset'], $data['size']);
222     }
223     
224     function clear() {
225         $this->files_map = array();
226         $this->free_map = array(0 => $this->max_size);
227     }
228     
229     function getAllFiles() {
230         return $this->files_map;
231     }
232     
233     protected function registerBlock($offset, $size) {
234         $old_size = $this->free_map[$offset];
235         
236         if($old_size < $size) {
237             throw new phpMorphy_Exception("Too small free block for register(free = $old_size, need = $size)");
238         }
239         
240         unset($this->free_map[$offset]);
241         
242         if($old_size > $size) {
243             $this->free_map[$offset + $size] = $old_size - $size;
244         }
245     }
246     
247     protected function freeBlock($offset, $size) {
248         $this->free_map[$offset] = $size;
249         $this->defrag();
250     }
251     
252     protected function defrag() {
253         ksort($this->free_map);
254         
255         $map_count = count($this->free_map);
256         
257         if($map_count < 2) {
258             return;
259         }
260         
261         $keys = array_keys($this->free_map);
262         $i = 0;
263         $prev_offset = $keys[$i];
264         
265         for($i++; $i < $map_count; $i++) {
266             $offset = $keys[$i];
267             
268             if($prev_offset + $this->free_map[$prev_offset] == $offset) {
269                 // merge
270                 $this->free_map[$prev_offset] += $this->free_map[$offset];
271                 
272                 unset($this->free_map[$offset]);
273             } else {
274                 $prev_offset = $offset;
275             }
276         }
277     }
278     
279     protected function getBlock($fileSize) {
280         foreach($this->free_map as $offset => $size) {
281             if($size >= $fileSize) {
282                 $this->registerBlock($offset, $fileSize);
283                 
284                 return $offset;
285             }
286         }
287         
288         throw new phpMorphy_Exception("Can`t find free space for $size block");
289     }
290     
291     protected function normalizePath($path) {
292         return $path;
293     }
294 }
295 
296 class phpMorphy_Shm_Cache implements phpMorphy_Shm_Cache_Interface {
297     const DEFAULT_MODE = 0644;
298     const READ_BLOCK_SIZE = 8192;
299 
300     protected static $EXTENSION_PRESENT = null;
301     
302     protected
303         $options,
304         $semaphore,
305         $segment
306         ;
307     
308     function __construct($options = array(), $clear = false) {
309         if(!isset(self::$EXTENSION_PRESENT)) {
310             self::$EXTENSION_PRESENT = extension_loaded('shmop');
311         }
312         
313         if(!self::$EXTENSION_PRESENT) {
314             throw new phpMorphy_Exception("shmop extension needed");
315         }
316         
317         $this->options = $options = $this->repairOptions($options);
318         
319         $this->semaphore = phpMorphy_Semaphore::create($options['semaphore_key'], $options['no_lock']);
320         
321         $this->segment = $this->getSegment($options['segment_id'], $options['segment_size']);
322         
323         if($clear) {
324             $this->semaphore->remove();
325             $this->initHeaderObject($this->segment);
326         }
327     }
328     
329     static function clearSemaphore($semaphoreId = null) {
330         $semaphoreId = isset($semaphoreId) ? $semaphoreId : PHPMORPHY_SEMAPHORE_KEY;
331         
332         $sem = phpMorphy_Semaphore::create($semaphoreId);
333         return $sem->remove();
334     }
335     
336     protected function repairOptions($options) {
337         $defaults = array(
338             'semaphore_key' => PHPMORPHY_SEMAPHORE_KEY,
339             'segment_id' => PHPMORPHY_SHM_SEGMENT_ID,
340             'segment_size' => PHPMORPHY_SHM_SEGMENT_SIZE,
341             'with_mtime' => false,
342             'header_max_size' => PHPMORPHY_SHM_HEADER_MAX_SIZE,
343             'no_lock' => false,
344         );
345         
346         return (array)$options + $defaults;
347     }
348     
349     function close() {
350         if(isset($this->segment)) {
351             shmop_close($this->segment);
352             $this->segment = null;
353         }
354     }
355     
356     protected function safeInvoke($filePath, $method) {
357         $this->lock();
358         
359         try {
360             $header = $this->readHeader();
361             
362             $result = $this->$method($filePath, $header);
363             
364             // writeHeader is atomic
365             $this->writeHeader($this->segment, $header);
366             
367             $this->unlock();
368             
369             return $result;
370         } catch (Exception $e) {
371             $this->unlock();
372             
373             throw $e;
374         }
375     }
376     
377     protected function doGet($filePath, $header) {
378         $result = array();
379         foreach((array)$filePath as $file) {
380             $result[$file] = $this->getSingleFile($header, $file);
381         }
382         
383         if(!is_array($filePath)) {
384             $result = $result[$filePath];
385         }
386         
387         return $result;
388     }
389     
390     function get($filePath) {
391         if(!is_array($filePath)) {
392             return $this->createFileDescriptor($this->safeInvoke($filePath, 'doGet'));
393         } else {
394             $result = array();
395             
396             foreach($this->safeInvoke($filePath, 'doGet') as $file => $item) {
397                 $result[$file] = $this->createFileDescriptor($item);
398             }
399             
400             return $result;
401         }
402     }
403 
404     
405     protected function getSingleFile($header, $filePath) {
406         try {
407             $fh = false;
408             
409             if(false !== $header->exists($filePath)) {
410                 $result = $header->lookup($filePath);
411                 
412                 if(!$this->options['with_mtime']) {
413                     return $result;
414                 }
415                 
416                 if(false === ($mtime = filemtime($filePath))) {
417                     throw new phpMorphy_Exception("Can`t get mtime attribute for '$filePath' file");
418                 }
419                 
420                 if($result['mtime'] === $mtime) {
421                     return $result;
422                 }
423                 
424                 $fh = $this->openFile($filePath);
425                 
426                 // update
427                 $header->delete($filePath);
428                 $result = $header->register($filePath, $fh);
429                 
430                 $this->saveFile($fh, $result['offset']);
431                 
432                 fclose($fh);
433                 
434                 return $result;
435             }
436             
437             // register
438             $fh = $this->openFile($filePath);
439             
440             $result = $header->register($filePath, $fh);
441             
442             $this->saveFile($fh, $result['offset']);
443             
444             fclose($fh);
445             
446             return $result;
447         } catch (Exception $e) {
448             if(isset($fh) && $fh !== false) {
449                 fclose($fh);
450             }
451             
452             throw $e;
453         }
454     }
455     
456     protected function doClear($filePath, $header) {
457         $header->clear();
458     }
459     
460     function clear() {
461         $this->safeInvoke(null, 'doClear');
462     }
463     
464     protected function doDelete($filePath, $header) {
465         foreach((array)$filePath as $file) {
466             $hdr->delete($file);
467         }
468     }
469     
470     function delete($filePath) {
471         $this->safeInvoke($filePath, 'doDelete');
472     }
473     
474     protected function doReload($filePath, $header) {
475         $return = array();
476                 
477         foreach((array)$filePath as $file) {
478             $fh = $this->openFile($file);
479             
480             // update
481             $hdr->delete($file);
482             $result = $hdr->register($file, $fh);
483             
484             $this->saveFile($fh, $result['offset']);
485             
486             fclose($fh);
487             $fh = false;
488             
489             $return[$file] = $result;
490         }
491         
492         if(!is_array($filePath)) {
493             $return = $return[$filePath];
494         }
495         
496         return $return;
497     }
498     
499     function reload($filePath) {
500         if(!is_array($filePath)) {
501             return $this->createFileDescriptor($this->safeInvoke($filePath, 'doReload'));
502         } else {
503             $result = array();
504             
505             foreach($this->safeInvoke($filePath, 'doReload') as $file => $item) {
506                 $result[$file] = $this->createFileDescriptor($item);
507             }
508             
509             return $result;
510         }
511     }
512     
513     function reloadIfExists($filePath) {
514         try {
515             return $this->reload($filePath);
516         } catch (Exception $e) {
517             return false;
518         }
519     }
520     
521     function free() {
522         $this->lock();
523         if(false === shmop_delete($this->segment)) {
524             throw new phpMorphy_Exception("Can`t delete $this->segment segment");
525         }
526         
527         $this->close();
528         
529         $this->unlock();
530     }
531     
532     function getFilesList() {
533         $this->lock();
534         
535         $result = $this->readHeader()->getAllFiles();
536         
537         $this->unlock();
538         
539         return $result;
540     }
541     
542     protected function createFileDescriptor($result) {
543         return new phpMorphy_Shm_Cache_FileDescriptor($this->segment, $result['size'], $this->options['header_max_size'] + $result['offset']);
544     }
545     
546     protected function openFile($filePath) {
547         if(false === ($fh = fopen($filePath, 'rb'))) {
548             throw new phpMorphy_Exception("Can`t open '$filePath' file");
549         }
550         
551         return $fh;
552     }
553     
554     protected function lock() {
555         $this->semaphore->lock();
556     }
557     
558     protected function unlock() {
559         $this->semaphore->unlock();
560     }
561     
562     protected function getFilesOffset() {
563         return $this->options['header_max_size'];
564     }
565     
566     protected function getMaxOffset() {
567         return $this->options['segment_size'] - 1;
568     }
569     
570     protected function saveFile($fh, $offset) {
571         if(false === ($stat = fstat($fh))) {
572             throw new phpMorphy_Exception("Can`t fstat '$filePath'");
573         }
574         
575         $file_size = $stat['size'];
576         $chunk_size = self::READ_BLOCK_SIZE;
577         
578         $max_offset = $offset + $file_size;
579         
580         if($max_offset >= $this->getMaxOffset()) {
581             throw new phpMorphy_Exception("Can`t write '$filePath' file to $offset offset, not enough space");
582         }
583         
584         $i = 0;
585         while(!feof($fh)) {
586             $data = fread($fh, $chunk_size);
587             if(false === (shmop_write($this->segment, $data, $this->getFilesOffset() + $offset + $i))) {
588                 throw new phpMorphy_Exception("Can`t write chunk of file '$filePath' to shm");
589             }
590             
591             $i += $chunk_size;
592         }
593     }
594     
595     protected function getSegment($segmentId, $segmentSize) {
596         $this->lock();
597         
598         try {
599             $shm_id = $this->openSegment($segmentId, $segmentSize, $is_new);
600             
601             if($is_new) {
602                 $this->initHeaderObject($shm_id, false);
603             }
604         } catch (Exception $e) {
605             $this->unlock();
606             throw $e;
607         }
608         
609         $this->unlock();
610         
611         return $shm_id;
612     }
613     
614     protected function initHeaderObject($shmId, $lock = true) {
615         if($lock) {
616             $this->lock();
617             $this->writeHeader($shmId, $this->createHeader($shmId));
618             $this->unlock();
619         } else {
620             $this->writeHeader($shmId, $this->createHeader($shmId));
621         }
622     }
623     
624     protected function readHeader() {
625         if(false === ($data = shmop_read($this->segment, 0, $this->getFilesOffset()))) {
626             throw new phpMorphy_Exception("Can`t read header for " . $this->segment);
627         }
628         
629         if(false === ($result = unserialize($data))) {
630             throw new phpMorphy_Exception("Can`t unserialize header for " . $this->segment);
631         }
632         
633         return $result;
634     }
635     
636     protected function writeHeader($shmId, phpMorphy_Shm_Header $header) {
637         $data = serialize($header);
638         
639         if($GLOBALS['__phpmorphy_strlen']($data) > $this->getFilesOffset()) {
640             throw new phpMorphy_Exception("Too long header, try increase PHPMORPHY_SHM_HEADER_MAX_SIZE");
641         }
642         
643         if(false === shmop_write($shmId, $data, 0)) {
644             throw new phpMorphy_Exception("Can`t write shm header");
645         }
646     }
647     
648     protected function createHeader($shmId) {
649         return new phpMorphy_Shm_Header($shmId, $this->options['segment_size']);
650     }
651     
652     protected function openSegment($segmentId, $size, &$new = null) {
653         $new = false;
654         
655         if(false === ($handle = @shmop_open($segmentId, 'w', 0, 0))) {
656             if(false === ($handle = shmop_open($segmentId, 'n', self::DEFAULT_MODE, $size))) {
657                 throw new phpMorphy_Exception("Can`t create SHM segment with '$segmentId' id and $size size");
658             }
659             
660             $new = true;
661         }
662         
663         return $handle;
664     }
665 }
666 
667 
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -
Webylon 3.2 API Docs API documentation generated by ApiGen 2.8.0