Overview

Namespaces

  • pgn
    • exceptions
    • tags
  • utils

Classes

  • pgn\Game
  • pgn\PGN
  • pgn\tags\Annotator
  • pgn\tags\Black
  • pgn\tags\BlackElo
  • pgn\tags\BlackNA
  • pgn\tags\BlackTitle
  • pgn\tags\BlackType
  • pgn\tags\BlackUSCF
  • pgn\tags\Board
  • pgn\tags\Date
  • pgn\tags\ECO
  • pgn\tags\Event
  • pgn\tags\EventCountry
  • pgn\tags\EventDate
  • pgn\tags\EventRounds
  • pgn\tags\EventSponsor
  • pgn\tags\EventType
  • pgn\tags\FEN
  • pgn\tags\Mode
  • pgn\tags\NIC
  • pgn\tags\Opening
  • pgn\tags\PlyCount
  • pgn\tags\Result
  • pgn\tags\Round
  • pgn\tags\Section
  • pgn\tags\SetUp
  • pgn\tags\Site
  • pgn\tags\Source
  • pgn\tags\SourceDate
  • pgn\tags\Stage
  • pgn\tags\SubVariation
  • pgn\tags\Tag
  • pgn\tags\Termination
  • pgn\tags\Time
  • pgn\tags\TimeControl
  • pgn\tags\UknownTag
  • pgn\tags\UTCDate
  • pgn\tags\UTCTime
  • pgn\tags\Variation
  • pgn\tags\White
  • pgn\tags\WhiteElo
  • pgn\tags\WhiteNA
  • pgn\tags\WhiteTitle
  • pgn\tags\WhiteType
  • pgn\tags\WhiteUSCF
  • utils\Parser
  • utils\String

