0, 'height' => 0]; /** * Barcode dimension. * * @var int * @since 1.0.0 */ protected int $margin = 10; /** * Content to encrypt. * * @var string * @since 1.0.0 */ protected string $content = ''; /** * Show text below barcode. * * @var bool * @since 1.0.0 */ protected bool $showText = true; /** * Background color. * * @var int[] * @since 1.0.0 */ protected array $background = ['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]; /** * Front color. * * @var int[] * @since 1.0.0 */ protected array $front = ['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]; /** * Constructor * * @param string $content Content to encrypt * @param int $width Barcode width * @param int $height Barcode height * @param int $orientation Orientation of the barcode * * @since 1.0.0 */ public function __construct(string $content = '', int $width = 100, int $height = 20, int $orientation = OrientationType::HORIZONTAL) { $this->setContent($content); $this->setDimension($width, $height); $this->setOrientation($orientation); } /** * Set barcode dimensions * * @param int $width Barcode width * @param int $height Barcode height * * @return void * * @since 1.0.0 */ public function setDimension(int $width, int $height) : void { if ($width < 0) { throw new \OutOfBoundsException((string) $width); } if ($height < 0) { throw new \OutOfBoundsException((string) $height); } $this->dimension['width'] = $width; $this->dimension['height'] = $height; } /** * Set barcode margins * * @param int $margin Barcode margin * * @return void * * @since 1.0.0 */ public function setMargin(int $margin) : void { $this->margin = $margin; } /** * Set barcode orientation * * @param int $orientation Barcode orientation * * @return void * * @since 1.0.0 */ public function setOrientation(int $orientation) : void { if (!OrientationType::isValidValue($orientation)) { throw new InvalidEnumValue($orientation); } $this->orientation = $orientation; } /** * Get content * * @return string Returns the string representation of the code * * @since 1.0.0 */ public function getContent() : string { return $this->content; } /** * Set content to encrypt * * @param string $content Barcode content * * @return void * * @since 1.0.0 */ public function setContent(string $content) : void { $this->content = $content; } /** * Get image reference * * @return mixed * * @since 1.0.0 */ public function get() { $codeString = static::$CODE_START . $this->generateCodeString() . static::$CODE_END; return $this->createImage($codeString); } /** * Save to file * * @param string $file File path/name * * @return void * * @since 1.0.0 */ public function saveToPngFile(string $file) : void { $res = $this->get(); \imagepng($res, $file); \imagedestroy($res); } /** * Save to file * * @param string $file File path/name * * @return void * * @since 1.0.0 */ public function saveToJpgFile(string $file) : void { $res = $this->get(); \imagejpeg($res, $file); \imagedestroy($res); } /** * Validate the barcode string * * @param string $barcode Barcode string * * @return bool Returns true if the string is valid for the specific code implementetion otherwise false is returned * * @since 1.0.0 */ public static function isValidString(string $barcode) : bool { $length = \strlen($barcode); for ($i = 0; $i < $length; ++$i) { if (!isset(static::$CODEARRAY[$barcode[$i]]) && !\in_array($barcode[$i], static::$CODEARRAY)) { return false; } } return true; } /** * Generate weighted code string * * @return string Returns the code string generated from the human readable content * * @since 1.0.0 */ protected function generateCodeString() : string { $keys = \array_keys(static::$CODEARRAY); $values = \array_flip($keys); $codeString = ''; $length = \strlen($this->content); $checksum = static::$CHECKSUM; for ($pos = 1; $pos <= $length; ++$pos) { $activeKey = \substr($this->content, ($pos - 1), 1); $codeString .= static::$CODEARRAY[$activeKey]; $checksum += $values[$activeKey] * $pos; } $codeString .= static::$CODEARRAY[$keys[($checksum - ((int) ($checksum / 103) * 103))]]; return $codeString; } /** * Create barcode image * * @param string $codeString Code string to render * * @return mixed * * @since 1.0.0 */ protected function createImage(string $codeString) { $dimensions = $this->calculateDimensions($codeString); $image = \imagecreate($dimensions['width'], $dimensions['height']); if ($image === false) { throw new \Exception(); // @codeCoverageIgnore } $black = \imagecolorallocate($image, 0, 0, 0); $white = \imagecolorallocate($image, 255, 255, 255); $location = 0; $length = \strlen($codeString); \imagefill($image, 0, 0, $white); for ($position = 1; $position <= $length; ++$position) { $cur_size = $location + (int) (\substr($codeString, ($position - 1), 1)); if ($this->orientation === OrientationType::HORIZONTAL) { \imagefilledrectangle( $image, $location + $this->margin, 0 + $this->margin, $cur_size + $this->margin, $dimensions['height'] - $this->margin - 1, ($position % 2 == 0 ? $white : $black) ); } else { \imagefilledrectangle( $image, 0 + $this->margin, $location + $this->margin, $dimensions['width'] - $this->margin - 1, $cur_size + $this->margin, ($position % 2 == 0 ? $white : $black) ); } $location = $cur_size; } return $image; } /** * Calculate the code length for image dimensions * * @param string $codeString Code string to render * * @return int Length of the code * * @since 1.0.0 */ private function calculateCodeLength(string $codeString) : int { $codeLength = 0; $length = \strlen($codeString); for ($i = 1; $i <= $length; ++$i) { $codeLength = $codeLength + (int) (\substr($codeString, ($i - 1), 1)); } return $codeLength; } /** * Calculate the code dimensions * * @param string $codeString Code string to render * * @return array * * @since 1.0.0 */ private function calculateDimensions(string $codeString) : array { $codeLength = $this->calculateCodeLength($codeString); $dimensions = ['width' => 0, 'height' => 0]; if ($this->orientation === OrientationType::HORIZONTAL) { $dimensions['width'] = $codeLength + $this->margin * 2 + 1; $dimensions['height'] = $this->dimension['height']; } else { $dimensions['width'] = $this->dimension['width']; $dimensions['height'] = $codeLength + $this->margin * 2 + 1; } return $dimensions; } }