1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12: 
 13: class Wicked_Page_StandardPage extends Wicked_Page {
 14: 
 15:      16:  17:  18:  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:  29:  30:  31: 
 32:     protected $_locks = null;
 33: 
 34:      35:  36:  37:  38: 
 39:     protected $_lock = null;
 40: 
 41:      42:  43:  44:  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:             
 58:             
 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:         
 88:         
 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:         
 99:         
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: 127: 128: 129: 130: 131: 132: 133: 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: 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: 196: 197: 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:         
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:         
216:         $show_restore = false;
217:         $page = $this;
218:         $i = 0;
219:         require WICKED_TEMPLATES . '/history/summary.inc';
220: 
221:         
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:         
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: 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: 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: 368: 369: 370: 371: 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: