How update Access Keys in Magento 2.x in console of shell-在命令行更新Magento许可密钥对,Invalid credentials

背景 :

起源于直接在 Magento 秘钥管理页面直接删除了 key,然后即便在后台管理页面setup的System config 更新,但是命令安composer安装插件时,还是提示秘钥不正确,错误提示

Invalid credentials for ‘https://repo.magento.com/packages.json’, aborting

解决步骤

  1. 切换到对应网站目录
  2. composer config -l 显示下配置,最后两行即是密钥对
    1. [http-basic.repo.magento.com.username]
    2. [http-basic.repo.magento.com.password]
  3. composer更新
    • composer global config http-basic.repo.magento.com <public_key> <private_key>

主要参考链接

stackexchange

save product redirect to dashboard in Magento backend 编辑保存产品跳转到后台首页

去检查防火墙设置,check firewall seetings on host

我的解决办法,可能不适合你,因为我使用的是宝塔面板,里面有一个收费插件, Nginx防火墙 ,我看到了日志里有关于CC的拦截警告,我的IP也在其中,添加到白名单之后,正常工作。

前面是问题背景和尝试的办法:

Magento Version is 1.9.4.0 点击修改保存按钮后,直接跳转到Dashboard页面了,产品也没保存成功。

网上有些人遇到过,第三个连接提到了 mod_secure 需要关闭,但我不建议这样做。

以下连接:

1.https://magento.stackexchange.com/questions/181083/product-save-and-continue-redirect-to-dashboard

2.https://community.magento.com/t5/Magento-1-x-Technical-Issues/Magento-not-saving-product-edits-and-redirects-to-dashboard/td-p/40275

3. https://stackoverflow.com/questions/37999189/magento-not-saving-product-edits-and-redirects-to-dashboard

我尝试过,换到另外一个服务器,没问题。当然第二台服务器没有开启防火墙

[Solved]Magento install with docker MySql 8 error connect refuse 数据库拒绝链接错误

问题点:

数据库的加密方式( caching_sha2_password )问题造成的。

当然,你有义务去检查的账号密码,至少在命令行里可以正常使用。还有mysql.user的host里是 %(代表已开启远程链接)。

参考链接 中第四点

select host,user,plugin,authentication_string from mysql.user;

看下plugin的加密方式,mysql 8 之后使用了caching_sha2_password,而非比较传统的mysql_native_password,所以如下更新

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';  ### 把root改成123456 mysql的登录密码
flush privileges; ### 刷新生效

这样子,root就可以链接了,更好的做法是选择你相应的数据库user 而不是root。

此外,版本低于12的Navicat可以连接了。

当然,此外是否配置了正确的端口映射/防火墙等其他问题,也是需要注意。

【翻译】使用composer 安装Magento 2.3.x

官方原文链接

RoadMap

We use Composer to manage Magento components and their dependencies. Using Composer to get the Magento software metapackage provides the following advantages:

我们使用Composer来管理Magento组件及其依赖项。使用Composer获得Magento软件metapackage有以下优势:

  • Reuse third-party libraries without bundling them with source code
  • Reduce extension conflicts and compatibility issues by using a component-based architecture with robust dependency management
  • Adhere to PHP-Framework Interoperability Group (FIG) standards
  • Repackage Magento Open Source with other components
  • Use the Magento software in a production environment

– 重用第三方库,而不用将它们与源代码绑定
-通过使用基于组件的体系结构和健壮的依赖关系管理,减少扩展冲突和兼容性问题
-遵守PHP框架互操作性组(FIG)标准
-可以用其他组件重新打包Magento开源代码
-在生产环境中使用Magento软件

You must create a Composer project from our metapackage if you want to use the Magento Web Setup Wizard to upgrade the Magento software and third-party extensions.

如果您想使用Magento Web安装向导升级Magento软件和第三方扩展,则必须从我们的集合包中创建Composer项目。 (这也是我首先翻译这个文章的意图,因为手动向导安装无法在网页前端升级操作,官方有讲)

Prerequisites

Before you continue, you must do the following:

