コード例 #1
0
 /**
  * @return string
  */
 private function generateToken($random = NULL)
 {
     if ($random === NULL) {
         $random = Nette\Utils\Random::generate(10);
     }
     return $random . base64_encode(sha1($this->getToken() . $random, TRUE));
 }
コード例 #2
0
ファイル: ProductImageService.php プロジェクト: shophp/shophp
 public function create(Product $product, FileUpload $fileUpload)
 {
     switch ($fileUpload->getContentType()) {
         case 'image/jpeg':
             $suffix = 'jpg';
             break;
         case 'image/png':
             $suffix = 'png';
             break;
         case 'image/gif':
             $suffix = 'gif';
             break;
         default:
             throw new EntityInvalidArgumentException(sprintf('File is of an unknown type %s.', $fileUpload->getContentType()));
     }
     $baseName = sprintf('%s-%%s.%s', Strings::webalize($product->getName()), $suffix);
     do {
         $fileName = sprintf($baseName, Random::generate(5, '0-9a-zA-Z'));
         $path = sprintf('%s/%s', $this->imagesDir, $fileName);
     } while (file_exists($path));
     $fileUpload->move($path);
     $image = new ProductImage($product, $fileName);
     $this->createEntity($image);
     $product->addImage($image);
     return $image;
 }
コード例 #3
0
 /**
  * Callback for ForgottenPasswordForm onSuccess event.
  * @param Form      $form
  * @param ArrayHash $values
  */
 public function formSucceeded(Form $form, $values)
 {
     $user = $this->userManager->findByEmail($values->email);
     if (!$user) {
         $form->addError('No user with given email found');
         return;
     }
     $password = Nette\Utils\Random::generate(10);
     $this->userManager->setNewPassword($user->id, $password);
     try {
         // !!! Never send passwords through email !!!
         // This is only for demonstration purposes of Notejam.
         // Ideally, you can create a unique link where user can change his password
         // himself for limited amount of time, and then send the link.
         $mail = new Nette\Mail\Message();
         $mail->setFrom('*****@*****.**', 'Notejamapp');
         $mail->addTo($user->email);
         $mail->setSubject('New notejam password');
         $mail->setBody(sprintf('Your new password: %s', $password));
         $this->mailer->send($mail);
     } catch (Nette\Mail\SendException $e) {
         Debugger::log($e, Debugger::EXCEPTION);
         $form->addError('Could not send email with new password');
     }
 }
コード例 #4
0
 function sendFormSucceeded(\Nette\Forms\BootstrapUIForm $form)
 {
     $email = $form->getValues()->email;
     if ($form->values->layer == 'admin') {
         $lostPass = $this->database->table("helpdesk_emails")->where("template", "lostpass-admin")->fetch();
     } else {
         $lostPass = $this->database->table("helpdesk_emails")->where("template", "lostpass-member")->fetch();
     }
     if (!\Nette\Utils\Validators::isEmail($email)) {
         $this->presenter->flashMessage("Adresa je neplatná");
         $this->presenter->redirect(":Front:Sign:lostpass");
     }
     $passwordGenerate = \Nette\Utils\Random::generate(12, "987654321zyxwvutsrqponmlkjihgfedcba");
     if ($this->database->table('users')->where(array('email' => $email))->count() == 0) {
         $this->flashMessage("E-mail nenalezen");
         $this->presenter->redirect(":Front:Sign:lostpass");
     }
     $member = new \App\Model\MemberModel($this->database);
     $member->setActivation($email, $passwordGenerate);
     $latte = new \Latte\Engine();
     $latte->setLoader(new \Latte\Loaders\StringLoader());
     $params = array('code' => $passwordGenerate, 'email' => $email, 'settings' => $this->presenter->template->settings);
     $mail = new \Nette\Mail\Message();
     $mail->setFrom($this->presenter->template->settings['contacts:email:hq'])->addTo($email)->setSubject("Informace o novém hesle")->setHTMLBody($latte->renderToString($lostPass->body, $params));
     $mailer = new \Nette\Mail\SendmailMailer();
     $mailer->send($mail);
     $this->presenter->flashMessage('Informace o zapomenutém hesle odeslány', 'success');
     $this->presenter->redirect(this);
 }
