探索中小企業信息化最佳解決方案

企業郵局的服務網上一直就有,不過大部分都是收費的,而且價格不菲。以前據說Sogou的企業郵局免費,而且很好用,不過早就不能申請了:( ,找來找去,發現Google Apps提供免費的企業郵局服務,而且基於Gmail的郵件系統,品質也值得信任。經過一段時間的準備,終於把全公司的郵箱遷移到了Google Apps了。

使用了一段時間以後,發現Google Apps不僅僅是個企業郵局而已。使用的好的話,甚至可以替代OA來作為企業辦公自動化的平台!尤其是對中小企業,辦公自動化和信息化無非就是實現郵箱系 統、信息共享、信息發佈和簡單的工作流,而這些都可以通過Google Apps來進行實現!更加美妙的是,你不需要去考慮空間、維護、備份、安全等繁瑣的問題,一切都有Google幫你搞定!

google_apps6464full

googleappsgraphic

言歸正傳,總覺得網上關於Google Apps的大部分也就是內容僅僅是介紹一些如何註冊和配置郵箱而已,其餘Google Apps的使用介紹太少了。也許牛人們覺得Gmail,Google Doc,Google Calendar等應用太簡單,不值得說吧。但就我一段時間使用Google Apps來說,雖然Google Apps總體來說是由Gmail,Doc,Caledar等等應用組成的,但是作為Google Apps的團隊來用,還是有一些不太一樣的地方。這裡,就把我這段時間使用的Google Apps 經驗和技巧簡單總結一下。希望對正在尋找企業郵箱、信息系統、辦公自動化解決方案的中小企業有點用處。(僅限免費的標準版服務的介紹)

一、 註冊和登錄

關於Google Apps註冊的文章網上有很多了。 這裡我隨便找了兩個比較詳細的鏈接。

http://chinaz.com/Webbiz/Free/062510I62007.html

http://wmblog.yo2.cn/articles/google-apps.html

可惜的是,.cn結尾的域名始終無法註冊。(曾經有把.cn寫成.CN跳過驗證可以註冊的方法,現在也都不靈了)連用.com等國際域名註冊的時候,在填寫企業信息的時候也不能填寫是中國,這裡再小小抗議一下!

Google Apps註冊是以域名為主體的。整個Google Apps的各種應用也是基於這個域名來使用的,可以說,一個企業的域名在Google Apps可以看作是一個身份證;

假設註冊好的域名是abc.com ,則 https://www.google.com/a/abc.com/ 就是相應Google Apps的登錄頁面;輸入設置好的管理員的用戶名和密碼,就可以登錄到Google Apps的後台管理信息中心。用戶管理和一些應用服務的配置都在這個後台管理中心來進行配置。

另外,相應的各種服務鏈接和配置也在後台統一進行管理;

GoogleApps1

如果是用一般用戶登錄,進入的就是普通用戶的登錄界面,主要是各種服務的鏈接。

GoogleApps2

值得一說的是,Google Apps的用戶都是用戶自己的域名做後綴,[email protected]還是有區別的,[email protected]oogle App裡面才可以使用。最直觀的就是普通的Gmail,Google Doc,Google Calendar等應用,[email protected]

a. 後台概述

上次說過,用管理員用戶登錄以後,系統自動導向到後台的信息中心。

GoogleApps1_thumb1

如圖,主界面中是此帳號的Google Apps下啟用的服務。當前標準版的Google Apps裡提供的服務主要有 電子郵件、在線文檔、日曆、網站、即時通信、移動版、起始頁、通訊錄、網頁等;(還有一個Google App Engine 服務,是用來在Google的基礎架構上運行定制化網絡應用程序的,目前沒使用過,這裡不討論)。點擊「添加更多服務」來增加更多的服務,相信 Google Apps 會不斷推出一些新的應用服務。

其餘菜單項可用來設置各種Google Apps內的應用。「高級工具」菜單提供了一些從windows本地訪問Google Apps應用的小應用程序的說明和下載;「支持」菜單是一些幫助和說明信息;「服務設置」裡面的內容和點擊主界面裡的鏈接是一樣的,就是對各個應用分別進 行設置。這些功能不詳細說明了;

b. 域名設置

Google Apps 的帳戶是以域(@abc.com)註冊的,所以「域名設置」是整個系統的基本配置。

進入「域名設置」後,有四個子選項。 其中「基本」中配置該域名對應的組織名稱、語言等等最基本的信息。用戶只要根據自己的需求進行配置就可以了;

GoogleApps3_thumb

「帳戶信息」子菜單中,用戶可以管理帳戶的類型。如果希望從基本版升級到專業版,就可以在本菜單進行升級;另外,還有關於主管理員、郵件提醒和訂閱的相關配置。

GoogleApps4_thumb

「域名」菜單,列出了主域名,例如 abc.com ;這個菜單主要是用來管理域名別名的;域名別名的概念就是,一個Google Apps應用的主域下,還可以設置另外一個別名域,比如efg.net,域名別名功能主要是在郵件系統中使用。當一個企業需要用到不止一個域名時,這個功 能就很有用了;用戶可以用統一的平台管理發到不同域下的郵件。

設置方法也很簡單,

1、 點擊添加域名,例如 efg.net( cn結尾的同樣不能使用:( );

2、 兩種方式驗證域名所有權;

3、 據說明,設置新的域名的MX記錄,(和主域名設置MX記錄的方式相同,主要用於郵件的收發)

設置好了以後,新的別名域名即設置好了; 可以在「域名」菜單中查看和管理;

c. 用戶和群組

以上功能其實都屬於對Google Apps的一次性基本配置;一般只要按照菜單和說明進行簡單配置即可,比較簡單;重點說一下「用戶和群組」功能;Google Apps作為企業(團隊)使用的信息平台,自然需要企業(團隊)內的所有用戶都來使用。用戶的創建和管理就在這裡;

點擊「用戶和群組」後,默認進入「用戶」子菜單,列出了當前域下所有的用戶;管理員可以在這裡查看用戶的名字、帳號、狀態、郵件空間使用、上次登錄日期等幾個數據;也可以進行刪除用戶的操作;

GoogleApps6_thumb

創建新用戶可以通過點擊「創建新用戶」的方式在頁面上創建;也可以通過點擊「同時上傳多個用戶」來批量上傳,上傳多個用戶時需要按照系統要求的格式來準備.csv的文件。

GoogleApps7_thumb

另外,菜單中還有一個「申請更多用戶」的功能。如果默認的免費企業用戶的1000個不夠用,可以嘗試一下。不過能否通過,沒試過。

手工點擊「創建新用戶」時,只要簡單的輸入姓名信息、用戶名,並設置密碼(或者設置臨時密碼)。

在用戶列表中,點擊具體用戶的名字,可以進行詳細帳戶信息配置:

GoogleApps8_thumb

如上圖,包括可以更改姓名、更改密碼等;也可以設置多個有權限管理域的管理員。值得一提的是暱稱功能。暱稱主要是在郵件系統時使用。例如,我們的主域是abc.com; 創建了一個用戶叫 user, 那這個用戶的帳號和郵件地址就是 [email protected] ;  但是,這個user的用戶,同時還兼任公司HR的職務,他希望用他的郵箱也能收到發向 [email protected] 下的郵件。那麼只要點擊「添加暱稱」,向 [email protected]@abc.com的暱稱即可。 [email protected][email protected];另外,剛才在說域的時候我們配置過別名域。系統默認在新建一個用戶以後,系統會把對應別名域下的郵箱地址作為暱稱添加到用戶上;例如 efg.net是一個別名域, 那默認 [email protected] 就是 [email protected],同樣通過一個郵箱可以收到;

這裡明確一下,[email protected] ; [email protected] ;[email protected] 都是郵件地址;但只有 [email protected],可用來登錄Google Apps。另外,別名域下就不能設置多個暱稱了。

現在通過一個郵箱地址已經可以收到發往多個郵件地址的郵件,那我們當然也希望往外發郵件的時候,也可以使用不同地址作為發件人。這個問題,其實屬於Gmail的基本功能,只要簡單的在設置菜單裡「添加其他帳戶」,並相應配置即可。這裡不詳細說明了。

最後菜單是修改用戶所屬群組的,操作和界面很簡單,不細說了。

群組的概念應該理解為郵件和權限組;在「群組」菜單對群組進行新建和管理;每個群組都可以若干用戶成為其成員。每個群組都[email protected][email protected]來使用,比如Doc/Website。同樣不能作為系統帳號登錄平台;

群組裡面比較特殊的是「角色和許可」。用來限制哪些用戶可以向這個群組(郵件列表)發送郵件。主要有「任意電子郵件地址」、「主域內用戶」、「成員」、「所有者」幾個級別;一般來說,群組的郵件列表主要為內部用戶使用,(如果開放給 )用戶可以根據實際情況來配置。

沒想到現在Google Apps已經有這麼多限制了。問題是,我甚至擔心Google Apps的免費服務會逐漸縮水,以致到關閉免費服務什麼的……唉,算了,想那麼多也沒用,就相信Google 「Don』t be evil」的承諾還有效吧。探索還要繼續寫下去,50人免費帳戶的Google Apps對有些小公司和團隊也不錯,而且估計大部分內容應該和專業版也是相通的吧。

三、 企業郵局

企業郵局是Google Apps的核心功能。首先每個Google Apps都是以電子郵件為帳號的,後綴就是申請時的主域。在整個Google Apps各個應用中,只要涉及到共享設置和提醒功能的時候都是以用戶的Email帳號或者郵件組(群組)為單位設置的。

a. 企業郵局的設置

企業郵局設置主要是在驗證了域的權限之後,需要設置對應域名的MX記錄。設置MX的記錄的主要目的就是使其它外部郵箱可以正確的解析發往主域的郵 件。具體的配置方法可以在後台菜單 「服務設置」-「電子郵件」 裡面的「有關如何啟動電子郵件的說明」,中找到詳細的配置說明,這裡就不細說了。

另外,如果設置別名域名,那對於別名域名也需要進行MX記錄的設置。

對於企業郵局的通用設置,在「服務設置」-「電子郵件」中有若干選項,根據需要配置即可;比較有用的是,可以設置一個公共郵箱,用於接收發送到主域但是無法匹配具體用戶的郵件。

GoogleApps9_thumb

b. 企業郵局的使用

對於用戶來說,企業郵局和正常使用Gmail沒有太大的區別。網頁版訪問和客戶端軟件(Outlook,Foxmail等)都是可以的,Gmail 一些其他的功能,如設置過濾、在線web版Gtalk,加載實驗室功能等。關於Gmail的使用和技巧文章很多,這裡就不詳細說了;

c. 聯繫人

Gmail的通訊錄功能很方便,可以記錄聯繫人詳細信息,並設置分組;使用一些插件和小軟件,可以方便的在Gmail通訊錄與Outlook或者手 機通訊錄之間進行同步;在web端撰寫郵件,輸入收件人信息的時候,系統也會根據輸入的字母或者漢字對通訊錄進行搜索,並彈出提示;

在這裡,Google Apps作為企業和團隊的合作平台,體現出了與普通Gmail用戶的區別。可以把整個域內的所有用戶看作是一個公共通訊錄(當然,公共通訊錄只有用戶名和 Email地址,也包括對用戶群組的地址提示)。在web端輸入收件人信息的時候,系統不僅僅搜索個人的通訊錄,也會同時搜索整個域內的用戶,並進行輸入 提示。個人通訊錄部分提示,和公共通訊錄的提示,系統會用一根黑顏色的分割線區分開。優先提示個人通訊錄內的信息;(系統最多提示15個)

GoogleApps10_thumb

四、 在線文檔和日曆-Google Doc & Google Calendar

在線文檔和日曆功能相對簡單,和獨立的在線文檔和日曆功能並沒有什麼太多區別;不太一樣的應該主要集中在共享設置時對域內外用戶配置策略。 Google Apps主要在企業或者團隊中進行工作協作和共享,所以文檔和日曆可以方便的共享給域內部分用戶、部分組或者全部域內用戶是非常有用的。

另外,日曆和文檔作為Google Apps體系中的應用單元,可以很方便被調用;比如,每次會議我們可以在日曆上進行預約、邀請和提醒;要求團隊裡每個人把每次開會時的總結和需要討論的文 檔上傳到Doc上;最後,嵌入到對應的日曆項中;這樣,每個人在參加會議之前都會收到提醒,並可以提前瀏覽一下會議的內容和需要討論的東西;開會時,只要 打開日曆項,就可以有計劃有順序的進行會議了。(日曆中添加Doc作為附件是LAB功能,貌似Google Apps默認開啟的,而獨立的Calendar裡面是默認關閉的。這個功能我覺得對Google Apps用戶來說實在很有用,如果能添加非Docs內的文件作為附件就更好了!)

GoogleApps11_thumb

再比如,Doc和日曆裡面的內容都可以作為內容單元嵌入到Google Apps 網站(sites)模塊裡面,等到介紹Sites裡面的時候再說。

在用Apps日曆功能時有個功能點,我們會用到多人編輯同一個日曆的情況;不過,目前的Google Calendar只支持不同日曆配置不同顏色,顯示在一個界面;如果能支持同一個日曆,不同人添加(編輯)也用不同顏色顯示就好了:)

Docs和Calendar兩個模塊可以說是Google Apps最基礎的單元(同時也是Google網絡應用服務體系最基礎的單元), 其內容和配置很豐富,也在不斷更新,但也都不複雜;如何利用好,其實已經不是系統或者軟件的問題,而是思路的問題了。你可以要求每天早上系統默認發送當日 日程到團隊成員郵箱;也可以定制每次提醒,發送到受邀人員的手機;……  管理沒有固定的做法和模式,把各種因素和工具結合在一起實現管理目標就是最好的;使用Google Apps也是,Google只是給我們提供一個平台,怎麼用,還要結合企業(團隊)的實際情況:)。

