1<?php
2
3/**
4 * DokuWiki DAVCard PlugIn - Ajax component
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Böhler <dev@aboehler.at>
7 */
8
9if(!defined('DOKU_INC')) die();
10
11class action_plugin_davcard_ajax extends DokuWiki_Action_Plugin {
12
13    /**
14     * @var helper_plugin_davcard
15     */
16    private $hlp = null;
17
18    function __construct() {
19        $this->hlp =& plugin_load('helper','davcard');
20    }
21
22    function register(Doku_Event_Handler $controller) {
23        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call_unknown');
24    }
25
26    function handle_ajax_call_unknown(&$event, $param) {
27      if($event->data != 'plugin_davcard') return;
28
29      $event->preventDefault();
30      $event->stopPropagation();
31      global $INPUT;
32
33      $action = trim($INPUT->post->str('action'));
34      $id = trim($INPUT->post->str('id'));
35      $page = trim($INPUT->post->str('page'));
36      $params = $INPUT->post->arr('params');
37      if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
38        $user = $_SERVER['REMOTE_USER'];
39      else
40        $user = null;
41
42      if(!checkSecurityToken())
43      {
44          echo "CSRF Attack.";
45          return;
46      }
47
48      $data = array();
49
50      $data['result'] = false;
51      $data['html'] = $this->getLang('unknown_error');
52
53      $acl = $this->hlp->checkAddressbookPermission($id);
54      if($acl > AUTH_READ)
55      {
56          $write = true;
57      }
58      elseif($acl < AUTH_READ)
59      {
60        $data['result'] = false;
61        $data['html'] = $this->getLang('no_permission');
62        // Overwrite $action to bypass switch statement below
63        $action = 'invalid';
64      }
65      else
66      {
67          $write = false;
68      }
69
70      // Parse the requested action
71      switch($action)
72      {
73          // Add a new Contact
74          case 'newContact':
75              if($write && ($this->hlp->addContactEntryToAddressbookForPage($id, $user, $params) === true))
76              {
77                  $data['result'] = true;
78              }
79              else
80              {
81                  $data['result'] = false;
82                  if(!$write)
83                    $data['html'] = $this->getLang('no_permission');
84                  else
85                    $data['html'] = $this->getLang('error_adding');
86              }
87          break;
88
89          // Retrieve contact details
90          case 'getContactDetails':
91              $contactdata = $this->hlp->getContactByUri($id, $params['uri']);
92              if($contactdata['result'] === true)
93              {
94                  // When we support pictures for editing contacts,
95                  // we need to use the following line:
96                  // $contactdata['photo'] = base64_encode($contactdata['photo']);
97                  // For now, we just save bandwidth :)
98                  unset($contactdata['photo']);
99                  $data['result'] = true;
100                  $data['contactdata'] = $contactdata;
101              }
102              else
103              {
104                  $data['result'] = false;
105                  $data['html'] = sprintf($this->getLang('contact_not_found'), 'ID='.$id.' URI='.$params['uri']);
106              }
107          break;
108
109          // Edit a contact
110          case 'editContact':
111              if($write && ($this->hlp->editContactEntryToAddressbookForPage($id, $user, $params['uri'], $params) === true))
112              {
113                  $data['result'] = true;
114              }
115              else
116              {
117                  $data['result'] = false;
118                  if(!$write)
119                    $data['html'] = $this->getLang('no_permission');
120                  else
121                    $data['html'] = $this->getLang('error_editing');
122              }
123          break;
124          // Delete a Contact
125          case 'deleteContact':
126              if($write && ($this->hlp->deleteContactEntryToAddressbookForPage($id, $user, $params['uri']) === true))
127              {
128                  $data['result'] = true;
129              }
130              else
131              {
132                  $data['result'] = false;
133                  if(!$write)
134                    $data['html'] = $this->getLang('no_permission');
135                  else
136                    $data['html'] = $this->getLang('error_deleting');
137              }
138          break;
139          // Get AJAX popup
140          case 'getContactAjax':
141              $contactdata = $this->hlp->getContactByUri($id, $params['uri']);
142              $cardpattern = $this->getConf('popup_content');
143              if($contactdata['result'] === false)
144              {
145                  echo hsc($contactdata['formattedname']);
146                  return;
147              }
148              echo '<div class="plugin_davcard_popup_container">';
149              foreach($contactdata['photo'] as $data)
150              {
151                  if(isset($data['type']))
152                    $type = $data['type'];
153                  else
154                    $type = '';
155                  echo '<div class="plugin_davcard_popup_image">';
156                  $imgdata = base64_encode($data['photo']);
157                  $pattern = '/^(?:[;\/?:@&=+$,]|(?:[^\W_]|[-_.!~*\()\[\] ])|(?:%[\da-fA-F]{2}))*$/';
158
159                  // PNG images
160                  if($type == 'png')
161                  {
162                      $imgdata = 'data:image/png;base64,'.$imgdata;
163                      echo '<img src="'.hsc($imgdata).'" alt="contact image" />';
164                  }
165                  // JPEG images
166                  elseif(($type == 'jpeg') || ($type == 'jpg'))
167                  {
168                      $imgdata = 'data:image/jpeg;base64,'.$imgdata;
169                      echo '<img src="'.hsc($imgdata).'" alt="contact image" />';
170                  }
171                  // GIF images
172                  elseif($type == 'gif')
173                  {
174                      $imgdata = 'data:image/gif;base64,'.$imgdata;
175                      echo '<img src="'.hsc($imgdata).'" alt="contact image" />';
176                  }
177                  // URLs (no type given)
178                  elseif(preg_match( $pattern, $string ) == 1)
179                  {
180                      echo '<img src="'.hsc($data['photo']).'" alt="contact image" />';
181                  }
182                  echo '</div>';
183              }
184              echo '<div class="plugin_davcard_popup_content">';
185              $contactname = explode(';', $contactdata['structuredname']);
186              if(count($contactname) > 1)
187              {
188                  $cardpattern = str_replace('<DCLASTNAME>', $contactname[0], $cardpattern);
189                  $cardpattern = str_replace('<DCFIRSTNAME>', $contactname[1], $cardpattern);
190              }
191              if(count($contactdata['addr']) > 0)
192              {
193                  foreach($contactdata['addr'] as $data)
194                  {
195                      if(isset($data['type']) && ($data['type'] == 'work'))
196                        $prefix = 'WORK';
197                      else
198                        $prefix = 'PRIVATE';
199                      $cardpattern = str_replace('<DC'.$prefix.'STREET>', $data['address'][2], $cardpattern);
200                      $cardpattern = str_replace('<DC'.$prefix.'CITY>', $data['address'][3], $cardpattern);
201                      $cardpattern = str_replace('<DC'.$prefix.'ZIP>', $data['address'][5], $cardpattern);
202                      $cardpattern = str_replace('<DC'.$prefix.'COUNTRY>', $data['address'][6], $cardpattern);
203                  }
204              }
205              if(count($contactdata['tel']) > 0)
206              {
207                  $telArr = array();
208                  foreach($contactdata['tel'] as $data)
209                  {
210                      if(isset($data['type']))
211                        $type = $data['type'];
212                      else
213                        $type = 'other';
214                      $type = $data['type'];
215                      $telArr[] = $this->getLang('tel'.$type).': '.$data['number'];
216                  }
217                  $telStr = implode(' \\\\ ', $telArr);
218                  $cardpattern = str_replace('<DCPHONE>', $telStr, $cardpattern);
219              }
220              if(count($contactdata['mail']) > 0)
221              {
222                  $mailArr = array();
223                  foreach($contactdata['mail'] as $data)
224                  {
225                      $mailArr[] = '[['.$data['mail'].']]';
226                  }
227                  $mailStr = implode(' \\\\ ', $mailArr);
228                  $cardpattern = str_replace('<DCEMAIL>', $mailStr, $cardpattern);
229              }
230              if($contactdata['birthday'] != '')
231              {
232                  $date = DateTime::createFromFormat('Ymd', $contactdata['birthday']);
233                  $dateStr = $date->format($this->getConf('date_format'));
234                  $cardpattern = str_replace('<DCBIRTHDAY>', $dateStr, $cardpattern);
235              }
236              if($contactdata['note'] != '')
237              {
238                  $notestr = str_replace('\n', ' \\ ', $contactdata['note']);
239                  $cardpattern = str_replace('<DCNOTE>', $notestr, $cardpattern);
240              }
241              if($contactdata['title'] != '')
242              {
243                  $cardpattern = str_replace('<DCTITLE>', $contactdata['title'], $cardpattern);
244              }
245              if($contactdata['url'] != '')
246              {
247                  $url = $contactdata['url'];
248                  if(strpos($url, '://') === false)
249                    $url = 'http://'.$url;
250                  $url = '[['.$url.']]';
251                  $cardpattern = str_replace('<DCWEBSITE>', $url, $cardpattern);
252              }
253
254              $replace_match = '/^.*<DC.*>.*$(?:\r\n|\n)?/m';
255              $cardpattern = preg_replace($replace_match, '', $cardpattern);
256              echo $this->render_text($cardpattern);
257              echo '</div>';
258              echo '</div>';
259              return;
260          break;
261      }
262
263      // If we are still here, JSON output is requested
264
265      //json library of DokuWiki
266      require_once DOKU_INC . 'inc/JSON.php';
267      $json = new JSON();
268
269      //set content type
270      header('Content-Type: application/json');
271      echo $json->encode($data);
272    }
273
274}
275