<?php
/*
Plugin Name: QR Code Generator
Description: Easily create QR Codes for use on websites, web applications, and printed materials.
Version: 1.02
Requires at least: 3.00
*/

$GLOBALS['qrCodeGenerator']['defaultSize']   = 200;                 //
$GLOBALS['qrCodeGenerator']['defaultMargin'] = 0;                   //
$GLOBALS['qrCodeGenerator']['defaultMode']   = 'img';               // img or url (for image tag or image url)
$GLOBALS['qrCodeGenerator']['pluginName']    = "QR Code Generator"; // displayed in plugin menu

// DON'T UPDATE ANYTHING BELOW THIS LINE

$GLOBALS['qrCodeGenerator']['exampleFiles'] = array(
  'plaintext.php'    => 'Plain Text',
  'url.php'          => 'Web Address',
  'email.php'        => 'Email Address',
  'event.php'        => 'Calendar Event',
  'contact.php'      => 'Address Book Contact',
  'facebooklike.php' => 'Facebook Like',
  'advanced.php'     => 'Advanced Options: Set size, margin, and mode',
);

addAction('admin_postlogin', '_qrCodeGenerator_dispatch', null, 0);
addAction('plugin_actions',  '_qrCodeGenerator_addPluginAction', null, 1);


//
function qrCode($options) {

  // set defaults
  if (!@$options['size'])   { $options['size']   = $GLOBALS['qrCodeGenerator']['defaultSize']; }
  if (!@$options['margin']) { $options['margin'] = $GLOBALS['qrCodeGenerator']['defaultMargin']; }
  if (!@$options['mode'])   { $options['mode']   = $GLOBALS['qrCodeGenerator']['defaultMode']; }

  // error checking
  $errors = _qrCode_getOptionErrors($options);
  if ($errors) { return __FUNCTION__ . ": $errors"; }

  // create QR Code data
  $data = '';
  $type = $options['type'];
  if ($type == 'text')              { $data = $options['text']; }
  elseif ($type == 'url')           { $data = $options['url']; }
  elseif ($type == 'email')         { $data = 'mailto:' . $options['email']; }
  elseif ($type == 'event')         { $data = "BEGIN:VEVENT:\nSUMMARY:" . $options['title'] . "\nDTSTART:" . gmdate("Ymd\THis", strtotime($options['start'])) . "\nDTEND:" . gmdate("Ymd\THis", strtotime($options['end'])) . "\nEND:VEVENT";  }
  elseif ($type == 'contact')       { $data = 'MECARD:N:' . $options['lastName'] . "," . $options['firstName'] . ";ADR:" . $options['address'] . ";TEL:" . $options['phone'] . ";EMAIL:" . $options['email'] . ";;"; }
  elseif ($type == 'facebook_like') { $data = 'https://www.facebook.com/plugins/like.php?href=' . $options['url']; }
  else                              { die(__FUNCTION__ . ": Unknown type '" .htmlencode( $type ). "'"); }

  // build chart url
  $height    = $options['size'];
  $width     = $options['size'];
  $chartURL  = "https://chart.apis.google.com/chart?"; // docs: http://code.google.com/apis/chart/docs/gallery/qr_codes.html
  $chartURL .= http_build_query(array(
    'cht'  => 'qr',
    'chs'  => $height . 'x' . $width,
    'chl'  => $data,
    'chld' => '|' . $options['margin'],
  ));

  // error checking
  $maxLength = 1900;
  $urlLength = strlen($chartURL);
  if ($urlLength > $maxLength) { return "QR tag data is too long! Max length: $maxLength, URL length: $urlLength!"; }

  // create output
  $output = '';
  if     ($options['mode'] == 'img') { $output = "<img src='$chartURL' height='$height' width='$width' />"; }
  elseif ($options['mode'] == 'url') { $output = $chartURL; }
  else                               { die(__FUNCTION__ . ": Unknown mode '" .htmlencode( $options['mode'] ). "'"); }
  return $output;

}


