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 SyncPages class.
  4:  *
  5:  * Copyright 2008-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  Duck <duck@obala.net>
 11:  * @package Wicked
 12:  */
 13: class Wicked_Page_SyncPages extends Wicked_Page {
 14: 
 15:     /**
 16:      * Display modes supported by this page.
 17:      */
 18:     public $supportedModes = array(
 19:         Wicked::MODE_CONTENT => true);
 20: 
 21:     /**
 22:      * Sync driver
 23:      */
 24:     protected $_sync;
 25: 
 26:     /**
 27:      * Constructor
 28:      *
 29:      * @throws Wicked_Exception
 30:      */
 31:     public function __construct()
 32:     {
 33:         $this->_loadSyncDriver();
 34: 
 35:         // Do we need to perform any action?
 36:         switch (Horde_Util::getGet('actionID')) {
 37:         case 'sync_download':
 38:             $page = Horde_Util::getGet('sync_page');
 39:             return $this->download($page);
 40: 
 41:         case 'sync_upload':
 42:             $page = Horde_Util::getGet('sync_page');
 43:             return $this->upload($page);
 44:         }
 45:     }
 46: 
 47:     /**
 48:      * Renders this page in content mode.
 49:      *
 50:      * @return string  The page content.
 51:      * @throws Wicked_Exception
 52:      */
 53:     public function content()
 54:     {
 55:         global $session, $wicked;
 56: 
 57:         // Used in all cases.
 58:         $form = $this->_syncForm();
 59: 
 60:         // We have no data to check
 61:         if (!$session->get('wicked', 'sync')) {
 62:             ob_start();
 63:             require WICKED_TEMPLATES . '/sync/header.inc';
 64:             require WICKED_TEMPLATES . '/sync/footer.inc';
 65:             return ob_get_clean();
 66:         }
 67: 
 68:         // New pages on remote server
 69:         $new_remote = array();
 70:         foreach ($session->get('wicked', 'sync_pages/') as $pageName => $info) {
 71:             if (!$wicked->pageExists($pageName)) {
 72:                 $new_remote[$pageName] = array(
 73:                     'page_version' => $info['page_version'],
 74:                     'page_checksum' => $info['page_checksum'],
 75:                     'version_created' => $info['version_created'],
 76:                     'change_author' => $info['change_author'],
 77:                     'change_log' => $info['change_log']
 78:                 );
 79:             }
 80:         }
 81: 
 82:         // New pages on local server
 83:         $new_local = array();
 84:         $local_pages = $wicked->getPages(false);
 85:         foreach ($local_pages as $pageName) {
 86:             if ($session->exists('wicked', 'sync_pages/' . $pageName)) {
 87:                 continue;
 88:             }
 89:             $page = Wicked_Page::getPage($pageName);
 90:             $new_local[$pageName] = array(
 91:                 'page_version' => $page->_page['page_version'],
 92:                 'page_checksum' => md5($page->getText()),
 93:                 'version_created' => $page->_page['version_created'],
 94:                 'change_author' => $page->_page['change_author'],
 95:                 'change_log' => $page->_page['change_log']
 96:             );
 97:         }
 98: 
 99:         // Pages with differences
100:         $sync_pages = array();
101:         foreach ($local_pages as $pageName) {
102:             // Is a new page
103:             if (isset($new_local[$pageName]) ||
104:                 isset($new_remote[$pageName])) {
105:                 continue;
106:             }
107: 
108:             // Compare checksum
109:             $page = Wicked_Page::getPage($pageName);
110:             $spage = $session->get('wicked', 'sync_pages/' . $pageName);
111:             if (md5($page->getText()) == $spage['page_checksum']) {
112:                 continue;
113:             }
114: 
115:             $sync_pages[] = $pageName;
116:         }
117: 
118:         // Output
119:         Horde::addScriptFile('tables.js', 'horde', true);
120:         ob_start();
121:         require WICKED_TEMPLATES . '/sync/header.inc';
122:         require WICKED_TEMPLATES . '/sync/list.inc';
123:         require WICKED_TEMPLATES . '/sync/footer.inc';
124:         return ob_get_clean();
125:     }
126: 
127:     /**
128:      * Renders this page in display or block mode.
129:      *
130:      * @return string  The contents.
131:      * @throws Wicked_Exception
132:      */
133:     public function displayContents($isBlock)
134:     {
135:         return $this->content();
136:     }
137: 
138:     /**
139:      * Page name
140:      */
141:     public function pageName()
142:     {
143:         return 'SyncPages';
144:     }
145: 
146:     /**
147:      * Page title
148:      */
149:     public function pageTitle()
150:     {
151:         return _("Sync Pages");
152:     }
153: 
154:     /**
155:      * Prepare page link
156:      */
157:     protected function _viewLink($pageName, $local = true)
158:     {
159:         if ($local) {
160:             return  '<a href="' .  Wicked::url($pageName) . '" target="_blank">' . _("View local") . '</a>';
161:         } else {
162:             return  '<a href="' .  $GLOBALS['session']->get('wicked', 'sync_display')  . $pageName . '" target="_blank">' . _("View remote") . '</a>';
163:         }
164:     }
165: 
166:     /**
167:      * Get and process sync info form
168:      *
169:      * @throws Wicked_Exception
170:      */
171:     protected function _syncForm()
172:     {
173:         global $session;
174: 
175:         require_once 'Horde/Form.php';
176: 
177:         $vars = Horde_Variables::getDefaultVariables();
178:         $form = new Horde_Form($vars, _("Sync data"), 'syncdata');
179:         $form->setButtons(array(_("Fetch page list"), _("Save login info"), _("Remove login info")), _("Reset"));
180:         $form->addHidden('', 'page', 'text', true);
181: 
182:         $defaults = array(
183:             'driver' => 'wicked',
184:             'prefix' => 'wiki',
185:             'url' => 'http://wiki.example.org/rpc.php',
186:             'display' => 'http://wiki.example.org/display.php?page=',
187:             'edit' => 'http://wiki.example.org/display.php?page=EditPage&referrer=',
188:             'user' => '',
189:             'password' => '',
190:         );
191: 
192:         // Prepare default values
193:         $stored = @unserialize($GLOBALS['prefs']->getValue('sync_data'));
194:         if ($vars->get('sync_select') && isset($stored[$vars->get('sync_select')])) {
195:             $defaults = $stored[$vars->get('sync_select')];
196:             foreach ($defaults as $k => $v) {
197:                 if ($vars->exists('sync_' . $k)) {
198:                     $vars->set('sync_' . $k, $v);
199:                 }
200:             }
201:         }
202: 
203:         if ($session->exists('wicked', 'sync')) {
204:             $defaults = $session->get('wicked', 'sync');
205:         }
206: 
207:         // Add stored info selection
208:         $enum = array();
209:         foreach ($stored as $k => $v) {
210:             $enum[$k] = $v['url'] . ' (' . $v['user'] . ')';
211:         }
212:         if (!empty($enum)) {
213:             require_once 'Horde/Form/Action.php';
214:             $v = &$form->addVariable(_("Stored"), 'sync_select', 'enum', false, null, false, array($enum, _("Custom")));
215:             $v->setAction(Horde_Form_Action::factory('submit'));
216:             $v->setOption('trackchange', true);
217:         }
218: 
219:         // Add standard form info
220:         $v = &$form->addVariable(_("Driver"), 'sync_driver', 'enum', true, null, false, array(array('wicked' => 'Wicked'), false));
221:         $v->setDefault($defaults['driver']);
222: 
223:         $v = &$form->addVariable(_("Prefix"), 'sync_prefix', 'text', true);
224:         $v->setDefault($defaults['prefix']);
225: 
226:         $v = &$form->addVariable(_("Url"), 'sync_url', 'text', true);
227:         $v->setDefault($defaults['url']);
228: 
229:         $v = &$form->addVariable(_("User"), 'sync_user', 'text', false, false, _("By default, your login data will be used"));
230:         $v->setDefault($defaults['user']);
231: 
232:         $form->addVariable(_("Password"), 'sync_password', 'password', false, false, _("By default, your login data will be used"));
233: 
234:         $v = &$form->addVariable(_("Display"), 'sync_display', 'text', false);
235:         $v->setDefault($defaults['display']);
236: 
237:         $v = &$form->addVariable(_("Edit"), 'sync_edit', 'text', false);
238:         $v->setDefault($defaults['edit']);
239: 
240:         // Process
241:         if ($form->validate()) {
242:             $info = array(
243:                 'driver' => $vars->get('sync_driver'),
244:                 'prefix' => $vars->get('sync_prefix'),
245:                 'url' => $vars->get('sync_url'),
246:                 'display' => $vars->get('sync_display'),
247:                 'edit' => $vars->get('sync_edit'),
248:                 'user' => $vars->get('sync_user'),
249:                 'password' => $vars->get('sync_password'),
250:                 'pages' => array(),
251:             );
252: 
253:             switch (Horde_Util::getFormData('submitbutton')) {
254:             case _("Fetch page list"):
255:                 // Load driver
256:                 $session->set('wicked', 'sync', $info);
257:                 $this->_loadSyncDriver();
258: 
259:                 // We submitted the form so we should fetch pages
260:                 $pages = $this->_sync->getMultiplePageInfo();
261:                 if (!empty($pages)) {
262:                     foreach ($pages as $key => $val) {
263:                         $session->set('wicked', 'sync_pages/' . $key, $val);
264:                     }
265:                 }
266:                 break;
267: 
268:             case _("Save login info"):
269:                 $data = unserialize($GLOBALS['prefs']->getValue('sync_data'));
270:                 $key = md5($info['url'] . $info['user']);
271:                 $data[$key] = $info;
272:                 unset($data[$key]['password'],
273:                       $data[$key]['pages']);
274:                 $GLOBALS['prefs']->setValue('sync_data', serialize($data));
275:                 $GLOBALS['notification']->push(_("Sync login info was stored"), 'horde.success');
276: 
277:                 Wicked::url('SyncPages', true)->redirect();
278: 
279:             case _("Remove login info"):
280:                 $data = unserialize($GLOBALS['prefs']->getValue('sync_data'));
281:                 $key = md5($info['url'] . $info['user']);
282:                 unset($data[$key]);
283:                 $GLOBALS['prefs']->setValue('sync_data', serialize($data));
284:                 $GLOBALS['notification']->push(_("Sync login info was removed."), 'horde.success');
285: 
286:                 Wicked::url('SyncPages', true)->redirect();
287:             }
288:         }
289: 
290:         Horde::startBuffer();
291:         $form->renderActive(null, null, null, 'get');
292:         return Horde::endBuffer();
293:     }
294: 
295:     /**
296:      * Get page info
297:      *
298:      * @param boolean $local Get local or remote info
299:      */
300:     public function getLocalPageInfo($pageName)
301:     {
302:         $page = Wicked_Page::getPage($pageName);
303:         return array(
304:             'page_version' => $page->_page['page_version'],
305:             'page_checksum' => md5($page->getText()),
306:             'version_created' => $page->_page['version_created'],
307:             'change_author' => $page->_page['change_author'],
308:             'change_log' => $page->_page['change_log'],
309:         );
310:     }
311: 
312:     /**
313:      * Get page info
314:      *
315:      * @param boolean $local Get local or remote info
316:      *
317:      * @throws Wicked_Exception
318:      */
319:     public function getRemotePageInfo($pageName)
320:     {
321:         global $session;
322: 
323:         if (!$session->exists('wicked', 'sync_pages/' . $pageName)) {
324:             $session->set('wicked', 'sync_pages/' . $pageName, $this->_sync->getPageInfo($pageName));
325:         }
326: 
327:         return $session->get('wicked', 'sync_pages/' . $pageName);
328:     }
329: 
330:     /**
331:      * Download remote page to local server
332:      *
333:      * @throws Wicked_Exception
334:      */
335:     public function download($pageName)
336:     {
337:         $text = $this->_sync->getPageSource($pageName);
338:         $page = Wicked_Page::getPage($pageName);
339:         if (!$page->allows(Wicked::MODE_EDIT)) {
340:             throw new Wicked_Exception(sprintf(_("You don't have permission to edit \"%s\"."), $pageName));
341:         }
342: 
343:         try {
344:             $content = $page->getText();
345:             if (trim($text) == trim($content)) {
346:                 $GLOBALS['notification']->push(_("No changes made"), 'horde.message');
347:                 return;
348:             }
349:             $page->updateText($text, _("Downloaded from remote server"));
350:         } catch (Wicked_Exception $e) {
351:             // Maybe the page does not exists, if not create it
352:             if ($GLOBALS['wicked']->pageExists($pageName)) {
353:                 throw $e;
354:             }
355:             $GLOBALS['wicked']->newPage($pageName, $text);
356:         }
357: 
358:         $GLOBALS['notification']->push(sprintf(_("Page \"%s\" was sucessfuly downloaded from remote to local wiki."), $pageName), 'horde.success');
359: 
360:         // Show the newly saved page.
361:         Wicked::url($pageName, true)->redirect();
362:     }
363: 
364:     /**
365:      * Upload local page to remote server
366:      */
367:     public function upload($pageName)
368:     {
369:         $page = Wicked_Page::getPage($pageName);
370:         $content = $page->getText();
371:         $this->_sync->editPage($pageName, $content, _("Uploaded from remote server"), true);
372:         $GLOBALS['notification']->push(sprintf(_("Page \"%s\" was sucessfully uploaded from local to remote wiki."), $pageName), 'horde.success');
373: 
374:         // Show the newly updated page.
375:         Wicked::url($pageName, true)->redirect();
376:     }
377: 
378:     /**
379:      * Load sync driver
380:      */
381:     protected function _loadSyncDriver()
382:     {
383:         global $session;
384: 
385:         if ($this->_sync) {
386:             return true;
387:         } elseif (!$session->get('wicked', 'sync_driver')) {
388:             return false;
389:         }
390: 
391:         $this->_sync = Wicked_Sync::factory($session->get('wicked', 'sync_driver'),
392:                                             $session->get('wicked', 'sync'));
393:     }
394: 
395: }
396: 
API documentation generated by ApiGen