先决条件
在你继续之前,你必须做以下事情:
-设置一个满足系统需求的服务器(2G以上内存,apache 2.2 or 2.4,
MySQL 5.6, 5.7 /MariaDB 10.0, 10.1, 10.2,PHP 7.1.3+/ 7.2.x 及扩展/OPcache/PHP配置设置 ,SSL 1.1以上/不支持自签名,系统依赖,MAT/SMTP 邮箱服务,Redis3.2/Varnish 4.x 5.2/ Elasticsearch 5.2.x 2.x/ RabbitMQ 3.7.x )
-创建Magento文件系统所有者(详细)
-安装Composer
-获取Magento代码存储库的身份验证密钥 (详细

Get the metapackage

To get the Magento metapackage:

  1. Log in to your Magento server as, or switch to, the Magento file system owner.
  2. Change to the web server docroot directory or a directory that you have configured as a virtual host docroot.
  3. Create a new Composer project using the Magento Open Source or Magento Commerce metapackage.

获取安装包

-以Magento文件系统所有者(详细)的身份登录Magento服务器,或切换到该服务器。
-更改到web服务器docroot目录或已配置为虚拟主机docroot的目录。
-使用Magento开源或Magento 商业版的 metapackage 创建一个新的Composer项目。

开源版

composer create-project --repository=https://repo.magento.com/ magento/project-community-edition <install-directory-name>

商业版

composer create-project --repository=https://repo.magento.com/ magento/project-enterprise-edition <install-directory-name>

When prompted, enter your Magento authentication keys. Your public key is your username; your private key is your password.

If you encounter errors, such as Could not find package... or ...no matching package found, make sure there are no typos in your command. If you still encounter errors, you may not be authorized to download Magento Commerce. Contact Magento support for help.

See troubleshooting for help with more errors.

当提示时,输入Magento身份验证密钥。你的公钥是你的用户名;您的私钥是您的密码。
如果遇到错误,比如找不到包…还是……没有找到匹配的包,请确保您的命令中没有输入错误。如果您仍然遇到错误,您可能没有授权下载Magento Commerce。联系Magento寻求帮助。
有关更多错误,请参见疑难解答。

Set file permissions设置文件权限

You must set read-write permissions for the web server group before you install the Magento software. This is necessary so that the Setup Wizard and command line can write files to the Magento file system.

在安装Magento软件之前,必须为web服务器组设置读写权限。这是必要的,以便安装向导和命令行可以将文件写入Magento文件系统。

cd /var/www/html/<magento install directory>
find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +
find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +
chown -R :www-data . # Ubuntu
chmod u+x bin/magento

安装magento 一种是命令行一种是页面安装向导

(已经到这一步了,别折腾自己了,选择页面向导安装吧)

http://<Magento-host-or-IP>/<path-to-magento-root>/setup
For example: http://localhost/magento2ee/setup

命令行方式

This example assumes that the Magento install directory is named magento2ee, the db-host is on the same machine (localhost), and that the db-namedb-user, and db-password are all magento:

假设文件夹名为 magento2ee ,数据库在同一台服务器,数据库链接参数如上。

bin/magento setup:install \
--base-url=http://localhost/magento2ee \
--db-host=localhost \
--db-name=magento \
--db-user=magento \
--db-password=magento \
--backend-frontname=admin \
--admin-firstname=admin \
--admin-lastname=admin \
[email protected] \
--admin-user=admin \
--admin-password=admin123 \
--language=en_US \
--currency=USD \
--timezone=America/Chicago \
--use-rewrites=1

命令行更多官方细节

Disallowed file type. magento upload error

后台上传图片遇到这个错误。

如果确保文件类型没错的话,正常的解决办法是 增加后台对于图片
Maximum width  的设置:

System > Configuration > Catalog > Product Image

一般设置到1200~1500px左右,或者按照你实际的来。

参考链接

此外还有一些文章提到CSRF问题,和magento 漏洞有关,希望可以帮到你

中文版

Magento PATCH_SUPEE-11085 get Fatal error: Can’t use method return value in write context in /app/code/core/Mage/Authorizenet/Model/Directpost.php on line 391

Note:这篇文章的解决对象是PHP 5.5 以下版本的magento 报错,如果不是PHP 5.5以下版本,可能帮不到你。我使用的是1.9版本的Magento

PATCH_SUPEE-11085 主要是Magento 应对Authrize 变更key的加密类型,Pacth在SSH很好打。但是在后台创建订单时会像文章标体那样报错。

主要问题点是 PHP 5.5以下版本empty() 函数不能检查变量。

所以把line 391代码修改来适配

$response_data = $response->getData('x_SHA2_Hash'); //rewrite for PHP 5.5 lower BY Burt
  $hashConfigKey = !empty($response_data) ? 'signature_key' : 'trans_md5';

主要参考资料

stock flow

Magento Guide Authorize key

Magento的订单状态,Magento Order Status 与 Magento Order State的区别和联系

 

Magento的订单状态,在后台一般现实的是 Order Status ,但是在数据库 sales_flat_order 表里却有两个字段 state 和status,而且两者有高重复度的值。到底两者有什么区别和联系?虽然很基础,但很多次会被困扰,准备一次讲清楚。

先讲state(可翻译成,状态/国家/州):

1.可用值包含 new, processing, complete, holded, closed, canceled 等

一般不可以自定义

2.用于订单内部处理 internally .

3.一个state【订单州】可以有很多个status【订单地位】.

 

再说status(可翻译成,状态/地位):

1.显示为Processing ,Pending ,Payment Suspected Fraud ,Payment Review Pending ,On Hold ,Complete ,Closed ,Canceled ,Pending PayPal

2.字段值可以自己定义的,System –> Order Statuses,可以创建新的【订单地位】,并和【订单州】关联

order status processing
order status的变化

 

 

参考链接

https://magento.stackexchange.com/questions/515/what-are-the-definitions-of-the-order-statuses-or-where-should-i-integrate-my/516

https://www.magestore.com/manage-magento-online-store/magento-order-status-and-magento-order-state

https://docs.magento.com/m1/ce/user_guide/order-processing/order-status.html

Magento: Difference between order states and statuses

 

Magento CAPTCHA not show image backend and frontend 验证码不显示1.x版本

最近,Magento官方给出防止暴力破解安全防范意见:

全文连接在此

主要操作包括修改后台管理地址、限制登录错误次数、CAPTCHA、开启安全扫描、两步验证等(个人建议应该加上:使用更强壮的管理员密码)

关于CAPTCHA,以前就遇到过设置了,但是前台或者后台验证码图片并不显示的问题,但是不是必选项,没有深入的了解过。

【对了,如果不熟悉怎么设置CAPTCHA 可以点击这个连接(1.x版本,留意关于contact部分因为市场已经改版,所以失效)来了解如何操作】

简单来说就是文件权限问题。/media/captcha 这个文件夹(里面还有admin和base两个子文件夹)需要有读写权限。修改成775一般就可以了。我直接在FTP里修改还不成功,需要重命名后手动创建。这样前台就可以正常显示了。

终究来说,还是主机没有一个很好的config来适配Magento。

问题到此解决,如果没有办法直接访问FTP修改权限,网络也提供了数据库关闭此项设置的mysql语句:

Update 
  core_config_data  set value=0
WHERE  path LIKE  '%admin/captcha/enable%'

来自 stackflow

这样,你至少还可以继续登录后台。

 

喜乐打赏

中文翻译Custom Magento System Configuration

这是Alan 一个系类中的一篇文章(2010年2月28),翻译成中文,方便自己方便后来的人。很多地方翻译的不是很好,还有很多地方需要后面优化。

原文地址

One of the more powerful parts of the Magento eCommerce System is the Admin’s System Config section. As a developer, it will allow you to quickly and easily setup forms elements that allow your end-users to configure their Magento System and your custom modules.

管理员系统设置 部分是Magento 系统最有权利的部分。作为一个开发者,在这个部分允许你快速方便地设置表单元素,以便终端使用着配置他们的Magento 系统模块和自定义的模块。

Like a lot of things in Magento, it can be intimidating the first time you attempt to setup a new configuration section from scratch, but once you’ve done it once the power of (nearly) code-less forms will become addictive. Let’s get started.

像Magento 里的其他事情一样,第一次尝试从头去配置一个新的设置部分会被吓到,但是你一旦掌握的了如何使用它你会喜欢上这些,开始吧。

We’ll be building off the module we created in the Magento Controller Dispatch and Hello World article, although any empty module should suffice. The impatient can download the complete module for this article here.

我们将在上面连接文章里的模块里创建,或者一个空白的模块也可以。如果不耐烦可以点击上面下载这篇文章的完整模块

The following is part of a longer series about Magento aimed at developers familiar with PHP MVC development. While each article can be read stand alone, each article does build on concepts and code covered in previous articles. If you’re confused, be sure to catch up on the older stuff first.

下面是一个关于 Magento 的长系列的一部分, 它针对的是熟悉 PHP MVC 开发的开发者。虽然每篇文章都可以单独阅读, 但每篇文章都是建立在以前文章所涵盖的概念和代码之上的。如果你感到困惑, 一定要先赶上旧的教程。

 

Adding A System Config File

The first thing we need to do is add a system configuration file to our module. This file is separate from config.xml, and can be found at the following location

第一件事我们要做的是,为我们的模块添加一个系统配置文件。这个文件是单独自 config.xml的,可以在一下路径里找到:

app/code/local/Alanstormdotcom/Helloworld/etc/system.xml

While similar to the global config, the system configuration information is stored separately. If you need to view the system config file, it exists as it’s own entity. You can view the entire system config by executing the following PHP code from any controller action

有些像 全局配置,系统配置信息是分别保存的。如果你要查看系统配置文件,它以自己的实体实例存在。(暂时完全不懂,后面再修改)。你可以查看整个系统的配置,用一下PHP代码从任何controller。【这里会返回一个很大的xml,包含了已安装的插件信息,包含core,可以搜索关键字 module= 】

//header('Content-Type: text/xml');            
header('Content-Type: text/plain');            
echo $config = Mage::getConfig()
->loadModulesConfiguration('system.xml')        
->getNode()
->asXML();            
exit;

The loadModulesConfiguration method will look in each configured module’s etc folder for a file with the passed in name (in this case, system.xml). Magento has a number of other configuration files (api.xml, wsdl.xml, wsdl2.xml, convert.xml, compilation.xml, install.xml), and as a module developer you can leverage this functionality to create your own.

loadModulesConfiguration方法将会查询在每一个已经配置的模块的etc文件下,传入的名字的文件(在本例子中,为system.xml)。Magento有很多的其他配置文件比如api.xml,wsdl.xml.wsdl2.xml,convert.xml,compliation.xml,install.xml。作为一个开发者,可以利用这些功能去创建自己的 配置文件 。

 

Adding a new Tab

The first thing we’re going to do is a add a custom “Tab” to the System Configuration. Tabs are the navigation headers down the left hand side of the Admin in System->Configuration. The default tabs are General, Catalog, Customers, Sales, Services, and Advanced.

第一件事,我们要做的是添加一个Tab在系统设置里。Tabs是在后台管理页面导航栏头部system–> configuration 下进入,左边栏的那一部分。默认的Tabs有这些:General, Catalog, Customers, Sales, Services, and Advanced 等

Let’s create a new one named “Hello Config”. Create a new system config file and add the following

Location: app/code/local/Alanstormdotcom/Helloworld/etc/system.xml
<config>
    <tabs>
        <helloconfig translate="label" module="helloworld">
            <label>Hello Config</label>
            <sort_order>99999</sort_order>
        </helloconfig>
    </tabs>    
</config>

首先创建一个‘Hello Config’的模块,创建一个新的系统配置文件【system.xml】并写入代码。

A few explanations are in order. The name of the <helloconfig /> node is arbitrary, but should be unique among Tabs. It will serve as an identifier for your tab which we’ll use later in the config.

按数序介绍:<helloconfig />代码段是任意定义的但是要唯一。这个用作你 稍后配置的的tab的一个标识符。

The module="helloworld" attribute identifies which module this tab “belongs” to, <label> determines the name that will be used for your tab, and <sort_order> determines where the tab shows up in relation to the other tabs in the left hand navigation.

module="helloworld" 这个属性用来标识这个tab属于那个模块。<label>决定了用作tab的名字。<sort_order>决定了这个tab在左侧导航的排序。

With this in place, head over to the System -> Config section. One of two things should happen

操作了这些之后,回到 System -> Config部分,有两件事可以发现:

  1. The page will load as expected, but without your new tab
  2. You’ll get an error something like the following:
    Fatal error: Class 'Mage_Helloworld_Helper_Data' not found in

1.网页可以正常刷新显示,但是没有我们的新tab

2.会得到错误提示 ‘Mage_Helloworld_Helper_Date’

A Brief Interlude(插曲) for Helper Classes

Like a lot of popular PHP MVC systems, Magento has Helper classes, which are used for a variety of tasks that don’t fit neatly into Model, View, or Controller. Helper classes are one of the abstracted grouped class names, meaning system users can override default classes and module developers need to add a section to their config.xml to specify the base class name for Helpers.

如同其他PHP的MVC系统一样,Magento拥有Helper类,用于不适合在Model,View或Controller中合适贴合的各种任务。Helper类是grouped class names的一个实例化。意味着系统使用者可以覆写默认的classes,模块开发者需要在 config.xml 文件中添加一个段落用来给Helpers致命基本的类名。

A lot of the Magento System code assumes a module has a default Helper class. If you got the exception mentioned above, it’s because your Helloworld module didn’t have this default Helper class and the System was trying to use it. Let’s add one now.

Magento系统假定一个模块是有默认的Helper类。如果你看到了上面提到的错误,这是因为Hello World 模块没有一个默认的Helper类而系统又尝试去使用它,现在我们自己添加一个。

First, we need to add a section the to module’s main config.xml file (NOT the system config)

首先我们在 config.xml(注意不是system.xml文件)添加模块的主配置段落。

File: app/code/local/Alanstormdotcom/Helloworld/etc/config.xml

<!-- ... -->
<global>
    <!-- ... -->
    <helpers>
        <helloworld>
            <class>Alanstormdotcom_Helloworld_Helper</class>
        </helloworld>
    </helpers>    
    <!-- ... -->
</global>
<!-- ... -->    

If you’ve spent anytime in the Magento config this should be straight forward. The <helloworld /> tag should be named after your module, and the <class /> tag should contain the base name of all your Helper classes, named with the Magento standard convention

如果已经有配置Magento 的经验,可以直接跳过此段落。【算了还是继续看吧】<helloworld /> 应当在模块后命名,<class />应当包含Helper 类基本的名字,以Magento 的标准约定方式命名:

Packagename_Modulename_Helper

Helper’s are loaded with the global Mage object’s static helper method. The following call (assuming the above config file)

Helper 类加载的是全局变量Mage 对象的静态 helper方法。以下调用(假定以下配置文件)

Mage::helper('helloworld/foo');

将会调用

app/code/local/Alanstormdotcom/Helloworld/Helper/Foo.php
class Alanstormdotcom_Helloworld_Helper_Foo

Magento also has the concept of a default Helper for a module. If you provide the Helper class with only the module name

Magento默认模块有一个默认的Helper类,如果你提供的Helper类只有模块名字:

Mage::helper('helloworld');

it will look for a data Helper located at

app/code/local/Alanstormdotcom/Helloworld/Helper/Data.php
class Alanstormdotcom_Helloworld_Helper_Data ...

That means the following two calls are equivalent.

这意味着以下两个调用是等价的:

Mage::helper('helloworld');
Mage::helper('helloworld/data');

Finally, we need to add the actual Helper class. Add the following file, and you’ll be good to go.

最后,我们需要添加的当前的Helper类,添加一下代码到文件:

File: app/code/local/Alanstormdotcom/Helloworld/Helper/Data.php
class Alanstormdotcom_Helloworld_Helper_Data extends Mage_Core_Helper_Abstract
{
}   

With all this done, clear your Magento cache and reload the System admin. Your error message should be gone, but your new tab is still missing.

操作完以上后,清空缓存并刷新页面,错误信息会消失,但是tab还是空的。

Note: If you’re curious about the kind of things a helper can do for you, checkout the Mage_Core_Helper_Abstract class for a list of useful methods that all helpers will have.

备注:如果你有兴趣了解各种helper可以做的事情,你可以检查Mage_Core_Helper_Abstract类去找出所有helper有的有用的方法。

Adding A New Section

The Helper interlude out of the way, our next step is figuring out why our configured Tab isn’t showing up. Each Tab has a number of sections. For example, the Advanced tab has (by default) an Admin, System, Advanced, and Developer section.

Helper类的事情讲完了,我们下一步解决为什么配置的tab没有显示。每一个tab都有几个小分类,比如默认的Advanced有Admin, System, Advanced, and Developer等小分类。

If a Tab is configured with no sections, it won’t show up. Let’s fix this by adding a <section /> node to our system config

如果Tab设置成没有小分类,它不会显示,添加<section /> 标签在system.xml中来修复此问题:

Location: app/code/local/Alanstormdotcom/Helloworld/etc/system.xml
<config>
    <tabs>
        <helloconfig translate="label" module="helloworld">
            <label>Hello Config</label>
            <sort_order>99999</sort_order>
        </helloconfig>
    </tabs>    
    <sections>
        <helloworld_options translate="label" module="helloworld">
            <label>Hello World Config Options</label>
            <tab>helloconfig</tab>
            <frontend_type>text</frontend_type>
            <sort_order>1000</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>1</show_in_store>                    
        </helloworld_options>
    </sections>        
</config>

There’s some familiar nodes in this new configuration section, as well as a few new faces.

这里有些熟悉的标签这新的配置代码段落,当然也有新面孔。

What is a <helloworld_options/>?

Similar to the <helloconfig /> tag above, this in a arbitrary name that’s used to identify your new section.

<helloconfig />标签一样,这是一个任意定义的名字用来标识新的小分类。

What is a <label />?

A label defines the display value used in the HTML interface for your new section.

标签用来定义显示在HTML界面的名称。

What is a <tab />?

This identifies which Tab your new section should be grouped under. We want our section to show up under our new helloconfig Tab. The helloconfig name comes from the tag used to create the Tab (<helloconfig/>)

这个标识符新的小分类分组在那个Tab下面,我们希望小分类展示在新的Hello Config Tab,这个helloconfig 名字来自与我们创建的Tab (<helloconfig/>)

What is a <frontend_type />?

This one it tricky. <frontend_type /> has meaning in other sections of the configuration (see below), but it doesn’t appear to do anything here. However, sections in the Core modules use this tag, so it’s best to follow the convention, even when you’re not sure what it does.

这一个有点难回答。<frontend_type/> 在配置的其他部分中有意义 (见下文), 但它在这里似乎不起任何作用。但是, 核心模块中的节使用此标记, 因此最好遵循该Magento 约定, 即使您不确定它的用途。

What is a <sort_order />?

Again, <sort_order /> determines where this sections shows up vertically(垂直) compared to other sections in the Tab.

有一次<sort_order /> 决定了这个小分类与其他小分类在这个tab里的垂直顺序。

What is a <show_in_default /><show_in_website /><show_in_store />?

These are boolean config options, with a valid value of 1 or 0. They determine the level of configuration score/granularity(分数/粒度) this section has.

这些是一些布尔值类型的配置选项,可以值只有1或0.这些设置决定此部分的配置xi范围级别。

With our section configured, Let’s head over to System -> Config again (reloading the Admin page often won’t be enough). You should now see your section and tab near the bottom of the left hand navigation. You can add more sections by adding additional nodes to the <sections /> node.

带着我们的此段小分类的配置,再次回到System -> Config (刷新这个admin的页面通常是不行的,可能要推出登录)。你将会看到小分类和Tab出现在左侧导航区块的下方。你可以通过配置<sections />代码添加更多的小分类。

 

Access Control 访问控制

If you click your new section link you’ll be disappointed by the results. A blank admin page will load, and the entire left hand navigation will vanish(烟消云散). That’s because the Adminhtml application can’t find an entry for our new section in the Access Control List (ACL).

如果你点击了你新的小分类,看到结果后你会失望。你个空白的页面将会出现,整个左边的导航区块会消失。这是因为Adminhtml应用程序在ACL(访问控制列表)找不到我们新的小分类的入口。

ACL is a topic all its own, but I’ll try to explain enough here so this doesn’t seem like total magic. This section is optional, and if you’re not interested skip to the end for the magic XML to paste into your config.xml

ACL是一个主题,但是作者准备详尽的解释它,以至于它不会看起来完全就是一个魔术。这个章节是可选阅读的,如果没有兴趣,可以跳转到最后把充满魔术的XML贴到config.xml 里去(那样子就失去作者和翻译的意义了)

There are certain(某些) resources (where resource is a loosely defined term(学术;长期)) that require a user to be authenticated before using them. Resource here is an abstracted(抽象) term. It might be a page in the admin, or it might be access to a certain feature. The Magento team decided that System Config sections should have ACL protection.

有些资源(那些被术语松散定义的)需要用户在使用前被授权。资源在这里是一个抽象概念,可以是admin里第一个page或者是可以进入某些功能的权利。Magento team 决定系统设置章节需要一个ACL保障。

Resources are defined via URI’s. For example, the “web” config section (under the General tab), if defined with a URI of

admin/system/config/web

资源可以用URI来定义,比如系统自带的web设置小分类(在 General tab下),如果一个资源被以下URI定义:

Our helloworld_options section would have a URI of

admin/system/config/helloworld_options

那我们的小分类 helloworld_options 应该用URI这样定义

The Admin application (often called Adminhtml) is built using the same framework as the store application (the store application is often called the frontend application). In Adminhtml action controllers, whenever a user needs to access a resource protected by ACL, the Adminhtml developer must

Admin应用程序(一般叫做Adminhtml)是和store应用程序(通常叫做 frontend 应用程序)一样的框架架构。在Adminhtml的操作控制器中,每当用户需要去访问ACL保护的资源时,Adminhtml需要以下操作:

  1. Derive a URI for whatever resource the end-user is trying to access
  2. Check that URI against the ACL system, which will determine if the
    logged in user has the right privileges that particular resource
  3. If the user does have the correct privileges, proceed. If they don’t, boot them
    or do something appropriate (like stop rendering the navigation and content areas)

1.为准备访问资源的终端用户分配一个RUI.

2.检查URI和ACL是否匹配,这将决定了登录的用户是对特定的资源有正确的权限。

3.如果用户有正确的权限,继续处理。如果没有,引导他们或者做一个正确的事情(比如停止加载导航和内容区块)

For those interested, this is done for the System Config sections in the _isSectionAllowedmethod in the following controller

app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php

如果想了解更多,在下面列出的控制器中,_isSectionAllowed 这个方法是为系统设置章节完成的。(翻译的不是特别好)

If you go to System -> Permissions -> Roles, add click the Add a new role button, you can see a graphical tree representation of all the Role Resources defined in your Magento install.

如果你在后台的 系统–>权限和角色–>角色 中,点击新增一个角色,你可以看到一个树形图形表示所有在Magento 已经安装的 角色资源。

 

Adding an ACL role (添加一个访问控制列表的角色)

That out of the way, we need to define an ACL resource for our new section. You only need to do this if you’re adding a new section. If you’re adding config options to an existing section you don’t need to touch ACL.

.叉开一个话题,我们需要为我们的新章节(小分类)定一个一个ACL资源。你只需要做这些当你在添加一个新的的章节时。如果你为一个已经存在的章节添加控制选项,你不需要接触到ACL.

In your module’s config.xml, add the following section

在你的模块的 config.xml文件,添加一下代码

File: app/code/local/Alanstormdotcom/Helloworld/etc/config.xml    
<config>    
    <!-- ... -->
    <adminhtml>
        <acl>
            <resources>
                <admin>
                    <children>
                        <system>
                            <children>
                                <config>
                                    <children>
                                        <helloworld_options>
                                            <title>Store Hello World Module Section</title>
                                        </helloworld_options>
                                    </children>
                                </config>
                            </children>
                        </system>
                    </children>
                </admin>
            </resources>
        </acl>
    </adminhtml>
    <!-- ... -->
</config>

Yes, that’s a mouthful. Let’s break it down a bit. First off, all defined resources are contained in the following node structure.

是的,这是一大段代码,让我我们分解理解它。第一,我们定义的资源包含以下节点代码结构:

<adminhtml>
    <acl>
        <resources>
        </resources>
    </acl>
</adminhtml>

Within resource, each descending node represents a URI portion. So, this far down

在资源内部,每个降序节点代码代表一个URI 部分,所以一下的代码

<admin>
    <children>
        <system>
            <children>

gives us a URI of

给出了URI的一部分

admin/system

If you follow that all the way down, you get to the node for our config

如果继续往下看完所有,你可以看到我们设置的节点代码:

<helloworld_options>
    <title>Store Hello World Module Section</title>
</helloworld_options>

Title is what will show up in the Permissions admin.

title是现在后台 权限和角色设置下的名字。

With this in your config and your Magento cache cleared, you should now be able to view your config section. You may need to log out of the application and back into to see it. The Admin has some additional caching beyond the standard Magento cache that I haven’t been able to track down. If(typo) you log out, log back in, and navigate to your section you should now see a blank config page titled “Hello World Config Options”.

操作完上面的射中后并且清空Magento 缓存,你会看到你的设置的 小分类,你需要登出登录Magento 才能看到效果。因为Admin会有一些附加的缓存,超越了Magento 缓存里,作者找不到他们。如果你登出在登入,导航部分的你的小分类将会展示一个有着‘Hello World Config Options’标题的空白设置页面。

 

Adding Groups (添加分组)

So, we now have a blank config section. Our next step is adding a group.

到此,我们已经有了一个空白的设置小分类。我们的下一步是添加一个分组(就是点击小分类后,右侧栏位显示的不同设置的可以点击折叠或展开的,分组显示)

Groups are used to group together different configuration options, and are displayed in the Magento admin with a pop-open widget. For example, in a stock install the Advanced section has a single group named “Disable modules output”. Let’s create a group named “messages” by adding a <groups /> node to our config, nested within the <sections> node.

分组是用来分组聚集不用的配置选项,用来展示Magento 管理后台(admin不知道翻译的对不对)弹出展示的部件。举个例子,在后台设置 Advanced 章节只有有一个单独的分组叫做 ‘Disable modules output’(禁止模块输出)【用来控制插件的disabled或者enbale】,

让我们一起创建一个叫‘messages’的分组,用在config里添加一个<groups /> 的节点代码,把它嵌入<sections>的节点代码中(system.xml)。

Location: app/code/local/Alanstormdotcom/Helloworld/etc/system.xml
<config>
    <tabs>
        <helloconfig translate="label" module="helloworld">
            <label>Hello Config</label>
            <sort_order>99999</sort_order>
        </helloconfig>
    </tabs>    
    <sections>
        <helloworld_options translate="label" module="helloworld">
            <label>Hello World Config Options</label>
            <tab>helloconfig</tab>
            <frontend_type>text</frontend_type>
            <sort_order>1000</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>1</show_in_store>
            <groups>
                <messages translate="label">
                    <label>Demo Of Config Fields</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>1</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>                
                </messages>
            </groups>
        </helloworld_options>
    </sections>        
</config>

Each tag within this node is analogous(类似) to the tags from the top level <section /> node.

If you reload your page, you’ll now see an empty pop-open box with the title “Demo Of Config Fields”.

此节点代码每一个标记都类似于顶层<section /> 节点代码的标记。

如果你刷新你的设置页面,你将会看到一个空的弹出显示的窗口,标题是‘Demo Of Config Fields’

Adding Config Fields (设置项)

Finally, we need to add our individual configuration fields. You’ll do this by adding a <fields /> node to your <messages /> node. We’ll start with a field name “hello_message”.

最后我们需要为添加单个的设置项,需要添加一个<fields />到<messages /> 代码段。我们把hello_message最为设置项的名字。

<!-- ... -->
<messages translate="label">
    <label>Demo Of Config Fields</label>
    <frontend_type>text</frontend_type>
    <sort_order>1</sort_order>
    <show_in_default>1</show_in_default>
    <show_in_website>1</show_in_website>
    <show_in_store>1</show_in_store>                
    <fields>
        <hello_message>
            <label>Message</label>
            <frontend_type>text</frontend_type>
            <sort_order>1</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>1</show_in_store>                    
        </hello_message>
    </fields>                    
</messages>
<!-- ... -->    

Again, fields within your new <hello_message> node are analogous to the other nodes you’ve added so far. However, this time <frontend_type>text</frontend_type> actually does something useful by letting the system know what kind of form element you want. Reload your page, and you should now see an individual text field in the popup box.

同样的,我们新的<hello_message>代码段和其他已经添加的代码段是类似的。然而,这次的<frontend_type>text</frontend_type>实际上起到了一些作用:告诉system我们需要什么样的表格元素。刷新载入页面,我们可以看到一个新的文本设置醒在弹出的页面【应该就是鼠标点击之后看到】

Once all this configuration information is in place, you’re done. No code is needed to save/load/update your config value. The system handles that all for you.

一旦这些设置信息准备就绪了,我们也就成功了。不要代码来保存/上传/更新我们的配置设定值。system会帮我们处理。

You’re not limited to text fields. Let’s add a field called <hello_time/>

我们不限于文本选项,让我添加一个选项叫做 <hello_time/>【还是在system.xml里】

<!-- ...-->
<fields>
    <hello_message>
        <label>Message</label>
        <frontend_type>text</frontend_type>
        <sort_order>1</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>1</show_in_website>
        <show_in_store>1</show_in_store>                    
    </hello_message>
    <hello_time>
        <label>Time to Say Hello</label>
        <frontend_type>time</frontend_type>
        <sort_order>1</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>1</show_in_website>
        <show_in_store>1</show_in_store>                    
    </hello_time>        
</fields>
<!-- ... -->

Notice that the main difference here is the

<frontend_type>time</frontend_type>

留意此处有一个不同的地方【frontend_tyoe】标签

Reload your page, and you’ve now got a config field for saving a time value.

刷新页面,这时候我们有了ige保存时间数值的选项。

Many, but not all, of the built in Varien data form classes (lib/Varien/Data/Form/Element) are supported. The <frontend_type /> tag acts as an identifier for a factory-ish pattern. Let’s try changing our hello message to a select field.

经常,但不是每一次,被来自(lib/Varien/Data/Form/Element)的Varien data的类是支持的【没看懂,先直译】,这些<frontend_type />的标签实际是一个工厂模式的标识符。让我尝试修改我们的 hello message变成一个select设置选项。

<!-- ... -->
<hello_message>
    <label>Message</label>
    <frontend_type>select</frontend_type>
    <sort_order>1</sort_order>
    <show_in_default>1</show_in_default>
    <show_in_website>1</show_in_website>
    <show_in_store>1</show_in_store>                    
</hello_message>
<!-- ... -->

If you reload your page you’ll see that you have an HTML select, but without any values. We’re going to need to add a source model to our field definition. Try this instead.

如果你刷新页面,你将可以看到一个html选择器,但是没有任何选项值。我们现在为选项定义【没翻译好】增加一个资源模型。尝试用一下代替上面代码

<hello_message>
    <label>Message</label>
    <frontend_type>select</frontend_type>
    <!-- adding a source model -->
    <source_model>helloworld/words</source_model> 
                           
    <sort_order>1</sort_order>
    <show_in_default>1</show_in_default>
    <show_in_website>1</show_in_website>
    <show_in_store>1</show_in_store>                    
</hello_message>    

The <source_model> element defines a URI for a Model class that we’ll use to provide default values for the select. This means we’ll need to make sure that our module config.xml has its models section setup

<source_model>元素定义了一个Model类的URI,那些我们用来给selec提供一个默认值。这一位置,我们要保证,我们的模型有一个models片段在config.xml

File: app/code/local/Alanstormdotcom/Helloworld/etc/config.xml
<config>    
    <!-- ... -->
    <global>
    <!-- ... -->
        <models>
            <!-- ... -->
            <helloworld>
                <class>Alanstormdotcom_Helloworld_Model</class>
            </helloworld>    
            <!-- ... -->
        </models>
    </global>
</config>

See the Magento Models and ORM Basics and the Class Instantiation Abstraction and Autoload article if you’re not sure what’s going on in that config.

有两篇帮助文章,用来搞懂config文件的作用

So, with that in place, if we reload our page after a cache clearing, we’ll end up with an Error something like

做到这一步,清空缓存重新加载页面,会看到下面这种的错误提示:

Warning: include(Alanstormdotcom/Helloworld/Model/Words.php)

That’s because we haven’t defined our source Model class. Let’s do that now.

这是因为我们还没有定义资源Model的类,让我们来添加它:

Note: If the warning you’re getting uses a Mage/Helloworld/... path, that means you haven’t setup your <model /> section correctly in config.xml.

注意:如果错误提示是Mage/Helloworld/... 的路径,这说明你还没有在config.xml里正确地配置<model />

To define our source Model, add the following file

为了定义我的资源Model,添加一下文件:

File: app/code/local/Alanstormdotcom/Helloworld/Model/Words.php
class Alanstormdotcom_Helloworld_Model_Words
{
    public function toOptionArray()
    {
        return array(
            array('value'=>1, 'label'=>Mage::helper('helloworld')->__('Hello')),
            array('value'=>2, 'label'=>Mage::helper('helloworld')->__('Goodbye')),
            array('value'=>3, 'label'=>Mage::helper('helloworld')->__('Yes')),            
            array('value'=>4, 'label'=>Mage::helper('helloworld')->__('No')),                        
        );
    }

}

Source Models are classes that respond to a method named toOptionsArray. This method should return an array of values that are used to populate the default values of our form elements (which descend from the Varien_Data_Form_Element_Abstract hierarchy). For a select element, this means defining a set of value/label pairs. In the above example, we’re passing our labels through the Helper’s translation method (__). While not necessary, this is always a good practice. You never know when you’re going to get big in Japan!

资源Model使用来回应叫做toOptionsArray这个方法的类。此方法是用来返回数组的值,哪些我们用来填充表格元素的默认值(继承于Varien_Data_Form_Element_Abstract 结构)。对一个select元素而言,这以为只定义了一对值/标签。在上面的例子中,我们传递我们的标签通过Helper的翻译方法  (__) 。虽然不是必要的,但仍然是一个好的经验。这句话不翻译了,没有实际意义。

Reload your page, and you should have a working select field.

刷新页面,我们可以看到select字段可以正常工作了。

For those interested in the Magento internals, the initFields method in the following class is where the source Model is used to set the field’s value

app/code/core/Mage/Adminhtml/Block/System/Config/Form.php

对此感兴趣的可以在下面文件可以了解Magento内部代码,initFields这个方法是我们资源Model用来设定字段值【待改进】。

Adding to Existing Config Sections/Groups(添加到已经存在的分类和分组)

In addition to setting up your own config Tabs and sections, you can add to an existing System Config section by adding appropriate sections to your own system.xml file.

除了设置我们自己的Tabs和小分类,我们还可以添加一个已经旬在的System Config的章节里去,做法是在system.xml里添加合适的代码段。

For example, if you add the following

File: app/code/local/Alanstormdotcom/Helloworld/etc/system.xml
<config>
    <!-- ... -->
    <sections>
        <!-- ... -->
        <general>
            <groups>
                <example>
                    <label>Example of Adding a Group</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>1</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>                    
                </example>
            </groups>
        </general>
        <!-- ... -->
    </section>
</config>

you’ll have a new group in the general Tab called “Example of Adding a Group”.

你讲会得到一个新的group的叫做Example of Adding a Group,在普通的Tab里。

Retrieving Values(检索值)

We’ve covered how to setup forms for creating configuration values. To retrieve values in our client applications and modules, we’ll use the getStoreConfig method on the global Mage object. For example, to grab the value of the select we created above, we’d use

我们已经了解如何去设置一个表格彬彬个创建设置的值。为了在客户程序和模块里索引值,我们将会全局Mage 对象在使用getStoreConfig 返回广发。例如,为了抓去我们上面创建select的值,我们应当如此操作:

Mage::getStoreConfig('helloworld_options/messages/hello_message');

The getStoreConfig method accepts a single parameter that’s a URI in the following format

getStoreConfig 发发接受一个单个的参数,所以URI会这样的格式

section_name/group_name/field_name

You can also grab an array of all your config values by specifying a partial path

你也可以用特定的部分路径去扎un去我们设置值的数组形式

Mage::getStoreConfig('helloworld_options/messages');
Mage::getStoreConfig('helloworld_options');

Finally, if you need to grab a value for a store that isn’t the store being used by the current session, getStoreConfig accepts a second parameter, the store ID

最后,如果抓取的store的值不是希望的,可以在getStoreConfig 添加第二个参数,store ID

Mage::getStoreConfig('helloworld_options',1);

Wrapup(提要)

We started off wanting to setup some System Config sections, and ended up exploring Helper classes, Access Control Lists, and the Varian Form hierarchy. In addition to what we covered above, it’s possible to create System Config options that use custom frontend and backend Models, which I’ll try to cover in a latter article.

我们从想在System Config添加一个Tba开始,讲到了 Helper 的类,访问控制列表ACL 和Varian的表格层次结构。此外我们上面所包括的,如何在System Config 选项里使用我们自定义的前台和后台的Modles,我们将在下一篇文章讲到。

You can download the complete module for this article here.

 

Magento cron job not work on 1.9.1的问题

magento的cron job问题,从一开始学习的时候,也缠绕过我,很难解决。

最近又遇到的了一个问题,mg 1.9.1 安装的了一些安全补丁patch之后,cron job在AOE Scheduler extension(这真的是一个好用的插件,文章尾部会有下载连接)的heartbeat检测超过一个小时没运行。

解决办法主要参考这里源链接

1.关掉Aschroder SMTP 插件的Queue Usage 。

思路清奇,不过在1.x版本的magento谁又没有安装过呢。

2.根目录的cron.php 增加一行

$isShellDisabled = true;

47行左右。

3.xtento 给出的指导wiki源链接 (值得翻译的一篇文章)

在cron tab 使用

wget -O /dev/null -q http://www.YOURDOMAIN.com/PATH_TO_MAGENTO/cron.php > /dev/null

 

五分钟一次 */5 * * * *

 

我是第三种解决问题,当然第一种和第二种也都调整了。

有时间设置No.1 No.2回原值,试试看。

 

关于magento cron job的基础设置:

crontab */5 * * * * /usr/bin/php -f /home/yourdomainname/public_html/cron.php

水水哥的文章 源链接

SSH 查看 cron tab

crontab -l     //列出

crontab -e    //编辑

 

记得看到有一篇文章说某个Patch修复安全问题后,会导致cron job出问题,应该是第二种方法解决。

 

下载链接:

Aoe_Scheduler-0.3.2 百度云

magento order number 自定义

主要涉及2个表,eav_entity_type和eav_entity_store

SELECT entity_type_id,entity_type_code,increment_pad_length FROM `eav_entity_type` WHERE entity_type_code =’order’;

SELECT * FROM `eav_entity_store`;

一般order很长,第一个increment_pad_length(eav_entity_type)是订单号码除了increment_prefix(eav_entity_store表)的长度。

increment_last_id(eav_entity_type)是系统组后一个订单号码


如果系统已经有了订单,存在了订单号码,可以sql语句更新

参考:

 

mysql_connect(“localhost”,$user,$psw);

mysql_select_db($db);
$store_id=1;
$prefix=’ABC’;
$start_num=’10001′;

$rs=mysql_query(“SELECT * FROM `sales_flat_order` a WHERE a.`store_id`='”.$store_id.”‘”);

while ($rw=mysql_fetch_array($rs))
{
$order_id=$rw[‘entity_id’];
$order_num = $rw[‘increment_id’];
$order_num_new=$prefix.$start_num;
$start_num++;

echo $order_id.'<br/>’;
echo $order_num.'<br/>’;
echo $order_num_new.'<br/>’;

mysql_query(“update `sales_flat_order` set `increment_id`='”.$order_num_new.”‘ where `increment_id`='”.$order_num.”‘”);
mysql_query(“update `sales_flat_order_grid` set `increment_id`='”.$order_num_new.”‘ where `increment_id`='”.$order_num.”‘”);

mysql_query(“update `sales_flat_creditmemo` set `increment_id`='”.$order_num_new.”‘ where `order_id`='”.$order_id.”‘”);
mysql_query(“update `sales_flat_creditmemo_grid` set `increment_id`='”.$order_num_new.”‘,`order_increment_id`='”.$order_num_new.”‘ where `order_id`='”.$order_id.”‘”);
mysql_query(“update `sales_flat_invoice` set `increment_id`='”.$order_num_new.”‘ where `order_id`='”.$order_id.”‘”);
mysql_query(“update `sales_flat_invoice_grid` set `increment_id`='”.$order_num_new.”‘,`order_increment_id`='”.$order_num_new.”‘ where `order_id`='”.$order_id.”‘”);
mysql_query(“update `sales_flat_shipment` set `increment_id`='”.$order_num_new.”‘ where `order_id`='”.$order_id.”‘”);
mysql_query(“update `sales_flat_shipment_grid` set `increment_id`='”.$order_num_new.”‘,`order_increment_id`='”.$order_num_new.”‘ where `order_id`='”.$order_id.”‘”);
}

magento compiler 后Class ‘Aschroder_SMTPPro_Model_Mysql4_Setup’ not found and Mage registry key “_singleton/dewatasoft_changeattributeset/observer” already exists 错误

错误的原因是手动运行后台的tool–>compiler 设置了enable有些插件没办正确的编译,比如smtppro和changeattributeset这个两个。

解决问题的关键是,关闭compiler。当然这个时候还能登陆后台,去手动关闭是最快的解决办法了。

进入不了后台,网上推荐有两种办法:

1.FTP暂时关闭插件

具体为登陆ftp之后/app/etc/modules/文件夹下重命名对应的插件xml,刷新缓存,就可以登陆后台,再进行操作。

2.SSH进入,关闭compiler

登陆网站所在根目录后 ,执行php -f compiler.php disable

其他的命令包含php -f compiler.php compile 和php -f compiler.php enable

以上内容参考:

stackexchange上Murtuza Zabuawala的回答

stackexchange上Mayers的回答

还有一个值得阅读的帖子

Mage registry key “_singleton/tax/observer” already exists

Magento 后台CMS page 404错误,Error 404 Page Not Found on CMS-page of Magento

登陆后台 点击cms–page 弹出Error 404 Page Not Found 错误页面。如果文件没有丢失的话,是因为删除了store view或者是store的问题。

解决办法,mysql查询:

DELETE FROM cms_page_store
WHERE store_id NOT IN (SELECT store_id FROM core_store);

已经存在的cms page里有些scope指定了store viewsh或store

先删除store view,这里就会出现这个错误。

参考链接:

mdnsolutions.com/

PHP7环境安装magento报错Fatal error: Uncaught Error: Function name must be a string in \app\code\core\Mage\Core\Model\Layout.php:555 Stack trace: #0

magento安装在php7以上的环境是时候,安装或运行的时候有个错误:

Fatal error: Uncaught Error: Function name must be a string in C:\xampp\htdocs\magento\app\code\core\Mage\Core\Model\Layout.php:555 Stack trace: #0 C:\xampp\htdocs\magento\app\code\core\Mage\Core\Controller\Varien\Action.php(390): Mage_Core_Model_Layout->getOutput() #1 C:\xampp\htdocs\magento\app\code\core\Mage\Install\controllers\WizardController.php(120): Mage_Core_Controller_Varien_Action->renderLayout() #2 C:\xampp\htdocs\magento\app\code\core\Mage\Core\Controller\Varien\Action.php(418): Mage_Install_WizardController->beginAction() #3 C:\xampp\htdocs\magento\app\code\core\Mage\Core\Controller\Varien\Router\Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('begin') #4 C:\xampp\htdocs\magento\app\code\core\Mage\Core\Controller\Varien\Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http)) #5 > C:\xampp\htdocs\magento\app\code\core\Mage\Core\Model\App.php(354): Mage_Core_Controller_Varien_Front->dispatch() #6 C:\xampp\htdocs\magento\app\Mage.php(683): Mage_Core_Mo in C:\xampp\htdocs\magento\app\code\core\Mage\Core\Model\Layout.php on line 555

解决方式是:

本地化app\code\core\Mage\Core\Model\Layout.php文件,

找到

$out .= $this->getBlock($callback[0])->$callback[1]();

改成

$out .= $this->getBlock($callback[0])->{$callback[1]}();

清空cache和session就可以。

 

因为在PHP7里需要声明$callback这个变量。

参考连接:

stackexchange 这个页面有给出其他几根收影响的文件。

stackoverflow

magento批量更新库存,价格,客户组价格bulk update Group Price

批量更新库存,价格等简单属性的字段值,magento自带的import/export就可以实现。

Group Price是没有自带功能或者免费插件可以实现批量更新的字段。(其实tier price也是)

下面是整理出可以用的脚本文件,收集整理来源与网络。

主要参考的有:

https://community.magento.com/t5/Programming-Questions/update-group-prices-from-CSV-file-programmatically/m-p/43281#

stackoverflow准备用SOAP API

API方法二

 

对SOAP不是很熟悉,还是采用更直接的PHP脚本:

<?php
define('MAGENTO', realpath(dirname(__FILE__))); 
 require_once MAGENTO . '/app/Mage.php'; 
 Mage::setIsDeveloperMode(true);
ini_set('display_errors', 1);
 umask(0); 
 Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); 
 $count = 0; 
 

 set_time_limit(0);
ini_set('memory_limit','1024M');
 
/***************** UTILITY FUNCTIONS ********************/
function _getConnection($type = 'core_read'){
    return Mage::getSingleton('core/resource')->getConnection($type);
}
 
function _getTableName($tableName){
    return Mage::getSingleton('core/resource')->getTableName($tableName);
}
 
function _getAttributeId($attribute_code = 'price'){
    $connection = _getConnection('core_read');
    $sql = "SELECT attribute_id
                FROM " . _getTableName('eav_attribute') . "
            WHERE
                entity_type_id = ?
                AND attribute_code = ?";
    $entity_type_id = _getEntityTypeId();
    return $connection->fetchOne($sql, array($entity_type_id, $attribute_code));
}
 
function _getEntityTypeId($entity_type_code = 'catalog_product'){
    $connection = _getConnection('core_read');
    $sql        = "SELECT entity_type_id FROM " . _getTableName('eav_entity_type') . " WHERE entity_type_code = ?";
    return $connection->fetchOne($sql, array($entity_type_code));
}
 
function _checkIfSkuExists($sku){
    $connection = _getConnection('core_read');
    $sql        = "SELECT COUNT(*) AS count_no FROM " . _getTableName('catalog_product_entity') . " WHERE sku = ?";
    $count      = $connection->fetchOne($sql, array($sku));
    if($count > 0){
        return true;
    }else{
        return false;
    }
}
 
function _getIdFromSku($sku){
    $connection = _getConnection('core_read');
    $sql        = "SELECT entity_id FROM " . _getTableName('catalog_product_entity') . " WHERE sku = ?";
    return $connection->fetchOne($sql, array($sku));
}
 
function _updateStocks($data){
    $connection     = _getConnection('core_write');
    $sku            = $data[0];
    $newQty         = $data[1];
    $productId      = _getIdFromSku($sku);
    $attributeId    = _getAttributeId();
 
    $sql            = "UPDATE " . _getTableName('cataloginventory_stock_item') . " csi,
                       " . _getTableName('cataloginventory_stock_status') . " css
                       SET
                       csi.qty = ?,
                       csi.is_in_stock = ?,
                       css.qty = ?,
                       css.stock_status = ?
                       WHERE
                       csi.product_id = ?
                       AND csi.product_id = css.product_id";
					   
					   ;
    $isInStock      = $newQty > 0 ? 1 : 0;
    $stockStatus    = $newQty > 0 ? 1 : 0;
    $connection->query($sql, array($newQty, $isInStock, $newQty, $stockStatus, $productId));
}


function _updatePrices($data){
	
	
    $connection     = _getConnection('core_write');
    $sku            = $data[0];

	$entity_id = _getIdFromSku($sku);
	
	$newPrice1       = $data[2];
     $newPrice2       = $data[3];
     $newPrice4       = $data[4];
     $newPrice5       = $data[6];
	
	$id_newPrice1 = '4' ;
	 $id_newPrice2 = '5';
	 $id_newPrice4='6' ;
	 $id_newPrice5 = '3';
	 
	 $combind_groupid_groupprice = array(
											array($newPrice1 ,$id_eco_3pb),
											array($newPrice2,$id_newPrice2),
											array($newPrice4,$id_newPrice4),
											array($newPrice5 ,$id_newPrice5 )
											);
	
		foreach ($combind_groupid_groupprice as $groupid_groupprice){
    /*  catalog_product_entity_group_price table */
		if($groupid_groupprice[0] > 0){
		
		$sql_price_one = "INSERT INTO " . _getTableName('catalog_product_entity_group_price') . " 
		(entity_id,all_groups,customer_group_id,value,website_id)
							VALUES (?,?,?,?,?) ON DUPLICATE KEY UPDATE 
					  value = ?,customer_group_id =?";
		$connection->query($sql_price_one, array($entity_id,0,$groupid_groupprice[1],$groupid_groupprice[0],0,
									$groupid_groupprice[0],$groupid_groupprice[1]));
		
		}
		else{}
		
		}
		
}

/***************** UTILITY FUNCTIONS ********************/
 
$csv                = new Varien_File_Csv();
$data               = $csv->getData(MAGENTO . '/var/import/updateGP.csv'); //path to csv
array_shift($data);
 
$message = '';
$count   = 1;
foreach($data as $_data){
    if(_checkIfSkuExists($_data[0])){
        try{
            //_updateStocks($_data);  //update qty
			
			_updatePrices($_data);
            $message .= $count . '> Success:: Qty (' . $_data[1] . ') of Sku (' . $_data[0] . ') has been updated.
<br />';
 
        }catch(Exception $e){
            $message .=  $count .'> Error:: while Upating  Qty (' . $_data[1] . ') of Sku (' . $_data[0] . ') => '.$e->getMessage().'
<br />';
        }
    }else{
        $message .=  $count .'>>> Error:: Product with Sku (' . $_data[0] . ') does\'t exist.
<br />';
    }
    $count++;
}
echo $message;

 

csv文件放在对应的path然后第一列是sku,第二列是qty,第三group pirce,注意id的对应关系。

tier price大致类似,找到对应数据库就好。

在magento论坛里的增加后面几个保存价格index特tmp的表格,我没有些,还是交给自带的index更新吧

 

XAMPP magento Fatal error: Uncaught Error: Function name must be a string in

环境是win7 64bit & XAMPP v3.2.2 & Magento 1.9.1.0

全新官方压缩包打开安装时,有错误

XAMPP Fatal error: Uncaught Error: Function name must be a string in 。。。

\app\code\core\Mage\Core\Model\Layout.php line 555

然后在 stackoverflow 找到了答案

$out .= $this->getBlock($callback[0])->$callback[1]();

local化之后,改成

$out .= $this->getBlock($callback[0])->{$callback[1]}();

 

同样答题者,给出一个连接关于mangento和PHP7 的兼容问题。

 

 

 

Apache Service detected with wrong path ON XAMPP upgrade V3.2.2

XAMPP更新的时候,如果已经老版本存在的话,需要修改环境变量的PATH,还有可能需要修改注册表

进入注册表—>

点击HKEY_LOCAL_MACHINE—->system—->currentControlSet—->Services—->找到Apache2.4,
修改ImagePath

保存退出,重启XAMPP

 

此外,新版V3.2.2安装时候,提示关闭windows的UAC

在控制面板–用户账户–更改用户账户设置 

滑块拉到最低,保存,重启。

magento addAttributeToFilter 的方法和AND OR使用

文章整理来自网络,主要参考有:

http://fishpig.co.uk/magento/tutorials/addattributetofilter/

http://stackoverflow.com/questions/5301231/addattributetofilter-and-or-condition-in-magentos-collection


主要的句子

$_products = Mage::getResourceModel('catalog/product_collection')
   ->addAttributeToSelect(array('name', 'product_url', 'small_image'))
   ->addAttributeToFilter('sku', array('like' => 'UX%'))
    ->load();

 

addAttributeToSelect没什么要说的,只要筛选正确的数据表有的字段就可以

 

eq的两种写法写法

$_products->addAttributeToFilter('status', array('eq' => 1)); // Using the operator
$_products->addAttributeToFilter('status', 1); // Without using the operator

如果上面有不同的筛选,就相当于AND了,OR的写法:

// OR QUERY

$collection->addAttributeToFilter(array(

array(

'attribute' => 'sku','like' => '%ch%'),

array(

'attribute' => 'status','eq' => '1')

));

 

noequal

$_products->addAttributeToFilter('sku', array('neq' => 'test-product'));

 

$_products->addAttributeToFilter('sku', array('like' => 'UX%'));//like

 

$_products->addAttributeToFilter('sku', array('nlike' => 'err-prod%'));//nolike

 

$_products->addAttributeToFilter('id', array('in' => array(1,4,98)));//in

 

$_products->addAttributeToFilter('id', array('nin' => array(1,4,98))); //not in

 

$_products->addAttributeToFilter('description', array('null' => true));  //null

 

$_products->addAttributeToFilter('description', array('notnull' => true)); //not mull

 

$_products->addAttributeToFilter('id', array('gt' => 5));//Greater Than - gt

 

$_products->addAttributeToFilter('id', array('lt' => 5)); //Less Than - lt

 

$_products->addAttributeToFilter('id', array('gteq' => 5)); //Greater Than or Equals To- gteq

 

$_products->addAttributeToFilter('id', array('lteq' => 5)); //Less Than or Equals To - lteq

 

排错方法

// Method 1
Mage::getResourceModel('catalog/product_collection')->load(true);

// Method 2
$collection = Mage::getResourceModel('catalog/product_collection')

echo $collection->getSelect();

 

 

mysql语句根据sku 查询magento的产品名

答案来自http://stackoverflow.com/questions/5323102/magento-products-import-from-database-using-sql-query

第一步,找出各个属性对应的attribute_code

select attribute_code, attribute_id, backend_type from eav_attribute
    where entity_type_id = (select entity_type_id from eav_entity_type where entity_type_code = 'catalog_product')
      and attribute_code in ('name', 'url_path', 'price', 'image', 'description', 'manufacturer');

一般结果为

+----------------+--------------+--------------+
| attribute_code | attribute_id | backend_type |
+----------------+--------------+--------------+
| description    |           61 | text         |
| image          |           74 | varchar      |
| manufacturer   |           70 | int          |
| name           |           60 | varchar      |
| price          |           64 | decimal      |
| url_path       |           87 | varchar      |
+----------------+--------------+--------------+

对应的name是60

第二步

select p.sku, p.entity_id, n.value name
    from catalog_product_entity p
    join catalog_product_entity_varchar n on n.entity_id = p.entity_id
  where n.attribute_id = 60 AND p.sku='001-C';

可以得出结果了,其他属性自己添加查询

再次感谢Joseph Mastey的回答