タグ別アーカイブ: php

symfony2 passing multiple services

symfony2のサービスコンテナ(Service Container)を使って複数のサービスを受け渡す方法

例えば、ログインしていないユーザにID、パスワード、新しいパスワードを入力してもらって、パスワード更新をする処理の場合。Validatorの中では、

1.現状のユーザ情報を取得するためにdoctrine.orm.entity_managerが必要
2.パスワードを暗号化して比較するのにsecurity.encoder_factoryが必要

従って、services.xmlには以下のように記載する

<services>
  <service id="hc100_validator.constraint.validpassword" class="Hc100\DemoBundle\Validator\Constraints\ValidPasswordValidator">
    <argument type="service" id="doctrine.orm.entity_manager"/>
    <argument type="service" id="security.encoder_factory"/>
    <tag name="validator.constraint_validator" alias="validpassword" />
  </service>
</services>

後はカスタムバリデーターの中で以下のようにして受け取れる

  private $entityManager;
  private $encoderFactory;

  public function __construct(EntityManager $entityManager, EncoderFactory $encoderFactory)
  {
    $this->entityManager = $entityManager;
    $this->encoderFactory = $encoderFactory;
  }

ちなみに、フォーム内の複数の要素をバリデーションに使う場合はConstraintに以下を定義

  public function getTargets()
  {
    return Constraint::CLASS_CONSTRAINT;
  }

そうすれば、バリデーターでは$valueではなく、Entityとしてうけとれる

  public function validate($user, Constraint $constraint)
  {
    $database_user = $this->entityManager->getRepository('Hc100DemoBundle:User')
      ->findOneBy(array('userId' => $user->getUserId()));
    if (!$database_user) {
      $this->context->addViolation($constraint->message);
    }

    $encoder = $this->encoderFactory->getEncoder($database_user);
    if ($database_user->getPassword() != $encoder->encodePassword($user->getPassword(), $database_user->getSalt())) {
      $this->context->addViolation($constraint->message);
    }
  }

この場合はAssertはメソッドにではなくて、クラスに指定する必要があるのでよろしく!

getting week spans

仕事で指定した日付の週の始めの日と終わりの日を算出する必要があった

毎月の収支表みたいなものを出力するためなので、月はまたがないので1日から始まって31(か30か29か28)日に終わる

日付系のは慎重に作らないとよくバグる。しかもよく考えないと2000年問題みたいなのにハマるからね

とりあえずこんな感じ。もっとスマートに計算できないのかな〜

/**
 * get a span of week of a certain date,
 * and stay in the same month.
 */
function getWeekSpanOfDate($date, $end_of_span_day) {
  // 1(monday) - 7(sunday)
  $day = date("N", strtotime($date));

  // month
  $month = date("n", strtotime($date));

  // days to end of span
  $dates_to_end_of_span = ($end_of_span_day + 7 - $day) % 7;

  // days to start of span
  $dates_to_start_of_span = 6 - $dates_to_end_of_span;

  // dates
  $start_date_time = strtotime($date)-($dates_to_start_of_span*(24*60*60));
  $end_date_time = strtotime($date)+($dates_to_end_of_span*(24*60*60));

  // format
  $start_date = date("Y-m-d", $start_date_time);
  $end_date = date("Y-m-d", $end_date_time);

  // out of month exception
  if (date("n", $start_date_time) != $month)
    $start_date = date("Y-m-01", strtotime($date));

  if (date("n", $end_date_time) != $month)
    $end_date = date("Y-m-t", strtotime($date));// "t" represents days in a month

  return array ($start_date, $end_date);
}

/**
 * Test
 */
for ($i=1; $i<=31; $i++) {
  // set the end of the week to wednesday (3)
  $end_of_span_day = 3;

  $date = sprintf('2013-05-%02d', $i);
  list($start_date, $end_date) = getWeekSpanOfDate($date, $end_of_span_day);
  echo sprintf("%s is in %s %s\n", $date, $start_date, $end_date);
}

結果

2013-05-01 is in 2013-05-01 2013-05-01
2013-05-02 is in 2013-05-02 2013-05-08
2013-05-03 is in 2013-05-02 2013-05-08
2013-05-04 is in 2013-05-02 2013-05-08
2013-05-05 is in 2013-05-02 2013-05-08
2013-05-06 is in 2013-05-02 2013-05-08
2013-05-07 is in 2013-05-02 2013-05-08
2013-05-08 is in 2013-05-02 2013-05-08
2013-05-09 is in 2013-05-09 2013-05-15
2013-05-10 is in 2013-05-09 2013-05-15
2013-05-11 is in 2013-05-09 2013-05-15
2013-05-12 is in 2013-05-09 2013-05-15
2013-05-13 is in 2013-05-09 2013-05-15
2013-05-14 is in 2013-05-09 2013-05-15
2013-05-15 is in 2013-05-09 2013-05-15
2013-05-16 is in 2013-05-16 2013-05-22
2013-05-17 is in 2013-05-16 2013-05-22
2013-05-18 is in 2013-05-16 2013-05-22
2013-05-19 is in 2013-05-16 2013-05-22
2013-05-20 is in 2013-05-16 2013-05-22
2013-05-21 is in 2013-05-16 2013-05-22
2013-05-22 is in 2013-05-16 2013-05-22
2013-05-23 is in 2013-05-23 2013-05-29
2013-05-24 is in 2013-05-23 2013-05-29
2013-05-25 is in 2013-05-23 2013-05-29
2013-05-26 is in 2013-05-23 2013-05-29
2013-05-27 is in 2013-05-23 2013-05-29
2013-05-28 is in 2013-05-23 2013-05-29
2013-05-29 is in 2013-05-23 2013-05-29
2013-05-30 is in 2013-05-30 2013-05-31
2013-05-31 is in 2013-05-30 2013-05-31

話変わるけど、

;
echo date("Y-m-d", strtotime('2013-02-31'));
;

これやると何が表示されると思う?

2013-03-03

親切なんだか、ややこしいのか、よく分からないが