/**
  * Create a member property
  *
  * <b>Request Type: </b>POST<br/>
  * <b>Request Endpoint: </b>http://{{server-domain}}/api/common/member-propertys<br/>
  * <b>Content-type: </b>application/json<br/>
  * <b>Summary: </b>This api is for create a new member property.<br/>
  *
  * <b>Request Example:</b>
  * <pre>
  *{
  *   "order": 7,
  *   "name": "name",
  *  "type": "input",
  *   "defaultValue": "Devin Jin",
  *   "isRequired": true,
  *   "isUnique": true,
  *   "isVisible": true,
  *   "isDefault": true
  * }
  */
 public function actionCreate()
 {
     $accountId = $this->getAccountId();
     //can not exceed 100 properties for an account
     $propertiesCount = MemberProperty::count(['accountId' => $accountId]);
     if ($propertiesCount >= MemberProperty::MAX_COUNT) {
         throw new BadRequestHttpException(Yii::t('member', 'property_max_error'));
     }
     $params = $this->getParams();
     // get the max order property
     $condition = ['accountId' => $accountId, 'isDeleted' => MemberProperty::NOT_DELETED];
     $orderProperty = MemberProperty::find()->where($condition)->orderBy(['order' => SORT_DESC])->one();
     $order = 1;
     if (!empty($orderProperty)) {
         $order = $orderProperty['order'] + 1;
     }
     $property = new MemberProperty();
     $property->load($params, '');
     $property->order = $order;
     $property->accountId = $accountId;
     if ($property->save()) {
         //update all the members of the account
         Member::updateAll(['$push' => ['properties' => ['id' => $property->_id, 'name' => $property->name, 'value' => $property->defaultValue]]], ['accountId' => $accountId]);
         return $property;
     } else {
         if ($property->hasErrors()) {
             throw new BadRequestHttpException(Json::encode($property->errors));
         }
     }
     throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
 }
 public static function getPropertyIds($condition)
 {
     $propertyIds = MemberProperty::find()->select(['_id'])->where($condition)->all();
     $propertyIdStrs = [];
     foreach ($propertyIds as $propertyId) {
         $propertyIdStrs[] = (string) $propertyId['_id'];
     }
     return $propertyIdStrs;
 }
 private static function _getPropertyId($condition)
 {
     $propertyIds = MemberProperty::find()->select(['_id'])->where($condition)->all();
     $propertyIdStrs = [];
     if (empty($propertyIds)) {
         LogUtil::error(['message' => 'Run update StatsMemberCampaignLog fail, because the propertyIds is empty', 'condition' => $condition], 'resque');
     } else {
         foreach ($propertyIds as $propertyId) {
             $propertyIdStrs[] = (string) $propertyId['_id'];
         }
     }
     return $propertyIdStrs;
 }
 public function perform()
 {
     # Run task
     $args = $this->args;
     if (empty($args['locationPath']) || empty($args['accountId']) || empty($args['filePath']) || empty($args['qiniuBucket']) || empty($args['fileName'])) {
         ResqueUtil::log(['error' => 'missing params in MemberCheckCode', 'args' => $args]);
     }
     //get qiniu file
     $qiniuFile = Yii::$app->curl->get($args['filePath'], [], false);
     if (false === file_put_contents($args['locationPath'], $qiniuFile)) {
         ResqueUtil::log(['message' => 'Fail to get file from qiniu in MemberCheckCode class', 'args' => $args]);
         return false;
     }
     $phpreader = new \PHPExcel_Reader_Excel2007();
     $filePath = $args['locationPath'];
     if (!$phpreader->canRead($filePath)) {
         $phpreader = new \PHPExcel_Reader_Excel5();
         if (!$phpreader->canRead($filePath)) {
             $phpreader = \PHPExcel_IOFactory::createReader('CSV')->setDelimiter(',')->setInputEncoding('GBK')->setEnclosure('"')->setLineEnding("\r\n")->setSheetIndex(0);
             if (!$phpreader->canRead($filePath)) {
                 ResqueUtil::log(['error' => 'file can not read  in MemberCheckCode', 'args' => $args]);
                 return false;
             }
         }
     }
     $phpexcel = $phpreader->load($filePath);
     //read the first of table with excel.
     $currentSheet = $phpexcel->getSheet(0);
     //get the largest column
     $allColumn = $currentSheet->getHighestColumn();
     //get total row num
     $allRow = $currentSheet->getHighestRow();
     //make a key to be called a name for redis set
     $cacheSetInsert = self::SET_HEAD_INSERT . md5($args['accountId'] . "_" . $args['fileName']);
     $cacheSetUpdate = self::SET_HEAD_UPDATE . md5($args['accountId'] . "_" . $args['fileName']);
     //make a key to be called a name for redis hash
     $cacheHash = md5($args['accountId'] . "_" . $args['fileName']);
     $ignorePropertyKey = self::MEMBER_FILE_IGNORE . $cacheHash;
     $missPropertyKey = self::MEMBER_FILE_MISS . $cacheHash;
     $repeatTitleKey = self::MEMBER_REPEAT_TITLE . $cacheHash;
     //the key for wrong number for store in redis
     $wrongKey = self::MEMBER_WRONG;
     //the key for right number for  store in redis
     $rightKey = self::MEMBER_RIGHT;
     $total = $wrong = $right = $rightInsert = $rightUpdate = 0;
     $redis = Yii::$app->cache->redis;
     $redis->expire($cacheHash, self::EXPIRE);
     $title = [];
     // verify the member of phone.
     $re = "/^0?1[0-9]{10}\$/";
     $reTel = "/^09[0-9]{8}\$/";
     // verify the member of birthday (YYYY-MM-DD)
     $reDateOne = "/^(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)\$/";
     // define the default of property.
     $defaultProperties = ['name' => 'name', 'mobile' => 'tel', 'gender' => 'gender', 'birthday' => 'birthday', 'email' => 'email'];
     $dbExistProperties = ['name' => 'Name', 'tel' => 'Mobile', 'gender' => 'Gender', 'birthday' => 'Birthday', 'email' => 'Email'];
     $ignoreProperties = [];
     $columnElements = [];
     // all elements of a column
     $property = [];
     $titles = [];
     $realTitles = [];
     $rowIndex = 1;
     $defaulyProperties = [];
     $properties = [];
     $requiredProperty = [];
     $existsTitle = [];
     if ($allRow <= 1) {
         ResqueUtil::log(['error' => 'the file of excel hasn`t data']);
         $array = ['value' => null, 'rows' => null, 'cols' => null, 'property' => null, 'wrongNum' => self::MEMBER_NO_DATA];
         $this->storeError($redis, $array, $args);
         return false;
     }
     // get title of excel.
     $mapTitlePropertyId = [];
     $titleIndexClo = -1;
     for ($columnIndex = 'A'; $columnIndex <= $allColumn; $columnIndex++) {
         $titleIndexClo++;
         $titleName = strtolower(trim((string) $currentSheet->getCell($columnIndex . $rowIndex)->getValue()));
         if (empty($titleName)) {
             continue;
         }
         if (array_key_exists((string) $titleName, $defaultProperties)) {
             $findValues = $defaultProperties[(string) $titleName];
             $propertyValueOne = MemberProperty::findOne(['name' => new \MongoRegex("/^{$findValues}\$/i"), 'accountId' => new MongoId($args['accountId']), 'isDeleted' => false]);
             $property[] = empty($propertyValueOne) ? [] : $propertyValueOne;
             $titles[] = empty($defaultProperties[(string) $titleName]) ? "" : $defaultProperties[(string) $titleName];
             $realTitles[] = empty($propertyValueOne) ? '' : (string) $propertyValueOne['name'];
             $mapTitlePropertyId[$titleName] = $propertyValueOne['_id'];
         } else {
             $findValue = (string) $titleName;
             $propertyValueOne = MemberProperty::findOne(['propertyId' => new \MongoRegex("/^{$findValue}\$/i"), 'accountId' => new MongoId($args['accountId']), 'isDeleted' => false]);
             $property[] = empty($propertyValueOne) ? [] : $propertyValueOne;
             $titles[] = empty((string) $titleName) ? '' : (string) $titleName;
             $realTitles[] = empty($propertyValueOne) ? '' : (string) $propertyValueOne['propertyId'];
             $mapTitlePropertyId[$titleName] = $propertyValueOne['_id'];
         }
         if (!in_array((string) $titleName, $title)) {
             $title[] = (string) $titleName;
         } else {
             $existsTitle[] = (string) $titleName;
         }
     }
     // Get index of mobile in titles.
     $mobileIndex = array_search(Member::DEFAULT_PROPERTIES_MOBILE, $titles);
     $mobileColumn = \PHPExcel_Cell::stringFromColumnIndex($mobileIndex);
     $mobiles = [];
     // Verify if the title is repeated.
     if (count($existsTitle) > 0) {
         ResqueUtil::log(['error' => 'the title is repeated', 'args' => ['existsTitle' => $existsTitle]]);
         $array = ['value' => null, 'rows' => null, 'cols' => null, 'property' => null, 'wrongNum' => self::MEMBER_TITLE_REPEATED];
         $this->storeError($redis, $array, $args);
         $redis->sadd($repeatTitleKey, serialize($existsTitle));
         unset($existsTitle);
         return false;
     }
     // get all property.
     $defaulyProperty = MemberProperty::find()->select(['_id', 'name'])->from('memberProperty')->where(['isRequired' => true, 'isVisible' => true, 'isDefault' => true, 'isDeleted' => false, 'accountId' => new MongoId($args['accountId'])])->all();
     foreach ($defaulyProperty as $data) {
         $defaulyProperties[] = $data['name'];
     }
     $propertyValue = MemberProperty::find()->select(['_id', 'propertyId'])->from('memberProperty')->where(['isRequired' => true, 'isVisible' => true, 'isDefault' => false, 'isDeleted' => false, 'accountId' => new MongoId($args['accountId'])])->all();
     foreach ($propertyValue as $data) {
         $properties[] = $data['propertyId'];
     }
     $propertyItems = array_merge($defaulyProperties, $properties);
     // get required properties in db.
     foreach ($propertyItems as $item) {
         if (array_key_exists($item, $dbExistProperties)) {
             $itemValue = $dbExistProperties[$item];
         } else {
             $itemValue = $item;
         }
         if (!in_array(strtolower($itemValue), $title) && !in_array($itemValue, $requiredProperty)) {
             $requiredProperty[] = $itemValue;
         }
     }
     if (count($requiredProperty) > 0) {
         ResqueUtil::log(['error' => 'Resqued property is miss', 'args' => ['title' => $requiredProperty]]);
         $array = ['value' => null, 'rows' => null, 'cols' => null, 'property' => null, 'wrongNum' => self::MEMBER_NO_EXIST];
         $this->storeError($redis, $array, $args);
         $redis->sadd($missPropertyKey, serialize($requiredProperty));
         unset($requiredProperty);
         return false;
     }
     // check content for excel.
     $batchIndex = 1;
     $batchIndexColumn = [];
     $batch = 1;
     $batchs = ceil(($allRow - 1) / self::BATCH_COUNT);
     $decimal = $allRow % self::BATCH_COUNT;
     $result = [];
     $resultTitle = [];
     // Mapping between name and properties.
     $nameAndProperties = $defaulyProperty = MemberProperty::find()->select(['_id', 'name', 'propertyId'])->from('memberProperty')->where(['isDeleted' => false, 'accountId' => new MongoId($args['accountId'])])->all();
     $mapProperties = [];
     if (!empty($nameAndProperties)) {
         foreach ($nameAndProperties as $item) {
             $mapProperties[] = $item->toArray();
         }
         $result = ArrayHelper::map($mapProperties, 'propertyId', 'name');
         $resultTitle = ArrayHelper::map($mapProperties, 'name', 'propertyId');
     }
     // Get all tag
     $tags = Account::getAllTags(new MongoId($args['accountId']));
     for ($rowIndex = 2; $rowIndex <= $allRow; $rowIndex++) {
         if ($batchIndex == self::BATCH_COUNT) {
             $batchIndex = 1;
             $batchIndexColumn = [];
             ++$batch;
         }
         $columnValue = [];
         $telName = '';
         $telId = '';
         $telValue = '';
         $updateMember = [];
         $insertMember = [];
         $titleIndex = -1;
         for ($columnIndex = 'A'; $columnIndex <= $allColumn; $columnIndex++) {
             $titleIndex++;
             // get member propery by propertyId(the title of excel).
             //++$titleIndex;
             $columnNum = \PHPExcel_Cell::columnIndexFromString($columnIndex) - 1;
             $value = trim((string) $currentSheet->getCell($columnIndex . $rowIndex)->getValue());
             $mobile = trim((string) $currentSheet->getCell($mobileColumn . $rowIndex)->getValue());
             if ($titleIndex < count($title) && $columnNum == $titleIndex) {
                 if (empty((string) $title[$titleIndex])) {
                     continue;
                 }
                 // Verify if the mobile is right.
                 if (empty($mobile)) {
                     $array = ['value' => $mobile, 'rows' => $rowIndex, 'cols' => $mobileIndex + 1, 'property' => $title[$mobileIndex], 'wrongNum' => self::MEMBER_PROPERTY_REQUIRED];
                     $this->storeError($redis, $array, $args);
                     return false;
                 } else {
                     if (strstr($mobile, self::MEMBER_ENGLISH_COLON)) {
                         // check mobile.(T:1312797391);
                         $str = explode(self::MEMBER_ENGLISH_COLON, $mobile);
                         // T:1312797391
                         if ($str[0] != 'T') {
                             $array = ['value' => $mobile, 'rows' => $rowIndex, 'cols' => $mobileIndex + 1, 'property' => $title[$mobileIndex], 'wrongNum' => self::MEMBER_PROPERTY_ERROR];
                             $this->storeError($redis, $array, $args);
                             return false;
                         }
                         $telValue = $str[1];
                     } else {
                         if (strstr($mobile, self::MEMBER_CHINESE_COLON)) {
                             $str = explode(self::MEMBER_CHINESE_COLON, $mobile);
                             if ($str[0] != 'T') {
                                 $array = ['value' => $mobile, 'rows' => $rowIndex, 'cols' => $mobileIndex + 1, 'property' => $title[$mobileIndex], 'wrongNum' => self::MEMBER_PROPERTY_ERROR];
                                 $this->storeError($redis, $array, $args);
                                 return false;
                             }
                             $telValue = $str[1];
                         } else {
                             $array = ['value' => $mobile, 'rows' => $rowIndex, 'cols' => $mobileIndex + 1, 'property' => $title[$mobileIndex], 'wrongNum' => self::MEMBER_PROPERTY_ERROR];
                             $this->storeError($redis, $array, $args);
                             return false;
                         }
                     }
                     if ((string) $title[$titleIndex] == self::MEMBER_MOBILE) {
                         $value = (string) $telValue;
                     }
                     // get mobile in excel.
                     if (!in_array((string) $telValue, $mobiles)) {
                         $mobiles[] = (string) $telValue;
                     }
                 }
                 // validate tag.
                 if ($titles[$titleIndex] == self::MEMBER_TAGS) {
                     if (!empty($value) && !in_array($value, $tags)) {
                         $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ILLEGAL];
                         $this->storeError($redis, $array, $args);
                         return false;
                     }
                     $columnValue[$rowIndex][] = ['tags' => $value];
                 } else {
                     // get all the ignore properties.
                     if (empty($property[$titleIndex])) {
                         if (!in_array((string) $title[$titleIndex], $ignoreProperties)) {
                             $ignoreProperties[] = (string) $title[$titleIndex];
                         }
                     } else {
                         if ($property[$titleIndex]['isVisible'] == false) {
                             if (!in_array((string) $title[$titleIndex], $ignoreProperties)) {
                                 $ignoreProperties[] = (string) $title[$titleIndex];
                             }
                             continue;
                         }
                         // Varitify if it`s required.
                         if (strcasecmp($property[$titleIndex]['type'], self::MEMBER_RADIO) != 0 && (string) $title[$titleIndex] != self::MEMBER_MOBILE) {
                             if ($property[$titleIndex]['isRequired'] == true && empty($value)) {
                                 $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_REQUIRED];
                                 $this->storeError($redis, $array, $args);
                                 return false;
                             }
                         }
                         // Varitify if it`s isUnique in excel.
                         if (!empty($value) && $property[$titleIndex]['isUnique'] == true) {
                             if ((string) $title[$titleIndex] != self::MEMBER_MOBILE) {
                                 // check db.
                                 $batchIndexColumn[$columnNum][] = $value;
                                 if ($decimal == 0 || $rowIndex == $allRow || $rowIndex == self::BATCH_COUNT) {
                                     // check update or insert, if the data will be insert, I will validate unique, not do it.
                                     $members = Member::findMobiles($mobiles, new MongoId($args['accountId']));
                                     if (!empty($members)) {
                                         $memberId = [];
                                         foreach ($members as $member) {
                                             $mobile = '';
                                             $uniqueFileValue = '';
                                             $uniqueFileId = '';
                                             foreach ($member['properties'] as $propertyItem) {
                                                 if ($propertyItem['name'] == Member::DEFAULT_PROPERTIES_MOBILE) {
                                                     $mobile = $propertyItem['value'];
                                                     $index = array_search($mobile, $mobiles);
                                                     unset($batchIndexColumn[$columnNum][$index]);
                                                 }
                                                 if ($propertyItem['id'] == $mapTitlePropertyId[$title[$titleIndex]]) {
                                                     $uniqueFileValue = $propertyItem['value'];
                                                     $uniqueFileId = $propertyItem['id'];
                                                 }
                                             }
                                             $rindex = ($batch - 1) * self::BATCH_COUNT + $index + 2;
                                             $uniqueFileValue = trim((string) $currentSheet->getCell(\PHPExcel_Cell::stringFromColumnIndex($titleIndex) . $rindex)->getValue());
                                             $isExisUpdatetProperties = Member::findOne(['properties' => ['$elemMatch' => ['id' => $uniqueFileId, 'value' => $uniqueFileValue]], '_id' => ['$ne' => $member['_id']], 'isDeleted' => false, 'accountId' => new MongoId($args['accountId'])]);
                                             if (!empty($isExisUpdatetProperties)) {
                                                 if ($property[$titleIndex]['isDefault'] == true) {
                                                     $array = ['value' => $value, 'rows' => $rindex, 'cols' => $titleIndex + 1, 'property' => $property[$titleIndex]['name'], 'wrongNum' => self::MEMBER_PROPERTY_UNIQUE];
                                                     $this->storeError($redis, $array, $args);
                                                     return false;
                                                 } else {
                                                     $array = ['value' => $value, 'rows' => $rindex, 'cols' => $titleIndex + 1, 'property' => $property[$titleIndex]['propertyId'], 'wrongNum' => self::MEMBER_PROPERTY_UNIQUE];
                                                     $this->storeError($redis, $array, $args);
                                                     return false;
                                                 }
                                             }
                                         }
                                     }
                                     $isExistProperties = Member::findOne(['properties' => ['$elemMatch' => ['value' => ['$in' => $batchIndexColumn[$columnNum]], 'id' => $property[$titleIndex]['_id']]], 'isDeleted' => false, 'accountId' => new MongoId($args['accountId'])]);
                                     if (!empty($isExistProperties)) {
                                         foreach ($isExistProperties['properties'] as $propertyItem) {
                                             if ($property[$titleIndex]['_id'] == $propertyItem['id']) {
                                                 if ($property[$titleIndex]['isDefault'] == true) {
                                                     $colIndexNum = array_search(strtolower((string) $propertyItem['name']), $title) + 1;
                                                 } else {
                                                     $colIndexNum = array_search(strtolower($resultTitle[(string) $propertyItem['name']]), $title) + 1;
                                                 }
                                                 if ($rowIndex == 2) {
                                                     $columnElements[$columnNum][] = '';
                                                 }
                                                 if (in_array((string) $propertyItem['value'], $columnElements[$columnNum])) {
                                                     $rowIndexNum = array_search((string) $propertyItem['value'], $columnElements[$columnNum]) + 2;
                                                 } else {
                                                     if ($rowIndex <= self::BATCH_COUNT) {
                                                         $rowIndexNum = ($batch - 1) * self::BATCH_COUNT + count($batchIndexColumn[$columnNum]) + 1;
                                                     } else {
                                                         $rowIndexNum = ($batch - 1) * self::BATCH_COUNT + count($batchIndexColumn[$columnNum]);
                                                     }
                                                 }
                                                 if ($rowIndex == 2) {
                                                     unset($columnElements[$columnNum][0]);
                                                 }
                                             }
                                             continue;
                                         }
                                         if ($property[$titleIndex]['isDefault'] == true) {
                                             $array = ['value' => $value, 'rows' => $rowIndexNum, 'cols' => $colIndexNum, 'property' => $property[$titleIndex]['name'], 'wrongNum' => self::MEMBER_PROPERTY_UNIQUE];
                                             $this->storeError($redis, $array, $args);
                                             return false;
                                         } else {
                                             $array = ['value' => $value, 'rows' => $rowIndexNum, 'cols' => $colIndexNum, 'property' => $property[$titleIndex]['propertyId'], 'wrongNum' => self::MEMBER_PROPERTY_UNIQUE];
                                             $this->storeError($redis, $array, $args);
                                             return false;
                                         }
                                     }
                                 }
                                 // check excel.
                                 $isInsert = $redis->Hset($cacheHash . $columnNum, $value, $columnNum);
                                 if ($isInsert == 0) {
                                     $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_UNIQUE];
                                     $this->storeError($redis, $array, $args);
                                     return false;
                                 }
                             }
                             $columnElements[$columnNum][] = $value;
                         }
                         switch ($property[$titleIndex]['type']) {
                             case Member::DEFAULT_PROPERTIES_EMAIL:
                                 $EmailTitle = $title[$titleIndex];
                                 $EmailTitles = $titles[$titleIndex];
                                 $EmailParams = ['redis' => $redis, 'args' => $args, 'titleIndex' => $titleIndex, 'EmailTitles' => $EmailTitles];
                                 $EmailTitleIndex = $titleIndex + 1;
                                 $propertyError = self::MEMBER_PROPERTY_ERROR;
                                 $Emailarray = ['value' => $value, 'rows' => $rowIndex, 'cols' => $EmailTitleIndex, 'property' => $EmailTitle, 'wrongNum' => $propertyError];
                                 $columnValue[$rowIndex][] = $this->validateEmail($Emailarray, $EmailParams, $property, $result, $realTitles, $titles);
                                 break;
                             case self::MEMBER_DATE:
                                 if (!empty($value)) {
                                     if (strstr($value, '-')) {
                                         $str = explode('-', $value);
                                         if (count($str) != 3) {
                                             $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ERROR];
                                             $this->storeError($redis, $array, $args);
                                             return false;
                                         }
                                     }
                                     if (strstr($value, self::MEMBER_LINE)) {
                                         $str = explode(self::MEMBER_LINE, $value);
                                         if (count($str) == 3) {
                                             $time = $str[2] . '-' . $str[0] . '-' . $str[1];
                                         } else {
                                             $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ERROR];
                                             $this->storeError($redis, $array, $args);
                                             return false;
                                         }
                                     } else {
                                         $time = $value;
                                     }
                                 }
                                 if (!empty($value) && !preg_match($reDateOne, $time)) {
                                     $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ILLEGAL];
                                     $this->storeError($redis, $array, $args);
                                     return false;
                                 }
                                 if (!empty($value)) {
                                     if (strstr($value, self::MEMBER_LINE)) {
                                         $str = explode(self::MEMBER_LINE, $value);
                                         $dayStr = $str[2] . '-' . $str[0] . '-' . $str[1];
                                         $date = (int) strtotime($dayStr) * 1000;
                                     } else {
                                         $date = (int) strtotime($value) * 1000;
                                     }
                                 } else {
                                     $date = null;
                                 }
                                 if (!empty($value) && $date >= time() * 1000) {
                                     $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ILLEGAL];
                                     $this->storeError($redis, $array, $args);
                                     return false;
                                 }
                                 $columnValue[$rowIndex][] = ['id' => $property[$titleIndex]['_id'], 'name' => $property[$titleIndex]['isDefault'] == true ? $titles[$titleIndex] : $result[$realTitles[$titleIndex]], 'value' => $date];
                                 break;
                             case self::MEMBER_CHECKBOX:
                                 $checkboxValue = [];
                                 if (!empty($value) && strstr($value, self::MEMBER_ENGLISH_COMMA) && !strstr($value, self::MEMBER_CHINESE_COMMA)) {
                                     //english
                                     $checkboxValue = explode(self::MEMBER_ENGLISH_COMMA, $value);
                                     $checkboxValue = array_values(array_unique($checkboxValue));
                                 }
                                 if (!empty($value) && strstr($value, self::MEMBER_CHINESE_COMMA) && !strstr($value, self::MEMBER_ENGLISH_COMMA)) {
                                     // chinese
                                     $checkboxValue = explode(self::MEMBER_CHINESE_COMMA, $value);
                                     $checkboxValue = array_values(array_unique($checkboxValue));
                                 }
                                 if (!empty($value) && strstr($value, self::MEMBER_ENGLISH_COMMA) && strstr($value, self::MEMBER_CHINESE_COMMA)) {
                                     $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ERROR];
                                     $this->storeError($redis, $array, $args);
                                     return false;
                                 }
                                 // one value
                                 if (!empty($value) && !strstr($value, self::MEMBER_ENGLISH_COMMA) && !strstr($value, self::MEMBER_CHINESE_COMMA)) {
                                     $checkboxValue[] = $value;
                                 }
                                 if (count($checkboxValue) > 0) {
                                     foreach ($checkboxValue as $item) {
                                         if (!in_array($item, $property[$titleIndex]['options'])) {
                                             $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ILLEGAL];
                                             $this->storeError($redis, $array, $args);
                                             return false;
                                         }
                                         continue;
                                     }
                                 }
                                 $columnValue[$rowIndex][] = ['id' => $property[$titleIndex]['_id'], 'name' => $property[$titleIndex]['isDefault'] == true ? $titles[$titleIndex] : $result[$realTitles[$titleIndex]], 'value' => $checkboxValue];
                                 break;
                             case self::MEMBER_RADIO:
                                 if ((string) $title[$titleIndex] != Member::DEFAULT_PROPERTIES_GENDER) {
                                     if (!empty($value) && !in_array($value, $property[$titleIndex]['options'])) {
                                         $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ILLEGAL];
                                         $this->storeError($redis, $array, $args);
                                         return false;
                                     }
                                     $columnValue[$rowIndex][] = ['id' => $property[$titleIndex]['_id'], 'name' => $property[$titleIndex]['isDefault'] == true ? $titles[$titleIndex] : $result[$realTitles[$titleIndex]], 'value' => empty($value) ? $property[$titleIndex]['options'][0] : $value];
                                 } else {
                                     if (!empty($value) && $value == self::MEMBER_SC_GENDER || $value == self::MEMBER_TC_GENDER || strcasecmp($value, self::MEMBER_MALE) == 0) {
                                         $genderValue = self::MEMBER_MALE;
                                     } else {
                                         if (!empty($value) && $value == self::MEMBER_C_GENDER || strcasecmp($value, self::MEMBER_FEMALE) == 0) {
                                             $genderValue = self::MEMBER_FEMALE;
                                         } else {
                                             if (!empty($value) && $value == self::MEMBER_WEIZHI || $value == self::MEMBER_UNKNOW || strcasecmp($value, self::MEMBER_UNKNOWN) == 0) {
                                                 $genderValue = self::MEMBER_UNKNOWN;
                                             } else {
                                                 if (empty($value)) {
                                                     $genderValue = self::MEMBER_MALE;
                                                 } else {
                                                     $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ILLEGAL];
                                                     $this->storeError($redis, $array, $args);
                                                     return false;
                                                 }
                                             }
                                         }
                                     }
                                     $columnValue[$rowIndex][] = ['id' => $property[$titleIndex]['_id'], 'name' => $property[$titleIndex]['isDefault'] == true ? $titles[$titleIndex] : $result[$realTitles[$titleIndex]], 'value' => $genderValue];
                                 }
                                 break;
                             case MemberProperty::TYPE_TEXTAREA:
                                 $columnValue[$rowIndex][] = ['id' => $property[$titleIndex]['_id'], 'name' => $property[$titleIndex]['isDefault'] == true ? $titles[$titleIndex] : $result[$realTitles[$titleIndex]], 'value' => str_replace("\\n", PHP_EOL, $value)];
                                 break;
                             default:
                                 if ((string) $title[$titleIndex] == Member::DEFAULT_PROPERTIES_NAME) {
                                     $valueLen = mb_strlen($value, 'utf-8');
                                     if (!empty($value)) {
                                         if ($valueLen < 2 || $valueLen > 30) {
                                             $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ILLEGAL];
                                             $this->storeError($redis, $array, $args);
                                             return false;
                                         }
                                     }
                                     $columnValue[$rowIndex][] = ['id' => $property[$titleIndex]['_id'], 'name' => $property[$titleIndex]['isDefault'] == true ? $titles[$titleIndex] : $result[$realTitles[$titleIndex]], 'value' => $value];
                                 } else {
                                     switch ((string) $title[$titleIndex]) {
                                         case self::MEMBER_MOBILE:
                                             if (!empty($value) && !preg_match($re, $value) && !preg_match($reTel, $value)) {
                                                 $array = ['value' => $value, 'rows' => $rowIndex, 'cols' => $titleIndex + 1, 'property' => $title[$titleIndex], 'wrongNum' => self::MEMBER_PROPERTY_ILLEGAL];
                                                 $this->storeError($redis, $array, $args);
                                                 return false;
                                             }
                                             $columnValue[$rowIndex][] = ['id' => $property[$titleIndex]['_id'], 'name' => $property[$titleIndex]['isDefault'] == true ? $titles[$titleIndex] : $result[$realTitles[$titleIndex]], 'value' => $value];
                                             $telName = $defaultProperties[(string) $title[$titleIndex]];
                                             $telId = (string) $property[$titleIndex]['_id'];
                                             $telValue = $value;
                                             break;
                                         default:
                                             $columnValue[$rowIndex][] = ['id' => $property[$titleIndex]['_id'], 'name' => $property[$titleIndex]['isDefault'] == true ? $titles[$titleIndex] : $result[$realTitles[$titleIndex]], 'value' => $value];
                                             break;
                                     }
                                 }
                                 break;
                         }
                     }
                 }
             }
         }
         // verify if the column value has already exist. if it is exist, will store $updateMember,
         // if it isn`s exist, will store $insertMember.
         $total++;
         $memberOne = null;
         if (!empty($telId)) {
             $memberOne = Member::findOne(['properties' => ['$elemMatch' => ['id' => new MongoId($telId), 'name' => $telName, 'value' => $telValue]], 'accountId' => new MongoId($args['accountId'])]);
         }
         if (!empty($memberOne)) {
             $updateMember[] = $columnValue[$rowIndex];
             $redis->sadd($cacheSetUpdate, serialize($updateMember));
         } else {
             if (!empty($columnValue[$rowIndex])) {
                 $insertMember[] = $columnValue[$rowIndex];
                 $redis->sadd($cacheSetInsert, serialize($insertMember));
             }
         }
         ++$batchIndex;
     }
     unset($columnElements);
     $redis->del($cacheHash . $columnNum);
     //store the number of the wrong code and the number of the right code
     $rightInsert = $redis->scard($cacheSetInsert);
     $rightUpdate = $redis->scard($cacheSetUpdate);
     $right = $rightInsert + $rightUpdate;
     $wrong = $total - $right;
     $redis->Hset($cacheHash, $wrongKey, $wrong);
     $redis->Hset($cacheHash, $rightKey, $right);
     // store the ignore of properties.
     if ($wrong == 0 && count($ignoreProperties) > 0) {
         $redis->sadd($ignorePropertyKey, serialize($ignoreProperties));
     } else {
         $redis->sadd($ignorePropertyKey, null);
     }
     return true;
 }