五、 協作平台 (Google Sites)

協作平台(Sites)在我看來是Google Apps真正體現意義的功能。

我們之前說了,Google Apps很適合用作中小企業(團隊)進行信息共享、工作協作之用;共享的內容可能是文檔、日曆、Email等具體的內容;不過,單純的通過日曆、Docs 的共享功能進行交流,信息多起來以後會很零散、混亂,缺乏整體性;而通過Sites可以方便通過各種方式把這些信息整合到一起,方便的可以查看和編輯,大大增強了信息共享和協作的效率;

協作平台(Sites)模塊整體設置沒有什麼太多的內容,主要是限制Sites的可使用範圍是域內or域外。

只要開啟了協作平台功能,那域內的每一個用戶都有權限去創建多個網站。我們可以通過創建網站時設置的關鍵字進行檢索和查找;協作平台的擁有者可以隨時通過瀏覽器對內容和結構進行調整,而被授予瀏覽權限的用戶可以瀏覽協作平台;每一個頁面會生成一個類似於 http://sites.google.com/a/user.com/sites1/ 的訪問地址;

創建好一個協作平台以後,界面右上角有「更多操作」的菜單,我們可以在這裡進行共享設置和管理站點來對站點進行基本的設置;

GoogleApps12_thumb

共享站點很簡單,和其他Google功能模塊設置共享權限差不多,這裡不詳細描述了。值得一說的是,這裡設置的是整個站點的可見性的權限。但是如果站點內嵌入的一些其他元素,比如Google Docs內的文檔,或者日曆的話,相應文檔和日曆的共享權限也需要設置;