コード例 #5
0
 /**
  * @param array $credentials
  * @return Identity
  * @throws AuthenticationException
  */
 public function authenticate(array $credentials)
 {
     $email = $credentials[0]['email'];
     $user = $this->users->getUser($email);
     if ($user === NULL && $this->autoRegister === FALSE || $user instanceof UserEntity && $user->getActive() == 0) {
         throw new AuthenticationException("User '{$email}' not found.", self::IDENTITY_NOT_FOUND);
     } else {
         if ($user === NULL && $this->autoRegister === TRUE) {
             $result = $this->users->register(array("login" => $email, "password" => Random::generate(), "name" => $credentials[0]['firstName'] . " " . $credentials[0]['lastName'], "firstname" => $credentials[0]['firstName'], "lastname" => $credentials[0]['lastName'], "lastLogged" => new DateTime(), "ip" => $_SERVER['REMOTE_ADDR']));
             if ($result instanceof ContactEntity) {
                 return new Identity($result->getUserID(), $result->getUser()->getRole()->getName(), $result->getUser()->toArray());
             } else {
                 throw new AuthenticationException("User '{$email}' cannot be registered.", self::IDENTITY_NOT_FOUND);
             }
         } else {
             if ($user instanceof UserEntity) {
                 $user->setLastLogged(new DateTime());
                 $user->setIp($_SERVER['REMOTE_ADDR']);
                 $this->users->updateUser($user);
                 $data = $user->toArray();
                 unset($data['password']);
                 return new Identity($user->getUserID(), $user->getRole()->getName(), $data);
             } else {
                 throw new AuthenticationException("User '{$email}' cannot be connected.", self::IDENTITY_NOT_FOUND);
             }
         }
     }
 }
コード例 #6
0
 protected function generateHash()
 {
     do {
         $hash = Nette\Utils\Random::generate(32);
     } while ($this->getTable()->where([$this->tables['identityHash']['hash'] => $hash])->fetch());
     return $hash;
 }
コード例 #7
0
 public function generate($length = self::DEFAULT_LENGTH, $charlist = self::DEFAULT_CHARLIST)
 {
     Validators::assert($length, 'integer', 'length');
     if ($length < 1) {
         throw new InvalidArgumentException("Length must be greater or equal 1, value '{$length}' given.");
     }
     return Random::generate($length, $charlist);
 }
コード例 #8
0
ファイル: PasteManager.php プロジェクト: hadikcz/PasteIt
 /**
  * Save past text into database
  * Return generated hash
  * @param array $data
  * @return string
  */
 public function save($data)
 {
     $data->hash = Random::generate(6, '0-9a-zA-Z');
     $data->inserted = $this->dateTime->getTimestamp();
     $data->id_user = '';
     $this->dtb->table('pastes')->insert($data);
     return $data->hash;
 }
コード例 #9
0
ファイル: CacheMacro.php プロジェクト: nakoukal/fakturace
	/**
	 * New node is found.
	 * @return bool
	 */
	public function nodeOpened(Latte\MacroNode $node)
	{
		$this->used = TRUE;
		$node->isEmpty = FALSE;
		$node->openingCode = Latte\PhpWriter::using($node)
			->write('<?php if (Nette\Bridges\CacheLatte\CacheMacro::createCache($netteCacheStorage, %var, $_g->caches, %node.array?)) { ?>',
				Nette\Utils\Random::generate()
			);
	}
コード例 #10
0
ファイル: UIMacros.php プロジェクト: janlanger/nette-skeleton
 /**
  * generates random number for front assets versing
  */
 public function macroVersion(MacroNode $node, PhpWriter $writer)
 {
     $length = 10;
     $word = $node->tokenizer->fetchWord();
     if (is_numeric($word)) {
         $length = (int) $word;
     }
     return $writer->write(' ?>?' . Random::generate($length) . '<?php ');
 }
コード例 #11
0
ファイル: CacheMacro.php プロジェクト: nette/caching
 /**
  * New node is found.
  * @return bool
  */
 public function nodeOpened(Latte\MacroNode $node)
 {
     if ($node->modifiers) {
         throw new Latte\CompileException('Modifiers are not allowed in ' . $node->getNotation());
     }
     $this->used = TRUE;
     $node->empty = FALSE;
     $node->openingCode = Latte\PhpWriter::using($node)->write('<?php if (Nette\\Bridges\\CacheLatte\\CacheMacro::createCache($this->global->cacheStorage, %var, $this->global->cacheStack, %node.array?)) { ?>', Nette\Utils\Random::generate());
 }
