예제 #1
0
 /**
  * Creates a pkpass file
  *
  * @param  Passbook\PassInterface $pass
  * @throws FileException          If an IO error occurred
  * @return SplFileObject
  */
 public function package(PassInterface $pass)
 {
     $pass->setPassTypeIdentifier($this->passTypeIdentifier);
     $pass->setTeamIdentifier($this->teamIdentifier);
     $pass->setOrganizationName($this->organizationName);
     // Serialize pass
     $json = self::serialize($pass);
     $outputPath = rtrim($this->getOutputPath(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
     $passDir = $outputPath . $pass->getSerialNumber() . DIRECTORY_SEPARATOR;
     $passDirExists = file_exists($passDir);
     if ($passDirExists && !$this->isOverwrite()) {
         throw new FileException("Temporary pass directory already exists");
     } elseif (!$passDirExists && !mkdir($passDir, 0777, true)) {
         throw new FileException("Couldn't create temporary pass directory");
     }
     // Pass.json
     $passJSONFile = $passDir . 'pass.json';
     file_put_contents($passJSONFile, $json);
     // Images
     /** @var \Passbook\Pass\Image $image */
     foreach ($pass->getImages() as $image) {
         $fileName = $passDir . $image->getContext();
         if ($image->isHighRetina()) {
             $fileName .= '@3x';
         } else {
             if ($image->isRetina()) {
                 $fileName .= '@2x';
             }
         }
         $fileName .= '.' . $image->getExtension();
         copy($image->getPathname(), $fileName);
     }
     // Localizations
     foreach ($pass->getLocalizations() as $localization) {
         // Create dir (LANGUAGE.lproj)
         $localizationDir = $passDir . $localization->getLanguage() . '.lproj' . DIRECTORY_SEPARATOR;
         mkdir($localizationDir, 0777, true);
         // pass.strings File (Format: "token" = "value")
         $localizationStringsFile = $localizationDir . 'pass.strings';
         file_put_contents($localizationStringsFile, $localization->getStringsFileOutput());
         // Localization images
         foreach ($localization->getImages() as $image) {
             $fileName = $localizationDir . $image->getContext();
             if ($image->isHighRetina()) {
                 $fileName .= '@3x';
             } else {
                 if ($image->isRetina()) {
                     $fileName .= '@2x';
                 }
             }
             $fileName .= '.' . $image->getExtension();
             copy($image->getPathname(), $fileName);
         }
     }
     // Manifest.json - recursove, also add files in sub directories
     $manifestJSONFile = $passDir . 'manifest.json';
     $manifest = array();
     $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($passDir), RecursiveIteratorIterator::SELF_FIRST);
     foreach ($files as $file) {
         // Ignore "." and ".." folders
         if (in_array(substr($file, strrpos($file, '/') + 1), array('.', '..'))) {
             continue;
         }
         //
         $filepath = realpath($file);
         if (is_file($filepath) === true) {
             $relativePathName = str_replace($passDir, '', $file->getPathname());
             $manifest[$relativePathName] = sha1_file($filepath);
         }
     }
     file_put_contents($manifestJSONFile, json_encode($manifest, JSON_UNESCAPED_SLASHES));
     // Signature
     $signatureFile = $passDir . 'signature';
     $p12 = file_get_contents($this->p12->getRealPath());
     $certs = array();
     if (openssl_pkcs12_read($p12, $certs, $this->p12->getPassword()) == true) {
         $certdata = openssl_x509_read($certs['cert']);
         $privkey = openssl_pkey_get_private($certs['pkey'], $this->p12->getPassword());
         openssl_pkcs7_sign($manifestJSONFile, $signatureFile, $certdata, $privkey, array(), PKCS7_BINARY | PKCS7_DETACHED, $this->wwdr->getRealPath());
         // Get signature content
         $signature = @file_get_contents($signatureFile);
         // Check signature content
         if (!$signature) {
             throw new FileException("Couldn't read signature file.");
         }
         // Delimeters
         $begin = 'filename="smime.p7s"';
         $end = '------';
         // Convert signature
         $signature = substr($signature, strpos($signature, $begin) + strlen($begin));
         $signature = substr($signature, 0, strpos($signature, $end));
         $signature = base64_decode($signature);
         // Put new signature
         if (!file_put_contents($signatureFile, $signature)) {
             throw new FileException("Couldn't write signature file.");
         }
     } else {
         throw new FileException("Error reading certificate file");
     }
     // Zip pass
     $zipFile = $outputPath . $pass->getSerialNumber() . self::PASS_EXTENSION;
     $this->zip($passDir, $zipFile);
     // Remove temporary pass directory
     $this->rrmdir($passDir);
     return new SplFileObject($zipFile);
 }
예제 #2
0
 /**
  * Creates a pkpass file
  *
  * @param  Passbook\PassInterface $pass
  * @throws FileException          If an IO error occurred
  * @return SplFileObject
  */
 public function package(PassInterface $pass)
 {
     $pass->setPassTypeIdentifier($this->passTypeIdentifier);
     $pass->setTeamIdentifier($this->teamIdentifier);
     $pass->setOrganizationName($this->organizationName);
     // Serialize pass
     $json = self::serialize($pass);
     $outputPath = rtrim($this->getOutputPath(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
     $passDir = $outputPath . $pass->getSerialNumber() . DIRECTORY_SEPARATOR;
     $passDirExists = file_exists($passDir);
     if ($passDirExists && !$this->isOverwrite()) {
         throw new FileException("Temporary pass directory already exists");
     } elseif (!$passDirExists && !mkdir($passDir, 0777, true)) {
         throw new FileException("Couldn't create temporary pass directory");
     }
     // Pass.json
     $passJSONFile = $passDir . 'pass.json';
     file_put_contents($passJSONFile, $json);
     // Images
     foreach ($pass->getImages() as $image) {
         $fileName = $passDir . $image->getContext();
         if ($image->isRetina()) {
             $fileName .= '@2x';
         }
         $fileName .= '.' . $image->getExtension();
         copy($image->getPathname(), $fileName);
     }
     // Manifest.json
     $manifestJSONFile = $passDir . 'manifest.json';
     $manifest = array();
     foreach (scandir($passDir) as $file) {
         if ($file == '.' or $file == '..') {
             continue;
         }
         $manifest[$file] = sha1_file($passDir . $file);
     }
     file_put_contents($manifestJSONFile, json_encode($manifest));
     // Signature
     $signatureFile = $passDir . 'signature';
     $p12 = file_get_contents($this->p12->getRealPath());
     $certs = array();
     if (openssl_pkcs12_read($p12, $certs, $this->p12->getPassword()) == true) {
         $certdata = openssl_x509_read($certs['cert']);
         $privkey = openssl_pkey_get_private($certs['pkey'], $this->p12->getPassword());
         openssl_pkcs7_sign($manifestJSONFile, $signatureFile, $certdata, $privkey, array(), PKCS7_BINARY | PKCS7_DETACHED, $this->wwdr->getRealPath());
         // Get signature content
         $signature = @file_get_contents($signatureFile);
         // Check signature content
         if (!$signature) {
             throw new FileException("Couldn't read signature file.");
         }
         // Delimeters
         $begin = 'filename="smime.p7s"';
         $end = '------';
         // Convert signature
         $signature = substr($signature, strpos($signature, $begin) + strlen($begin));
         $signature = substr($signature, 0, strpos($signature, $end));
         $signature = base64_decode($signature);
         // Put new signature
         if (!file_put_contents($signatureFile, $signature)) {
             throw new FileException("Couldn't write signature file.");
         }
     } else {
         throw new FileException("Error reading certificate file");
     }
     // Zip pass
     $zipFile = $outputPath . $pass->getSerialNumber() . self::PASS_EXTENSION;
     $zip = new ZipArchive();
     if (!$zip->open($zipFile, $this->isOverwrite() ? ZIPARCHIVE::OVERWRITE : ZipArchive::CREATE)) {
         throw new FileException("Couldn't open zip file.");
     }
     if ($handle = opendir($passDir)) {
         while (false !== ($entry = readdir($handle))) {
             if ($entry == '.' or $entry == '..') {
                 continue;
             }
             $zip->addFile($passDir . $entry, $entry);
         }
         closedir($handle);
     } else {
         throw new FileException("Error reading pass directory");
     }
     $zip->close();
     // Remove temporary pass directory
     $this->rrmdir($passDir);
     return new SplFileObject($zipFile);
 }