| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | namespace Wambo\Catalog\Model; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use Wambo\Catalog\Error\SKUException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  * Class SKU represents an unique identifier (stock keeping unit) for a product (e.g. "fancy-short-1") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  * @package Wambo\Catalog\Model | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | class SKU | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |      * @var string $whiteSpacePattern A regular expression that matches white-space characters | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |     private $whiteSpacePattern = '/[\s]/'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |      * @var string $invalidCharactersPattern A regular expression that matches all characters that are invalid for a SKU | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     private $invalidCharactersPattern = '/[^a-z0-9-]/'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |      * @var string $uppercaseCharactersPattern A regular expression that matches uppercase characters | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |     private $uppercaseCharactersPattern = '/[A-Z]/'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |      * @var string $invalidPrefixCharacters A regular expression that matches characters that cannot be used as a prefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |      *      for SKUs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     private $invalidPrefixCharacters = '/^[-]/'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |      * @var string $invalidSuffixCharacters A regular expression that matches characters that cannot be used as a prefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |      *      for SKUs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |     private $invalidSuffixCharacters = '/[-]$/'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |      * @var int $minLength Defines the minimum length for a SKU | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |     private $minLength = 2; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |      * @var int $maxLength Defines the maximum length of a SKU | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |     private $maxLength = 32; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |      * @var string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |     private $sku; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |      * Create a new SKU instance | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |      * @param string $sku A unique identifier for a product (e.g. "fancy-short-1") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |      * @throws SKUException If the given $sku is invalid | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 61 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 62 | 52 |  |     public function __construct(string $sku) | 
            
                                                                        
                            
            
                                    
            
            
                | 63 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 64 | 52 |  |         $this->validateSKU($sku); | 
            
                                                                        
                            
            
                                    
            
            
                | 65 | 21 |  |         $this->sku = $sku; | 
            
                                                                        
                            
            
                                    
            
            
                | 66 | 21 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |      * Get a string representation of the current SKU. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |      *  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 | 8 |  |     public function __toString() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 | 8 |  |         return $this->sku; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |      * Validate the given SKU | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |      * @param string $sku A unique identifier for a product (e.g. "fancy-short-1") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |      * @return void | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |      * @throws SKUException If the given $sku is invalid | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 | 52 |  |     private function validateSKU(string $sku) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 | 52 |  |         if (strlen($sku) == 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 | 1 |  |             throw new SKUException("A SKU cannot be empty"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         // check for white-space | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 | 51 |  |         $containsWhitespace = preg_match($this->whiteSpacePattern, $sku) == 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 | 51 |  |         if ($containsWhitespace) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 | 4 |  |             throw new SKUException(sprintf("A SKU cannot contain white space characters: \"%s\"", $sku)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |         // uppercase | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 | 47 |  |         $containsUppercaseCharacters = preg_match($this->uppercaseCharactersPattern, $sku) == 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 | 47 |  |         if ($containsUppercaseCharacters) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 | 6 |  |             throw new SKUException(sprintf("A SKU cannot contain uppercase characters: \"%s\"", $sku)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |         // check for invalid characters | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 | 41 |  |         $containsInvalidCharacters = preg_match($this->invalidCharactersPattern, $sku) == 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 | 41 |  |         if ($containsInvalidCharacters) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 | 13 |  |             throw new SKUException(sprintf("The SKU \"%s\" contains invalid characters. A SKU can only contain the following characters: a-z, 0-9 and -", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |                 $sku)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |         // check prefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 | 28 |  |         $prefixMatches = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 | 28 |  |         $prefixContainsInvalidCharacters = preg_match($this->invalidPrefixCharacters, $sku, $prefixMatches) == 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 | 28 |  |         if ($prefixContainsInvalidCharacters) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 | 1 |  |             throw new SKUException(sprintf("A SKU cannot start with the given characters: \"%s\"", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 | 1 |  |                 implode("", $prefixMatches))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |         // check suffix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 | 27 |  |         $suffixMatches = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 | 27 |  |         $suffixContainsInvalidCharacters = preg_match($this->invalidSuffixCharacters, $sku, $suffixMatches) == 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 | 27 |  |         if ($suffixContainsInvalidCharacters) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 | 1 |  |             throw new SKUException(sprintf("A SKU cannot end with the given characters: \"%s\"", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 | 1 |  |                 implode("", $suffixMatches))); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |         // check minimum length | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 | 26 |  |         if (strlen($sku) < $this->minLength) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 | 4 |  |             throw new SKUException(sprintf("The given SKU \"%s\" is too short. The minimum length for a SKU is: %s", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 | 4 |  |                 $sku, $this->minLength)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |         // check maximum length | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 | 22 |  |         if (strlen($sku) > $this->maxLength) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 | 1 |  |             throw new SKUException(sprintf("The given SKU \"%s\" is too long (%s character). The maximum length for a SKU is: %s", | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 | 1 |  |                 strlen($sku), $sku, $this->maxLength)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |         } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 139 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 140 |  |  | } |