管理站點內有很多功能,剛開始我們需要進行一些基本的配置。包括「常規」菜單裡面「站點名稱」、「站點類別」、「站點說明」等等;也包括「站點外觀」裡面對站點佈局、顏色字體和主題的設置等等;

GoogleApps13_thumb

在「站點佈局」內,可以很方便的設置整個佈局。雖然選項並不多(只能修改標題高度、側邊欄位置等),但對於企業應用來說已經足夠了。同時在側邊欄內也可以嵌入若干功能小工具,包括文本、導航、最近站點活動、我最近的活動、倒計時這幾個,相信以後相關功能會越來越多。

GoogleApps14_thumb

以上是協作平台的一個基本配置介紹。

協作平台真正加入內容還需要用到頁面。整個的組織架構是以頁面為單位,每一個頁面可以用來添加文本、插入各種內容元素等;同時,可以對頁面進行多層級樹形結構設置。

每個頁面新建的時候,可以選擇頁面的模板類型。目前有五種類型:網頁、公告式頁面、文件箱式頁面、列表式頁面和起始頁;同時,可以輸入頁面名稱和所在位置。(即所在的樹形結構的位置)

GoogleApps15_thumb

1、 網頁式是最基本的一種頁面。點擊「編輯頁面」後就可以在瀏覽器內直接進行編輯。窗口提供一個簡單的富文本編輯器。還可以直接點擊<HTML>按鈕,進行代碼編輯。同時最上端菜單有「插入」、「格式」、「表格」、「佈局」等菜單;

頁面的內容可以靈活的進行編輯。可以輸入文本、超鏈接;調節格式、佈局和表格等;最靈活的應用體現在可以向頁面內插入各類內容單元,如Google Docs裡的文檔、日曆項、Google Adsense、Google地圖、Picasa相冊演示、視頻等等;也可以將Google的通用小工具(Gadget)嵌入到頁面中。

GoogleApps16_thumb

另外,嵌入的單元也有少量配置項可以選擇;

而且,用戶可以針對每個頁面添加附件、或者進行評論。

GoogleApps17_thumb