コード例 #12
0
ファイル: CacheMacro.php プロジェクト: 4iz278/cviceni
 /**
  * New node is found.
  * @return bool
  */
 public function nodeOpened(Latte\MacroNode $node)
 {
     if ($node->modifiers) {
         trigger_error("Modifiers are not allowed in {{$node->name}}", E_USER_WARNING);
     }
     $this->used = TRUE;
     $node->isEmpty = FALSE;
     $node->openingCode = Latte\PhpWriter::using($node)->write('<?php if (Nette\\Bridges\\CacheLatte\\CacheMacro::createCache($netteCacheStorage, %var, $_g->caches, %node.array?)) { ?>', Nette\Utils\Random::generate());
 }
コード例 #13
0
ファイル: WorkerManager.php プロジェクト: venne/venne
 /**
  * @return \Venne\Queue\Worker
  */
 public function createWorker()
 {
     $id = Random::generate(20);
     $this->configManager->lock();
     $data = $this->configManager->loadConfigFile();
     $data['worker'][$id] = array('id' => $id, 'state' => self::STATE_PAUSED, 'lastCheck' => null, 'lastJob' => null);
     $this->configManager->saveConfigFile($data);
     $this->configManager->unlock();
     return $this->getWokrer($id);
 }
コード例 #14
0
 /**
  * @return string Password grade hash (do not store!)
  */
 protected function computeUnsafeHash()
 {
     if ($this->getValue('hash', FALSE)) {
         throw new InvalidStateException('Hash already set');
     }
     if (!$this->user) {
         throw new InvalidArgumentException();
     }
     return md5($this->createdAt->format('u') . $this->user->email) . Random::generate(15);
 }
コード例 #15
0
ファイル: ScudPresenter.php プロジェクト: pogodi/Brain
 /**
  * @param $key
  * @throws BadRequestException
  */
 public function actionIn($key)
 {
     $response = $this->api->call('scud', "SCUD_CheckAccess/{$key}");
     if ($response['status'] === "OK") {
         $identity = new Identity(Random::generate(32));
         $this->getUser()->login($identity);
         $this->redirect("Dashboard:default");
     }
     throw new BadRequestException();
 }
コード例 #16
0
 /**
  * Returns unique token for method and params
  * @param  string $control
  * @param  string $method
  * @param  array $params
  * @return string
  */
 public function getCsrfToken($control, $method, $params)
 {
     $session = $this->getSession('Nextras.Application.UI.SecuredLinksPresenterTrait');
     if (!isset($session->token)) {
         $session->token = Nette\Utils\Random::generate();
     }
     $params = Nette\Utils\Arrays::flatten($params);
     $params = implode('|', array_keys($params)) . '|' . implode('|', array_values($params));
     return substr(md5($control . $method . $params . $session->token . $this->getSession()->getId()), 0, 8);
 }
コード例 #17
0
 /**
  * @return string
  */
 private function getConfirmationToken()
 {
     $sessionSection = $this->getPresenter()->getSession('Librette.ConfirmationDialog');
     if (!isset($sessionSection->token)) {
         $sessionSection->token = Random::generate(10);
     }
     $parameters = $this instanceof Presenter ? $this->request->getParameters() : $this->getParameters();
     $signalIdentifier = [get_class($this), $this->getPresenter()->signal, $parameters];
     return substr(md5(serialize($signalIdentifier) . $sessionSection->token), 0, 10);
 }
