<?php

/**
 * DokuWiki DAVCard PlugIn - Ajax component
 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
 * @author  Andreas Böhler <dev@aboehler.at>
 */

if(!defined('DOKU_INC')) die();

class action_plugin_davcard_ajax extends DokuWiki_Action_Plugin {

    /**
     * @var helper_plugin_davcard
     */
    private $hlp = null;

    function __construct() {
        $this->hlp =& plugin_load('helper','davcard');
    }

    function register(Doku_Event_Handler $controller) {
        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call_unknown');
    }

    function handle_ajax_call_unknown(&$event, $param) {
      if($event->data != 'plugin_davcard') return;
      
      $event->preventDefault();
      $event->stopPropagation();
      global $INPUT;
      
      $action = trim($INPUT->post->str('action'));
      $id = trim($INPUT->post->str('id'));
      $page = trim($INPUT->post->str('page'));
      $params = $INPUT->post->arr('params');
      if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
        $user = $_SERVER['REMOTE_USER'];
      else
        $user = null;
      
      if(!checkSecurityToken())
      {
          echo "CSRF Attack.";
          return;
      }
      
      $data = array();
      
      $data['result'] = false;
      $data['html'] = $this->getLang('unknown_error');
      
      $acl = $this->hlp->checkAddressbookPermission($id);
      if($acl > AUTH_READ)
      {
          $write = true;
      }
      elseif($acl < AUTH_READ)
      {
        $data['result'] = false;
        $data['html'] = $this->getLang('no_permission');
        // Overwrite $action to bypass switch statement below
        $action = 'invalid';
      }
      else 
      {
          $write = false;
      }
      
      // Parse the requested action
      switch($action)
      {
          // Add a new Contact
          case 'newContact':
              if($write && ($this->hlp->addContactEntryToAddressbookForPage($id, $user, $params) === true))
              {
                  $data['result'] = true;
              }
              else
              {
                  $data['result'] = false;
                  if(!$write)
                    $data['html'] = $this->getLang('no_permission');
                  else
                    $data['html'] = $this->getLang('error_adding');
              }
          break;
          
          // Retrieve contact details
          case 'getContactDetails':
              $contactdata = $this->hlp->getContactByUri($id, $params['uri']);
              if($contactdata['result'] === true)
              {
                  // When we support pictures for editing contacts,
                  // we need to use the following line: 
                  // $contactdata['photo'] = base64_encode($contactdata['photo']);
                  // For now, we just save bandwidth :)
                  unset($contactdata['photo']);
                  $data['result'] = true;
                  $data['contactdata'] = $contactdata;
              }
              else
              {
                  $data['result'] = false;
                  $data['html'] = sprintf($this->getLang('contact_not_found'), 'ID='.$id.' URI='.$params['uri']);
              }
          break;

          // Edit a contact
          case 'editContact':
              if($write && ($this->hlp->editContactEntryToAddressbookForPage($id, $user, $params['uri'], $params) === true))
              {
                  $data['result'] = true;
              }
              else 
              {
                  $data['result'] = false;
                  if(!$write)
                    $data['html'] = $this->getLang('no_permission');
                  else
                    $data['html'] = $this->getLang('error_editing');
              }
          break;
          // Delete a Contact
          case 'deleteContact':
              if($write && ($this->hlp->deleteContactEntryToAddressbookForPage($id, $user, $params['uri']) === true))
              {
                  $data['result'] = true;
              }
              else
              {
                  $data['result'] = false;
                  if(!$write)
                    $data['html'] = $this->getLang('no_permission');
                  else
                    $data['html'] = $this->getLang('error_deleting');
              }
          break;
          // Get AJAX popup
          case 'getContactAjax':
              $contactdata = $this->hlp->getContactByUri($id, $params['uri']);
              $cardpattern = $this->getConf('popup_content');
              if($contactdata['result'] === false)
              {
                  echo hsc($contactdata['formattedname']);
                  return;
              }
              echo '<div class="plugin_davcard_popup_container">';
              foreach($contactdata['photo'] as $data)
              {
                  if(isset($data['type']))
                    $type = $data['type'];
                  else
                    $type = '';
                  echo '<div class="plugin_davcard_popup_image">';
                  $imgdata = base64_encode($data['photo']);
                  $pattern = '/^(?:[;\/?:@&=+$,]|(?:[^\W_]|[-_.!~*\()\[\] ])|(?:%[\da-fA-F]{2}))*$/';

                  // PNG images
                  if($type == 'png')
                  {
                      $imgdata = 'data:image/png;base64,'.$imgdata;
                      echo '<img src="'.hsc($imgdata).'" alt="contact image" />';
                  }
                  // JPEG images
                  elseif(($type == 'jpeg') || ($type == 'jpg'))
                  {
                      $imgdata = 'data:image/jpeg;base64,'.$imgdata;
                      echo '<img src="'.hsc($imgdata).'" alt="contact image" />';
                  }
                  // GIF images
                  elseif($type == 'gif')
                  {
                      $imgdata = 'data:image/gif;base64,'.$imgdata;
                      echo '<img src="'.hsc($imgdata).'" alt="contact image" />';
                  }
                  // URLs (no type given)
                  elseif(preg_match( $pattern, $string ) == 1)
                  {
                      echo '<img src="'.hsc($data['photo']).'" alt="contact image" />';
                  }
                  echo '</div>';
              }
              echo '<div class="plugin_davcard_popup_content">';
              $contactname = explode(';', $contactdata['structuredname']);
              if(count($contactname) > 1)
              {
                  $cardpattern = str_replace('<DCLASTNAME>', $contactname[0], $cardpattern);
                  $cardpattern = str_replace('<DCFIRSTNAME>', $contactname[1], $cardpattern);
              }
              if(count($contactdata['addr']) > 0)
              {
                  foreach($contactdata['addr'] as $data)
                  {
                      if(isset($data['type']) && ($data['type'] == 'work'))
                        $prefix = 'WORK';
                      else
                        $prefix = 'PRIVATE';
                      $cardpattern = str_replace('<DC'.$prefix.'STREET>', $data['address'][2], $cardpattern);
                      $cardpattern = str_replace('<DC'.$prefix.'CITY>', $data['address'][3], $cardpattern);
                      $cardpattern = str_replace('<DC'.$prefix.'ZIP>', $data['address'][5], $cardpattern);
                      $cardpattern = str_replace('<DC'.$prefix.'COUNTRY>', $data['address'][6], $cardpattern);
                  }
              }
              if(count($contactdata['tel']) > 0)
              {
                  $telArr = array();
                  foreach($contactdata['tel'] as $data)
                  {
                      if(isset($data['type']))
                        $type = $data['type'];
                      else
                        $type = 'other';
                      $type = $data['type'];
                      $telArr[] = $this->getLang('tel'.$type).': '.$data['number'];
                  }
                  $telStr = implode(' \\\\ ', $telArr);
                  $cardpattern = str_replace('<DCPHONE>', $telStr, $cardpattern);
              }
              if(count($contactdata['mail']) > 0)
              {
                  $mailArr = array();
                  foreach($contactdata['mail'] as $data)
                  {
                      $mailArr[] = '[['.$data['mail'].']]';
                  }
                  $mailStr = implode(' \\\\ ', $mailArr);
                  $cardpattern = str_replace('<DCEMAIL>', $mailStr, $cardpattern);
              }
              if($contactdata['birthday'] != '')
              {
                  $date = DateTime::createFromFormat('Ymd', $contactdata['birthday']);
                  $dateStr = $date->format($this->getConf('date_format'));
                  $cardpattern = str_replace('<DCBIRTHDAY>', $dateStr, $cardpattern);
              }
              if($contactdata['note'] != '')
              {
                  $notestr = str_replace('\n', ' \\ ', $contactdata['note']);
                  $cardpattern = str_replace('<DCNOTE>', $notestr, $cardpattern);
              }
              if($contactdata['title'] != '')
              {
                  $cardpattern = str_replace('<DCTITLE>', $contactdata['title'], $cardpattern);
              }
              if($contactdata['url'] != '')
              {
                  $url = $contactdata['url'];
                  if(strpos($url, '://') === false)
                    $url = 'http://'.$url;
                  $url = '[['.$url.']]';
                  $cardpattern = str_replace('<DCWEBSITE>', $url, $cardpattern);
              }
              
              $replace_match = '/^.*<DC.*>.*$(?:\r\n|\n)?/m';
              $cardpattern = preg_replace($replace_match, '', $cardpattern);
              echo $this->render_text($cardpattern);
              echo '</div>';
              echo '</div>';
              return;
          break;
      }
    
      // If we are still here, JSON output is requested
      
      //json library of DokuWiki
      require_once DOKU_INC . 'inc/JSON.php';
      $json = new JSON();
 
      //set content type
      header('Content-Type: application/json');
      echo $json->encode($data);            
    }
 
}              