2、 公告類頁面就是個類似BBS的頁面組織形式。用戶可以新建帖子,或者瀏覽別人的帖子。同時對帖子添加附件和添加評論。每個帖子編輯的時候就是一個獨立的網頁式頁面,和前面提到的功能相同;

GoogleApps18_thumb

3、 文件箱式頁面是一個文件上傳下載的管理類頁面;可以自定義文件夾,並把上傳的文件歸類的各文件夾內。遺憾的是,在一個文件箱式頁面內部的文件夾沒有層級劃分的機制,如果有多個層級,只能用頁面來進行。

GoogleApps19_thumb

这个类别页面管理文件还有简单的版本管理。如果重新上传文件的名字相同,系统会自动更新版本号,而且,还会保留以前版本的内容,很好用:)只要点击当前版本可以看到历史版本列表;

GoogleApps20_thumb

4、 列表式頁面是一個類似數據統計表單的匯總頁面。用戶可以自定義需要統計的內容(列表的具體項),然後添加每一個條目的內容來進行匯總。比如,我們可以定義一個公司員工通訊錄,裡面記錄員工的相應信息,並進行管理;

這類頁面非常適合用於需要長期維護,修改頻繁,又需要給其他人共享的列表類信息。

GoogleApps21_thumb

5、 起始類頁面就可以看作簡單的一個網頁式頁面+個人小工具添加器,很簡單,不詳細說了;

總之,協作平台的功能我覺得是非常靈活的。用戶很是可以發揮自己的想像,去組合和創造使用的方式,來豐富和完善工作中的一些方法。使得信息的共享、發佈和協作更加容易。

Source : google.org.cn

趙燕萍大鬧元朗聯興行最新進展

雖然唔識個店員,如果我在現場,會響前面行來行去,唔比個臭八婆 :bbs38: 影得咁放肆。
大家都係顧客,睇下佢會唔會發癲影埋我。

FACEBOOK  反趙燕萍GROUP

寸爆「七折港女」與連鎖建材店爭拗的片段近日熱爆網絡,點擊率已逾三十五萬次,事件惹傳言滿天飛,如港女因事件避走北京;而不值「七折港女」所為的網友, 更在交友網站Facebook開設群組,要求她回應事件;另外又傳出店長被無情解僱,不過涉事建材店昨日澄清純屬誤傳,店長仍在上班,而事件也希望就此平 息。

網絡聲討「寸爆七折港女」

Tornado Facebook發佈開源Web Server

Facebook發佈了一個開源實時Web server。被稱為Tornado的開源Web server用Python語言編寫,設計能處理數千條同時發生的請求。Tornado與現有的用Python語言編寫的Web框架類似,突出的是速度和 處理海量的同時發生的連接請求的能力。Facebook的開放程序主管David Recordon認為,開放Tornado的源代碼,可以促進整個互聯網的創新。

http://www.tornadoweb.org/

PayPal Set Up for VirtueMart

How do I install PayPal?
You don’t have to install it. PayPal is a part of the official distribution and installed per default.
You just have to go to “Store” => “Payment method list” and click on “PayPal”.
If you want to know which files are responsible for PayPal:
VIRTUEMART:
* /site_root/administrator/components/com_virtuemart/notify.php
This is the script where paypal.com should post to when a transaction is made. If the transaction was VERIFIED, the order status is usually update to the oder status you have set in the configuration (you can set that for Confirmed, Pending & Failed payments).
* /site_root/administrator/components/com_virtuemart/classes/payment/ps_paypal.php
This is the main class for the paypal configuration. It actually doesn’t play any role on checkout.
* site_root/administrator/components/com_virtuemart/classes/payment/ps_paypal.cfg.php
The configuration file for the paypal settings. Remember that this file must be writable to save changes to the configuration.

How do setup PayPal?
This payment method is to be set up as every other payment method: go to “Store” => “List Payment Methods”, then select “PayPal” from the list. Once the payment method form for PayPal has opened, you can activate/deactivate it, rename it (the name of the payment method doesn’t really matter!), restrict it to a shopper group, define a discount value and change the method’s position in a list with other payment methods (list order).
Please note that there’s an important Configuration Panel, which can be reached by clicking on the Tab Heading “Configuration”.
Test Mode [yes/no; default=no]
When you enable the test mode, you can debug the script using Eliteweaver’s ipn testing environment. Last time I used that, i didn’t worked and didn’t recognize that the script was posting back (I know it did!). This is NOT FOR THE PAYPAL SANDBOX!
PayPal Email
Your business email, which is your login at paypal (or paypal sandbox).
Order Status for confirmed Payments
Order Status for Pending Payments
Order Status for failed Payments

With these settings you can define, which Order Status should be set when a payment was successful / is pending / has failed.
IMPORTANT: PayPal seems to return “Pending” very often, although the payment will be no problem. A further investigation, why the payment is still pending is not made at this time (we’ll have to improve the paypal notify script to check that).
That’s why you see “An error occured while processing your transaction. The status of your order could not be updated“: You obviously haven’t set the Order Status for pending payments to “confirmed”.
Payment Extra Info
The textarea is used by each payment method. You can fill in HTML/PHP/Javascript here. It is executed:
* on the “Thankyou” page
* each time the order is viewed by the customer (and it’s order status is not “confirmed”)
So you can use it to
* process additional affiliate tasks
* show your bank account details
* whatever you want to display to the customer
I have rewritten the Payment Extrainfo Code for PayPal, so i directly redirects the customer to PayPal after clicking on “Confirm” to place the order. Just copy and paste it into your PayPal Extrainfo box.
CODE FOR USE IN VIRTUEMART

Code:
<?php
$db1 = new ps_DB();
$q "SELECT country_2_code FROM #__vm_country WHERE country_3_code='".$user->country."' ORDER BY country_2_code ASC";
$db1->query($q);

$url "https://www.paypal.com/cgi-bin/webscr";
$tax_total $db->f("order_tax") + $db->f("order_shipping_tax");
$discount_total $db->f("coupon_discount") + $db->f("order_discount");
$post_variables = Array(
"cmd" => "_ext-enter",
"redirect_cmd" => "_xclick",
"upload" => "1",
"business" => PAYPAL_EMAIL,
"receiver_email" => PAYPAL_EMAIL,
"item_name" => $VM_LANG->_('PHPSHOP_ORDER_PRINT_PO_NUMBER').": "$db->f("order_id"),
"order_id" => $db->f("order_id"),
"invoice" => $db->f("order_number"),
"amount" => round$db->f("order_subtotal")+$tax_total-$discount_total2),
"shipping" => sprintf("%.2f"$db->f("order_shipping")),
"currency_code" => $_SESSION['vendor_currency'],

"address_override" => "1",
"first_name" => $dbbt->f('first_name'),
"last_name" => $dbbt->f('last_name'),
"address1" => $dbbt->f('address_1'),
"address2" => $dbbt->f('address_2'),
"zip" => $dbbt->f('zip'),
"city" => $dbbt->f('city'),
"state" => $dbbt->f('state'),
"country" => $db1->f('country_2_code'),
"email" => $dbbt->f('user_email'),
"night_phone_b" => $dbbt->f('phone_1'),
"cpp_header_image" => $vendor_image_url,

"return" => SECUREURL ."index.php?option=com_virtuemart&page=checkout.result&order_id=".$db->f("order_id"),
"notify_url" => SECUREURL ."administrator/components/com_virtuemart/notify.php",
"cancel_return" => SECUREURL ."index.php",
"undefined_quantity" => "0",

"test_ipn" => PAYPAL_DEBUG,
"pal" => "NRUBJXESJTY24",
"no_shipping" => "1",
"no_note" => "1"
);
if( $page == "checkout.thankyou" ) {
$query_string "?";
foreach( $post_variables as $name => $value ) {
$query_string .= $name"=" urlencode($value) ."&";
}
vmRedirect$url $query_string );
} else {
echo '<form action="'.$url.'" method="post" target="_blank">';
echo '<input type="image" name="submit" src="https://www.paypal.com/en_US/i/btn/x-click-but6.gif" border="0" alt="Click to pay with PayPal - it is fast, free and secure!" />';

foreach( $post_variables as $name => $value ) {
echo '<input type="hidden" name="'.$name.'" value="'.htmlspecialchars($value).'" />';
}
echo '</form>';

}
?>

If you don’t want your customer to be redirected after confirmation, but still want him to click on “Pay with PayPal”, change

Code:
if( $page == "checkout.thankyou" ) {

to

Code:
if( false ) {

Don’t forget to save all your changes.  Roll Eyes
Common Questions
My PayPal doesn’t work. What’s wrong?
It could be anything. Please review your settings and read the other Questions/Answers.
How can I use the PayPal Sandbox for debugging my PayPal Payment Method?
This is really easy: you just need to change the payment extrainfo in the payment method form for PayPal:
Change

Code:
$url = "https://www.paypal.com/cgi-bin/webscr";

to

Code:
$url = "https://www.sandbox.paypal.com/cgi-bin/webscr";

and save. Please remember: DO NOT TURN ON DEBUG MODE WHEN WORKING WITH THE SANDBOX!
I’m getting the message “An error occured while processing your transaction. The status of your order could not be updated.” when returning from PayPal.
Please be careful before you blame VirtueMart.
There are many reasons why this message could be displayed.

  • Your script can’t be reached from the internet
    It’s important that your notify.php is not protected by .htaccess files (which is the case when you secure your /administrator directory).
    Try to point to it with your browser.
  • There’s a parsing error in your script.
    If you have no idea why things go wrong, do the following:
    * Enable Debug Mode
    * Go to http://www.eliteweaver.co.uk/testing/ipntest.php and debug your script.
    * Click on “Follow IPN” after you have clicked on “Submit IPN” to see the real debug output of your notify.php script
  • Your Payment returned the payment status “Pending” or “Failed”.
    When you have a pending or failed payment, the notify.php script changes the order status to whatever you have set in the paypal configuration for it. BUT: if this isn’t “confirmed”, you will see this error message.

How can I change the return page?
The file behind that default return page is
/site_root/administrator/components/com_virtuemart/html/checkout.result.php
You can also change the return page in the payment extrainfo in the payment method form for PayPal or set your own Notify URL in your PayPal Account.
I hope that clears it a little bit.

Etag和Expires原來和設定

摘要
1、Etag和Expires中Client 端Http Request Header及Server端Http Reponse Header工作原理。
2、靜態下Apache、Lighttpd和Nginx中Etag和Expires配置
3、非實時交互動態頁面中Etag和Expires處理
在客戶端通過瀏覽器發出第一次請求某一個URL時,根據 HTTP 協議的規定,瀏覽器會向服務器傳送報頭(Http Request Header),服務器端響應同時記錄相關屬性標記(Http Reponse Header),服務器端的返回狀態會是200,格式類似如下:
HTTP/1.1 200 OK
Date: Tue, 03 Mar 2009 04:58:40 GMT
Content-Type: image/jpeg
Content-Length: 83185
Last-Modified: Tue, 24 Feb 2009 08:01:04 GMT
Cache-Control: max-age=2592000

Expires: Thu, 02 Apr 2009 05:14:08 GMT
Etag: 「5d8c72a5edda8d6a:3239〞

客戶端第二次請求此URL時,根據 HTTP 協議的規定,瀏覽器會向服務器傳送報頭(Http Request Header),服務器端響應並記錄相關記錄屬性標記文件沒有發生改動,服務器端返回304,直接從緩存中讀取:
HTTP/1.x 304 Not Modified
Date: Tue, 03 Mar 2009 05:03:56 GMT
Content-Type: image/jpeg
Content-Length: 83185
Last-Modified: Tue, 24 Feb 2009 08:01:04 GMT
Cache-Control: max-age=2592000
Expires: Thu, 02 Apr 2009 05:14:08 GMT
Etag: 「5d8c72a5edda8d6a:3239〞
其中Last-ModifiedExpiresEtag是標記頁面緩存標識

一、Last-Modified、Expires和Etag相關工作原理
1、Last-Modified
在瀏覽器第一次請求某一個URL時,服務器端的返回狀態會是200,內容是你請求的資源,同時有一個Last-Modified的屬性標記(Http Reponse Header)此文件在服務期端最後被修改的時間,格式類似這樣:
Last-Modified: Tue, 24 Feb 2009 08:01:04 GMT
客戶端第二次請求此URL時,根據 HTTP 協議的規定,瀏覽器會向服務器傳送 If-Modified-Since 報頭(Http Request Header),詢問該時間之後文件是否有被修改過:
If-Modified-Since: Tue, 24 Feb 2009 08:01:04 GMT
如果服務器端的資源沒有變化,則自動返回 HTTP 304 (NotChanged.)狀態碼,內容為空,這樣就節省了傳輸數據量。當服務器端代碼發生改變或者重啟服務器時,則重新發出資源,返回和第一次請求時類 似。從而保證不向客戶端重複發出資源,也保證當服務器有變化時,客戶端能夠得到最新的資源。
註:如果If-Modified-Since的時間比服務器當前時間(當前的請求時間request_time)還晚,會認為是個非法請求

2、Etag工作原理
HTTP 協議規格說明定義ETag為「被請求變量的實體標記」 。簡單點即服務器響應時給請求URL標記,並在HTTP響應頭中將其傳送到客戶端,類似服務器端返回的格式:
Etag: 「5d8c72a5edda8d6a:3239〞
客戶端的查詢更新格式是這樣的:
If-None-Match: 「5d8c72a5edda8d6a:3239〞
如果ETag沒改變,則返回狀態304。
即:在客戶端發出請求後,Http Reponse Header中包含 Etag: 「5d8c72a5edda8d6a:3239〞
標識,等於告訴Client端,你拿到的這個的資源有表示ID:5d8c72a5edda8d6a:3239。當下次需要發Request索要同一個 URI的時候,瀏覽器同時發出一個If-None-Match報頭( Http RequestHeader)此時包頭中信息包含上次訪問得到的Etag: 「5d8c72a5edda8d6a:3239〞標識。
If-None-Match: 「5d8c72a5edda8d6a:3239「
,這樣,Client端等於Cache了兩份,服務器端就會比對2者的etag。如果If-None-Match為False,不返回200,返回304 (Not Modified) Response。

3、Expires
給出的日期/時間後,被響應認為是過時。如Expires: Thu, 02 Apr 2009 05:14:08 GMT
需和Last-Modified結合使用。用於控制請求文件的有效時間,當請求數據在有效期內時客戶端瀏覽器從緩存請求數據而不是服務器端. 當緩存中數據失效或過期,才決定從服務器更新數據。

4、Last-Modified和Expires
Last-Modified標識能夠節省一點帶寬,但是還是逃不掉發一個HTTP請求出去,而且要和Expires一起用。而Expires標識卻使得瀏覽器乾脆連HTTP請求都不用發,比如當用戶F5或者點擊Refresh按鈕的時候就算對於有Expires的URI,一樣也會發一個HTTP請求出去,所以,Last-Modified還是要用的,而 且要和Expires一起用。

5、Etag和Expires
如果服務器端同時設置了Etag和Expires時,Etag原理同樣,即與Last-Modified/Etag對應的HttpRequest Header:If-Modified-Since和If-None-Match。我們可以看到這兩個Header的值和WebServer發出的 Last-Modified,Etag值完全一樣;在完全匹配If-Modified-Since和If-None-Match即檢查完修改時間和 Etag之後,服務器才能返回304.

6、Last-Modified和Etag
Last-Modified 和ETags請求的http報頭一起使用,服務器首先產生 Last-Modified/Etag標記,服務器可在稍後使用它來判斷頁面是否已經被修改,來決定文件是否繼續緩存
過程如下:
1. 客戶端請求一個頁面(A)。
2. 服務器返回頁面A,並在給A加上一個Last-Modified/ETag。
3. 客戶端展現該頁面,並將頁面連同Last-Modified/ETag一起緩存。
4. 客戶再次請求頁面A,並將上次請求時服務器返回的Last-Modified/ETag一起傳遞給服務器。
5. 服務器檢查該Last-Modified或ETag,並判斷出該頁面自上次客戶端請求之後還未被修改,直接返迴響應304和一個空的響應體。
註:
1、Last-Modified和Etag頭都是由Web Server發出的Http Reponse Header,Web Server應該同時支持這兩種頭。
2、Web Server發送完Last-Modified/Etag頭給客戶端後,客戶端會緩存這些頭;
3、客戶端再次發起相同頁面的請求時,將分別發送與Last-Modified/Etag對應的Http RequestHeader:If-Modified-Since和If-None-Match。我們可以看到這兩個Header的值和 WebServer發出的Last-Modified,Etag值完全一樣;
4、通過上述值到服務器端檢查,判斷文件是否繼續緩存;

二、Apache、Lighttpd和Nginx中針配置Etag和Expires,有效緩存純靜態如css/js/pic/頁面/流媒體等文件。
A、Expires
A.1、Apache Etag
使用Apache的mod_expires 模塊來設置,這包括控制應答時的Expires頭內容和Cache-Control頭的max-age指令
ExpiresActive On
ExpiresByType image/gif 「access plus 1 month」
ExpiresByType image/jpg 「access plus 1 month」
ExpiresByType image/jpeg 「access plus 1 month」
ExpiresByType image/x-icon 「access plus 1 month」
ExpiresByType image/bmp 「access plus 1 month」
ExpiresByType image/png 「access plus 1 month」
ExpiresByType text/html 「access plus 30 minutes」
ExpiresByType text/css  「access plus 30 minutes」
ExpiresByType text/txt  「access plus 30 minutes」
ExpiresByType text/js   」access plus 30 minutes」
ExpiresByType application/x-javascript   」access plus 30 minutes」
ExpiresByType application/x-shockwave-flash     」access plus 30 minutes」

<ifmodule mod_expires.c>
<filesmatch 「\.(jpg|gif|png|css|js)$」>
ExpiresActive on
ExpiresDefault 「access plus 1 year」
</filesmatch>
</ifmodule>
當設置了expires後,會自動輸出Cache-Control 的max-age 信息
具體關於 Expires 詳細內容可以查看Apache官方文檔。
在這個時間段裡,該文件的請求都將直接通過緩存服務器獲取,
當然如果需要忽略瀏覽器的刷新請求(F5),緩存服務器squid還需要使用 refresh_pattern 選項來忽略該請求
refresh_pattern -i \.gif$ 1440 100% 28800 ignore-reload
refresh_pattern -i \.jpg$ 1440 100% 28800 ignore-reload
refresh_pattern -i \.jpeg$ 1440 100% 28800 ignore-reload
refresh_pattern -i \.png$ 1440 100% 28800 ignore-reload
refresh_pattern -i \.bmp$ 1440 100% 28800 ignore-reload
refresh_pattern -i \.htm$ 60 100% 100 ignore-reload
refresh_pattern -i \.html$ 1440 50% 28800 ignore-reload
refresh_pattern -i \.xml$ 1440 50% 28800 ignore-reload
refresh_pattern -i \.txt$ 1440 50% 28800 ignore-reload
refresh_pattern -i \.css$ 1440 50% 28800 reload-into-ims
refresh_pattern -i \.js$ 60 50% 100 reload-into-ims
refresh_pattern . 10 50% 60
有關Squid中Expires的說明,請參考Squid官方中refresh_pattern介紹。

A.2、Lighttpd Expires
和Apache一樣Lighttpd設置expire也要先查看是否支持了mod_expire模塊,
下面的設置是讓URI中所有images目錄下的文件1小時後過期;
expire.url = ( 「/images/」 => 「access 1 hours」 )
下面是讓作用於images目錄及其子目錄的文件;
$HTTP[“url”] =~ 「^/images/」 {
expire.url = ( 「」 => 「access 1 hours」 )
}
也可以指定文件的類型;
$HTTP[“url”] =~ 「\.(jpg|gif|png|css|js)$」 {
expire.url = ( 「」 => 「access 1 hours」 )
}
具體參考Lighttpd官方Expires解釋

A.3、Nginx中Expires
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 1h;
}
這類文件並不常修改,通過 expires 指令來控制其在瀏覽器的緩存,以減少不必要的請求。 expires 指令可以控制 HTTP 應答中的「 Expires 」和「 Cache-Control 」的頭標(起到控制頁面緩存的作用)。其他請參考Nginx中Expires

B.1、Apache中Etag設置
在Apache中設置Etag的支持比較簡單,只用在含有靜態文件的目錄中建立一個文件.htaccess, 裡面加入:
FileETag MTime Size
這樣就行了,詳細的可以參考Apache的FileEtag文檔頁

B.2、Lighttpd Etag
在Lighttpd中設置Etag支持:
etag.use-inode: 是否使用inode作為Etag
etag.use-mtime: 是否使用文件修改時間作為Etag
etag.use-size: 是否使用文件大小作為Etag
static-file.etags: 是否啟用Etag的功能
第四個參數肯定是要enable的, 前面三個就看實際的需要來選吧,推薦使用修改時間

B.3、 Nginx Etag
Nginx中默認沒有添加對Etag標識.Igor Sysoev的觀點」在對靜態文件處理上看不出如何Etag好於Last-Modified標識。」
Note:
Yes, it』s addition,and it』s easy to add, however, I do not see howETag is better than Last-Modified for static files. -Igor Sysoev
A nice short description is here:
http://www.mnot.net/cache_docs/#WORK
It looks to me that it makes some caches out there to cache theresponse from the origin server more reliable as in rfc2616(ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt) is written.
3.11 Entity Tags 13.3.2 Entity Tag Cache Validators 14.19 ETag
當然也有第三方nginx-static-etags 模塊了,請參考
http://mikewest.org/2008/11/generating-etags-for-static-content-using-nginx

三、對於非實時交互動態頁面中Epires和Etag處理
對數據更新並不頻繁、如tag分類歸檔等等,可以考慮對其cache。簡單點就是在非實時交互的動態程序中輸出expires和etag標識,讓其緩存。 但需要注意關閉session,防止http response時http header包含session id標識;
3.1、Expires
如expires.php
<?php
header(』Cache-Control: max-age=86400,must-revalidate』);
header(』Last-Modified: 『 .gmdate(』D, d M Y H:i:s』) . 『 GMT』 );
header(」Expires: 」 .gmdate (』D, d M Y H:i:s』, time() + 『86400′ ). 『 GMT』);
?>
以上信息表示該文件自請求後24小時後過期。
其他需要處理的動態頁面直接調用即可。
3.2、Etag
根據Http返回狀態來處理。當返回304直接從緩存中讀取
如etag.php
<?php
cache();
echo date(」Y-m-d H:i:s」);
function cache()
{
$etag = 「http://longrujun.name」;
if ($_SERVER[‘HTTP_IF_NONE_MATCH’] == $etag)
{
header(』Etag:』.$etag,true,304);
exit;
}
else header(』Etag:』.$etag);
}
?>

Apache的prefork模式和worker模式

prefork模式
這個多路處理模塊(MPM)實現了一個非線程型的、預派生的web服務器,它的工作方式類似於Apache 1.3。它適合於沒有線程安全庫,需要避免線程兼容性問題的系統。它是要求將每個請求相互獨立的情況下最好的MPM,這樣若一個請求出現問題就不會影響到其他請求。

這個MPM具有很強的自我調節能力,只需要很少的配置指令調整。最重要的是將MaxClients設置為一個足夠大的數值以處理潛在的請求高峰,同時又不能太大,以致需要使用的內存超出物理內存的大小。

worker模式
此多路處理模塊(MPM)使網絡服務器支持混合的多線程多進程。由於使用線程來處理請求,所以可以處理海量請求,而系統資源的開銷小於基於進程的MPM。但是,它也使用了多進程,每個進程又有多個線程,以獲得基於進程的MPM的穩定性。

控制這個MPM的最重要的指令是,控制每個子進程允許建立的線程數的ThreadsPerChild指令,和控制允許建立的總線程數的MaxClients指令。

prefork和worker模式的切換
1.將當前的prefork模式啟動文件改名
mv httpd httpd.prefork
2.將worker模式的啟動文件改名
mv httpd.worker httpd
3.修改Apache配置文件
vi /usr/local/apache2/conf/extra/httpd-mpm.conf
找到裡邊的如下一段,可適當修改負載等參數:

StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0

4.重新啟動服務
/usr/local/apache2/bin/apachectl restart
即可換成worker方式啟動apache2

處於穩定性和安全性考慮,不建議更換apache2的運行方式,使用系統默認prefork即可。另外很多php模塊不能工作在worker模式下,例如redhat linux自帶的php也不能支持線程安全。所以最好不要切換工作模式。

prefork和worker模式的比較
prefork模式使用多個子進程,每個子進程只有一個線程。每個進程在某個確定的時間只能維持一個連接。在大多數平台上,Prefork MPM在效率上要比Worker MPM要高,但是內存使用大得多。prefork的無線程設計在某些情況下將比worker更有優勢:它可以使用那些沒有處理好線程安全的第三方模塊,並且對於那些線程調試困難的平台而言,它也更容易調試一些。

worker模式使用多個子進程,每個子進程有多個線程。每個線程在某個確定的時間只能維持一個連接。通常來說,在一個高流量的HTTP服務器上,Worker MPM是個比較好的選擇,因為Worker MPM的內存使用比Prefork MPM要低得多。但worker MPM也由不完善的地方,如果一個線程崩潰,整個進程就會連同其所有線程一起」死掉」.由於線程共享內存空間,所以一個程序在運行時必須被系統識別為」每個線程都是安全的」。

總的來說,prefork方式速度要稍高於worker,然而它需要的cpu和memory資源也稍多於woker。

prefork模式配置詳解

ServerLimit 256
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 256
MaxRequestsPerChild 0

ServerLimit
默認的MaxClient最大是256個線程,如果想設置更大的值,就的加上ServerLimit這個參數。20000是ServerLimit這個參數的最大值。如果需要更大,則必須編譯apache,此前都是不需要重新編譯Apache。
生效前提:必須放在其他指令的前面

StartServers
指定服務器啟動時建立的子進程數量,prefork默認為5。

MinSpareServers
指定空閒子進程的最小數量,默認為5。如果當前空閒子進程數少於MinSpareServers ,那麼Apache將以最大每秒一個的速度產生新的子進程。此參數不要設的太大。

MaxSpareServers
設置空閒子進程的最大數量,默認為10。如果當前有超過MaxSpareServers數量的空閒子進程,那麼父進程將殺死多餘的子進程。此參數不要設的太大。如果你將該指令的值設置為比MinSpareServers小,Apache將會自動將其修改成」MinSpareServers+1〞。

MaxClients
限定同一時間客戶端最大接入請求的數量(單個進程並發線程數),默認為256。任何超過MaxClients限制的請求都將進入等候隊列,一旦一個鏈接被釋放,隊列中的請求將得到服務。要增大這個值,你必須同時增大ServerLimit。

MaxRequestsPerChild
每個子進程在其生存期內允許伺服的最大請求數量,默認為10000.到達MaxRequestsPerChild的限制後,子進程將會結束。如果 MaxRequestsPerChild為」0〞,子進程將永遠不會結束。將MaxRequestsPerChild設置成非零值有兩個好處:
1.可以防止(偶然的)內存洩漏無限進行,從而耗盡內存。
2.給進程一個有限壽命,從而有助於當服務器負載減輕的時候減少活動進程的數量。

worker模式配置詳解

StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0

StartServers
服務器啟動時建立的子進程數,默認值是」3〞。

MaxClients
允許同時伺服的最大接入請求數量(最大線程數量)。任何超過MaxClients限制的請求都將進入等候隊列。默認值是」400〞 ,16(ServerLimit)乘以25(ThreadsPerChild)的結果。因此要增加MaxClients的時候,你必須同時增加 ServerLimit的值。

MinSpareThreads
最小空閒線程數,默認值是」75〞。這個MPM將基於整個服務器監視空閒線程數。如果服務器中總的空閒線程數太少,子進程將產生新的空閒線程。

MaxSpareThreads
設置最大空閒線程數。默認值是」250〞。這個MPM將基於整個服務器監視空閒線程數。如果服務器中總的空閒線程數太多,子進程將殺死多餘的空閒線程。 MaxSpareThreads的取值範圍是有限制的。Apache將按照如下限制自動修正你設置的值:worker要求其大於等於 MinSpareThreads加上ThreadsPerChild的和。

ThreadsPerChild
每個子進程建立的常駐的執行線程數。默認值是25。子進程在啟動時建立這些線程後就不再建立新的線程了。

MaxRequestsPerChild
設置每個子進程在其生存期內允許伺服的最大請求數量。到達MaxRequestsPerChild的限制後,子進程將會結束。如果MaxRequestsPerChild為」0〞,子進程將永遠不會結束。將MaxRequestsPerChild設置成非零值有兩個好處:
1.可以防止(偶然的)內存洩漏無限進行,從而耗盡內存。
2.給進程一個有限壽命,從而有助於當服務器負載減輕的時候減少活動進程的數量。
注意對於KeepAlive鏈接,只有第一個請求會被計數。事實上,它改變了每個子進程限制最大鏈接數量的行為。