コード例 #18
0
 function signUpFormSucceeded(\Nette\Forms\BootstrapUIForm $form)
 {
     $activationCode = \Nette\Utils\Random::generate(12, "987654321zyxwvutsrqponmlkjihgfedcba");
     $password = \Nette\Security\Passwords::hash($form->values->pwd);
     $arr = array("email" => $form->values->email, "username" => $form->values->username, "password" => $password, "activation" => $activationCode, "newsletter" => (bool) $form->values->newsletter, "state" => 0, "users_roles_id" => 4, "date_created" => date("Y-m-d H:i:s"));
     if ($this->presenter->template->settings['members:groups:enabled']) {
         $arr["categories_id"] = $form->values->group;
     }
     $userId = $this->database->table("users")->insert($arr);
     $this->database->table("users")->where(array("id" => $userId->id))->update(array("uid" => \Nette\Utils\Strings::padLeft($userId->id, 6, '0')));
     if ($this->template->settings['members:signup:contactEnabled']) {
         $arrContacts = array("categories_id" => 44, "users_id" => $userId, "name" => $form->values->name, "street" => $form->values->street, "city" => $form->values->city, "zip" => $form->values->zip, "countries_id" => 1);
         if ($this->presenter->template->settings['members:signup:companyEnabled']) {
             $arrContacts["company"] = $form->values->company;
             $arrContacts["vatin"] = $form->values->vatin;
             $arrContacts["vatid"] = $form->values->vatid;
         }
         $contactId = $this->database->table("contacts")->insert($arrContacts);
         $this->database->table("contacts")->get($contactId)->update(array("order" => $contactId));
     }
     if ($form->values->vatin) {
         $ares = new \h4kuna\Ares\Ares();
         $aresArr = $ares->loadData('')->toArray();
     }
     $latte = new \Latte\Engine();
     $latte->setLoader(new \Latte\Loaders\StringLoader());
     $params = array('username' => $form->values->username, 'activationCode' => $activationCode, 'settings' => $this->presenter->template->settings, 'form' => $form, 'aresArr' => $aresArr);
     $helpdesk = $this->database->table("helpdesk")->get(3);
     $helpdesk_signup_member = $helpdesk->related("helpdesk_emails", "helpdesk_id")->get(5);
     $helpdesk_signup_confirmbyadmin = $helpdesk->related("helpdesk_emails", "helpdesk_id")->get(6);
     $helpdesk_signup_adminconfirm = $helpdesk->related("helpdesk_emails", "helpdesk_id")->get(7);
     try {
         if ($this->presenter->template->settings['members:signup:confirmByAdmin']) {
             $email_signup_confirmbyamin = $latte->renderToString($helpdesk_signup_confirmbyadmin->body, $params);
             $email_signup_adminconfirm = $latte->renderToString($helpdesk_signup_adminconfirm->body, $params);
             $mail = new \Nette\Mail\Message();
             $mail->setFrom($this->presenter->template->settings['contacts:email:hq'])->addTo($form->values->email)->setHTMLBody($email_signup_confirmbyamin);
             $this->presenter->mailer->send($mail);
             $mailA = new \Nette\Mail\Message();
             $mailA->setFrom($this->presenter->template->settings['contacts:email:hq'])->addTo($this->presenter->template->settings['contacts:email:hq'])->setHTMLBody($email_signup_adminconfirm);
             $this->presenter->mailer->send($mailA);
             $this->flashMessage('Registrace byla dokončena. Po ověření Vám bude zaslán e-mail, po kterém se můžete přihlásit', 'note');
         } else {
             $email_signup_member = $latte->renderToString($helpdesk_signup_member->body, $params);
             $mail = new \Nette\Mail\Message();
             $mail->setFrom($this->presenter->template->settings['contacts:email:hq'])->addTo($form->values->email)->setHTMLBody($email_signup_member);
             $this->presenter->mailer->send($mail);
             $this->presenter->flashMessage('Vaše registrace proběhla úspěšně. Po ověření se můžete přihlásit.', 'note');
         }
         $this->presenter->redirect(":Front:Sign:ed");
     } catch (\Nette\Mail\SmtpException $e) {
         $this->presenter->flashMessage('E-mail nebyl odeslán' . $e->getMessage(), 'error');
         $this->presenter->redirect(":Front:Sign:up");
     }
 }
コード例 #19
0
 public static function preparePost($vpId = null, $authorVpId = null, $postValues = [])
 {
     if ($vpId === null) {
         $vpId = IdUtil::newId();
     }
     $post = array_merge(['post_date' => "2015-02-02 14:19:59", 'post_date_gmt' => "2015-02-02 14:19:59", 'post_modified' => '0000-00-00 00:00:00', 'post_modified_gmt' => '0000-00-00 00:00:00', 'post_content' => "Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!", 'post_title' => "Hello world!", 'post_excerpt' => "", 'post_status' => "publish", 'comment_status' => "open", 'ping_status' => "open", 'post_password' => "", 'post_name' => "hello-world", 'to_ping' => "", 'pinged' => "", 'post_content_filtered' => "", 'guid' => "http://127.0.0.1/wordpress/?p=" . Random::generate(), 'menu_order' => 0, 'post_type' => "post", 'post_mime_type' => "", 'vp_id' => $vpId, 'vp_post_parent' => 0, 'vp_post_author' => 0], $postValues);
     if ($authorVpId !== null) {
         $post['vp_post_author'] = $authorVpId;
     }
     return $post;
 }