Exceptions

  • pgn\exceptions\InvalidClassNameException
  • pgn\exceptions\InvalidDataException
  • pgn\exceptions\InvalidGameFormatException
  • pgn\exceptions\InvalidGamePathException
  • pgn\exceptions\PGNException
  • utils\ParserException
  • Overview
  • Namespace
  • Class
  1: <?php
  2: /* 
  3:  * Copyright (c) 2016 Geraldo B. Landre
  4:  * 
  5:  * See the file LICENSE for copying permission.
  6:  */
  7: namespace pgn\tags;
  8: 
  9: use pgn\exceptions\InvalidDataException;
 10: use pgn\exceptions\InvalidGameFormatException;
 11: 
 12: /**
 13:  * Abstract class representing a Tag in a PGN game
 14:  *
 15:  * @author Geraldo
 16:  */
 17: abstract class Tag {
 18: 
 19:     /**
 20:      * @return the name of the tag
 21:      */
 22:     abstract public function getName();
 23: 
 24:     protected $data;
 25:     protected $errorMsg;
 26: 
 27:     /**
 28:      * Returns the tag as a string. The default string patter is:
 29:      * [TagName "content"]
 30:      * @return string 
 31:      */
 32:     public function __toString() {
 33:         return '[' . $this->getName() . ' "' . $this->get() . '"]';
 34:     }
 35:     
 36:     /**
 37:      * Sets the tag with the data if it's a valid data
 38:      * @param string $data
 39:      * @throws InvalidDataException throws an exception if the data is not in the correct format
 40:      * @see Tag::validate
 41:      */
 42:     public function set($data) {
 43:         if ($this->validate($data)) {
 44:             $this->data = $data;
 45:         } else {
 46:             throw new InvalidDataException("[" . __CLASS__ . "]" . $this->errorMsg);
 47:         }
 48:     }
 49: 
 50:     /**
 51:      * Returns the data of the tag as a string
 52:      * @see Tag::formatted
 53:      * @return string formatted data
 54:      */
 55:     public function get() {
 56:         return $this->formatted($this->data);
 57:     }
 58: 
 59:     /**
 60:      * 
 61:      * @param mixed $data
 62:      * @return boolean returns if a data is valid
 63:      */
 64:     public function validate($data) {
 65: 
 66:         if ($data === "0") {
 67:             return true;
 68:         }
 69:         
 70:         if ($data === \NULL) {
 71:             return false;
 72:         }
 73: 
 74:         if (is_array($data)) {
 75:             return false;
 76:         }
 77: 
 78:         if (empty($data)) {
 79:             return false;
 80:         }
 81: 
 82:         return true;
 83:     }
 84: 
 85:     /**
 86:      * Returns the default value of the Tag
 87:      * @return string
 88:      */
 89:     public function getDefaultValue() {
 90:         return '?';
 91:     }
 92: 
 93:     /**
 94:      * Returns its data as a formatted string
 95:      * It's recommended to be overwritten
 96:      * 
 97:      * @see http://php.net/manual/pt_BR/function.strval.php
 98:      * @return string
 99:      */
100:     protected function formatted($data) {
101:         if (isset($data)) {
102:             return strval($data);
103:         }
104:         return $this->getDefaultValue();
105:     }
106: 
107:     /**
108:      * 
109:      * @param string $unparsedTag
110:      * @param string [] $errors array of strings
111:      * @return Tag The tag created
112:      */
113:     static public function parse($unparsedTag, &$errors) {
114: 
115:         if (!(boolean) preg_match("/^" . self::validPattern() . "$/", $unparsedTag)) {
116:             $errors[] = "[" . __CLASS__ . "] error trying to parse '$unparsedTag':[tag does not match with the pattern]";
117:             return NULL;
118:         }
119: 
120:         if (!is_array($errors)) {
121:             $errors = array();
122:         }
123: 
124:         $tagName = self::parseTagName($unparsedTag);
125:         $tagValue = self::parseTagValue($unparsedTag);
126:         
127:         return self::createTag($tagName, $tagValue);
128:     }
129: 
130:     /**
131:      * Parses a string in correct format of a tag 
132:      * and returns the value of the tag
133:      * @throws \pgn\exceptions\InvalidGameFormatException if tag was not on correct format
134:      * @assert('[TestName "Test Value"]') === "TestName"
135:      * @assert('[TestName "Test Value"') === "TestName"
136:      * @assert('asdf') throws InvalidGameFormatException
137:      * @param string $unparsedTag
138:      */
139:     static public function parseTagName($unparsedTag) {
140:         return self::parseTagAndGetMatch($unparsedTag, 1);
141:     }
142: 
143:     /**
144:      * Parses a string in correct format of a tag 
145:      * and returns the value of the tag
146:      * if the string is not in the correct format throws an exception
147:      * @throws \pgn\exceptions\InvalidGameFormatException if tag was not on correct format
148:      * @assert('[TestName "Test Value"]') === "Test Value"
149:      * @assert('[TestName "Test Value"') === "Test Value"
150:      * @assert('asdf') throws InvalidGameFormatException
151:      * @param string $unparsedTag
152:      */
153:     static public function parseTagValue($unparsedTag) {
154:         return self::parseTagAndGetMatch($unparsedTag, 2);
155:     }
156: 
157:     /**
158:      * Get the regex pattern of a valid tag string
159:      * @return string regex pattern of a valid tag string
160:      */
161:     static public function validPattern() {
162:         return "\[.*\s+\".*\"\]";
163:     }
164: 
165:     /**
166:      * Creates a tag, based on tags classes (@see \pgn\tags)
167:      * @param string $tagName the name of the tag
168:      * @param string $tagValue the value of the tag
169:      * @return \pgn\tags\Tag
170:      */
171:     static public function createTag($tagName, $tagValue) {
172:         try {
173:             $namespace = "\\pgn\\tags\\";
174:             $className = $namespace . $tagName;
175:             $tag = new $className ();
176:             $tag->set($tagValue);
177:             return $tag;
178:         } 
179:         catch(InvalidDataException $ex) {
180:             $errors = "[" . __CLASS__ . "] bad value [$tagValue] for tag $tagName [" . $ex->getMessage() . "]";
181:         } 
182:         catch (\Exception $ex) {
183:             $errors = "[" . __CLASS__ . "] urecognized Tag: $tagName [" . $ex->getMessage() . "]";
184:             return self::createUknownTag($tagName, $tagValue, $errors);
185:         }
186:     }
187: 
188:     /**
189:      * Creates an Uknown Tag (@see \pgn\tags\UknownTag)
190:      * @param string $tagName name of the tag
191:      * @param string $tagValue value of the tag
192:      * @param string $errors output parameter to store errors and warnings
193:      * @return \pgn\tags\UknownTag or NULL if it was not possible to create a tag
194:      */
195:     static private function createUknownTag($tagName, $tagValue, &$errors) {
196:         try {
197:             $tag = new UknownTag();
198:             $tag->setName($tagName);
199:             $tag->set($tagValue);
200:             return $tag;
201:         } catch (\Exception $ex) {
202:             $errors[] = "[" . __CLASS__ . "] error trying to parse '$unparsedTag' [" . $ex->getMessage() . "]";
203:             return NULL;
204:         }
205:     }
206: 
207:     /**
208:      * Parses a tag according to the correct format: [TagName "TagValue"]
209:      * and returns an array with those values. If the string is not in the
210:      * correct format, returns null.
211:      * 
212:      * @param string $unparsedTag string to be parsed
213:      * @return array array containing the matches or null if the string does not match
214:      */
215:     static private function parseTag($unparsedTag) {
216:         $matches = array();
217:         if (preg_match("/^" . self::validPattern() . "$/", $unparsedTag)) {
218:             $pattern = "/^\[(.*)\s+\"(.*)\"\]$/";
219:             preg_match($pattern, $unparsedTag, $matches);
220:         }
221:         return (count($matches == 3)) ? $matches : NULL;
222:     }
223: 
224:     /**
225:      * Parses a string in correct format of a tag
226:      * put the hole tag at index 0, the tag name at index 1 and the tag value
227:      * at index 2. Returns the value in the index passed
228:      * if the string is not in the correct format throws an exception
229:      * @param string $unparsedTag The tag to be parsed
230:      * @param int $index 0 to return the hole tag;
231:      *                   1 to return the tag name;
232:      *                   2 to return the tag value.
233:      * @return string the tag information located in the matches array (indexes 0, 1 or 2)
234:      * @throws \pgn\exceptions\InvalidGameFormatException if tag was not on correct format
235:      */
236:     static private function parseTagAndGetMatch($unparsedTag, $index) {
237:         $matches = self::parseTag($unparsedTag);
238:         if ($matches != NULL) {
239:             return $matches[$index];
240:         }
241:         throw new InvalidGameFormatException("[" . __CLASS__ . "]: bad tag format: " . $unparsedTag);
242:     }
243: 
244: }
API documentation generated by ApiGen