Overview

Packages

  • None
  • Wicked

Classes

  • Text_Wiki_Parse_Heading2
  • Text_Wiki_Parse_Toc2
  • Text_Wiki_Render_Latex_Heading2
  • Text_Wiki_Render_Latex_Toc2
  • Text_Wiki_Render_Plain_Heading2
  • Text_Wiki_Render_Plain_Toc2
  • Text_Wiki_Render_Rst
  • Text_Wiki_Render_Rst_Blockquote
  • Text_Wiki_Render_Rst_Bold
  • Text_Wiki_Render_Rst_Code
  • Text_Wiki_Render_Rst_Deflist
  • Text_Wiki_Render_Rst_Emphasis
  • Text_Wiki_Render_Rst_Freelink
  • Text_Wiki_Render_Rst_Heading2
  • Text_Wiki_Render_Rst_Links
  • Text_Wiki_Render_Rst_List
  • Text_Wiki_Render_Rst_Newline
  • Text_Wiki_Render_Rst_Paragraph
  • Text_Wiki_Render_Rst_Raw
  • Text_Wiki_Render_Rst_Toc2
  • Text_Wiki_Render_Rst_Tt
  • Text_Wiki_Render_Rst_Url
  • Text_Wiki_Render_Xhtml_Attribute
  • Text_Wiki_Render_Xhtml_Code2
  • Text_Wiki_Render_Xhtml_Freelink2
  • Text_Wiki_Render_Xhtml_Heading2
  • Text_Wiki_Render_Xhtml_Image2
  • Text_Wiki_Render_Xhtml_Interwiki
  • Text_Wiki_Render_Xhtml_Registrylink
  • Text_Wiki_Render_Xhtml_Toc2
  • Text_Wiki_Render_Xhtml_Url
  • Text_Wiki_Render_Xhtml_Wickedblock
  • Text_Wiki_Render_Xhtml_Wikilink2
  • Wicked
  • Wicked_Api
  • Wicked_Driver
  • Wicked_Driver_Sql
  • Wicked_Exception
  • Wicked_Factory_Driver
  • Wicked_Page
  • Wicked_Page_AddPage
  • Wicked_Page_AllPages
  • Wicked_Page_AttachedFiles
  • Wicked_Page_BackLinks
  • Wicked_Page_DeletePage
  • Wicked_Page_EditPage
  • Wicked_Page_LeastPopular
  • Wicked_Page_LikePages
  • Wicked_Page_MergeOrRename
  • Wicked_Page_MostPopular
  • Wicked_Page_NewPage
  • Wicked_Page_RecentChanges
  • Wicked_Page_RevertPage
  • Wicked_Page_Search
  • Wicked_Page_StandardHistoryPage
  • Wicked_Page_StandardPage
  • Wicked_Page_SyncDiff
  • Wicked_Page_SyncPages
  • Wicked_Sync
  • Wicked_Sync_Wicked
  • Wicked_Test
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Wicked Page class for most pages.
  4:  *
  5:  * Copyright 2003-2012 Horde LLC (http://www.horde.org/)
  6:  *
  7:  * See the enclosed file COPYING for license information (GPL). If you
  8:  * did not receive this file, see http://www.horde.org/licenses/gpl.
  9:  *
 10:  * @author  Tyler Colbert <tyler@colberts.us>
 11:  * @package Wicked
 12:  */
 13: class Wicked_Page_StandardPage extends Wicked_Page {
 14: 
 15:     /**
 16:      * Display modes supported by this page.
 17:      *
 18:      * @var array
 19:      */
 20:     public $supportedModes = array(
 21:         Wicked::MODE_DISPLAY => true,
 22:         Wicked::MODE_EDIT => true,
 23:         Wicked::MODE_REMOVE => true,
 24:         Wicked::MODE_HISTORY => true,
 25:         Wicked::MODE_DIFF => true);
 26: 
 27:     /**
 28:      * A Horde_Locks instance for un-/locking this page.
 29:      *
 30:      * @var Horde_Lock
 31:      */
 32:     protected $_locks = null;
 33: 
 34:     /**
 35:      * Lock information if this page is currently locked.
 36:      *
 37:      * @var array
 38:      */
 39:     protected $_lock = null;
 40: 
 41:     /**
 42:      * Constructs a standard page class to represent a wiki page.
 43:      *
 44:      * @param string $pagename The name of the page to represent.
 45:      */
 46:     public function __construct($pagename)
 47:     {
 48:         if (is_array($pagename)) {
 49:             $this->_page = $pagename;
 50:             return;
 51:         }
 52: 
 53:         $page = null;
 54:         try {
 55:             $page = $GLOBALS['wicked']->retrieveByName($pagename);
 56:         } catch (Wicked_Exception $e) {
 57:             // If we can't load $pagename, see if there's default data for it.
 58:             // Protect against directory traversion.
 59:             $pagepath = realpath(WICKED_BASE . '/data/'
 60:                                  . $GLOBALS['conf']['wicked']['format']);
 61:             $pagefile = realpath($pagepath . '/' . $pagename);
 62:             if ($pagefile &&
 63:                 Horde_String::common($pagefile, $pagepath) == $pagepath &&
 64:                 substr($pagename, 0, 1) != '.' &&
 65:                 file_exists($pagefile) &&
 66:                 ($text = file_get_contents($pagefile))) {
 67:                 try {
 68:                     $GLOBALS['wicked']->newPage($pagename, $text);
 69:                     try {
 70:                         $page = $GLOBALS['wicked']->retrieveByName($pagename);
 71:                     } catch (Wicked_Exception $e) {
 72:                         $GLOBALS['notification']->push(sprintf(_("Unable to create %s"), $pagename), 'horde.error');
 73:                     }
 74:                 } catch (Wicked_Exception $e) {}
 75:             }
 76:         }
 77: 
 78:         if ($page) {
 79:             $this->_page = $page;
 80:         } else {
 81:             if ($pagename == 'Wiki/Home') {
 82:                 $GLOBALS['notification']->push(_("Unable to create Wiki/Home. The wiki is not configured."), 'horde.error');
 83:             }
 84:             $this->_page = array();
 85:         }
 86: 
 87:         // Make sure 'wicked' permission exists. Set reasonable defaults if
 88:         // necessary.
 89:         $perms = $GLOBALS['injector']->getInstance('Horde_Perms');
 90:         $corePerms = $GLOBALS['injector']->getInstance('Horde_Core_Perms');
 91:         if (!$perms->exists('wicked')) {
 92:             $perm = $corePerms->newPermission('wicked');
 93:             $perm->addGuestPermission(Horde_Perms::SHOW | Horde_Perms::READ, false);
 94:             $perm->addDefaultPermission(Horde_Perms::SHOW | Horde_Perms::READ | Horde_Perms::EDIT | Horde_Perms::DELETE, false);
 95:             $perms->addPermission($perm);
 96:         }
 97: 
 98:         // Make sure 'wicked:pages' exists. Copy from 'wicked' if it does not
 99:         // exist.
100:         if (!$perms->exists('wicked:pages')) {
101:             $perm = $corePerms->newPermission('wicked:pages');
102:             $copyFrom = $perms->getPermission('wicked');
103:             $perm->addGuestPermission($copyFrom->getGuestPermissions(), false);
104:             $perm->addDefaultPermission($copyFrom->getDefaultPermissions(), false);
105:             $perm->addCreatorPermission($copyFrom->getCreatorPermissions(), false);
106:             foreach ($copyFrom->getUserPermissions() as $user => $uperm) {
107:                 $perm->addUserPermission($user, $uperm, false);
108:             }
109:             foreach ($copyFrom->getGroupPermissions() as $group => $gperm) {
110:                 $perm->addGroupPermission($group, $gperm, false);
111:             }
112:             $perms->addPermission($perm);
113:         }
114: 
115:         if ($GLOBALS['conf']['lock']['driver'] != 'none') {
116:             $this->supportedModes[Wicked::MODE_LOCKING] = $this->supportedModes[Wicked::MODE_UNLOCKING] = true;
117:             $this->_locks = $GLOBALS['injector']->getInstance('Horde_Lock');
118:             $locks = $this->_locks->getLocks('wicked', $pagename, Horde_Lock::TYPE_EXCLUSIVE);
119:             if ($locks) {
120:                 $this->_lock = reset($locks);
121:             }
122:         }
123:     }
124: 
125:     /**
126:      * Returns if the page allows a mode. Access rights and user state
127:      * are taken into consideration.
128:      *
129:      * @see $supportedModes
130:      *
131:      * @param integer $mode  The mode to check for.
132:      *
133:      * @return boolean  True if the mode is allowed.
134:      */
135:     public function allows($mode)
136:     {
137:         switch ($mode) {
138:         case Wicked::MODE_EDIT:
139:             if ($this->isLocked()) {
140:                 return Wicked::lockUser() == $this->_lock['lock_owner'];
141:             }
142:             break;
143: 
144:         case Wicked::MODE_LOCKING:
145:             if ($GLOBALS['browser']->isRobot()) {
146:                 return false;
147:             }
148:             if ($GLOBALS['registry']->isAdmin()) {
149:                 return true;
150:             }
151:             if (($this->getPermissions() & Horde_Perms::EDIT) == 0) {
152:                 return false;
153:             }
154:             break;
155: 
156:         case Wicked::MODE_UNLOCKING:
157:             if ($GLOBALS['registry']->isAdmin()) {
158:                 return true;
159:             }
160:             if ($this->_lock) {
161:                 return Wicked::lockUser() == $this->_lock['lock_owner'];
162:             }
163:             return false;
164:         }
165:         return parent::allows($mode);
166:     }
167: 
168:     /**
169:      * @throws Wicked_Exception
170:      */
171:     public function displayContents($isBlock)
172:     {
173:         $wiki = $this->getProcessor();
174:         $text = $wiki->transform($this->getText());
175:         $attachments = array();
176: 
177:         if (!$isBlock) {
178:             $pageId = $GLOBALS['wicked']->getPageId($this->pageName());
179:             $attachments = $GLOBALS['wicked']->getAttachedFiles($pageId);
180:             if (count($attachments)) {
181:                 global $mime_drivers, $mime_drivers_map;
182:                 $result = Horde::loadConfiguration('mime_drivers.php', array('mime_drivers', 'mime_drivers_map'), 'horde');
183:                 extract($result);
184:             }
185:         }
186: 
187:         ob_start();
188:         require WICKED_TEMPLATES . '/display/standard.inc';
189:         $result = ob_get_contents();
190:         ob_end_clean();
191:         return $result;
192:     }
193: 
194:     /**
195:      * Renders this page in History mode.
196:      *
197:      * @throws Wicked_Exception
198:      */
199:     public function history()
200:     {
201:         try {
202:             $summaries = $GLOBALS['wicked']->getHistory($this->pageName());
203:         } catch (Wicked_Exception $e) {
204:             $GLOBALS['notification']->push('Error retrieving histories : ' . $e->getMessage(), 'horde.error');
205:             throw $e;
206:         }
207: 
208:         // Header.
209:         $show_restore = !$this->isLocked();
210:         $allow_diff = true;
211:         $show_edit = true;
212:         require WICKED_TEMPLATES . '/history/header.inc';
213:         $style = 'text';
214: 
215:         // First item is this page.
216:         $show_restore = false;
217:         $page = $this;
218:         $i = 0;
219:         require WICKED_TEMPLATES . '/history/summary.inc';
220: 
221:         // Now the rest of the histories.
222:         $show_restore = !$this->isLocked();
223:         $show_edit = false;
224:         foreach ($summaries as $page) {
225:             $i++;
226:             $page = new Wicked_Page_StandardHistoryPage($page);
227:             require WICKED_TEMPLATES . '/history/summary.inc';
228:         }
229: 
230:         // Footer.
231:         require WICKED_TEMPLATES . '/history/footer.inc';
232:     }
233: 
234:     public function isLocked($owner = null)
235:     {
236:         if (empty($this->_lock)) {
237:             return false;
238:         }
239:         if (is_null($owner)) {
240:             return true;
241:         }
242:         return $owner != $this->_lock['lock_owner'];
243:     }
244: 
245:     /**
246:      * @throws Wicked_Exception
247:      */
248:     public function lock()
249:     {
250:         if ($this->_locks) {
251:             $id = $this->_locks->setLock(Wicked::lockUser(), 'wicked', $this->pageName(), $GLOBALS['conf']['wicked']['lock']['time'] * 60, Horde_Lock::TYPE_EXCLUSIVE);
252:             if ($id) {
253:                 $this->_lock = $this->_locks->getLockInfo($id);
254:             } else {
255:                 throw new Wicked_Exception(_("The page is already locked."));
256:             }
257:         }
258:     }
259: 
260:     public function unlock()
261:     {
262:         if ($this->_locks && $this->_lock) {
263:             $this->_locks->clearLock($this->_lock['lock_id']);
264:             unset($this->_lock);
265:         }
266:     }
267: 
268:     public function getLockRequestor()
269:     {
270:         $requestor = $this->_lock['lock_owner'];
271:         if ($requestor) {
272:             $name = $GLOBALS['injector']
273:                 ->getInstance('Horde_Core_Factory_Identity')
274:                 ->create($requestor)
275:                 ->getValue('fullname');
276:             if (!strlen($name)) {
277:                 $name = $requestor;
278:             }
279:             return $name;
280:         }
281:         return _("a guest");
282:     }
283: 
284:     public function getLockTime()
285:     {
286:         $time = ceil(($this->_lock['lock_expiry_timestamp'] - time()) / 60);
287:         return sprintf(ngettext("%d minute", "%d minutes", $time), $time);
288:     }
289:     
290:     /**
291:      * @throws Wicked_Exception
292:      */
293:     public function updateText($newtext, $changelog)
294:     {
295:         $version = $this->version();
296:         $result = $GLOBALS['wicked']->updateText($this->pageName(), $newtext,
297:                                                  $changelog);
298: 
299:         $url = Wicked::url($this->pageName(), true, -1);
300:         $new_page = $this->getPage($this->pageName());
301: 
302:         $message = "Modified page: $url\n"
303:             . 'New Revision:  ' . $new_page->version() . "\n"
304:             . ($changelog ? 'Change log:  ' . $changelog . "\n" : '')
305:             . "\n"
306:             . $new_page->getDiff($version);
307:         Wicked::mail($message,
308:                      array('Subject' => '[' . $GLOBALS['registry']->get('name')
309:                            . '] changed: ' . $this->pageName()));
310: 
311:         $this->_page['page_text'] = $newtext;
312:     }
313: 
314:     public function pageID()
315:     {
316:         return isset($this->_page['page_id']) ? $this->_page['page_id'] : '';
317:     }
318: 
319:     public function pageName()
320:     {
321:         return isset($this->_page['page_name'])
322:             ? $this->_page['page_name']
323:             : '';
324:     }
325: 
326:     public function getText()
327:     {
328:         return isset($this->_page['page_text'])
329:             ? $this->_page['page_text']
330:             : '';
331:     }
332: 
333:     public function versionCreated()
334:     {
335:         return isset($this->_page['version_created'])
336:             ? $this->_page['version_created']
337:             : '';
338:     }
339: 
340:     public function hits()
341:     {
342:         return !empty($this->_page['page_hits'])
343:             ? $this->_page['page_hits']
344:             : 0;
345:     }
346: 
347:     public function changeLog()
348:     {
349:         return $this->_page['change_log'];
350:     }
351: 
352:     public function version()
353:     {
354:         if (isset($this->_page['page_version'])) {
355:             return $this->_page['page_version'];
356:         } else {
357:             return '';
358:         }
359:     }
360: 
361:     public function diff($version)
362:     {
363:         require WICKED_TEMPLATES . '/diff/diff.inc';
364:     }
365: 
366:     /**
367:      * Produces a diff for this page.
368:      *
369:      * @param string $version   Previous version, or null if diffing with
370:      *                          `before the beginning' (empty).
371:      * @param string $renderer  The diff renderer.
372:      */
373:     public function getDiff($version, $renderer = 'unified')
374:     {
375:         if (is_null($version)) {
376:             $old_page_text = '';
377:         } else {
378:             $old_page = $this->getPage($this->pageName(), $version);
379:             $old_page_text = $old_page->getText();
380:         }
381:         $diff = new Horde_Text_Diff('auto',
382:                                     array(explode("\n", $old_page_text),
383:                                           explode("\n", $this->getText())));
384:         $class = 'Horde_Text_Diff_Renderer_' . Horde_String::ucfirst($renderer);
385:         $renderer = new $class();
386:         return $renderer->render($diff);
387:     }
388: 
389: }
390: 
API documentation generated by ApiGen