コード例 #20
0
ファイル: SendPasswordForm.php プロジェクト: gritbox/gritbox
 public function formSucceeded($form, $values)
 {
     $user = $this->userRepository->findOneBy(['email' => $values->email]);
     if (!$user) {
         $form->addError("User with email " . $values->email . " does not exist.");
         return;
     }
     $hash = Nette\Utils\Random::generate(16);
     $this->passwordResetRepository->replace(["user_id" => $user->id, "hash" => $hash, "created" => new Nette\Utils\DateTime()]);
     $this->emailService->send($values->email, ['email' => $values->email, 'resetUrl' => $this->presenter->link("//Sign:in", ['newpasshash' => $hash])], 'passwordResetRequest.latte');
     $this->onFormSuccess($this);
 }
コード例 #21
0
ファイル: User.php プロジェクト: janlavicka/devstack
 public function __construct($email, $username, $name, $surname, $password)
 {
     $this->email = $email;
     $this->username = empty($surname) ? null : $username;
     $this->name = empty($name) ? null : $name;
     $this->surname = empty($surname) ? null : $surname;
     $this->password = Passwords::hash($password);
     $this->code = Random::generate();
     $this->frozen = true;
     $this->createdAt = new DateTime();
     $this->roles = new ArrayCollection();
 }
コード例 #22
0
ファイル: Request.php プロジェクト: trejjam/authorization
 public function generateHash($userId, $type, $timeout = NULL)
 {
     if (!$this->isTypeValid($type)) {
         throw new Trejjam\Authorization\User\RequestException("Type '{$type}' is not valid or registered");
     }
     $hash = Nette\Utils\Random::generate($this->tables['userRequest']['hash']['length'], '0-9A-Z');
     if (is_null($timeout)) {
         $timeout = $this->tables['userRequest']['timeout']['default'];
     }
     $insertion = $this->getTable()->insert([$this->tables['userRequest']['userId'] => isset($userId->{static::ROW}) ? $userId->id : $userId, $this->tables['userRequest']['hash']['name'] => Nette\Security\Passwords::hash($hash), $this->tables['userRequest']['type']['name'] => $type, $this->tables['userRequest']['timeout']['name'] => $timeout === FALSE ? NULL : new Nette\Database\SqlLiteral('NOW() + INTERVAL ' . $timeout)]);
     return [$insertion->id, $hash];
 }
コード例 #23
0
ファイル: OrderService.php プロジェクト: shophp/shophp
 public function createFromCart(Cart $cart, PaymentType $paymentType)
 {
     if (!$this->isPaymentTypeAvailable($paymentType)) {
         throw new EntityInvalidArgumentException(sprintf('Payment type %s is not available.', $paymentType->getLabel()));
     }
     do {
         $number = Random::generate(Order::NUMBER_LENGTH, '0-9');
     } while ($this->existsOrderWithNumber($number));
     $order = new Order($cart, $number, $paymentType);
     $this->createEntity($order);
     $this->orderSession->orderId = $order->getId();
     return $order;
 }
コード例 #24
0
ファイル: RegistrationModel.php プロジェクト: norik16/TripMap
 public function newPassword($user_email)
 {
     $newPassword = Random::generate(10, "a-zA-Z0-9");
     $user = $this->database->table('user')->where('email', $user_email)->fetch();
     if ($user->checked == 1) {
         $this->database->table('user')->where('email', $user_email)->update(['password' => Passwords::hash($newPassword)]);
         return $newPassword;
     } elseif ($user->checked) {
         return 1;
     } else {
         return 0;
     }
 }
コード例 #25
0
ファイル: ApikeyRepository.php プロジェクト: pogodi/Scud
 /**
  * @param $application
  * @return Apikey
  */
 public function generateKey($application)
 {
     $datetime = new \DateTime();
     $datetime->modify('+1 day');
     $apikey = ['application' => $application, 'key' => Random::generate(50), 'expiration' => $datetime];
     $row = $this->database->table(self::TABLE)->insert($apikey);
     $entity = new Apikey();
     $entity->setId($row['id']);
     $entity->setApplication($row['application']);
     $entity->setKey($row['key']);
     $entity->setExpiration($row['expiration']);
     return $entity;
 }
