1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13: class Wicked_Page_SyncPages extends Wicked_Page {
14:
15: 16: 17:
18: public $supportedModes = array(
19: Wicked::MODE_CONTENT => true);
20:
21: 22: 23:
24: protected $_sync;
25:
26: 27: 28: 29: 30:
31: public function __construct()
32: {
33: $this->_loadSyncDriver();
34:
35:
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: 49: 50: 51: 52:
53: public function content()
54: {
55: global $session, $wicked;
56:
57:
58: $form = $this->_syncForm();
59:
60:
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:
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:
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:
100: $sync_pages = array();
101: foreach ($local_pages as $pageName) {
102:
103: if (isset($new_local[$pageName]) ||
104: isset($new_remote[$pageName])) {
105: continue;
106: }
107:
108:
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:
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: 129: 130: 131: 132:
133: public function displayContents($isBlock)
134: {
135: return $this->content();
136: }
137:
138: 139: 140:
141: public function pageName()
142: {
143: return 'SyncPages';
144: }
145:
146: 147: 148:
149: public function pageTitle()
150: {
151: return _("Sync Pages");
152: }
153:
154: 155: 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: 168: 169: 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:
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:
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:
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:
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:
256: $session->set('wicked', 'sync', $info);
257: $this->_loadSyncDriver();
258:
259:
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: 297: 298: 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: 314: 315: 316: 317: 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: 332: 333: 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:
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:
361: Wicked::url($pageName, true)->redirect();
362: }
363:
364: 365: 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:
375: Wicked::url($pageName, true)->redirect();
376: }
377:
378: 379: 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: