Fecmall

第 2 位会员

会员
个人信息
  • 加入于 2017-05-31 17:38:45
  • 城市 Qingdao
  • GitHub https://github.com/fecshop
  • 最后登录时间 11天前
  • 签名 净化自己,潜心编码
个人简介
Terry,Fecmall开源产品作者,12年电商经验一线程序员开发者,擅长规划产品,架构设计。
个人成就
  • 发表文章次数 744
  • 发布回复次数 5760
  • 个人主页浏览次数 683
问一下搜索表full_search_product_en的更新方法7年前

然后,打开文件,https://github.com/fecshop/yii2_fecshop/blob/master/services/search/MongoSearch.php

找到函数

/**
     * @property $product_ids | Array ,里面的子项是MongoId类型。
     * 将产品表的数据同步到各个语言对应的搜索表中。
     */
    protected function actionSyncProductInfo($product_ids, $numPerPage)
    {
        $sModel = $this->_searchModel;
        if (is_array($product_ids) && !empty($product_ids)) {
            $productPrimaryKey = Yii::$service->product->getPrimaryKey();
            $searchModel = new $this->_searchModelName();
            $filter['select'] = $searchModel->attributes();
            $filter['asArray'] = true;
            $filter['where'][] = ['in', $productPrimaryKey, $product_ids];
            $filter['numPerPage'] = $numPerPage;
            $filter['pageNum'] = 1;
            $coll = Yii::$service->product->coll($filter);
            if (is_array($coll['coll']) && !empty($coll['coll'])) {
                foreach ($coll['coll'] as $one) {
                    //$langCodes = Yii::$service->fecshoplang->allLangCode;
                    //if(!empty($langCodes) && is_array($langCodes)){
                    //	foreach($langCodes as $langCodeInfo){
                    $one_name = $one['name'];
                    $one_description = $one['description'];
                    $one_short_description = $one['short_description'];
                    if (!empty($this->searchLang) && is_array($this->searchLang)) {
                        foreach ($this->searchLang as $langCode => $mongoSearchLangName) {
                            $sModel::$_lang = $langCode;
                            $searchModel = $this->_searchModel->findOne(['_id' => $one['_id']]);
                            if (!$searchModel['_id']) {
                                $searchModel = new $this->_searchModelName();
                            }else{
                                unset($one['_id']);
                            }
                            $one['name'] = Yii::$service->fecshoplang->getLangAttrVal($one_name, 'name', $langCode);
                            $one['description'] = Yii::$service->fecshoplang->getLangAttrVal($one_description, 'description', $langCode);
                            $one['short_description'] = Yii::$service->fecshoplang->getLangAttrVal($one_short_description, 'short_description', $langCode);
                            $one['sync_updated_at'] = time();
                            Yii::$service->helper->ar->save($searchModel, $one);
                            if ($errors = Yii::$service->helper->errors->get()) {
                                // 报错。
                                echo  $errors;
                                //return false;
                            }
                        }
                    }
                }
            }
        }
        //echo "MongoSearch sync done ... \n";
        
        return true;
    }

可以看到将各个语言的部分都更新了

问一下搜索表full_search_product_en的更新方法7年前

产品的编辑是在后台,后台编辑保存,对应的方法为: https://github.com/fecshop/yii2_fecshop/blob/master/app/appadmin/modules/Catalog/block/productinfo/Manageredit.php

public function save()
    {
        $this->initParamType();
        /*
         * if attribute is date or date time , db storage format is int ,by frontend pass param is int ,
         * you must convert string datetime to time , use strtotime function.
         */
        // var_dump()
        if (Yii::$app->request->post('operate') == 'copy') {
            if (isset($this->_param['_id'])) {
                unset($this->_param['_id']);
                //echo 111;
                //var_dump($this->_param);
                //exit;
            }
        }
        $this->_service->save($this->_param, 'catalog/product/index');
        
        $errors = Yii::$service->helper->errors->get();
        if (!$errors) {
            echo  json_encode([
                'statusCode'=>'200',
                'message'=>'save success',
            ]);
            exit;
        } else {
            echo  json_encode([
                'statusCode'=>'300',
                'message'=>$errors,
            ]);
            exit;
        }
    }

在上面的函数中存在下面这行代码,这个代码的作用是保存产品。 $this->_service->save($this->_param, 'catalog/product/index');

上面这行代码执行的是:https://github.com/fecshop/yii2_fecshop/blob/master/services/product/ProductMongodb.php

 /**
     * @property $one|array , 产品数据数组
     * @property $originUrlKey|string , 产品的原来的url key ,也就是在前端,分类的自定义url。
     * 保存产品(插入和更新),以及保存产品的自定义url
     * 如果提交的数据中定义了自定义url,则按照自定义url保存到urlkey中,如果没有自定义urlkey,则会使用name进行生成。
     */
    public function save($one, $originUrlKey = 'catalog/product/index')
    {
        if (!$this->initSave($one)) {
            return;
        }
        $one['min_sales_qty'] = (int)$one['min_sales_qty'];
        $currentDateTime = \fec\helpers\CDate::getCurrentDateTime();
        $primaryVal = isset($one[$this->getPrimaryKey()]) ? $one[$this->getPrimaryKey()] : '';
        if ($primaryVal) {
            $model = $this->_productModel->findOne($primaryVal);
            if (!$model) {
                Yii::$service->helper->errors->add('Product '.$this->getPrimaryKey().' is not exist');
                return;
            }
            //验证sku 是否重复
            $product_one = $this->_productModel->find()->asArray()->where([
                '<>', $this->getPrimaryKey(), (new \MongoDB\BSON\ObjectId($primaryVal)),
            ])->andWhere([
                'sku' => $one['sku'],
            ])->one();
            if ($product_one['sku']) {
                Yii::$service->helper->errors->add('Product Sku 已经存在,请使用其他的sku');
                return;
            }
        } else {
            $model = new $this->_productModelName();
            $model->created_at = time();
            $model->created_user_id = \fec\helpers\CUser::getCurrentUserId();
            $primaryVal = new \MongoDB\BSON\ObjectId();
            $model->{$this->getPrimaryKey()} = $primaryVal;
            //验证sku 是否重复
            $product_one = $this->_productModel->find()->asArray()->where([
                'sku' => $one['sku'],
            ])->one();
            if ($product_one['sku']) {
                Yii::$service->helper->errors->add('Product Sku 已经存在,请使用其他的sku');
                return;
            }
        }
        $model->updated_at = time();
        /*
         * 计算出来产品的最终价格。
         */
        $one['final_price'] = Yii::$service->product->price->getFinalPrice($one['price'], $one['special_price'], $one['special_from'], $one['special_to']);
        $one['score'] = (int) $one['score'];
        unset($one['_id']);
        /**
         * 保存产品
         */
        $saveStatus = Yii::$service->helper->ar->save($model, $one);
        
        /*
         * 自定义url部分
         */
        if ($originUrlKey) {
            $originUrl = $originUrlKey.'?'.$this->getPrimaryKey() .'='. $primaryVal;
            $originUrlKey = isset($one['url_key']) ? $one['url_key'] : '';
            $defaultLangTitle = Yii::$service->fecshoplang->getDefaultLangAttrVal($one['name'], 'name');
            $urlKey = Yii::$service->url->saveRewriteUrlKeyByStr($defaultLangTitle, $originUrl, $originUrlKey);
            $model->url_key = $urlKey;
            $model->save();
        }
        $product_id = $model->{$this->getPrimaryKey()};
        /**
         * 更新产品库存。
         */
        
        Yii::$service->product->stock->saveProductStock($product_id,$one);
        /**
         * 更新产品信息到搜索表。
         */
        Yii::$service->search->syncProductInfo([$product_id]);
        return true;
    }

在上面函数的最后,就是更新产品信息到搜索表,也就是下面的代码:

Yii::$service->search->syncProductInfo([$product_id]);

这个代码的作用是将save的product的信息更新到搜索部分

因appfront/config/main.php中87行prefix处包括匿名函数,故index-merge-config.php不能完成。 7年前

你在这个Q群里面把? 186604851 Q加我下好友,多谢

因appfront/config/main.php中87行prefix处包括匿名函数,故index-merge-config.php不能完成。 7年前

多谢,你测试过了吧?测试过了,我明天找时间直接复制上去

fecshop 直接生成订单的一个问题7年前

@dionyang #3楼 把你的想法,用代码的方式来呈现把,譬如你找一段fecshop的文件以及相应的代码,然后写出来你优化后的样子,这样更方便探讨。

fecshop 直接生成订单的一个问题7年前

您好, mongodb里product_flat的qty已经废弃了,没有用了,开始的时候qty是放到mongodb中的

后面进行了重构,放到了mysql中,product_flat的qty已经完全废弃了

后面找时间我删除下这些东西,目前还没有时间调整,给你造成的误解,见谅!

Yii2的缓存里,如何通配符查询?7年前

@laughmaker [#5楼](#comment5) 可以你的代码完整的贴一下吗?,后面有类似的需求可以参考一下你的代码,多谢!

Yii部署流程7年前

说详细一点,是安装还是部署到线上?

安装看文档:http://www.fecshop.com/doc/fecshop-guide/develop/cn-1.0/guide-fecshop-about-hand-install.html

因appfront/config/main.php中87行prefix处包括匿名函数,故index-merge-config.php不能完成。 7年前

上面的问题,已经解决,参看: https://stackoverflow.com/questions/7026690/reconstruct-get-code-of-php-function

在您的函数上面,进行了更改,将配置中出现函数的部分进行了处理,最终代码如下:

//单个制表符用几个空格来表示
const TAB_DEFAULT_SPACES = 4;
/**
 * 获取某维的缩进空格字符串
 * @param $dimensional 维数,即当前在数组的第几层。
 * @return string 返回当前层的缩进空格的字符串
 */
function obtainSpaces($dimensional)
{
    $spaceNumber = $dimensional * TAB_DEFAULT_SPACES;
    $spaceStr = '';
    for ($index = 0; $index < $spaceNumber; $index++) {
        $spaceStr .= ' ';
    }
    return $spaceStr;
}

/**
 * @param $val 数组的键值对里的值(如果不是数组的时候的)
 * @return string 返回相应类型所对应的字符串
 */
function formatNotArray($val)
{
    if (is_string($val)) {
        return "'".$val."'";
    }
    if (is_bool($val)) {
        return $val? 'true' : 'false';
    }
    if (is_object($val)) {
        $post_log = '';
        ob_start();
        ob_implicit_flush(false);
        $func = new ReflectionFunction($val);
        $filename = $func->getFileName();
        $start_line = $func->getStartLine() - 1; // it's actually - 1, otherwise you wont get the function() block
        $end_line = $func->getEndLine();
        $length = $end_line - $start_line;
        $source = file($filename);
        $body = implode("", array_slice($source, $start_line, $length));
        echo $body;
        $post_log = ob_get_clean();
        return $post_log;
    }
    //if()
    return is_null($val)? "''" : $val;
}



/**
 * 格式化数组(格式化成字符串)
 * @param $arr 要格式化的数组
 * @param $dimensional 维度,即当前数组处于被嵌套在第几层中
 * @param $pre_sapces_str 上一维度的输出空格字符串
 * @param $curr_spaces_str 当前维度的输出空格字符串
 * @return string 数组格式化后所得字符串
 */
function formatArray($arr,$dimensional,$pre_sapces_str,$curr_spaces_str)
{
    $str = PHP_EOL.$pre_sapces_str.'['.PHP_EOL;
    $index = 1;
    foreach ($arr as $k => $v) {
        1 != $index && $str .= PHP_EOL;
        $index = -1;
        $key = is_string($k)? "'".$k."'" : $k;
        $value = '';
        if (is_array($v)) {
            $value = toPhpCode($v, $dimensional);
            $str .= $curr_spaces_str.$key.'=>'.$value.',';
        }else if(is_object($v)) {
            $value = formatNotArray($v);
            $str .= $curr_spaces_str.$value;
        }else {
            $value = formatNotArray($v);
            $str .= $curr_spaces_str.$key.'=>'.$value.',';
        }
        //$str .= $curr_spaces_str.$key.'=>'.$value.',';
    }
    $str .= PHP_EOL.$pre_sapces_str.']';
    return $str;

}

/**
 * 转成php代码
 * @param $arr 要转的数组
 * @param int $dimensional 维度,即当前数组处于被嵌套在第几层中
 * @return string 格式化后所得字符串
 */
function toPhpCode($arr, $dimensional = 0)
{
    if (!is_array($arr)) {
        return formatNotArray($arr);
    }
    $pre_sapces_str = obtainSpaces($dimensional);
    $dimensional++;
    $curr_spaces_str = obtainSpaces($dimensional);
    return formatArray($arr,$dimensional,$pre_sapces_str,$curr_spaces_str);
}


多谢您的分享和帮助

因appfront/config/main.php中87行prefix处包括匿名函数,故index-merge-config.php不能完成。 7年前

你是否有办法,将函数的内容,以字符串的方式输出,譬如:

$var = function ($message) {
                        return $message;
                    };

php 有没有函数可以把这个函数代码打印出来?

在配置中会存在function,譬如:

'targets' => [
                'file' =>[
                    //'levels' => ['trace'],
                    'categories' => ['fecshop_debug'],
                    'class' => 'yii\log\FileTarget',
                    # 当 yii\log\Logger 对象刷新日志消息到 log targets 的时候,它们并 不能立即获取导出的消息。相反,消息导出仅仅在一个日志目标累积了一定数量的过滤消息的时候才会发生。你可以通过配置 个别的 log targets 的 yii\log\Target::exportInterval 属性来 自定义这个数量,就像下面这样:
                    'exportInterval' => 1,
                    # 输出文件
                    'logFile' => '@appfront/runtime/fecshop_logs/fecshop_debug.log',
                    # 你可以通过配置 yii\log\Target::prefix 的属性来自定义格式,这个属性是一个PHP可调用体返回的自定义消息前缀
                    'prefix' => function ($message) {
                        return $message;
                    },
                    # 除了消息前缀以外,日志目标也可以追加一些上下文信息到每组日志消息中。 默认情况下,这些全局的PHP变量的值被包含在:$_GET, $_POST, $_FILES, $_COOKIE,$_SESSION 和 $_SERVER 中。 你可以通过配置 yii\log\Target::logVars 属性适应这个行为,这个属性是你想要通过日志目标包含的全局变量名称。 举个例子,下面的日志目标配置指明了只有 $_SERVER 变量的值将被追加到日志消息中。
                    # 你可以将 logVars 配置成一个空数组来完全禁止上下文信息包含。或者假如你想要实现你自己提供上下文信息的方式, 你可以重写 yii\log\Target::getContextMessage() 方法。
                     'logVars' => [],
                ],
            ],

上面代码中的这个部分就是一个function

'prefix' => function ($message) {
                        return $message;
                    },
因appfront/config/main.php中87行prefix处包括匿名函数,故index-merge-config.php不能完成。 7年前

多谢您的用心的建议,并把代码贴出来分享,多谢,我先细看一下您的代码。

我写的代码的确存在问题,对于配置文件中的匿名函数不能更好的支持(fecshop目前没有匿名函数,所以也没有考虑这个)。

讨论技术知识,不用避嫌啊,直来直去就很好,我分享出来fecshop的代码,大家提意见,也可以帮助我提升技能,这样很好啊,感谢!

你是不是经常写shell脚本

1 != $index && $str .= PHP_EOL;

这行代码好有shell脚本的感觉。

求救!通过Paypal快速支付进来,表单不能返回Paypal支付...7年前

@Blueyii #3楼 你的网站搞的怎么样了?有线上地址发下观摩观摩。

AccessFilter对不符合规则请求页面跳转至site/login,这是在哪里实现的?7年前

@lesvere #14楼 你问的是Yii2的知识,不是问在fecshop中的问题对吧?

我上面的代码回复的是在fecshop中的处理。。。。你别混了哈

AccessFilter对不符合规则请求页面跳转至site/login,这是在哪里实现的?7年前

在登录前,调用下面的代码执行,设置登录成功后跳转的url

Yii::$service->customer->setLoginSuccessRedirectUrl($url);

登录成功后就跳转到传递的$url中了

AccessFilter对不符合规则请求页面跳转至site/login,这是在哪里实现的?7年前

@lesvere #10楼 你想要的是登录成功后,自定义跳转页面?

如果是,你的文字描述真的需要提高

AccessFilter对不符合规则请求页面跳转至site/login,这是在哪里实现的?7年前

你前面问的问题,fecshop 哪有 site/login 这个url,你描述问题请描述清楚,你到底要干什么 看不懂

自己写完了问题,先自己看看,自己把脑子清空了,是否自己能看懂自己表达的意思,这样问的问题就是在浪费时间

AccessFilter对不符合规则请求页面跳转至site/login,这是在哪里实现的?7年前

\vendor\fancyecommerce\fecshop\app\appfront\config\appfront.php

AccessFilter对不符合规则请求页面跳转至site/login,这是在哪里实现的?7年前

通过上面的文件中的配置:

// 首页对应的url key
        // 404页面对应的url key
        'errorHandler' => [
            'errorAction' => 'site/helper/error',
        ],
        // 首页对应的url key
        'urlManager' => [
            'rules' => [
                '' => 'cms/home/index',
            ],
        ],
Your Site Analytics