コード例 #26
0
 public function formPhotoSubmitted(Nette\Application\UI\Form $form)
 {
     $fd = $form->getValues();
     foreach ($fd->img as $img) {
         $name = date("Y_m_d_H_i_s_") . Nette\Utils\Random::generate(10);
         $img = \Nette\Utils\Image::fromFile($img);
         $img->save("./data/photo/original/" . $name . ".jpg");
         $img->resize(200, 200);
         create_square_image("./data/photo/original/" . $name . ".jpg", "./data/photo/thumb/" . $name . ".jpg", 200);
         //    $img->save("./data/photo/thumb/".  $name.".jpg");
     }
     $this->flashMessage("Moc děkujem za fotky :-)", "success");
     $this->redirect("this");
 }
コード例 #27
0
ファイル: Passwords.php プロジェクト: Komanc/security
 /**
  * Computes salted password hash.
  * @param  string
  * @param  array with cost (4-31), salt (22 chars)
  * @return string  60 chars long
  */
 public static function hash($password, array $options = NULL)
 {
     $cost = isset($options['cost']) ? (int) $options['cost'] : self::BCRYPT_COST;
     $salt = isset($options['salt']) ? (string) $options['salt'] : Nette\Utils\Random::generate(22, '0-9A-Za-z./');
     if (($len = strlen($salt)) < 22) {
         throw new Nette\InvalidArgumentException("Salt must be 22 characters long, {$len} given.");
     } elseif ($cost < 4 || $cost > 31) {
         throw new Nette\InvalidArgumentException("Cost must be in range 4-31, {$cost} given.");
     }
     $hash = crypt($password, '$2y$' . ($cost < 10 ? 0 : '') . $cost . '$' . $salt);
     if (strlen($hash) < 60) {
         throw new Nette\InvalidStateException('Hash returned by crypt is invalid.');
     }
     return $hash;
 }
コード例 #28
0
ファイル: RatingManager.php プロジェクト: kivi8/ars-poetica
 public function setManager($forWhat, $forId, $userId)
 {
     $this->forWhat = $forWhat;
     $this->forId = $forId;
     if ($userId) {
         $this->userId = $userId;
         $this->logged = true;
     } else {
         $voteId = $this->session->getSection('voteId');
         if (empty($voteId->id)) {
             $voteId->id = \Nette\Utils\Random::generate(50);
         }
         $this->userId = $voteId->id;
         $this->logged = false;
     }
 }
コード例 #29
0
 public function prepare_deletePostmeta()
 {
     $this->url($this->getPostTypeScreenUrl());
     $this->prepareTestPost();
     $this->byCssSelector('form#post #publish')->click();
     $this->waitForElement('#message.updated');
     $this->byCssSelector('#show-settings-link')->click();
     $this->byCssSelector('form#adv-settings #postcustom-hide')->click();
     $this->waitForElement('#metavalue');
     if ($this->elementExists("#enternew")) {
         $this->jsClickAndWait('#newmetaleft #enternew');
     }
     $this->waitForElement('#metakeyinput');
     $this->byCssSelector('#metakeyinput')->value('post_meta');
     $this->byCssSelector('#metavalue')->value(Random::generate());
     $this->byCssSelector('#newmeta-submit')->click();
     $this->waitForElement("input[id^='deletemeta']");
 }
コード例 #30
0
ファイル: Passwords.php プロジェクト: petrparolek/web_cms
 /**
  * Computes salted password hash.
  * @param  string
  * @param  array with cost (4-31), salt (22 chars)
  * @return string  60 chars long
  */
 public static function hash($password, array $options = NULL)
 {
     $cost = isset($options['cost']) ? (int) $options['cost'] : self::BCRYPT_COST;
     $salt = isset($options['salt']) ? (string) $options['salt'] : Nette\Utils\Random::generate(22, '0-9A-Za-z./');
     if (PHP_VERSION_ID < 50307) {
         throw new Nette\NotSupportedException(__METHOD__ . ' requires PHP >= 5.3.7.');
     } elseif (($len = strlen($salt)) < 22) {
         throw new Nette\InvalidArgumentException("Salt must be 22 characters long, {$len} given.");
     } elseif ($cost < 4 || $cost > 31) {
         throw new Nette\InvalidArgumentException("Cost must be in range 4-31, {$cost} given.");
     }
     $password = substr($password, 0, self::PASSWORD_MAX_LENGTH);
     $hash = crypt($password, '$2y$' . ($cost < 10 ? 0 : '') . $cost . '$' . $salt);
     if (strlen($hash) < 60) {
         throw new Nette\InvalidStateException('Hash returned by crypt is invalid.');
     }
     return $hash;
 }