Subversion Repositories oidplus

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 Daniel Marschall, ViaThinkSoft
  6.  *
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *     http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  */
  19.  
  20. class OIDplusGs1 extends OIDplusObject {
  21.         private $number;
  22.  
  23.         public function __construct($number) {
  24.                 $this->number = $number;
  25.         }
  26.  
  27.         public static function parse($node_id) {
  28.                 @list($namespace, $number) = explode(':', $node_id, 2);
  29.                 if ($namespace !== 'gs1') return false;
  30.                 return new self($number);
  31.         }
  32.  
  33.         public static function objectTypeTitle() {
  34.                 return "GS1 Based IDs (GLN/GTIN/SSCC/...)";
  35.         }
  36.  
  37.         public static function objectTypeTitleShort() {
  38.                 return "GS1";
  39.         }
  40.  
  41.         public static function ns() {
  42.                 return 'gs1';
  43.         }
  44.  
  45.         public static function root() {
  46.                 return 'gs1:';
  47.         }
  48.  
  49.         public function isRoot() {
  50.                 return $this->number == '';
  51.         }
  52.  
  53.         public function nodeId() {
  54.                 return 'gs1:'.$this->number;
  55.         }
  56.  
  57.         public function addString($str) {
  58.                 if (!preg_match('@^\\d+$@', $str, $m)) {
  59.                         throw new Exception('GS1 value needs to be numeric');
  60.                 }
  61.  
  62.                 return $this->nodeId() . $str;
  63.         }
  64.  
  65.         public function crudShowId(OIDplusObject $parent) {
  66.                 return $this->chunkedNotation(false);
  67.         }
  68.  
  69.         public function crudInsertPrefix() {
  70.                 return $this->isRoot() ? '' : substr($this->chunkedNotation(false), strlen(self::ns())+1);
  71.         }
  72.  
  73.         public function jsTreeNodeName(OIDplusObject $parent = null) {
  74.                 if ($parent == null) return $this->objectTypeTitle();
  75.                 return substr($this->nodeId(), strlen($parent->nodeId()));
  76.         }
  77.  
  78.         public function defaultTitle() {
  79.                 return $this->number;
  80.         }
  81.  
  82.         public function getContentPage(&$title, &$content) {
  83.                 if ($this->isRoot()) {
  84.                         $title = OIDplusGs1::objectTypeTitle();
  85.  
  86.                         $res = OIDplus::db()->query("select * from ".OIDPLUS_TABLENAME_PREFIX."objects where parent = '".OIDplus::db()->real_escape_string(self::root())."'");
  87.                         if (OIDplus::db()->num_rows($res) > 0) {
  88.                                 $content  = 'Please select an item in the tree view at the left to show its contents.';
  89.                         } else {
  90.                                 $content  = 'Currently, no GS1 based numbers are registered in the system.';
  91.                         }
  92.  
  93.                         if (OIDplus::authUtils()::isAdminLoggedIn()) {
  94.                                 $content .= '<h2>Manage root objects</h2>';
  95.                         } else {
  96.                                 $content .= '<h2>Available objects</h2>';
  97.                         }
  98.                         $content .= '%%CRUD%%';
  99.                 } else {
  100.                         if ($this->isBaseOnly()) {
  101.                                 $chunked = $this->chunkedNotation(true);
  102.                                 $content = '<h2>'.$chunked.'</h2>';
  103.                         } else {
  104.                                 $chunked = $this->chunkedNotation(true);
  105.                                 $checkDigit = $this->checkDigit();
  106.                                 $content = '<h2>'.$chunked.' - <abbr title="check digit">'.$checkDigit.'</abbr></h2>';
  107.                                 $content .= '<p><a target="_blank" href="https://www.ean-search.org/?q='.htmlentities($this->fullNumber()).'">Lookup in ean-search.org</a></p>';
  108.                                 $content .= '<img src="plugins/objectTypes/'.basename(__DIR__).'/barcode.php?number='.urlencode($this->fullNumber()).'">';
  109.                         }
  110.  
  111.                         $content .= '<h2>Description</h2><br><br>%%DESC%%<br><br>'; // TODO: add more meta information about the object type
  112.  
  113.                         if ($this->userHasWriteRights()) {
  114.                                 $content .= '<h2>Create or change subsequent objects</h2>';
  115.                         } else {
  116.                                 $content .= '<h2>Subsequent objects</h2>';
  117.                         }
  118.                         $content .= '%%CRUD%%';
  119.                 }
  120.         }
  121.  
  122.         # ---
  123.  
  124.         public function isBaseOnly() {
  125.                 return strlen($this->number) <= 7;
  126.         }
  127.  
  128.         public function chunkedNotation($withAbbr=true) {
  129.                 $curid = 'gs1:'.$this->number;
  130.  
  131.                 $res = OIDplus::db()->query("select id, title from ".OIDPLUS_TABLENAME_PREFIX."objects where id = '".OIDplus::db()->real_escape_string($curid)."'");
  132.                 if (OIDplus::db()->num_rows($res) == 0) return $this->number();
  133.  
  134.                 $hints = array();
  135.                 $lengths = array(strlen($curid));
  136.                 while (OIDplus::db()->num_rows($res = OIDplus::db()->query("select parent, title from ".OIDPLUS_TABLENAME_PREFIX."objects where id = '".OIDplus::db()->real_escape_string($curid)."'")) > 0) {
  137.                         $row = OIDplus::db()->fetch_array($res);
  138.                         $curid = $row['parent'];
  139.                         $hints[] = $row['title'];
  140.                         $lengths[] = strlen($curid);
  141.                 }
  142.  
  143.                 array_shift($lengths);
  144.                 $chunks = array();
  145.  
  146.                 $full = 'gs1:'.$this->number;
  147.                 foreach ($lengths as $len) {
  148.                         $chunks[] = substr($full, $len);
  149.                         $full = substr($full, 0, $len);
  150.                 }
  151.  
  152.                 $hints = array_reverse($hints);
  153.                 $chunks = array_reverse($chunks);
  154.  
  155.                 $full = array();
  156.                 foreach ($chunks as $c) {
  157.                         $full[] = $withAbbr ? '<abbr title="'.htmlentities(array_shift($hints)).'">'.$c.'</abbr>' : $c;
  158.                 }
  159.                 return implode(' ', $full);
  160.         }
  161.  
  162.         public function fullNumber() {
  163.                 return $this->number . $this->checkDigit();
  164.         }
  165.  
  166.         public function checkDigit() {
  167.                 $mul = 3;
  168.                 $sum = 0;
  169.                 for ($i=strlen($this->number)-1; $i>=0; $i--) {
  170.                         $sum += $this->number[$i] * $mul;
  171.                         $mul = $mul == 3 ? 1 : 3;
  172.                 }
  173.                 return 10 - ($sum % 10);
  174.         }
  175. }
  176.  
  177. OIDplusObject::$registeredObjectTypes[] = 'OIDplusGs1';
  178.  
  179.