/**
  * Execute step
  *
  * @return bool
  */
 public function execute()
 {
     $contact = $this->getContact();
     if (!$contact) {
         $contact = new waContact();
     }
     $data = waRequest::post('customer');
     if ($data && is_array($data)) {
         foreach ($data as $field => $value) {
             $contact->set($field, $value);
         }
     }
     $this->form = shopHelper::getCustomerForm();
     if ($shipping = $this->getSessionData('shipping') && !waRequest::post('ignore_shipping_error')) {
         $shipping_step = new shopOnestepCheckoutShipping();
         $rate = $shipping_step->getRate($shipping['id'], isset($shipping['rate_id']) ? $shipping['rate_id'] : null, $contact);
         if (!$rate || is_string($rate)) {
             // remove selected shipping method
             $this->setSessionData('shipping', null);
             /*
              $errors = array();
              $errors['all'] = sprintf(_w('We cannot ship to the specified address via %s.'), $shipping['name']);
              if ($rate) {
              $errors['all'] .= '<br> <strong>'.$rate.'</strong><br>';
              }
              $errors['all'] .= '<br> '._w('Please double-check the address above, or return to the shipping step and select another shipping option.');
              $errors['all'] .= '<input type="hidden" name="ignore_shipping_error" value="1">';
              wa()->getView()->assign('errors', $errors);
              return false;
             */
         }
     }
     if (wa()->getUser()->isAuth()) {
         $contact->save();
     } else {
         $errors = array();
         if (waRequest::post('create_user')) {
             $login = waRequest::post('login');
             if (!$login) {
                 $errors['email'][] = _ws('Required');
             }
             if (!waRequest::post('password')) {
                 $errors['password'] = _ws('Required');
             }
             $email_validator = new waEmailValidator();
             if (!$email_validator->isValid($login)) {
                 $errors['email'] = $email_validator->getErrors();
             }
             if (!$errors) {
                 $contact_model = new waContactModel();
                 if ($contact_model->getByEmail($login, true)) {
                     $errors['email'][] = _w('Email already registered');
                 }
             }
             if (!$errors) {
                 $contact->set('email', $login);
                 $contact->set('password', waRequest::post('password'));
             } else {
                 if (isset($errors['email'])) {
                     $errors['email'] = implode(', ', $errors['email']);
                 }
                 wa()->getView()->assign('errors', $errors);
                 return false;
             }
         }
         $this->setSessionData('contact', $contact);
     }
     if ($comment = waRequest::post('comment')) {
         $this->setSessionData('comment', $comment);
     }
     if (!$this->form->isValid($contact)) {
         return false;
     }
     return true;
 }
 /**
  * @param waContactForm $form
  * @param waContact $contact
  * @return bool
  */
 protected function saveFromPost($form, $contact)
 {
     $data = $form->post();
     if (!$data || !is_array($data)) {
         return false;
     }
     // save photo before all
     $photo_file = waRequest::file('photo_file');
     if (array_key_exists('photo', $data)) {
         if ($photo_file->uploaded() && ($avatar = $photo_file->waImage())) {
             // add/update photo
             $square = min($avatar->height, $avatar->width);
             // setPhoto with crop
             $rand = mt_rand();
             $path = wa()->getDataPath(waContact::getPhotoDir($contact->getId()), true, 'contacts', false);
             // delete old image
             if (file_exists($path)) {
                 waFiles::delete($path);
             }
             waFiles::create($path);
             $filename = $path . $rand . ".original.jpg";
             waFiles::create($filename);
             waImage::factory($photo_file)->save($filename, 90);
             $filename = $path . $rand . ".jpg";
             waFiles::create($filename);
             waImage::factory($photo_file)->crop($square, $square)->save($filename, 90);
             waContactFields::getStorage('waContactInfoStorage')->set($contact, array('photo' => $rand));
         } elseif (empty($data['photo'])) {
             // remove photo
             $contact->set('photo', "");
         }
         $this->form->values['photo'] = $data['photo'] = $contact->get('photo');
     }
     // Validation
     if (!$form->isValid($contact)) {
         return false;
     }
     // Password validation
     if (!empty($data['password']) && $data['password'] !== $data['password_confirm']) {
         $form->errors('password', _ws('Passwords do not match'));
         return false;
     } elseif (empty($data['password']) || empty($data['password_confirm'])) {
         unset($data['password']);
     }
     unset($data['password_confirm']);
     // get old data for logging
     if ($this->contact) {
         $old_data = array();
         foreach ($data as $field_id => $field_value) {
             $old_data[$field_id] = $this->contact->get($field_id);
         }
     }
     foreach ($data as $field => $value) {
         $contact->set($field, $value);
     }
     $errors = $contact->save();
     // If something went wrong during save for any reason,
     // show it to user. In theory it shouldn't but better be safe.
     if ($errors) {
         foreach ($errors as $field => $errs) {
             foreach ($errs as $e) {
                 $form->errors($field, $e);
             }
         }
         return false;
     }
     // get new data for logging
     $new_data = array();
     foreach ($data as $field_id => $field_value) {
         if (!isset($errors[$field_id])) {
             $new_data[$field_id] = $this->contact->get($field_id);
         }
     }
     $this->logProfileEdit($old_data, $new_data);
     return true;
 }