//
function _qrCode_getOptionErrors($options) {
  $errors = '';

  // types to options
  $typeOptions = array( 'text'          => array('type', 'size', 'margin', 'mode', 'text'),
                        'url'           => array('type', 'size', 'margin', 'mode', 'url'),
                        'email'         => array('type', 'size', 'margin', 'mode', 'email'),
                        'event'         => array('type', 'size', 'margin', 'mode', 'start', 'end', 'title'),
                        'contact'       => array('type', 'size', 'margin', 'mode', 'lastName', 'firstName', 'address', 'phone', 'email'),
                        'facebook_like' => array('type', 'size', 'margin', 'mode', 'url'));

  // error checking
  $type       = @$options['type'];
  $validTypes = implode(', ', array_keys($typeOptions));
  if (!is_array($options))       { $errors .= "First argument must be an options array!\n"; }
  if     (!$type)                { $errors .= "You must specify a code type.  Valid types ($validTypes).\n"; }
  elseif (!@$typeOptions[$type]) { $errors .= "Invalid type '" .htmlencode($options['type']). "', valid types ($validTypes).\n"; }
  if ($errors) { return $errors; } // if any errors here, return them first without doing any more checks

  // Check for required options
  $requiredOptions = array_values($typeOptions[$type]);
  foreach ($requiredOptions as $requiredOptionKey) {
    $isOptionDefined = array_key_exists($requiredOptionKey, $options);
    if (!$isOptionDefined) { $errors .= "Missing required option '" .htmlencode($requiredOptionKey). "' for type '" .htmlencode($type). "'!\n"; }
  }

  // Check for unknown options
  $validOptions      = $typeOptions[$type];
  $validOptionsAsCSV = join(', ', $validOptions);
  foreach(array_keys($options) as $thisOptionKey) {
    $isUnknownOption = !in_array($thisOptionKey, $validOptions);
    if ($isUnknownOption) { $errors .= "Unknown option '" .htmlencode($thisOptionKey). "', valid option names ($validOptionsAsCSV)\n"; }
  }

  ### check options

  if (array_key_exists('url', $options)) {
    if (!preg_match("|^\w+://|", $options['url'])) { $errors .= "Invalid value for option 'url'!\n"; }
  }

  if (array_key_exists('email', $options)) {
    if (!isValidEmail($options['email'])) { $errors .= "Invalid value for option 'email'!\n"; }
  }

  $dateFields = array('start', 'end');
  foreach ($dateFields as $key) {
    if (!array_key_exists($key, $options)) { continue; }
    if (strtotime($options[$key]) >= 0) { continue; }
    $errors .= "Invalid value for date option '$key'!\n";
  }

  if (array_key_exists('mode', $options)) {
    $modeOptions = array('img', 'url');
    if (!in_array($options['mode'], $modeOptions)) { $errors .= "Invalid value for option 'mode', must be either img or url!\n"; }
  }

  //
  return $errors;
}


// dispatch commands
function _qrCodeGenerator_dispatch() {
  if (@$_REQUEST['_pluginName'] != 'qrCodeGenerator') { return; } // only run for this plugin

  // show plugin menu as highlighted
  $_REQUEST['menu']   = 'admin';
  $_REQUEST['action'] = 'plugins';

  // dispatch plugin actions
  $action = @$_REQUEST['_pluginAction'];

  if ($action == 'examples') {
    _qrCodeGenerator_showExamples();
  }
}


// on plugin_actions: display a "Run" link
function _qrCodeGenerator_addPluginAction($pluginPath) {
  list($thisPluginPath, $thisPluginUrl) = getPluginPathAndUrl();
  if ($thisPluginPath != $pluginPath) { return; }

  echo "<a href='?_pluginName=qrCodeGenerator&amp;_pluginAction=examples' style='white-space: nowrap;'>Example Code</a><br/>";
}

//
function _qrCodeGenerator_showExamples() {
  
  // prepare adminUI() placeholders
  $adminUI = [];
  // page title
  $adminUI['PAGE_TITLE'] = [
    t("Plugins")                          => '?menu=admin&action=plugins',
    t("{$GLOBALS['qrCodeGenerator']['pluginName']} - Example Code") => '?_pluginName=qrCodeGenerator&_pluginAction=examples',
  ];
  
  // button
  $adminUI['BUTTONS'] = [
    [ 'name' => 'back_to_plugins', 'label' => 'Back to Plugins &gt;&gt;',  'onclick' => 'window.location="?menu=admin&action=plugins";', 'type' => 'button' ],
  ];
  
  // content
  $adminUI['CONTENT'] = ob_capture(function() {

    // get example file
    $exampleFile = @$_REQUEST['filename'];
    if ($exampleFile && !@$GLOBALS['qrCodeGenerator']['exampleFiles'][$exampleFile]) { // error checking
      die("Not a registered example file: '" .htmlencode($exampleFile). "'");
    }
  
    //
    list($examplePath, $exampleUrl) = getPluginPathAndUrl("examples/$exampleFile");
    $examplePath =  $GLOBALS['PROGRAM_DIR'] . "/plugins/$examplePath";
    ?>
      <ul style="padding-top: 0; padding-bottom: 0;">
  
        <?php foreach ($GLOBALS['qrCodeGenerator']['exampleFiles'] as $filename => $description): ?>
          <li><a href="?_pluginName=qrCodeGenerator&amp;_pluginAction=examples&amp;filename=<?php echo $filename ?>"><?php echo $description ?></a></li>
        <?php endforeach ?>
      </ul>
  
    <?php if ($exampleFile): ?>
      <?php echo adminUI_separator(t('Source Code')) ?>
  
      <div style="line-height: 1.5">
        <b>URL: <a href="<?php echo $exampleUrl ?>"><?php echo $exampleUrl ?></a></b><br/>
        <b>File: <?php echo $examplePath ?></b><br/>
        <xmp><?php
          $sourceCode = file_get_contents($examplePath);
          $sourceCode = preg_replace("|<br\s*/?>|", '', $sourceCode); // remove br tags
          $sourceCode = preg_replace("|<\?php.*?viewer_functions.*?\?>\s*|s", '', $sourceCode); // remove viewer_functions block
          echo $sourceCode;
        ?></xmp>
      </div>
  
      <?php echo adminUI_separator(t('Example Code')) ?>
  
      <iframe id='createpdf_output' src='<?php echo $exampleUrl ?>' height='250' width='100%' frameborder='1' style="border: 1px solid #999; padding: 5px;"></iframe><br/>
    <?php endif ?>

  <?php });
  // display content
  adminUI($adminUI);
  exit;
}

?>