├── data ├── plugin.csv ├── profiles │ ├── example.sql │ └── example ├── etc │ ├── system.xml │ ├── adminhtml.xml │ └── config.xml ├── app │ └── layout.xml ├── defaults.php.sample ├── views │ ├── attributes.sql │ ├── invitations.sql │ ├── inviters.sql │ ├── broken_configurables.sql │ ├── product_suppliers.sql │ └── product_purchases.sql ├── README ├── modules.xml ├── recipes │ ├── block.xml │ ├── model.xml │ ├── helper.xml │ ├── config_5_default_value.xml │ ├── banner_type.xml │ ├── layout.xml │ ├── rewrite.xml │ ├── translate.xml │ ├── config_1_tab.xml │ ├── override.xml │ ├── emailtemplate.xml │ ├── crontab.xml │ ├── pagelayout.xml │ ├── controller.xml │ ├── page_layout.xml │ ├── acl_1_section.xml │ ├── setup.xml │ ├── model_resource.xml │ ├── observer.xml │ ├── acl_2_group.xml │ ├── config_2_section.xml │ ├── config_3_group.xml │ ├── controller_override.xml │ ├── acl_3_field.xml │ ├── config_4_field.xml │ └── total.xml ├── cached-modules.txt ├── lipsum.txt ├── setup │ └── base.php ├── Block │ ├── Base.php │ └── Total.php ├── Model │ ├── Base.php │ ├── Setup.php │ └── Total.php ├── controller │ ├── Admin.php │ ├── Base.php │ └── Override.php ├── Helper │ └── Base.php ├── fixtures │ ├── reviews.yml │ ├── catalogevents.yml │ ├── categories.yml │ ├── products.yml │ ├── customers.yml │ └── orders.yml ├── cd-paths.php └── install.sh ├── .gitignore ├── README ├── lib ├── yml.php ├── bash_shortcuts ├── local.php ├── fixtures │ ├── products.php │ ├── orders.php │ ├── categories.php │ ├── general.php │ ├── base.php │ └── customers.php ├── color.php ├── yaml │ ├── sfYamlDumper.php │ └── sfYaml.php ├── xml.php ├── db.php ├── base.php ├── bash_completion ├── taxes.php ├── filters.php └── interaction.php ├── magento-version ├── magento ├── magento-db ├── magento-option-source-models ├── magento-test-togglehints ├── magento-package ├── magento-jobs-condensed ├── magento-reindex ├── magento-rewrites ├── magento-customer ├── magento-event-types ├── magento-resolve ├── magento-dump-table ├── magento-help ├── magento-test-reset-password ├── magento-layout-file ├── magento-email ├── magento-config-files ├── magento-svn-propedit ├── magento-test-fixture ├── magento-core-diff ├── magento-plugin-setup ├── magento-theme ├── magento-cms-search ├── magento-config-check-syntax ├── magento-stats ├── magento-modules ├── magento-jobs-odesk ├── magento-jobs-freelancer ├── magento-jobs-craigslist ├── magento-layout ├── magento-plugin ├── magento-test-performance ├── magento-controller ├── magento-events ├── magento-jobs-elance ├── magento-tax-rate ├── magento-tax-class ├── magento-permissions ├── magento-cache ├── magento-profile ├── magento-class ├── magento-config ├── magento-test-expunge-data ├── magento-tax-rule ├── magento-email-create-templates ├── magento-db-integrity ├── magento-users └── magento-cd /data/plugin.csv: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/profiles/example.sql: -------------------------------------------------------------------------------- 1 | select now() from dual; 2 | -------------------------------------------------------------------------------- /data/etc/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /data/etc/adminhtml.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /data/app/layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | data/profiles/* 2 | !data/profiles/example* 3 | mtest 4 | data/cached-modules.txt 5 | data/defaults.php 6 | -------------------------------------------------------------------------------- /data/defaults.php.sample: -------------------------------------------------------------------------------- 1 | "; 4 | $company = "ABC"; 5 | $default_path = "/path/to/some/magento/project"; 6 | $colorize_output = true; 7 | -------------------------------------------------------------------------------- /data/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%COMPANY%_%PLUGIN%> 6 | 0.0.1 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Magento Command Line Tools 2 | 3 | Type 'magento-help ' for more information on a tool. 4 | 5 | Most tools are sensitive to a particular magento root, and will read 6 | your magento configuration manually. 7 | 8 | -------------------------------------------------------------------------------- /data/views/attributes.sql: -------------------------------------------------------------------------------- 1 | create or replace view v_eav_attributes as 2 | select attribute_id, attribute_code, backend_type, entity_type_code 3 | from eav_attribute ea 4 | join eav_entity_type et on et.entity_type_id = ea.entity_type_id 5 | ; 6 | -------------------------------------------------------------------------------- /data/README: -------------------------------------------------------------------------------- 1 | %COMPANY% - %PLUGIN% Module 2 | 3 | This module adds the following functionality: 4 | 5 | In order to install this module, run install.sh to symlink files as appropriate. 6 | 7 | Let me know if you have any trouble installing. Thanks! 8 | %AUTHOR% 9 | -------------------------------------------------------------------------------- /data/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%COMPANY%_%PLUGIN%> 5 | true 6 | local 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/recipes/block.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%module_lower%> 7 | %company%_%module%_Block 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/recipes/model.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%module_lower%> 7 | %company%_%module%_Model 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/views/invitations.sql: -------------------------------------------------------------------------------- 1 | create or replace view enterprise_invitation_v as 2 | select 3 | (select email from customer_entity ce where ce.entity_id = ei.customer_id) inviter, 4 | email invitee, status, date invite_date, signup_date 5 | from enterprise_invitation ei order by date desc; 6 | -------------------------------------------------------------------------------- /data/recipes/helper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%module_lower%> 7 | %company%_%module%_Helper 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/recipes/config_5_default_value.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%section_lower%> 6 | <%group_lower%> 7 | <%field_lower%>%default_value% 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/recipes/banner_type.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%type_handle%>%type_name% 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /data/recipes/layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%scope%> 6 | 7 | 8 | <%module_lower%> 9 | %module_lower%.xml 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /data/recipes/rewrite.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%override_handle%> 7 | 8 | %to_path% 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /data/views/inviters.sql: -------------------------------------------------------------------------------- 1 | create or replace view enterprise_invitation_users_v as 2 | select inviter, 3 | sum(case when status = 'sent' then 1 else 0 end) sent, 4 | sum(case when status = 'accepted' then 1 else 0 end) accepted, 5 | sum(case when status = 'canceled' then 1 else 0 end) cancelled 6 | from enterprise_invitation_v group by inviter order by sent desc; 7 | -------------------------------------------------------------------------------- /data/recipes/translate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%scope%> 5 | 6 | 7 | <%module%> 8 | 9 | %module%.csv 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /data/recipes/config_1_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%tabname_lower% translate="label" module="%module_lower%"> 7 | 8 | %sort_order% 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/recipes/override.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%classtype%> 6 | <%rewrite_module_lower%> 7 | 8 | <%rewrite_handle%>%rewrite_class% 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /data/cached-modules.txt: -------------------------------------------------------------------------------- 1 | reward 2 | catalogevent 3 | giftcardaccount 4 | purchaseorder 5 | hackedreferralpoints 6 | specifichandling 7 | purchase 8 | salesorderplanning 9 | advancedstock 10 | backgroundtask 11 | orderpreparation 12 | scanner 13 | organizer 14 | page 15 | directory 16 | tax 17 | shipping 18 | customer 19 | catalog 20 | sales 21 | cataloginventory 22 | core 23 | rewards 24 | -------------------------------------------------------------------------------- /data/recipes/emailtemplate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /data/recipes/crontab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%cronjob_name%> 7 | 8 | %frequency__m_h_dom_mon_dow% 9 | 10 | 11 | %cron_target%::%cron_method% 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /data/recipes/pagelayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%layout_handle%> 8 | 9 | 10 | %layout_handle% 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /data/recipes/controller.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%scope%> 7 | 8 | <%module_lower%> 9 | %use% 10 | 11 | %company%_%module% 12 | %frontname% 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /data/views/broken_configurables.sql: -------------------------------------------------------------------------------- 1 | create or replace view broken_configurables as 2 | select oi.item_id, so.increment_id, oi.sku, oi.created_at, cast(oi.qty_ordered as decimal) ordered 3 | from sales_flat_order_item oi 4 | join sales_flat_order so on so.entity_id = oi.order_id 5 | where 6 | product_type = 'configurable' and 7 | item_id not in ( 8 | select parent_item_id 9 | from sales_flat_order_item 10 | where parent_item_id is not null 11 | ); 12 | -------------------------------------------------------------------------------- /data/recipes/page_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%handle% module="%module_lower%" translate="label"> 8 | 9 | 10 | %handle% 11 | 1 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /data/recipes/acl_1_section.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%tabname_lower%> 8 | 9 | <%section_lower% translate="title"> 10 | %section% 11 | %sort_order% 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /data/lipsum.txt: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. 2 | Etiam lacus ligula, accumsan id imperdiet rhoncus, dapibus vitae arcu. 3 | Nulla non quam erat, luctus consequat nisi. 4 | Integer hendrerit lacus sagittis erat fermentum tincidunt. 5 | Cras vel dui neque. In sagittis commodo luctus. 6 | Mauris non metus dolor, ut suscipit dui. 7 | Aliquam mauris lacus, laoreet et consequat quis, bibendum id ipsum. 8 | Donec gravida, diam id imperdiet cursus, nunc nisl bibendum sapien, eget tempor neque elit in tortor. 9 | -------------------------------------------------------------------------------- /lib/yml.php: -------------------------------------------------------------------------------- 1 | 5 | // @author $Author$ 6 | // @version $Id$ 7 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 8 | // 9 | 10 | require_once("base.php"); 11 | 12 | require_once(dirname(__FILE__)."/yaml/sfYaml.php"); 13 | require_once(dirname(__FILE__)."/yaml/sfYamlInline.php"); 14 | require_once(dirname(__FILE__)."/yaml/sfYamlParser.php"); 15 | require_once(dirname(__FILE__)."/yaml/sfYamlDumper.php"); 16 | -------------------------------------------------------------------------------- /magento-version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | init_magento(); 13 | 14 | print Mage::getVersion()."\n"; 15 | 16 | function putdocs() { 17 | return array( 18 | "Return the current code version of Magento", 19 | "Usage: magento-version", 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /data/recipes/setup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%module_lower%_setup> 8 | 9 | %company%_%module% 10 | %setup_full_classname% 11 | 12 | 13 | %connection% 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /data/recipes/model_resource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%module_lower%> 7 | %company%_%module%_Model 8 | %company%_%module%_Model 9 | 10 | <%module_lower%_mysql4> 11 | %company%_%module%_Model_Mysql4 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /data/recipes/observer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%scope%> 7 | 8 | <%event%> 9 | 10 | <%unique_event_handle%> 11 | %type% 12 | %class_handle% 13 | %method% 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /data/setup/base.php: -------------------------------------------------------------------------------- 1 | installEntities(); 11 | 12 | 13 | // run DDL directly 14 | $installer->startSetup(); 15 | /*$installer->run(" 16 | ADD DDL STATEMENTS HERE 17 | ");*/ 18 | $installer->endSetup(); 19 | 20 | -------------------------------------------------------------------------------- /lib/bash_shortcuts: -------------------------------------------------------------------------------- 1 | # Add the following few lines to bashrc to get useful shortcuts: 2 | ## source bash shortcuts 3 | # . "$PATH_TO_UTILS/lib/bash_shortcuts" 4 | 5 | # magento aliases. (don't copy into bashrc) 6 | function magento-model() { magento-class model "$@"; } 7 | function magento-block() { magento-class block "$@"; } 8 | function magento-helper() { magento-class helper "$@"; } 9 | function mcd { cd $(magento-cd $@); } 10 | function mdb { $(magento db); } 11 | alias mc='magento config' 12 | alias m='magento' 13 | -------------------------------------------------------------------------------- /magento: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | 13 | if(2 > $server->argc) { 14 | print_help(); 15 | } 16 | 17 | $command = $server->argv[1]; 18 | array_shift($server->argv); 19 | array_shift($server->argv); 20 | $args = implode(" ", $server->argv); 21 | 22 | print `magento-$command $args`; 23 | 24 | function putdocs() { 25 | print_error(`magento-help`); 26 | } 27 | -------------------------------------------------------------------------------- /data/recipes/acl_2_group.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%tabname_lower%> 8 | 9 | <%section_lower%> 10 | 11 | <%group_lower% translate="title"> 12 | Permissions 13 | %sort_order% 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /data/recipes/config_2_section.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%section_lower% translate="label" module="%module_lower%"> 7 | 8 | %tabname_lower% 9 | text 10 | %sort_order% 11 | %show_in_default% 12 | %show_in_website% 13 | %show_in_store% 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /magento-db: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | 14 | echo "mysql -h {$db_config_array['host']} -u {$db_config_array['username']} --password={$db_config_array['password']} {$db_config_array['dbname']}"; 15 | 16 | function putdocs() { 17 | return array( 18 | "Connect to this site's database using the specified default credentials.", 19 | "Usage: mdb", 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /data/Block/Base.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%section_lower%> 7 | 8 | <%group_lower% translate="label"> 9 | 10 | text 11 | %sort_order% 12 | %show_in_default% 13 | %show_in_website% 14 | %show_in_store% 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /magento-option-source-models: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | 13 | $command = 'ack "" '.$magento.' | awk \'{print $2}\' | grep -v "\-\->" | sed -e "s/.*>\([^<]\+\).*/\1/" | sort | uniq'; 14 | print `$command`; 15 | 16 | function putdocs() { 17 | return array( 18 | "Get a list of source models (lists of selects) available for configuration values", 19 | "Usage: magento-option-source-models", 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /data/recipes/controller_override.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%scope%> 7 | 8 | <%core_module%> 9 | 10 | <%core_controller%> 11 | %module_lower%/%new_controller% 12 | %override_actions% 13 | 14 | %module_lower%/%new_controller%/%new_action% 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /magento-test-togglehints: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | 14 | $path = "dev/debug/template_hints"; 15 | $val = (int)get_config_data($path)? 0 : 1; 16 | 17 | print "Turning ".($val?"ON":"OFF")." template hints.\n"; 18 | set_config_data($path, $val); 19 | 20 | function putdocs() { 21 | return array( 22 | "Turn on and off template hints for the frontend.", 23 | "Usage: magento-test-togglehints", 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /data/views/product_suppliers.sql: -------------------------------------------------------------------------------- 1 | create or replace view product_supplier as 2 | select entity_id, sku, pps_supplier_num, sup_name 3 | from catalog_product_entity ce 4 | left join purchase_product_supplier pps on ce.entity_id = pps.pps_product_id 5 | left join purchase_supplier ps on pps.pps_supplier_num = ps.sup_id; 6 | 7 | create or replace view product_supplier_purchases as 8 | select entity_id, sku, pps_supplier_num, sup_name, 9 | (select count(*) from sales_flat_order_item where product_id = ce.entity_id) sold 10 | from catalog_product_entity ce 11 | left join purchase_product_supplier pps on ce.entity_id = pps.pps_product_id 12 | left join purchase_supplier ps on pps.pps_supplier_num = ps.sup_id; 13 | -------------------------------------------------------------------------------- /data/recipes/acl_3_field.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%tabname_lower%> 8 | 9 | <%section_lower%> 10 | 11 | <%group_lower%> 12 | 13 | <%field_lower% translate="title"> 14 | %field% 15 | %sort_order% 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /magento-package: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | 13 | if(1 != $server->argc) { 14 | print_help(); 15 | exit; 16 | } 17 | 18 | $edition = get_edition(); 19 | if(0 == strcmp($edition, "community")) { 20 | $package = "default"; 21 | } else { 22 | $package = $edition; 23 | } 24 | 25 | print "$package\n"; 26 | 27 | function putdocs() { 28 | return array( 29 | "Find the package currently in use for the site theme and skin directories.", 30 | "Usage: magento-package", 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /data/fixtures/reviews.yml: -------------------------------------------------------------------------------- 1 | # generates randomized reviews 2 | # 3 | # review statuses: 4 | # 1 approved 5 | # 2 pending 6 | # 3 not approved 7 | # 8 | # review entities: 9 | # 1 product 10 | # 2 customer 11 | # 3 category 12 | # 13 | 14 | reviews: 15 | entity: review/review 16 | base: &reviews_base 17 | store_id: fixture_store_id 18 | title: fixture_sentence 19 | detail: fixture_paragraph 20 | nickname: fixture_string 21 | customer_id: ~ 22 | created_at: fixture_past_date 23 | entity_id: 1 # product 24 | entity_pk_value: fixture_product 25 | status_id: 1 # approved 26 | iterate: 1 27 | 28 | entries: 29 | userless: 30 | <<: *reviews_base 31 | iterate: numeric_prompt 32 | userful: 33 | <<: *reviews_base 34 | customer_id: fixture_customer 35 | iterate: numeric_prompt 36 | -------------------------------------------------------------------------------- /lib/local.php: -------------------------------------------------------------------------------- 1 | 5 | // @author $Author$ 6 | // @version $Id$ 7 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 8 | // 9 | 10 | require_once("base.php"); 11 | 12 | // don't prompt for DB credentials, just steal them from Magento 13 | $use_default_connection = true; 14 | $local_file = "$magento/app/etc/local.xml"; 15 | $app_config = simplexml_load_file($local_file); 16 | if(!$app_config) { 17 | throw new Exception("Failed to load config XML file."); 18 | } 19 | 20 | $db_config = $app_config->global->resources->default_setup->connection; 21 | $db_config_array = array( 22 | 'host' => (string)$db_config->host, 23 | 'username' => (string)$db_config->username, 24 | 'password' => (string)$db_config->password, 25 | 'dbname' => (string)$db_config->dbname, 26 | ); 27 | -------------------------------------------------------------------------------- /data/recipes/config_4_field.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%section_lower%> 7 | 8 | <%group_lower%> 9 | 10 | <%field_lower% translate="label"> 11 | 12 | %frontend_type% 13 | %sort_order% 14 | %show_in_default% 15 | %show_in_website% 16 | %show_in_store% 17 | %comment% 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /data/controller/Override.php: -------------------------------------------------------------------------------- 1 | r["date"] }).each do |r| 33 | print "%-12s\t%6s\t%-20s\t%-65s\t%s\n" % [r["util"], r["date"], r["budget"], r["title"], r["link"]] 34 | end 35 | -------------------------------------------------------------------------------- /magento-reindex: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | init_magento(); 13 | 14 | $indices = array( 15 | "all" => "Run All Indexes", 16 | "catalogrule" => "Catalog Price Rules", 17 | ); 18 | 19 | print "Available indices:\n"; 20 | foreach($indices as $key => $selection) { 21 | printf("%-15s %s\n", $key, $selection); 22 | } 23 | 24 | $choice = user_array_choice("\nPick a reindexing action", array_keys($indices)); 25 | $choice(); 26 | 27 | ### ACTUAL INDEX RUNNERS ### 28 | 29 | function catalogrule() { 30 | print_error("Running catalogrule index."); 31 | $observer = Mage::getModel("catalogrule/observer"); 32 | $observer->applyAllRules($observer); 33 | print_error("Finished with catalogrule index."); 34 | } 35 | -------------------------------------------------------------------------------- /data/fixtures/catalogevents.yml: -------------------------------------------------------------------------------- 1 | # generates randomized categories 2 | # 3 | # Display State (countdown timer): 4 | # 0 - Nowhere 5 | # 1 - Category Page 6 | # 2 - Product Page 7 | # 3 - Both 8 | # 9 | 10 | catalog_events: 11 | entity: enterprise_catalogevent/event 12 | entity_type: catalogevent 13 | base: &event_base 14 | category_id: fixture_event_category 15 | date_start: ~ 16 | date_end: ~ 17 | display_state: 0 18 | sort_order: ~ 19 | iterate: 1 20 | 21 | entries: 22 | past_events: 23 | <<: *event_base 24 | date_start: fixture_past_date 25 | date_end: fixture_past_date 26 | iterate: numeric_prompt 27 | current_events: 28 | <<: *event_base 29 | date_start: fixture_past_date 30 | date_end: fixture_future_date 31 | iterate: numeric_prompt 32 | future_events: 33 | <<: *event_base 34 | date_start: fixture_future_date 35 | date_end: fixture_future_date 36 | iterate: numeric_prompt 37 | -------------------------------------------------------------------------------- /magento-rewrites: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | init_magento(); 13 | 14 | $types = array("blocks", "models"); 15 | print "\n\n"; 16 | foreach($types as $type) { 17 | $modules = Mage::app()->getConfig()->getNode("global/$type"); 18 | printf("%60s:\n", ucfirst($type)); 19 | foreach($modules[0] as $name => $config) { 20 | if(!$config->rewrite) { continue; } 21 | foreach($config->rewrite[0] as $rewrite => $node) { 22 | printf("%60s\t%s\n", "$name/$rewrite", "$node"); 23 | } 24 | } 25 | print "\n\n"; 26 | } 27 | 28 | function putdocs() { 29 | return array( 30 | "Get a list of all rewritten classes in the Magento installation", 31 | "Usage: magento-rewrites", 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /magento-customer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | init_magento(); 14 | 15 | switch(count($server->argv)) { 16 | case 2: 17 | $user = $server->argv[1]; 18 | break; 19 | default: 20 | print_help(); 21 | break; 22 | } 23 | 24 | $customer = Mage::getModel("customer/customer"); 25 | $customer->setWebsiteId(Mage::app()->getStore()->getWebsite()->getId()); 26 | 27 | if(is_numeric($user)) { 28 | $customer = $customer->load($user); 29 | } else { 30 | $customer = $customer->loadByEmail($user); 31 | } 32 | 33 | print "Customer info for {$customer->getEmail()} (CID {$customer->getId()})\n"; 34 | 35 | 36 | function putdocs() { 37 | print_error("Usage: magento-customer CUSTOMER\n"); 38 | } 39 | -------------------------------------------------------------------------------- /magento-event-types: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | 13 | 14 | $results = explode("\n", `ack "protected ._eventPrefix " $magento 2>/dev/null | sed -e "s/\s*protected \\\$_eventPrefix\s*= '\(\w*\)';/\\1/"`); 15 | print_error(sprintf("%-100s\t%-4s\t%s\n", "FILE", "LINE", "TYPE")); 16 | foreach($results as $result) { 17 | if(!strlen(trim($result)) || false !== strpos($result, "//")) { continue; } 18 | 19 | $result = str_replace($magento, "", $result); 20 | 21 | list($file, $line, $type) = explode(":", $result); 22 | printf("%-100s\t%-4s\t%s\n", $file, $line, $type); 23 | } 24 | 25 | function putdocs() { 26 | return array( 27 | "Get a list of entities in Magento that fire default Magento events", 28 | "Usage: magento-event-types", 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /magento-resolve: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | init_magento(); 13 | 14 | if(2 != $server->argc) { 15 | print_help(); 16 | exit; 17 | } 18 | 19 | $handle = $server->argv[1]; 20 | $types = array("helper", "model", "block"); 21 | $found = array(); 22 | 23 | foreach($types as $type) { 24 | try { 25 | $class = Mage::getConfig()->getGroupedClassName($type, $handle); 26 | if(class_exists($class)) { 27 | $found[$type] = $class; 28 | } 29 | } catch(Exception $e) { 30 | // foo! 31 | } 32 | } 33 | 34 | foreach($found as $type => $class) { 35 | print "$type: $class\n"; 36 | } 37 | 38 | function putdocs() { 39 | return array( 40 | "Resolve a magento class handle into a classname.", 41 | "Usage: magento-resolve HANDLE", 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /magento-dump-table: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | 14 | if(2 != $server->argc) { 15 | print_help(); 16 | } 17 | 18 | $table = $server->argv[1]; 19 | $res = mysql_query("select * from $table") or die(mysql_error()); 20 | if(!mysql_num_rows($res)) { 21 | print_error("No rows found. Go away."); 22 | } 23 | 24 | while($row = mysql_fetch_assoc($res)) { 25 | if(!isset($headers)) { 26 | $headers = true; 27 | $keys = array_keys($row); 28 | print "\"".implode("\",\"", $keys)."\"\n"; 29 | } 30 | print "\"".implode("\",\"", $row)."\"\n"; 31 | } 32 | 33 | function putdocs() { 34 | return array( 35 | "Dump the entire contents of a Magento table in CSV format.", 36 | "Usage: magento-dump-table TABLENAME", 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /magento-help: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | 13 | $basedir = dirname(__FILE__); 14 | $commands = explode("\n", `ls $basedir | grep "magento-" | sed -e "s/magento-//"`); 15 | 16 | if(1 >= $server->argc) { 17 | print "\n"; 18 | readfile("$basedir/README"); 19 | print "\nAvailable commands:\n"; 20 | foreach($commands as $command) { 21 | print " $command\n"; 22 | } 23 | exit; 24 | } 25 | 26 | $cmd = $server->argv[1]; 27 | if(in_array($cmd, $commands)) { 28 | passthru("magento-$cmd --help"); 29 | } else { 30 | print "No help found because you're just making up pretend commands. So sad.\n"; 31 | } 32 | 33 | function putdocs() { 34 | return array( 35 | "Get a list of commands, and information about each command", 36 | "Usage: magento-help COMMAND", 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /data/Block/Total.php: -------------------------------------------------------------------------------- 1 | labeltotal 32 | // remember to use getColspan to get the columns right for checkout & cart 33 | protected $_template = "path/to/template.phtml"; 34 | 35 | 36 | protected function _construct() { 37 | parent::_construct(); 38 | $this->setTemplate($this->_template); 39 | } 40 | 41 | public function getTotal() { 42 | // grab the total charge 43 | } 44 | 45 | }//class %CLASS% 46 | -------------------------------------------------------------------------------- /magento-test-reset-password: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | init_magento(); 14 | 15 | switch($server->argc) { 16 | case 2: 17 | $user = $server->argv[1]; 18 | break; 19 | default: 20 | print_help(); 21 | break; 22 | } 23 | 24 | $customer = Mage::getModel("customer/customer"); 25 | $customer->setWebsiteId(Mage::app()->getStore()->getWebsite()->getId()); 26 | 27 | if(is_numeric($user)) { 28 | $customer = $customer->load($user); 29 | } else { 30 | $customer = $customer->loadByEmail($user); 31 | } 32 | 33 | $password = "password"; 34 | $customer->changePassword($password); 35 | print "$user's password is now $password\n"; 36 | 37 | function putdocs() { 38 | return array( 39 | "Reset passwords of users by email address or ID", 40 | "Usage: magento-test-reset-password USER", 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /magento-layout-file: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); // load everything 12 | 13 | switch($server->argc) { 14 | case 2: 15 | $module = $server->argv[1]; 16 | break; 17 | default: 18 | $module = current_module("local"); 19 | break; 20 | } 21 | 22 | if("" == $module) { 23 | print_help(); 24 | } 25 | 26 | print "Adding layout file for $module\n"; 27 | 28 | $package = trim(`magento-package`); 29 | $theme = trim(`magento-theme`); 30 | $target = "$magento/app/design/frontend/$package/$theme/layout"; 31 | $target_filename = strtolower("$module.xml"); 32 | 33 | if(file_exists("$target/$target_filename")) { 34 | print_error("Layout file already exists for $version."); 35 | exit; 36 | } 37 | 38 | `cp $support_dir/app/layout.xml $target/$target_filename`; 39 | 40 | function putdocs() { 41 | return array( 42 | "Create layout file for a module", 43 | "Usage: magento-layout-file MODULE", 44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /data/recipes/total.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | <%totalname%> 12 | %model_handle% 13 | %before% 14 | %after% 15 | %block_handle% 16 | %block_handle% 17 | 18 | 19 | 20 | 21 | 22 | 23 | <%totalname%> 24 | %model_handle% 25 | %before% 26 | %after% 27 | %block_handle% 28 | %block_handle% 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | <%totalname%>%priority% 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /lib/fixtures/products.php: -------------------------------------------------------------------------------- 1 | taxclasses)) { 5 | $classes = array(); 6 | $sqlst = "select class_id from tax_class where class_type = 'PRODUCT' order by rand() limit 1"; 7 | $res = mysql_query($sqlst); 8 | 9 | while($row = mysql_fetch_array($res)) { 10 | $classes[] = $row['class_id']; 11 | } 12 | $context->taxclasses = $classes; 13 | } 14 | 15 | shuffle($context->taxclasses); 16 | return $context->taxclasses; 17 | } 18 | 19 | function fixture_tax_class($entry, $context) { 20 | $classes = _classes($context); 21 | return $classes[0]; 22 | } 23 | 24 | function post_process_catalog_product($entry, $context, $entity) { 25 | $inv = Mage::getModel("cataloginventory/stock_item"); 26 | $inv->setData($entry); 27 | $inv->setProductId($entity->getEntityId()); 28 | $inv->save(); 29 | 30 | $num = $entry['num_categories']; 31 | if($num) { 32 | $cats = array(); 33 | for($i = 0; $i < $num; $i++) { 34 | $cats[] = fixture_visible_category(); 35 | } 36 | $entity->setCategoryIds($cats)->save(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /magento-email: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | init_magento(); 14 | 15 | $existing_templates = array(); 16 | $sqlst = "select orig_template_code from core_email_template"; 17 | $res = mysql_query($sqlst); 18 | if(mysql_num_rows($res)) { 19 | while($row = mysql_fetch_array($res)) { 20 | $existing_templates[] = $row['orig_template_code']; 21 | } 22 | } 23 | 24 | print "\n"; 25 | $email_templates = Mage::app()->getConfig()->getNode("global/template/email"); 26 | foreach($email_templates[0] as $template => $params) { 27 | $loaded = in_array($template, $existing_templates)?"loaded":"new"; 28 | printf("%-50s\t%-6s\t%s\t%-35s\t%s\n", $template, $loaded, $params->type, $params->file, $params->label); 29 | } 30 | print "\n"; 31 | 32 | function putdocs() { 33 | return array( 34 | "List all Magento emails, and whether they have been loaded into the database before.", 35 | "Usage: magento-email", 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /data/profiles/example: -------------------------------------------------------------------------------- 1 | 'siteaddress.com', 6 | 'config' => array( 7 | 'web/unsecure/base_url' => 'http://example.localdomain.com/', 8 | 'web/secure/base_url' => 'http://example.localdomain.com/', 9 | 10 | 'payment/checkmo/active' => 1, 11 | 'payment/authorizenet/test' => 1, 12 | 'payment/authorizenet/cgi_url' => 'https://test.authorize.net/gateway/transact.dll', 13 | 'payment/authorizenet/debug' => 1, 14 | 'payment/authorizenet/login' => '0:2:74532adb51f40419:u5Xq4CxS54A9GmDUkPOBvw==', 15 | 'payment/authorizenet/trans_key' => '0:2:424d60aa7a0eea05:/QRvmhK6KdDAujwiGmBzKw==', 16 | 17 | 'admin/security/session_cookie_lifetime' => '86400', 18 | 19 | 'design/theme/template'=> 'versiontwo', 20 | 'design/theme/skin' => 'versiontwo', 21 | 'design/theme/layout' => 'versiontwo', 22 | 23 | 'dev/js/merge_files' => '0', 24 | 'dev/css/merge_css_files' => '0', 25 | ), 26 | 'cms_pages' => array( 27 | 'home' => array( 28 | 'root_template' => 'version_two_homepage', 29 | ), 30 | ), 31 | 'delete_designs' => true, 32 | 'cache_all' => false, 33 | 'sql' => array('example.sql'), 34 | ); 35 | -------------------------------------------------------------------------------- /magento-config-files: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | init_magento(); 13 | 14 | $all_files = array(); 15 | $config = Mage::getConfig(); 16 | $modules = $config->getNode("modules")->children(); 17 | foreach($modules as $modName => $module) { 18 | if(!$module->is("active")) { 19 | print_error("$modName isn't active.\n"); 20 | continue; 21 | } 22 | $configDir = $config->getModuleDir("etc", $modName); 23 | $files = explode("\n", trim(`ls $configDir | grep xml`)); 24 | foreach($files as $file) { 25 | if(!isset($all_files[$file])) { 26 | $all_files[$file] = array(); 27 | } 28 | $all_files[$file][] = $modName; 29 | } 30 | } 31 | 32 | foreach($all_files as $file => $modules) { 33 | print str_repeat("=",20)." $file ".str_repeat("=",20)."\n"; 34 | for($i = 0; $i < count($modules); $i++) { 35 | printf("%-30s", $modules[$i]); 36 | if($i && ($i%3 == 2)) { 37 | print "\n"; 38 | } 39 | } 40 | print "\n\n"; 41 | } 42 | -------------------------------------------------------------------------------- /magento-svn-propedit: -------------------------------------------------------------------------------- 1 | mkdir -p media/content/images/cms-images 2 | mkdir -p webservice/uploads 3 | rm -f app/etc/use_cache.ser 4 | mkdir -p var/cache var/report var/locks var/log var/session var/logging 5 | mkdir -p media/catalog/product 6 | 7 | svn revert webservice/.htaccess 8 | svn revert webservice/.htpasswd 9 | svn revert app/etc/local.xml 10 | 11 | svn add . 12 | svn add app/etc/local.xml.dist 13 | svn add media 14 | svn add media/content 15 | 16 | svn mv app/etc/local.xml app/etc/local.xml.dist 17 | svn mv errors/local.xml errors/local.xml.dist 18 | 19 | svn propset svn:ignore "tmp" media 20 | svn propset svn:ignore "cache" media/catalog/product 21 | svn propset svn:ignore "staging" . 22 | svn propset svn:ignore ".thumbs" media/content/images/cms-images 23 | svn propset svn:ignore "local.xml 24 | use_cache.ser" app/etc 25 | svn propset svn:ignore ".htaccess 26 | .htpasswd" webservice 27 | svn propset svn:ignore "*" webservice/uploads 28 | svn propset svn:ignore "report 29 | cache 30 | tmp 31 | import 32 | export 33 | backups" var 34 | svn propset svn:ignore "*" var/locks 35 | svn propset svn:ignore "*" var/log 36 | svn propset svn:ignore "*" var/session 37 | svn propset svn:ignore "*" var/logging 38 | svn propset svn:ignore "local.xml" errors 39 | 40 | 41 | svn revert var/locks/* 42 | -------------------------------------------------------------------------------- /magento-test-fixture: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/yml.php"); 13 | require_once("lib/db.php"); 14 | session_start(); 15 | init_magento(); 16 | 17 | if(2 > $server->argc) { 18 | print_help(); 19 | } 20 | 21 | // include all fixture libraries 22 | $files = explode("\n", trim(`ls $lib_dir/fixtures`)); 23 | foreach($files as $file) { 24 | require_once("$lib_dir/fixtures/$file"); 25 | } 26 | 27 | // load requested fixtures 28 | try { 29 | for($i = 1; $i < $server->argc; $i++) { 30 | $fixture = $server->argv[$i]; 31 | print "loading fixture: $fixture\n"; 32 | load_fixture($fixture); 33 | print "\n"; 34 | } 35 | } catch(Exception $e) { 36 | print "Fixture import bailed partway through. Likely partial data needs to be expunged.\nException: ".$e->getMessage()."\n"; 37 | print $e->getTraceAsString(); 38 | } 39 | 40 | function putdocs() { 41 | return array( 42 | "Create nonce data to test the system at load.", 43 | "Usage: magento-test-fixture FIXTURE", 44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /magento-core-diff: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); // load everything 12 | 13 | $version = trim(`magento-version`); 14 | print_error("Local copy: $magento/app/code/core\n"); 15 | print_error("Comparing to $version\n"); 16 | print_error("\n\n"); 17 | 18 | $edition = get_edition(); 19 | $subdir = ""; 20 | if(0 == strcmp("enterprise", $edition)) { 21 | $subdir = "enterprise/"; 22 | } 23 | 24 | $clean_dir = "/var/www/magento/$subdir$version"; 25 | if(!file_exists($clean_dir)) { 26 | print_error("Can't do diff, looking for clean copy: $clean_dir. Go download a clean copy before continuing.\n"); 27 | exit; 28 | } 29 | 30 | passthru("diff --exclude='.svn' -r $clean_dir/app/code/core $magento/app/code/core"); 31 | 32 | function putdocs() { 33 | return array( 34 | "Does a recursive comparison between the current installation's core files", 35 | "and a clean copy of Magento to check for heretical changes to them. You need", 36 | "to have downloaded a copy of the Magento version matching this one to do", 37 | "the diff.", 38 | "Usage: magento-core-diff", 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /lib/color.php: -------------------------------------------------------------------------------- 1 | 6 | // @author $Author$ 7 | // @version $Id$ 8 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 9 | // 10 | 11 | require_once("base.php"); 12 | 13 | foreach($server->argv as $key => $param) { 14 | if(0 == strcmp("--color=1", $param)) { 15 | $colorize_output = true; 16 | unset($server->argv[$key]); 17 | $server->argc -= 1; 18 | } else if(0 == strcmp("--color=0", $param)) { 19 | $colorize_output = false; 20 | unset($server->argv[$key]); 21 | $server->argc -= 1; 22 | } 23 | } 24 | 25 | define('C_HI1', "\033[38;5;108m"); // green 26 | define('C_HI2', "\033[38;5;116m"); // blue 27 | define('C_HI3', "\033[38;5;174m"); // red 28 | define('C_HI4', "\033[38;5;151m"); // lime 29 | define('C_LO1', "\033[38;5;245m"); // gray 30 | define('C_LO2', "\033[38;5;223m"); // l. yellow 31 | define('C_LO3', "\033[38;5;181m"); // pink 32 | define('C_VLO1', "\033[38;5;240m"); // dk. gray 33 | define('C_RESET', "\033[37m"); 34 | 35 | function colorize($string, $color) { 36 | global $colorize_output; 37 | if(!$colorize_output) { return $string; } 38 | 39 | return $color.$string.C_RESET; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /magento-plugin-setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); // load everything 12 | 13 | switch($server->argc) { 14 | case 2: 15 | $module = $server->argv[1]; 16 | break; 17 | default: 18 | $module = current_module("local"); 19 | break; 20 | } 21 | 22 | print "Adding setup file for $module\n"; 23 | 24 | $module_path = module_path($module); 25 | $module_lower = strtolower($module); 26 | $target = "$magento/app/code/$module_path/sql/{$module_lower}_setup"; 27 | 28 | list($codepool, $company, $mod) = explode("/", $module_path); 29 | $version = module_version($company, $module); 30 | $target_filename = "mysql4-install-{$version}.php"; 31 | 32 | if(file_exists("$target/$target_filename")) { 33 | print_error("Setup file already exists for $version. Try incrementing your version and try again.\n"); 34 | exit; 35 | } 36 | 37 | `mkdir -p $target`; 38 | `cp $support_dir/setup/base.php $target/$target_filename`; 39 | 40 | function putdocs() { 41 | return array( 42 | "Create setup files for a module, including a setup class and mysql-* install file", 43 | "Usage: magento-plugin-setup [MODULE]", 44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /data/fixtures/categories.yml: -------------------------------------------------------------------------------- 1 | # generates randomized categories 2 | # 3 | # Display Mode: 4 | # PRODUCTS 5 | # PAGE 6 | # PRODUCTS_AND_PAGE 7 | # 8 | 9 | categories: 10 | entity: catalog/category 11 | entity_type: category 12 | base: &category_base 13 | parent_id: fixture_category_id 14 | all_children: ~ 15 | available_sort_by: ~ 16 | attribute_set_id: 3 17 | children: ~ 18 | children_count: 0 19 | custom_design: ~ 20 | custom_design_apply: ~ 21 | custom_design_from: ~ 22 | custom_design_to: ~ 23 | custom_layout_update: ~ 24 | custom_use_parent_settings: 1 25 | default_sort_by: ~ 26 | description: ~ 27 | display_mode: 'PRODUCTS' 28 | image: ~ 29 | include_in_menu: 1 30 | is_active: 1 31 | is_anchor: 0 32 | landing_page: ~ 33 | level: fixture_child_level 34 | meta_description: ~ 35 | meta_keywords: ~ 36 | meta_title: ~ 37 | name: fixture_capsed_string 38 | page_layout: ~ 39 | path: ~ 40 | path_in_store: ~ 41 | position: fixture_next_child_position 42 | url_key: fixture_url_key 43 | url_path: fixture_url_path 44 | iterate: 1 45 | 46 | entries: 47 | toplevel: 48 | <<: *category_base 49 | level: 2 50 | parent_id: fixture_root_category 51 | iterate: numeric_prompt 52 | children: 53 | <<: *category_base 54 | level: 3 55 | parent_id: fixture_toplevel_category 56 | iterate: numeric_prompt 57 | -------------------------------------------------------------------------------- /magento-theme: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 8 | // @author $Author$ 9 | // @version $Id$ 10 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 11 | 12 | $use_default_connection = true; 13 | require_once("lib/db.php"); 14 | 15 | switch($server->argc) { 16 | case 3: 17 | $scope = $server->argv[1]; 18 | $scope_id = $server->argv[2]; 19 | break; 20 | case 2: 21 | $scope = $server->argv[1]; 22 | $scope_id = "%"; 23 | break; 24 | default: 25 | $scope = "default"; 26 | $scope_id = 0; 27 | break; 28 | } 29 | 30 | $sqlst = "select value from core_config_data where path = 'design/theme/skin' and scope = '$scope' and scope_id like '$scope_id' limit 1"; 31 | $res = mysql_query($sqlst, $db_conn) or die("mysql error: ".mysql_error()); 32 | 33 | $row = mysql_fetch_array($res); 34 | 35 | if(!$row['value']) { 36 | $row['value'] = "default"; 37 | } 38 | 39 | print "{$row['value']}\n"; 40 | 41 | function putdocs() { 42 | return array( 43 | "Return the name of the currently configured theme.", 44 | "Usage: magento-theme", 45 | "", "It is possible to have multiple active themes, so we will use", 46 | "the current skin as a reasonable proxy for this information. Note that", 47 | "it is also possible to designate seasonal designs, which are not", 48 | "accounted for by this utility.", 49 | ); 50 | } 51 | -------------------------------------------------------------------------------- /data/Model/Setup.php: -------------------------------------------------------------------------------- 1 | array( 40 | 'entity_model' => 'catalog/product', 41 | 'attribute_model' => 'catalog/resource_eav_attribute', 42 | 'table' => 'catalog/product', 43 | 'additional_attribute_table' => 'catalog/eav_attribute', 44 | 'entity_attribute_collection' => 'catalog/product_attribute_collection', 45 | 'attributes' => array( 46 | 'new_attribute_name' => array( 47 | // attribute data 48 | ), 49 | ), 50 | ), 51 | ); 52 | }//end getDefaultEntities 53 | 54 | }//class %CLASS% 55 | -------------------------------------------------------------------------------- /magento-cms-search: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | //init_magento(); 14 | 15 | switch(count($server->argv)) { 16 | case 1: 17 | print_help(); 18 | exit; 19 | default: 20 | $pattern = $server->argv[1]; 21 | break; 22 | } 23 | 24 | // forget all this fancy stuff, let's do some SQL :) 25 | $pattern = mysql_real_escape_string($pattern); 26 | 27 | // do work 28 | print_set("select title, identifier from cms_block where content like '%$pattern%'", "CMS Blocks"); 29 | print_set("select title, identifier from cms_page where content like '%$pattern%'", "CMS Pages"); 30 | 31 | if(0 == strcmp(get_edition(), "enterprise")) { 32 | print_set("select name title, '-' identifier from enterprise_banner_content c, enterprise_banner b where c.banner_id = b.banner_id and banner_content like '%$pattern%'", "Banners"); 33 | } 34 | 35 | function print_set($sqlst, $title) { 36 | $res = mysql_query($sqlst) or die(mysql_error()); 37 | if(mysql_num_rows($res)) { 38 | print "$title\n"; 39 | while($row = mysql_fetch_array($res)) { 40 | printf(" %s (%s)\n", $row['title'], $row['identifier']); 41 | } 42 | print "\n"; 43 | } 44 | } 45 | 46 | function putdocs() { 47 | return array( 48 | "Search through CMS content created by the administrator for a string", 49 | "Usage: magento-cms-search PATTERN", 50 | ); 51 | } 52 | -------------------------------------------------------------------------------- /magento-config-check-syntax: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 8 | // @author $Author$ 9 | // @version $Id$ 10 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 11 | 12 | require_once("lib/base.php"); 13 | require_once("lib/xml.php"); 14 | 15 | switch(count($server->argv)) { 16 | case 2: 17 | $module = $server->argv[1]; 18 | break; 19 | default: 20 | print_help(); 21 | break; 22 | } 23 | 24 | # attempt to auto-detect a module 25 | if(0 == strcmp("-", $module)) { 26 | $module = current_module("local"); 27 | } 28 | 29 | try { 30 | $module_path = module_path($module); 31 | $files = `ls $magento/app/code/$module_path/etc`; 32 | $files = explode("\n", $files); 33 | foreach($files as $file) { 34 | if(!$file) { continue; } 35 | print "Checking $file\n"; 36 | $elem = @simplexml_load_file("$magento/app/code/$module_path/etc/$file"); 37 | if(!$elem) { 38 | throw new Exception("Parser failed while attempting to parse $file!! You suck!"); 39 | } 40 | } 41 | 42 | print "\nAll files seem to be valid XML.\n"; 43 | } catch( Exception $em_all ) { 44 | print_error($em_all->getMessage()."\n"); 45 | } 46 | 47 | function putdocs() { 48 | return array( 49 | "Check to make sure that a module's configuration files are valid XML", 50 | "Usage: magento-config-check-syntax module", 51 | ); 52 | } 53 | -------------------------------------------------------------------------------- /data/fixtures/products.yml: -------------------------------------------------------------------------------- 1 | # generates randomized products 2 | # 3 | # Status: 4 | # 1: Enabled 5 | # 2: Disabled 6 | # 7 | # Visibility: 8 | # 1: Not Visible 9 | # 2: Visible in Catalog 10 | # 3: Visible in Search 11 | # 4: Both 12 | # 13 | 14 | products: 15 | entity: catalog/product 16 | entity_type: catalog_product 17 | base: &products_base 18 | entity_type_id: fixture_entity_type 19 | attribute_set_id: 4 20 | type_id: simple 21 | sku: fixture_string 22 | has_options: 0 23 | required_options: 0 24 | created_at: ~ 25 | updated_at: ~ 26 | name: fixture_capsed_string 27 | meta_title: fixture_sentence 28 | meta_description: fixture_sentence 29 | image: ~ 30 | small_image: ~ 31 | thumbnail: ~ 32 | url_key: fixture_url_key 33 | url_path: fixture_url_path 34 | custom_design: ~ 35 | page_layout: ~ 36 | image_label: ~ 37 | small_image_label: ~ 38 | gift_message_available: 2 39 | price: fixture_double 40 | special_price: ~ 41 | cost: ~ 42 | weight: 1.000 43 | description: fixture_paragraph 44 | short_description: fixture_sentence 45 | meta_keyword: fixture_sentence 46 | custom_layout_update: ~ 47 | special_from_date: ~ 48 | special_to_date: ~ 49 | news_from_date: ~ 50 | news_to_date: ~ 51 | custom_design_from: ~ 52 | custom_design_to: ~ 53 | status: 1 54 | tax_class_id: fixture_tax_class 55 | visibility: 4 56 | enable_googlecheckout: 1 57 | is_in_stock: 1 58 | stock_id: 1 59 | use_config_manage_stock: 1 60 | qty: 100, 61 | is_in_stock: 1 62 | num_categories: 3 63 | iterate: 1 64 | 65 | entries: 66 | simple_products: 67 | <<: *products_base 68 | iterate: numeric_prompt 69 | -------------------------------------------------------------------------------- /magento-stats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | 14 | $schema = $db_config_array['dbname']; 15 | $tables = array( 16 | "admin_user" => "user_id", 17 | "catalog_category_entity" => "entity_id", 18 | "catalog_product_entity" => "entity_id", 19 | "core_store" => "store_id", 20 | "customer_entity" => "entity_id", 21 | "sales_flat_quote" => "entity_id", 22 | "sales_order" => "entity_id", 23 | "sales_flat_order" => "entity_id", 24 | "rating" => "rating_id", 25 | "review" => "review_id", 26 | ); 27 | $sqlst = "select table_name, table_rows, data_length from information_schema.tables where table_schema = '$schema' and table_name in (\"".implode("\", \"", array_keys($tables))."\")"; 28 | 29 | $res = mysql_query($sqlst); 30 | if(!$res) { 31 | throw new Exception("Failed at life."); 32 | } 33 | 34 | $format_string = "%30s\t%10s\t%10s\t%10s\t%10s\n"; 35 | printf($format_string, "TABLE", "ROWS", "DATA", "MIN", "MAX"); 36 | while($row = mysql_fetch_array($res)) { 37 | $pk = $tables[$row["table_name"]]; 38 | $sqlst = "select min($pk) min, max($pk) max from {$row['table_name']}"; 39 | $sres = mysql_fetch_array(mysql_query($sqlst)); 40 | 41 | $kbytes = $row['data_length']/1024; 42 | printf($format_string, $row["table_name"], $row["table_rows"], "{$kbytes}k", $sres['min'], $sres['max']); 43 | } 44 | 45 | function putdocs() { 46 | return array( 47 | "List critical stats from the database.", 48 | "Usage: magento-stats", 49 | ); 50 | } 51 | -------------------------------------------------------------------------------- /data/fixtures/customers.yml: -------------------------------------------------------------------------------- 1 | # generates default customer / address entries 2 | 3 | customers: 4 | entity: customer/customer 5 | bases: 6 | base: &customers_base 7 | confirmation: fixture_string 8 | created_at: fixture_past_date 9 | created_in: fixture_store_name 10 | default_billing: ~ 11 | default_shipping: ~ 12 | dob: ~ 13 | email: fixture_email 14 | firstname: fixture_capsed_string 15 | gender: ~ 16 | group_id: fixture_group_id 17 | lastname: fixture_capsed_string 18 | middlename: ~ 19 | password_hash: fixture_password_hash 20 | prefix: ~ 21 | store_id: fixture_store_id 22 | suffix: ~ 23 | taxvat: ~ 24 | website_id: fixture_website_id 25 | 26 | entries: 27 | testy_mctestington: 28 | <<: *customers_base 29 | firstname: Testy 30 | lastname: McTestington 31 | 32 | bulk_customers: 33 | <<: *customers_base 34 | iterate: 500 35 | 36 | addresses: 37 | entity: customer/address 38 | bases: 39 | base: &addresses_base 40 | city: fixture_capsed_string 41 | company: fixture_capsed_string 42 | country_id: fixture_country 43 | fax: fixture_phone 44 | firstname: fixture_capsed_string 45 | lastname: fixture_capsed_string 46 | middlename: ~ 47 | parent_id: fixture_customer_by_addresses 48 | postcode: fixture_zip 49 | prefix: ~ 50 | region: fixture_region 51 | region_id: fixture_region_id 52 | street: fixture_street 53 | suffix: ~ 54 | telephone: fixture_phone 55 | 56 | entries: 57 | bulk_addresses: 58 | <<: *addresses_base 59 | iterate: 1000 60 | 61 | chicago: 62 | <<: *addresses_base 63 | city: Chicago 64 | country_id: US 65 | postcode: 60606 66 | region: Illinois 67 | 68 | -------------------------------------------------------------------------------- /data/fixtures/orders.yml: -------------------------------------------------------------------------------- 1 | orders: 2 | entity: sales/order 3 | entity_type: order 4 | base: &order_base 5 | state: new 6 | status: pending 7 | protect_code: fixture_string 8 | shipping_description: 'Free Shipping - Free' 9 | is_virtual: 0 10 | store_id: fixture_store_id 11 | customer_id: fixture_customer 12 | base_discount_amount: 0 13 | base_grand_total: 0 14 | base_shipping_amount: 0 15 | base_shipping_tax_amount: 0 16 | base_subtotal: 0 17 | base_tax_amount: 0 18 | base_to_global_rate: 1 19 | base_to_order_rate: 1 20 | discount_amount: 0 21 | grand_total: 0 22 | shipping_amount: 0 23 | shipping_tax_amount: 0 24 | store_to_base_rate: 1 25 | store_to_order_rate: 1 26 | subtotal: 0 27 | tax_amount: 0 28 | total_qty_ordered: 0 29 | customer_is_guest: 0 30 | customer_note_notify: 0 31 | billing_address_id: fixture_customer_address 32 | customer_group_id: fixture_customer_group 33 | quote_id: 1 34 | shipping_address_id: fixture_customer_address 35 | base_shipping_discount_amount: 0 36 | base_subtotal_incl_tax: 0 37 | base_total_due: 0 38 | shipping_discount_amount: 0 39 | subtotal_incl_tax: 0 40 | total_due: 0 41 | weight: 0 42 | base_currency_code: USD 43 | customer_email: fixture_customer_email 44 | customer_firstname: fixture_capsed_string 45 | customer_lastname: fixture_capsed_string 46 | global_currency_code: USD 47 | order_currency_code: USD 48 | shipping_method: freeshipping_freeshipping 49 | store_currency_code: USD 50 | store_name: fixture_long_store_name 51 | total_item_count: 1 52 | gift_cards: "a:0:{}" 53 | stocks_updated: 1 54 | payment_validated: 0 55 | is_valid: 1 56 | entity_type_id: fixture_entity_type 57 | 58 | entries: 59 | sales: 60 | <<: *order_base 61 | iterate: numeric_prompt 62 | total_qty_ordered: 10 63 | -------------------------------------------------------------------------------- /lib/yaml/sfYamlDumper.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | require_once(dirname(__FILE__).'/sfYamlInline.php'); 12 | 13 | /** 14 | * sfYamlDumper dumps PHP variables to YAML strings. 15 | * 16 | * @package symfony 17 | * @subpackage yaml 18 | * @author Fabien Potencier 19 | * @version SVN: $Id: sfYamlDumper.class.php 10575 2008-08-01 13:08:42Z nicolas $ 20 | */ 21 | class sfYamlDumper 22 | { 23 | /** 24 | * Dumps a PHP value to YAML. 25 | * 26 | * @param mixed $input The PHP value 27 | * @param integer $inline The level where you switch to inline YAML 28 | * @param integer $indent The level o indentation indentation (used internally) 29 | * 30 | * @return string The YAML representation of the PHP value 31 | */ 32 | public function dump($input, $inline = 0, $indent = 0) 33 | { 34 | $output = ''; 35 | $prefix = $indent ? str_repeat(' ', $indent) : ''; 36 | 37 | if ($inline <= 0 || !is_array($input) || empty($input)) 38 | { 39 | $output .= $prefix.sfYamlInline::dump($input); 40 | } 41 | else 42 | { 43 | $isAHash = array_keys($input) !== range(0, count($input) - 1); 44 | 45 | foreach ($input as $key => $value) 46 | { 47 | $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value); 48 | 49 | $output .= sprintf('%s%s%s%s', 50 | $prefix, 51 | $isAHash ? sfYamlInline::dump($key).':' : '-', 52 | $willBeInlined ? ' ' : "\n", 53 | $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + 2) 54 | ).($willBeInlined ? "\n" : ''); 55 | } 56 | } 57 | 58 | return $output; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/xml.php: -------------------------------------------------------------------------------- 1 | preserveWhiteSpace = false; 20 | $dom->formatOutput = true; 21 | $loaded = $dom->loadXML($simplexml->asXML()); 22 | 23 | if(!$loaded) { 24 | throw new Exception("Invalid XML detected."); 25 | } 26 | 27 | $xml_output = $dom->saveXML(); 28 | 29 | // big groups get a little spacing 30 | $xml_output = preg_replace("/\n <([a-z]+)>\n/i", "\n\n <\\1>\n", $xml_output); 31 | $xml_output = str_replace("", "\n", $xml_output); 32 | 33 | return $xml_output; 34 | } 35 | 36 | // write some XML to a file, after formatting it nicely. 37 | function write_xml(SimpleXMLElement $xml, $filename) { 38 | $fp = fopen($filename, "w+"); 39 | if(!$fp) { 40 | throw new Exception("Couldn't open $filename for writing"); 41 | } 42 | 43 | fwrite($fp, get_xml_output($xml)); 44 | fclose($fp); 45 | } 46 | 47 | // recursively merge two xml structures 48 | function merge_xml($xml1, $xml2) { 49 | $xml1 = get_xml($xml1); 50 | $xml2 = get_xml($xml2); 51 | 52 | foreach($xml2 as $tag => $elem2) { 53 | if(!$xml1->{$tag}) { 54 | $xml1->{$tag} = trim((string)$elem2); 55 | } 56 | 57 | if(count($elem2->attributes())) { 58 | foreach($elem2->attributes() as $attr => $value) { 59 | $xml1->{$tag}->addAttribute($attr, $value); 60 | } 61 | } 62 | if($elem2->count()) { 63 | merge_xml($xml1->{$tag}, $elem2); 64 | } 65 | } 66 | 67 | return $xml1; 68 | } 69 | -------------------------------------------------------------------------------- /magento-modules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | 13 | $simple = false; 14 | if($server->argc) { 15 | $target_code_pool = $server->argv[1]; 16 | if(3 == $server->argc) { 17 | $simple = true; 18 | } 19 | } 20 | 21 | $results = `find $magento/app/code/*/* -maxdepth 1 -mindepth 1 -type d | grep -v .svn`; 22 | $results = explode("\n", $results); 23 | 24 | $output = array(); 25 | foreach($results as $raw_module) { 26 | if(!strlen($raw_module)) { continue; } 27 | 28 | $raw_module = str_replace("$magento/app/code/", "", $raw_module); 29 | list($code_pool, $company, $module) = explode("/", $raw_module); 30 | 31 | if(!$code_pool || !$company || !$module) { continue; } 32 | 33 | if(!isset($output[$code_pool])) { $output[$code_pool] = array(); } 34 | if(!isset($output[$code_pool][$company])) { $output[$code_pool][$company] = array(); } 35 | 36 | $output[$code_pool][$company][] = $module; 37 | } 38 | 39 | 40 | foreach($output as $code_pool => $companies) { 41 | if($target_code_pool && 0 !== strpos($code_pool, $target_code_pool)) { continue; } 42 | 43 | if(!$simple) { print "$code_pool:\n"; } 44 | foreach($companies as $company => $modules) { 45 | if(!$simple) { print "\t$company:\n"; } 46 | 47 | foreach($modules as $module) { 48 | if($simple) { 49 | print strtolower($module)."\n"; 50 | } else { 51 | print "\t\t$module\n"; 52 | } 53 | } 54 | 55 | } 56 | } 57 | 58 | function putdocs() { 59 | return array( 60 | "Display a list of modules in the various codepools of Magento.", 61 | "Usage: magento-modules [CODEPOOL] [SIMPLE]", 62 | "","Codepool may be one of [local|core|community]", 63 | "If simple behavior is enabled, a newline delimited list of modules will be", 64 | "printed without any headers.", 65 | ); 66 | } 67 | -------------------------------------------------------------------------------- /magento-jobs-odesk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'rss/1.0' 5 | require 'rss/2.0' 6 | require 'date' 7 | require 'optparse' 8 | require 'json' 9 | require 'net/http' 10 | 11 | options = {} 12 | optparse = OptionParser.new(:posix) do |opts| 13 | opts.banner = "Check oDesk for jobs relating to Magento.\nUsage: magento-jobs-odesk [options]" 14 | 15 | options[:days] = 7 16 | opts.on( "-d N", "--days=N", Integer, "How recent listings must be (default is #{options[:days]})" ) do |days| 17 | options[:days] = days 18 | end 19 | 20 | options[:json] = false 21 | opts.on( "-j", "--json", nil, "Output data as JSON" ) do 22 | options[:json] = true 23 | end 24 | 25 | opts.on( '-h', '--help', 'Display this screen' ) do 26 | puts opts 27 | exit 28 | end 29 | end 30 | 31 | begin 32 | optparse.parse! 33 | rescue OptionParser::ParseError => e 34 | puts e 35 | exit 36 | end 37 | 38 | def parse_tokens(description) 39 | tokens = {} 40 | 41 | d_plus_tokens = description.split("
") 42 | d_plus_tokens.each do |token| 43 | next unless token.match /([a-z ]*)<\/b>: (.*)/i 44 | 45 | tok_values = token.scan(/([a-z ]*)<\/b>: (.*)/i)[0] 46 | tokens[tok_values[0].downcase.to_sym] = tok_values[1] 47 | end 48 | 49 | tokens 50 | end 51 | 52 | today = Date.today 53 | urlbase = 'https://www.odesk.com/jobs/rss?q=magento' 54 | 55 | content = "" 56 | open(urlbase) do |s| content = s.read end 57 | rss = RSS::Parser.parse(content, false) 58 | 59 | results = [] 60 | rss.items.reverse.each do |item| 61 | date = Date.parse(item.pubDate.to_s) 62 | next if date+options[:days] < today 63 | 64 | title = item.title.sub(" - oDesk", "").encode('utf-8', 'iso-8859-1') 65 | link = item.link.gsub(/(jobs\/)[^%]*(%[^?]*)?.*/, '\\1\\2') 66 | tokens = parse_tokens(item.description) 67 | budget = (tokens.has_key? :budget)?tokens[:budget]:"" 68 | 69 | results << { :date => date.strftime("%m/%d"), :budget => budget, :title => title, :link => link, :area => '' } 70 | end 71 | 72 | if options[:json] 73 | puts results.to_json 74 | else 75 | results.each { |r| print "%6s\t%s\t%s\t%s\n" % [r[:date], r[:budget], r[:link], r[:title]] } 76 | end 77 | -------------------------------------------------------------------------------- /data/cd-paths.php: -------------------------------------------------------------------------------- 1 | '%magento%/app', 11 | 'local' => '%magento%/app/code/local', 12 | 'community' => '%magento%/app/code/community', 13 | 14 | 'design' => '%magento%/app/design/frontend/%edition_package%/%theme%', 15 | 'theme' => '%magento%/app/design/frontend/%edition_package%/%theme%', 16 | 'template' => '%magento%/app/design/frontend/%edition_package%/%theme%/template', 17 | 'layout' => '%magento%/app/design/frontend/%edition_package%/%theme%/layout', 18 | 'adminhtml' => '%magento%/app/design/adminhtml/default/default', 19 | 20 | 'tbase' => '%magento%/app/design/frontend/base/default/template', 21 | 'templatebase' => '%magento%/app/design/frontend/base/default/template', 22 | 'lbase' => '%magento%/app/design/frontend/base/default/layout', 23 | 'layoutbase' => '%magento%/app/design/frontend/base/default/layout', 24 | 25 | 'etc' => '%magento%/app/etc', 26 | 'modules' => '%magento%/app/etc/modules', 27 | 28 | 'var' => '%magento%/var', 29 | 'log' => '%magento%/var/log', 30 | 'logs' => '%magento%/var/log', 31 | 'report' => '%magento%/var/report', 32 | 'backups' => '%magento%/var/backups', 33 | 34 | 'skin' => '%magento%/skin/frontend/%edition_package%/%theme%', 35 | 'css' => '%magento%/skin/frontend/%edition_package%/%theme%/css', 36 | 'js' => '%magento%/skin/frontend/%edition_package%/%theme%/js', 37 | 'images' => '%magento%/skin/frontend/%edition_package%/%theme%/images', 38 | 39 | 'locale' => '%magento%/app/locale/en_US', 40 | 'email' => '%magento%/app/locale/en_US/template/email', 41 | 'emails' => '%magento%/app/locale/en_US/template/email', 42 | 43 | 'media' => '%magento%/media', 44 | 'images' => '%magento%/media/catalog', 45 | 'product' => '%magento%/media/catalog/product', 46 | 47 | 'root' => '%magento%/', 48 | '-' => '%magento%/', 49 | 'lib' => '%magento%/lib', 50 | ); 51 | -------------------------------------------------------------------------------- /magento-jobs-freelancer: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'rss/1.0' 5 | require 'rss/2.0' 6 | require 'date' 7 | require 'optparse' 8 | require 'json' 9 | 10 | 11 | options = {} 12 | optparse = OptionParser.new(:posix) do |opts| 13 | opts.banner = "Check Freelancer for jobs relating to Magento.\nUsage: magento-jobs-freelancer [options]" 14 | 15 | options[:days] = 7 16 | opts.on( "-d N", "--days=N", Integer, "How recent listings must be (default is #{options[:days]})" ) do |days| 17 | options[:days] = days 18 | end 19 | 20 | options[:json] = false 21 | opts.on( "-j", "--json", nil, "Output data as JSON" ) do 22 | options[:json] = true 23 | end 24 | 25 | opts.on( '-h', '--help', 'Display this screen' ) do 26 | puts opts 27 | exit 28 | end 29 | end 30 | 31 | begin 32 | optparse.parse! 33 | rescue OptionParser::ParseError => e 34 | puts e 35 | exit 36 | end 37 | 38 | def parse_tokens(description) 39 | tokens = {} 40 | 41 | d_plus_tokens = description.split("
") 42 | d_plus_tokens.each do |token| 43 | token = token.chomp.gsub(/^\n +/, '') 44 | next unless token.match /([a-zA-Z ]*):<\/b> (.*)/i 45 | 46 | tok_values = token.scan(/([a-zA-Z ]*):<\/b> (.*)/i)[0] 47 | tokens[tok_values[0].downcase.gsub(' ', '_').to_sym] = tok_values[1] 48 | end 49 | 50 | tokens 51 | end 52 | 53 | today = Date.today 54 | urlbase = 'http://www.freelancer.com/rss/search.xml?keyword=magento' 55 | 56 | content = "" 57 | open(urlbase) do |s| content = s.read end 58 | rss = RSS::Parser.parse(content, false) 59 | 60 | results = [] 61 | rss.items.reverse.each do |item| 62 | date = Date.parse(item.pubDate.to_s) 63 | next if date+options[:days] < today 64 | 65 | title = item.title.gsub(/ by \w+$/, "").encode('utf-8', 'iso-8859-1') 66 | link = item.link 67 | budget = nil 68 | match = item.description.match /Budget: ([^,]+)/ 69 | if match 70 | budget = match[1] 71 | end 72 | 73 | results << { :date => date.strftime("%m/%d"), :budget => budget, :title => title, :link => link, :area => '' } 74 | end 75 | 76 | if options[:json] 77 | puts results.to_json 78 | else 79 | results.each { |r| print "%6s\t%-18s\t%-65s\t%s\n" % [r[:date], r[:budget], r[:title], r[:link]] } 80 | end 81 | -------------------------------------------------------------------------------- /magento-jobs-craigslist: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | require 'rubygems' 4 | require 'hpricot' 5 | require 'open-uri' 6 | require 'date' 7 | require 'optparse' 8 | require 'json' 9 | 10 | 11 | options = {} 12 | optparse = OptionParser.new(:posix) do |opts| 13 | opts.banner = "Check major metro areas on Craigslist for Magento related jobs.\nUsage: magento-jobs-craigslist [options]" 14 | 15 | options[:days] = 7 16 | opts.on( "-d N", "--days=N", Integer, "How recent listings must be (default is #{options[:days]})" ) do |days| 17 | options[:days] = days 18 | end 19 | 20 | options[:json] = false 21 | opts.on( "-j", "--json", nil, "Output data as JSON" ) do 22 | options[:json] = true 23 | end 24 | 25 | opts.on( '-h', '--help', 'Display this screen' ) do 26 | puts opts 27 | exit 28 | end 29 | end 30 | 31 | begin 32 | optparse.parse! 33 | rescue OptionParser::ParseError => e 34 | puts e 35 | exit 36 | end 37 | 38 | today = Date.today 39 | urlbase = 'http://%s.craigslist.org/search/?areaID=11&subAreaID=&query=magento&catAbb=ggg' 40 | areas = [ 'newyork', 'chicago', 'sfbay', 'washingtondc.en', 'losangeles', 41 | 'houston', 'denver', 'boston', 'austin', 'atlanta', 'dallas', 42 | 'detroit', 'houston', 'lasvegas', 'miami', 'minneapolis', 43 | 'orangecounty', 'philadelphia', 'phoenix', 'portland', 'raleigh', 44 | 'sacramento', 'sandiego', 'seattle' ] 45 | 46 | #areas = [ 'newyork', 'chicago', 'sfbay' ] 47 | 48 | results = [] 49 | 50 | areas.each do |area| 51 | $stderr.print "#{area}|" 52 | 53 | doc = Hpricot(open(urlbase % area)) 54 | ((doc.search('blockquote')[1]).search("p")).each do |line| 55 | vals = line.innerHTML.scan(/(.*) - ([^<]*)<\/a>.*/) 56 | 57 | date = Date.parse(vals[0][0]) 58 | link = vals[0][1] 59 | title = vals[0][2].encode('utf-8', 'iso-8859-1') 60 | 61 | next if (today - date) > options[:days] 62 | results << { :date => date.strftime("%m/%d"), :link => link, :area => area, :title => title, :budget => '' } 63 | end 64 | end 65 | 66 | $stderr.puts "" 67 | if options[:json] 68 | puts results.to_json 69 | else 70 | (results.sort { |l,r| l[:date] <=> r[:date] }).each { |r| puts "%6s\t%-60s\t%-10s\t%s\n" % [r[:date], r[:link], r[:area], r[:title]] } 71 | end 72 | -------------------------------------------------------------------------------- /data/Model/Total.php: -------------------------------------------------------------------------------- 1 | setCode($_totalCode); 37 | } 38 | 39 | public function fetch(Mage_Sales_Model_Quote_Address $address) { 40 | // Only display for the shipping address quote 41 | if($address->getAddressType() == Mage_Sales_Model_Quote_Address::TYPE_BILLING) { 42 | return $this; 43 | } 44 | 45 | if ($this->_charge != 0) { 46 | $address->addTotal(array( 47 | 'code' => $this->getCode(), 48 | 'title' => Mage::helper('sales')->__($this->_label), 49 | 'value' => $this->_charge //This is for display only 50 | )); 51 | } 52 | 53 | return $this; 54 | } 55 | 56 | //This triggers right after the subtotal is calulated 57 | public function collect(Mage_Sales_Model_Quote_Address $address) { 58 | $charge = $this->_getCharge($address); 59 | 60 | $address->setSubtotal($address->getSubtotal() + $charge ); 61 | $address->setBaseSubtotal($address->getBaseSubtotal() + $charge ); 62 | 63 | //Then update the grandtotals 64 | $address->setGrandTotal($address->getSubtotal()); 65 | $address->setBaseGrandTotal($address->getBaseSubtotal()); 66 | 67 | return $this; 68 | } 69 | 70 | protected function _getCharge(Mage_Sales_Model_Quote_Address $address) { 71 | $items = $address->getAllItems(); 72 | 73 | $this->_charge = 0; 74 | return $this->_charge; 75 | } 76 | 77 | }//class %CLASS% 78 | -------------------------------------------------------------------------------- /magento-layout: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); // load everything 12 | init_magento(); 13 | 14 | if(2 != $server->argc) { 15 | print_help(); 16 | exit; 17 | } 18 | 19 | $action = $server->argv[1]; 20 | 21 | $layout = Mage::app()->getLayout(); 22 | $front = Mage::app()->getFrontController(); 23 | $request = $front->getRequest(); 24 | $request->setRequestUri($action); 25 | 26 | 27 | $request->setPathInfo()->setDispatched(false); 28 | if (!$request->isStraight()) { Mage::getModel('core/url_rewrite')->rewrite(); } 29 | $front->rewrite(); 30 | 31 | $correctRouter = null; 32 | 33 | $i = 0; 34 | while (!$request->isDispatched() && $i++<100) { 35 | foreach($front->getRouters() as $router) { if ($router->match($request)) { $correctRouter = $router; break; } } 36 | } 37 | if ($i>100) { Mage::throwException('Front controller reached 100 router match iterations'); } 38 | 39 | //This event give possibility to launch smth before sending ouptut(Allow cookie setting) 40 | $root = $layout->getBlock('root'); 41 | putBlock($root, 'root', "", 0); 42 | 43 | 44 | function putBlock($block, $alias, $offset = "", $level) { 45 | 46 | $extras = array(); 47 | $extras[] = count($block->getChild()) ? count($block->getChild()) : "-"; 48 | $extras[] = $block->getType(); 49 | 50 | // what is rendered? 51 | if(0 == strcmp($block->getType(), "cms/block")) { $extras[] = $block->getBlockId(); } 52 | else if(0 == strcmp($block->getType(), "cms/page")) { $extras[] = $block->getPage()->getIdentifier(); } 53 | else if($block->getTemplate()) { $extras[] = $block->getTemplate(); } 54 | else { $extras[] = "-"; } 55 | 56 | $extraString = "( ".implode($extras, " | ")." )"; 57 | 58 | if($level == 1) { $alias = colorize($alias, C_HI1); } 59 | 60 | echo sprintf("$offset%s %s\n", $alias, colorize($extraString, C_VLO1)); 61 | 62 | foreach($block->getChild() as $alias => $childBlock) { 63 | putBlock($childBlock, $alias, "$offset ", $level+1); 64 | } 65 | } 66 | 67 | function putdocs() { 68 | return array( 69 | "Display information about a controller action's layout.", 70 | "Usage: magento-layout ACTION", 71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /magento-plugin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 8 | // @author $Author$ 9 | // @version $Id$ 10 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 11 | 12 | require_once("lib/base.php"); 13 | 14 | print "Magento Module Creator\n\n"; 15 | 16 | $company = user_text("What company name should I use for the new plugin?", $company); 17 | $plugin = user_text("What is the CamelCase name of the new plugin?"); 18 | $pluginl = strtolower($plugin); 19 | $author = user_text("How should I attribute the author of the new plugin?", $author); 20 | $shell = user_yesno("Copy shell-based install file to target plugin?"); 21 | $code_dir = "$magento/app/code/local/$company/$plugin"; 22 | 23 | if(module_exists($plugin)) { 24 | die("Plugin already exists, sorry. Aborting.\n"); 25 | } 26 | 27 | print "Creating plugin in directory $code_dir..."; 28 | create_path("$code_dir"); 29 | create_path("$code_dir/etc"); 30 | print "Done!\n"; 31 | 32 | $subs = array( 33 | 'company' => $company, 34 | 'plugin' => $plugin, 35 | 'pluginl' => $pluginl, 36 | 'author' => $author, 37 | ); 38 | 39 | print "Creating necessary files..."; 40 | move_filtered_file("$support_dir/README", "$code_dir/README", $subs); 41 | move_filtered_file("$support_dir/modules.xml", "$code_dir/{$company}_{$plugin}.xml", $subs); 42 | move_filtered_file("$support_dir/etc/config.xml", "$code_dir/etc/config.xml", $subs); 43 | if($shell) { 44 | move_filtered_file("$support_dir/install.sh", "$code_dir/install.sh", $subs); 45 | } 46 | print "Done!\n"; 47 | 48 | print "I guess you'll want to read some of those files. Let me adjust file permissions for you."; 49 | system("find \"$code_dir\" -type d -exec chmod 0755 {} \;"); 50 | system("find \"$code_dir\" -type f -exec chmod 0775 {} \;"); 51 | print "...Done! You'll probably want tighter permissions when you deploy to production.\n"; 52 | print "Finished creating the plugin. Make sure to install it and add it to SVN. Have a nice day! :)\n"; 53 | 54 | function putdocs() { 55 | return array( 56 | "Create a new module with the necessary default files.", 57 | "Usage: magento-module", 58 | "","Only the necessary files will be created for the module. Use magento-config,", 59 | "magento-model, etc to create the actual functionality.", 60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /magento-test-performance: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | require 'hpricot' 4 | require 'open-uri' 5 | require 'net/http' 6 | require 'date' 7 | require 'zlib' 8 | require 'optparse' 9 | 10 | 11 | options = {} 12 | optparse = OptionParser.new(:posix) do |opts| 13 | opts.banner = "Check a URL for common performance optimizations. Runs like molasses for now.\nUsage: magento-test-performance [options]" 14 | 15 | opts.on( "-t", "--target=URL", String, "Which site should be checked?" ) do |target| 16 | options[:target] = target 17 | end 18 | 19 | opts.on( '-h', '--help', 'Display this screen' ) do 20 | puts opts 21 | exit 22 | end 23 | end 24 | 25 | begin 26 | optparse.parse! 27 | rescue OptionParser::ParseError => e 28 | puts e 29 | exit 30 | end 31 | 32 | def search_for_assets(node, attr) 33 | assets = [] 34 | @doc.search(node).each do |node| 35 | assets << full_path_to(node[attr]) if node[attr] 36 | end 37 | 38 | assets 39 | end 40 | 41 | def full_path_to asset 42 | return asset if /^http/.match asset 43 | return @base_url+asset if /^\//.match asset 44 | @dir_url+asset 45 | end 46 | 47 | def properties_for asset 48 | headers = { "accept-encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3" } 49 | url = URI.parse asset 50 | res = Net::HTTP.start(url.host, url.port) {|http| 51 | http.get(asset, headers) 52 | } 53 | 54 | headers = res.to_hash 55 | 56 | gzipped = headers['content-encoding'] && headers['content-encoding'][0] == "gzip" 57 | #content = gzipped ? Zlib::Inflate.inflate(res.read_body) : res.body 58 | content = gzipped ? Zlib::GzipReader.new(StringIO.new(res.body)).read : res.body 59 | 60 | { 61 | :url => asset, 62 | :response => res, 63 | :code => res.code, 64 | :expires => (headers["expires"] && Date.parse(headers["expires"][0]).to_s || nil), 65 | :mime => res.header.content_type, 66 | :gzipped => gzipped, 67 | :full_length => content.length, 68 | :compressed_length => (headers["content-length"] && headers["content-length"][0] || res.body.length), 69 | :etag => (headers["etag"] && headers["etag"][0].gsub('"',"") || nil), 70 | } 71 | end 72 | 73 | assets = [] 74 | 75 | @url = options[:target] 76 | @base_url = /http(s)?:\/\/[^\/\?]+/.match(@url).to_s 77 | @dir_url = @url[0..@url.rindex('/')] 78 | @doc = Hpricot(open(@url)) 79 | 80 | assets += search_for_assets("script", :src) 81 | assets += search_for_assets("img", :src) 82 | assets += search_for_assets("link", :href) 83 | assets += search_for_assets("style", :href) 84 | 85 | assets.each { |a| p properties_for a } 86 | -------------------------------------------------------------------------------- /magento-controller: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 9 | // @author $Author$ 10 | // @version $Id$ 11 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 12 | 13 | require_once("lib/base.php"); // load everything 14 | 15 | var_dump($server->argv); 16 | 17 | switch($server->argc) { 18 | case 2: 19 | $handle = $server->argv[1]; 20 | $template = "base"; 21 | break; 22 | case 3: 23 | $handle = $server->argv[1]; 24 | $template = $server->argv[2]; 25 | break; 26 | default: 27 | print_help(); 28 | break; 29 | } 30 | 31 | print "Creating controller for $handle\n"; 32 | 33 | try { 34 | list($module, $class) = explode("/", $handle); 35 | $module_path = module_path($module); 36 | print "This controller will be created in module $module_path\n"; 37 | 38 | // do all the work 39 | $subs = get_file_substitution_values($handle, "controller", $author, ""); 40 | $template = ucfirst($template); 41 | 42 | // do the rest of the work 43 | print "Creating controller.\n"; 44 | move_filtered_file("$support_dir/controller/$template.php", $subs['output_file'], $subs); 45 | print "controller created!\n\n"; 46 | 47 | list($codepool, $company, $plugin_dir) = explode("/", $module_path); 48 | switch(strtolower($template)) { 49 | case 'admin': 50 | $scope = "admin"; 51 | $use = "admin"; 52 | break; 53 | default: 54 | $scope = "frontend"; 55 | $use = "standard"; 56 | break; 57 | } 58 | print "add route:\n"; 59 | print "magento-config controller $module --scope=$scope --module={$company}_{$plugin_dir} --use=$use --frontname=$module\n\n"; 60 | print "add rewrite:\n"; 61 | print "magento-config rewrite $module --module=$module --action=someaction --from_path=path --to_path=path\n"; 62 | 63 | } catch( Exception $e ) { 64 | print_error("{$e->getMessage()}\n"); 65 | } 66 | 67 | function templates() { 68 | global $support_dir; 69 | return explode("\n",trim(`ls $support_dir/controller | sed -e "s/.php//"`)); 70 | } 71 | 72 | function putdocs() { 73 | $s = array( 74 | "Create a new Magento controller in the specified module", 75 | "Usage: magento-controller module/controller_path [template]", "", 76 | "Valid Templates:" 77 | ); 78 | foreach(templates() as $tpl) { $s[] = $tpl; } 79 | return $s; 80 | } 81 | -------------------------------------------------------------------------------- /magento-events: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | 13 | $results = `ack Mage::dispatchEvent $magento 2>/dev/null | grep -v "app/code/local" | grep -v "downloader/pearlib"`; 14 | $results = explode("\n", $results); 15 | print_error(sprintf("%-100s\t%-4s\t%s\n", "FILE", "LINE", "EVENT")); 16 | foreach($results as $result) { 17 | if(!strlen(trim($result))) { continue; } 18 | 19 | $matches = array(); 20 | preg_match("/([^:]+):(\d+):\W+(.*)/", $result, $matches); 21 | 22 | $file = str_replace($magento, "", $matches[1]); 23 | $line = $matches[2]; 24 | $event = $matches[3]; 25 | 26 | $eventMatches = array(); 27 | if(preg_match("/Mage::dispatchEvent\('(\w+)'\);/", $event, $eventMatches)) { 28 | $event = $eventMatches[1]; 29 | $matchType = 1; 30 | } else if(preg_match("/Mage::dispatchEvent\('(\w+)',.*/", $event, $eventMatches)) { 31 | $event = $eventMatches[1]; 32 | $matchType = 2; 33 | } else if(preg_match("/Mage::dispatchEvent\($/", $event)) { 34 | $event = get_next_line_event($file, $line+1, $magento); 35 | $matchType = 3; 36 | } else if(preg_match("/Mage::dispatchEvent\(\"?(['\$a-zA-Z._{}\-> ]+).*/", $event, $eventMatches)) { 37 | $event = $eventMatches[1]; 38 | $matchType = 4; 39 | } else { 40 | print "Found unmatcheable event:\n"; 41 | var_dump($event);exit; 42 | } 43 | 44 | printf("%-100s\t%-4s\t%s\n", $file, $line, $event); 45 | } 46 | 47 | function get_next_line_event($file, $line, $magento) { 48 | $cnt = `cat -n $magento/$file | grep -e "^ *$line"`; 49 | $cnt = preg_replace("/^\s*\d*\s*/", "", $cnt); 50 | $matches = array(); 51 | if(preg_match("/^'?([\$a-z_>. -]*)'?,$/i", $cnt, $matches)) { 52 | return $matches[1]; 53 | } else if(preg_match("/^([\$a-z_>. '\-\(\)]*),$/i", $cnt, $matches)) { 54 | return $matches[1]; 55 | } 56 | print "Found unmatcheable event:\n"; 57 | var_dump($cnt);exit; 58 | } 59 | 60 | function putdocs() { 61 | return array( 62 | "Find and list all Magento events fired via dispatchEvent, including", 63 | "relevant line and file information. This may take a while as it scans", 64 | "the entire magento installation.", 65 | "Usage: magento-events", 66 | ); 67 | } 68 | -------------------------------------------------------------------------------- /magento-jobs-elance: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'rss/1.0' 5 | require 'rss/2.0' 6 | require 'date' 7 | require 'optparse' 8 | require 'json' 9 | 10 | 11 | options = {} 12 | optparse = OptionParser.new(:posix) do |opts| 13 | opts.banner = "Check eLance for jobs relating to Magento.\nUsage: magento-jobs-elance [options]" 14 | 15 | options[:days] = 7 16 | opts.on( "-d N", "--days=N", Integer, "How recent listings must be (default is #{options[:days]})" ) do |days| 17 | options[:days] = days 18 | end 19 | 20 | options[:json] = false 21 | opts.on( "-j", "--json", nil, "Output data as JSON" ) do 22 | options[:json] = true 23 | end 24 | 25 | opts.on( '-h', '--help', 'Display this screen' ) do 26 | puts opts 27 | exit 28 | end 29 | end 30 | 31 | begin 32 | optparse.parse! 33 | rescue OptionParser::ParseError => e 34 | puts e 35 | exit 36 | end 37 | 38 | def parse_tokens(description) 39 | tokens = {} 40 | 41 | d_plus_tokens = description.split("
") 42 | d_plus_tokens.each do |token| 43 | token = token.chomp.gsub(/^\n +/, '') 44 | next unless token.match /([a-zA-Z ]*):<\/b> (.*)/i 45 | 46 | tok_values = token.scan(/([a-zA-Z ]*):<\/b> (.*)/i)[0] 47 | tokens[tok_values[0].downcase.gsub(' ', '_').to_sym] = tok_values[1] 48 | end 49 | 50 | tokens 51 | end 52 | 53 | today = Date.today 54 | urlbase = 'http://www.elance.com/php/search/main/resultsproject.php?matchType=project&page=&sortBy=timelistedSort&sortOrder=1&matchKeywords=magento&catFilter=100&subcatFilter=&timeleftFilter=0&timelistedFilter=0&budgetFilter=-1&featuredprojectFilter=false&pverifprojectFilter=false&statusFilter=10037&fixedprojectFilter=false&hourlyprojectFilter=false&groupFilter=&inDescrCheck=false&inSkillsCheck=false&inNameCheck=false&t=1300213187492&rss=1' 55 | 56 | 57 | content = "" 58 | open(urlbase) do |s| content = s.read end 59 | rss = RSS::Parser.parse(content, false) 60 | 61 | results = [] 62 | rss.items.reverse.each do |item| 63 | date = Date.parse(item.pubDate.to_s) 64 | next if date+options[:days] < today 65 | 66 | title = item.title.sub(" | Elance Job", "").encode('utf-8', 'iso-8859-1') 67 | link = item.link 68 | tokens = parse_tokens(item.description) 69 | budget = (tokens.has_key? :type_and_budget)?tokens[:type_and_budget].gsub(/(Fixed price |Escrow|Hourly |\(Rate not sure\))/, ''):"" 70 | 71 | results << { :date => date.strftime("%m/%d"), :budget => budget, :title => title, :link => link, :area => '' } 72 | end 73 | 74 | if options[:json] 75 | puts results.to_json 76 | else 77 | results.each { |r| print "%6s\t%-20s\t%-65s\t%s\n" % [r[:date], r[:budget], r[:title], r[:link]] } 78 | end 79 | -------------------------------------------------------------------------------- /magento-tax-rate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 8 | // @author $Author$ 9 | // @version $Id$ 10 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 11 | 12 | require_once("lib/base.php"); 13 | require_once("lib/db.php"); 14 | require_once("lib/taxes.php"); 15 | init_magento(); 16 | 17 | $rates = tax_rates(); 18 | $vars = user_action_vars(array("rates" => $rates)); 19 | $actions = array( 20 | "l" => array("name" => "List tax rates", "callback" => "list_tax_rates"), 21 | "a" => array("name" => "Add a tax rate", "callback" => "add_tax_rate"), 22 | "d" => array("name" => "Delete a tax rate", "callback" => "delete_tax_rate"), 23 | "w" => array("name" => "Write changes", "callback" => "write_user_action_changes"), 24 | "x" => array("name" => "Abandon changes and exit", "callback" => "abandon_user_action_changes"), 25 | ); 26 | 27 | print_graph(); 28 | list_tax_rates($vars); 29 | user_action($actions, $vars); 30 | 31 | function list_tax_rates($vars) { 32 | print "\nRates\n"; 33 | foreach($vars->rates as $rate => $rate_data) { 34 | printf("%-30s\t%s\n", $rate, $rate_data['rate']); 35 | } 36 | } 37 | 38 | function add_tax_rate($vars) { 39 | print "\nAdding a new tax rate.\n"; 40 | 41 | $countries = directory_countries(); 42 | $country = user_array_choice("Select a country for the new tax rate", $countries, "US"); 43 | $regions = directory_regions($country); 44 | $region = user_array_choice("Select a region for the new tax rate", array_keys($regions)); 45 | $postal = user_text("Select a post-code for the new tax rate", "*", "/^(\*|\d*)$/"); 46 | $rate = user_text("Select the new tax rate", "0.00", "/^\d\.\d+$/"); 47 | 48 | $code = "$country-$region-$postal-Rate 1"; 49 | 50 | $vars->rates[$code] = array('tax_country_id' => $country, 'tax_region_id' => $region, 'code' => $code, 'rate' => $rate); 51 | array_push($vars->query_stack, "insert into tax_calculation_rate (tax_country_id, tax_region_id, tax_postcode, code, rate) values ('$country', '$region', '$postal', '$code', '$rate')"); 52 | } 53 | 54 | function delete_tax_rate($vars) { 55 | print "\nDeleting an existing tax rate.\n"; 56 | $code = user_array_choice("Select a tax rate to delete", array_keys($vars->rates)); 57 | 58 | unset($vars->rates[$code]); 59 | array_push($vars->query_stack, "delete from tax_calculation_rate where code = '$code'"); 60 | } 61 | 62 | function putdocs() { 63 | require_once("lib/taxes.php"); 64 | print_error("List magento tax rates and interactively allow the user to modify that list of rates.\n"); 65 | print_error("Usage: magento-tax-rate\n"); 66 | print_error("\n\n"); 67 | print_graph(true); 68 | } 69 | -------------------------------------------------------------------------------- /lib/db.php: -------------------------------------------------------------------------------- 1 | 5 | // @author $Author$ 6 | // @version $Id$ 7 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 8 | // 9 | 10 | require_once("local.php"); 11 | require_once("interaction.php"); 12 | 13 | if(!isset($use_default_connection) || !$use_default_connection) { 14 | print_error("Current settings:\n"); 15 | foreach($db_config_array as $key => $value) { 16 | print_error(sprintf("%-10s: %s\n", $key, $value)); 17 | } 18 | 19 | if(!user_yesno("Use these settings?")) { 20 | verify_choices( $db_config_array ); 21 | } 22 | } 23 | 24 | $db_conn = mysql_connect($db_config_array['host'], $db_config_array['username'], $db_config_array['password']); 25 | if(!$db_conn) { 26 | throw new Exception("Failed to connect to database as $dbConfig->username"); 27 | } 28 | 29 | if(!mysql_select_db($db_config_array['dbname'], $db_conn)) { 30 | throw new Exception("Couldn't select database {$db_config_array['dbname']}."); 31 | } 32 | 33 | function start_db_transaction() { 34 | _autocommit(0); 35 | mysql_query("start transaction") or die(mysql_error()); 36 | } 37 | 38 | function commit_db_transaction() { 39 | mysql_query("commit") or die(mysql_error()); 40 | _autocommit(1); 41 | } 42 | 43 | function rollback_db_transaction() { 44 | mysql_query("rollback") or die(mysql_error()); 45 | _autocommit(1); 46 | } 47 | 48 | function _autocommit( $value ) { 49 | mysql_query("set @@autocommit = $value") or die(mysql_error()); 50 | } 51 | 52 | function get_config_data($path, $default = null) { 53 | $path = mysql_real_escape_string($path); 54 | $sqlst = "select value from core_config_data where path = \"$path\""; 55 | $res = mysql_query($sqlst); 56 | 57 | if(!$res) { 58 | print_error("$sqlst\n"); 59 | throw new Exception(mysql_error()); 60 | } 61 | 62 | if(!mysql_num_rows($res)) { return $default; } 63 | 64 | $row = mysql_fetch_array($res); 65 | return $row['value']; 66 | } 67 | 68 | function set_config_data($path, $value) { 69 | $path = mysql_real_escape_string($path); 70 | $value = mysql_real_escape_string($value); 71 | 72 | $sqlst = "update core_config_data set value='$value' where path='$path'"; 73 | $res = mysql_query($sqlst); 74 | 75 | if(!$res) { 76 | print_error("$sqlst\n"); 77 | throw new Exception(mysql_error()); 78 | } 79 | 80 | return mysql_affected_rows(); 81 | } 82 | 83 | function db_load_file($file_path) { 84 | global $db_config_array; 85 | 86 | $username = $db_config_array['username']; 87 | $password = $db_config_array['password']; 88 | $dbname = $db_config_array['dbname']; 89 | `mysql -u $username --password=$password $dbname < $file_path`; 90 | } 91 | 92 | function db_row($sqlst) { 93 | $res = mysql_query($sqlst) or die(mysql_error()); 94 | if(!mysql_num_rows($res)) { return null; } 95 | return mysql_fetch_array($res); 96 | } 97 | -------------------------------------------------------------------------------- /magento-tax-class: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 8 | // @author $Author$ 9 | // @version $Id$ 10 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 11 | 12 | require_once("lib/base.php"); 13 | require_once("lib/db.php"); 14 | require_once("lib/taxes.php"); 15 | init_magento(); 16 | 17 | $classes = tax_classes(); 18 | $vars = user_action_vars(array("classes" => $classes)); 19 | $actions = array( 20 | "l" => array("name" => "List tax classes", "callback" => "list_tax_classes"), 21 | "a" => array("name" => "Add a tax class", "callback" => "add_tax_class"), 22 | "d" => array("name" => "Delete a tax class", "callback" => "delete_tax_class"), 23 | "w" => array("name" => "Write changes", "callback" => "write_user_action_changes"), 24 | "x" => array("name" => "Abandon changes and exit", "callback" => "abandon_user_action_changes"), 25 | ); 26 | 27 | print_graph(); 28 | list_tax_classes($vars); 29 | user_action($actions, $vars); 30 | 31 | function list_tax_classes($vars) { 32 | print "\nTax Classes:\n"; 33 | foreach($vars->classes as $type => $classlist) { 34 | print "$type:\n"; 35 | foreach($classlist as $class) { 36 | print "\t$class\n"; 37 | } 38 | print "\n"; 39 | } 40 | } 41 | 42 | function delete_tax_class($vars) { 43 | print "\nDeleting an existing tax class.\n"; 44 | 45 | $ids = array(); 46 | foreach($vars->classes as $type => $classes) { 47 | print "$type\n"; 48 | foreach($classes as $id => $name) { 49 | $ids[$id] = $type; 50 | print " $id: $name\n"; 51 | } 52 | } 53 | 54 | $choices = array("") + array_keys($ids); 55 | $id = user_array_choice("Select an id to delete or press enter to skip and cancel", $choices); 56 | if(0 == strcmp("", $id)) { return; } 57 | 58 | $type = $ids[$id]; 59 | $name = $vars->classes[$type][$id]; 60 | unset($vars->classes[$type][$id]); 61 | array_push($vars->query_stack, "delete from tax_class where class_name = '$name' and class_type = '$type' limit 1"); 62 | } 63 | 64 | function add_tax_class($vars) { 65 | print "\nAdding a new tax class.\n"; 66 | $type = user_array_choice("Select a tax class type (".implode("/", array_keys($vars->classes))."):", array_keys($vars->classes)); 67 | $name = user_text("Select a name for the new tax class"); 68 | 69 | $vars->classes[$type][rand(5000,9999)] = $name; 70 | array_push($vars->query_stack, "insert into tax_class (class_name, class_type) values ('$name', '$type')"); 71 | } 72 | 73 | function putdocs() { 74 | require_once("lib/taxes.php"); 75 | print_error("List magento tax classes and interactively allow the user to modify that list of classes.\n"); 76 | print_error("Usage: magento-tax-class\n"); 77 | print_error("\n\n"); 78 | print_graph(true); 79 | } 80 | -------------------------------------------------------------------------------- /magento-permissions: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Usage: ./permissions.sh [owner.group] [directory_permissions] [file_permissions] 4 | # 5 | # Changes permissions on the magento directory. Meant to be invoked from the 6 | # magento root. Thanks to Igor Rafalovsky for better directory permissions. 7 | # 8 | # @author Joseph Mastey 9 | # @author $Author$ 10 | # @version $Id: permissions.sh 1388 2010-02-12 02:35:36Z joe $ 11 | # @copyright Copyright (c) JRM Ventures LLC, 2009- 12 | # 13 | 14 | if [[ $# == 1 ]]; then 15 | if [[ "-h" == $1 ]] || [[ "--help" == $1 ]]; then 16 | echo "Recursively fix permissions on a Magento directory." 17 | echo "Usage: magento-permissions [CHOWN_OWNER]" 18 | exit 19 | fi 20 | fi 21 | 22 | if [ ! -f "LICENSE.txt" ]; then 23 | print "This doesn't look like the magento directory. Aborting." 24 | exit 1 25 | fi 26 | 27 | if (( $# > 0 )); then 28 | owner=$1 29 | echo "Setting owner on all files to $owner." 30 | chown -R $owner . 31 | echo "Done." 32 | fi 33 | 34 | dir_permission='0755' 35 | file_permission='0644' 36 | echo -ne "Is apache the owner of these files (no assumes that it is part of the group)? [Y/n]: " 37 | read DECISION 38 | if [[ "$DECISION" =~ no? ]]; then 39 | dir_permission='0775' 40 | file_permission='0664' 41 | fi 42 | 43 | echo -ne "Changing directory permissions on all directories to $dir_permission. This may take a while." 44 | find -type d | grep -v .svn | xargs chmod $dir_permission 45 | echo " Done." 46 | 47 | echo -ne "Changing file permissions on all files to $file_permission. This may also take a while." 48 | find -type f | grep -v .svn | xargs chmod $file_permission 49 | echo " Done." 50 | 51 | echo -ne "Finding and changing .sh files to be executable." 52 | find -type f -name "*.sh" | xargs chmod +x 53 | echo " Done." 54 | 55 | echo -ne "Do you want to change media and other directories to allow apache to write to them? [Y/n]: " 56 | read DECISION 57 | if [[ "$DECISION" =~ no? ]]; then 58 | echo "Skipping media directories. Finished changing permissions." 59 | exit 60 | fi 61 | 62 | # 0777 would be ideal, but PHP on many installations has security problems with files and directories 63 | # running as 0777. this means that we still need to add apache to at least the owner group 64 | # update: actually, stage environment is okay with this, so run with it. 65 | open_dir_permission="0777" 66 | open_file_permission="0666" 67 | echo -ne "Changing permissions on {magento}/var, {magento}/media and {magento}/app/etc to $open_dir_permission to allow writing." 68 | find var -type d | grep -v .svn | xargs chmod $open_dir_permission 69 | find var -type f | grep -v .svn | xargs chmod $open_file_permission 70 | find media -type d | grep -v .svn | xargs chmod $open_dir_permission 71 | find media -type f | grep -v .svn | xargs chmod $open_file_permission 72 | find app/etc -type d | grep -v .svn | xargs chmod $open_dir_permission 73 | find app/etc -type f | grep -v .svn | xargs chmod $open_file_permission 74 | echo " Done." 75 | -------------------------------------------------------------------------------- /magento-cache: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | init_magento(); 14 | 15 | $entities = get_entities(); 16 | $vars = user_action_vars(array("entities" => $entities)); 17 | $actions = array( 18 | "l" => array("name" => "List caches", "callback" => "list_entities"), 19 | "t" => array("name" => "Toggle cache", "callback" => "toggle_cache"), 20 | "a" => array("name" => "Toggle all caches", "callback" => "toggle_all_caches"), 21 | "c" => array("name" => "Clear cache", "callback" => "clear_cache"), 22 | "w" => array("name" => "Write changes", "callback" => "write_user_action_changes"), 23 | "x" => array("name" => "Abandon changes and exit", "callback" => "abandon_user_action_changes"), 24 | ); 25 | 26 | list_entities($vars); 27 | user_action($actions, $vars); 28 | 29 | function get_entities() { 30 | $sqlst = "select code, value from core_cache_option"; 31 | $res = mysql_query($sqlst) or die(mysql_error()); 32 | if(!mysql_num_rows($res)) { return array(); } 33 | 34 | $entities = array(); 35 | while($row = mysql_fetch_array($res)) { 36 | $entities[] = $row; 37 | } 38 | 39 | return $entities; 40 | } 41 | 42 | function list_entities($vars) { 43 | print "\nCaches\n"; 44 | foreach($vars->entities as $entity) { 45 | printf("%-20s\t%s\n", $entity['code'], $entity['value']); 46 | } 47 | } 48 | 49 | function clear_cache($vars) { 50 | print "\nCleaning caches.\n"; 51 | Mage::app()->cleanCache(); 52 | print "\nDone.\n"; 53 | } 54 | 55 | 56 | function toggle_cache($vars) { 57 | print "\nToggling a cache value.\n"; 58 | foreach($vars->entities as $idx => $entity) { 59 | printf("%s\t%s\n", $idx, $entity['code']); 60 | 61 | } 62 | $idx = user_array_choice("Select a cache to toggle", array_keys($vars->entities)); 63 | if(!isset($vars->entities[$idx])) { 64 | print "Invalid option..."; 65 | return; 66 | } 67 | $code = $vars->entities[$idx]['code']; 68 | 69 | $vars->entities[$idx]['value'] = (int)!$vars->entities[$idx]['value']; 70 | array_push($vars->query_stack, "update core_cache_option set value = !value where code = '$code'"); 71 | } 72 | 73 | function toggle_all_caches($vars) { 74 | print "\nToggling all cache values.\n"; 75 | 76 | $tval = (int)!$vars->entities[0]['value']; 77 | 78 | foreach($vars->entities as $idx => $value) { 79 | $vars->entities[$idx]['value'] = $tval; 80 | $code = $vars->entities[$idx]['code']; 81 | array_push($vars->query_stack, "update core_cache_option set value = $tval where code = '$code'"); 82 | } 83 | } 84 | 85 | function putdocs() { 86 | return array( 87 | "Toggle on and off the caches for this site.", 88 | "Usage: magento-cache", 89 | ); 90 | } 91 | -------------------------------------------------------------------------------- /data/views/product_purchases.sql: -------------------------------------------------------------------------------- 1 | create or replace view product_purchases as 2 | select sku, 3 | cast(sum(qty_ordered-qty_refunded-qty_canceled) as decimal) ordered, 4 | cast(sum(qty_ordered) as decimal) base_ordered 5 | from sales_flat_order_item 6 | where product_type = 'simple' 7 | group by sku; 8 | 9 | create or replace view product_purchases_with_date as 10 | select cpe.sku sku, oi.product_type product_type, 11 | cast(sum(qty_ordered-qty_canceled) as decimal) qty, 12 | cast(oi.created_at as date) dt 13 | from sales_flat_order_item oi 14 | join catalog_product_entity cpe on cpe.entity_id = oi.product_id 15 | group by cpe.sku, product_type, cast(oi.created_at as date) 16 | order by sku, dt; 17 | 18 | create or replace view product_purchase_omnibus as 19 | select count(*) lines, oi.sku, oi.product_id, oi.name, 20 | sum(cast(qty_ordered-qty_refunded-qty_canceled as decimal)) ordered, 21 | sum(cast(qty_ordered as decimal)) base_ordered, 22 | ps.sup_name vendor, oi.product_type, 23 | cast(oi.created_at as date) purchase_date, 24 | attribute_set_name, cpi.price, cpi.min_price, 25 | (oi.price-oi.discount_amount) purchase_price, 26 | cost.value cost, 27 | (case 28 | when vis.value = 1 then 'Not Visible' 29 | when vis.value = 2 then 'Catalog' 30 | when vis.value = 3 then 'Search' 31 | when vis.value = 4 then 'Catalog/Search' 32 | end) visibility, 33 | (case 34 | when st.value = 1 then 'Enabled' 35 | else 'Disabled' 36 | end) enabled, 37 | group_concat(distinct ccev.value) event_names 38 | from sales_flat_order_item oi 39 | join sales_flat_order o on oi.order_id = o.entity_id 40 | left join eav_attribute_set ast on ast.attribute_set_id = cp.attribute_set_id 41 | left join purchase_product_supplier pps on pps.pps_product_id = oi.product_id 42 | left join purchase_supplier ps on ps.sup_id = pps.pps_supplier_num 43 | left join catalog_product_index_price cpi on cpi.entity_id = oi.product_id 44 | left join catalog_product_entity_int st on st.entity_id = cp.entity_id 45 | left join catalog_product_entity_int vis on vis.entity_id = cp.entity_id 46 | left join catalog_product_entity_decimal cost on cost.entity_id = cp.entity_id 47 | left join catalog_category_product ccp on ccp.product_id = cp.entity_id 48 | left join catalog_category_entity cce on cce.entity_id = ccp.category_id 49 | left join catalog_category_entity_varchar ccev on ccev.entity_id = ccp.category_id 50 | where 51 | o.status != 'canceled' and 52 | cpi.customer_group_id = 0 and 53 | cpi.website_id = 1 and 54 | cpi.tax_class_id = 2 and 55 | st.attribute_id = 84 and 56 | ccev.attribute_id = 33 and 57 | vis.attribute_id = 91 and 58 | cost.attribute_id = 68 59 | group by 60 | oi.sku, oi.product_id, oi.name, ps.sup_name, cast(oi.created_at as date), 61 | attribute_set_name, cpi.price, cpi.min_price, cost.value, oi.price, 62 | oi.discount_amount, vis.value, st.value, oi.product_type 63 | order by 64 | event_names asc, sku asc, purchase_date desc 65 | ; 66 | -------------------------------------------------------------------------------- /lib/fixtures/orders.php: -------------------------------------------------------------------------------- 1 | setMethod('free'); 19 | $entity->addPayment($payment); 20 | 21 | $qshipping = Mage::getModel("sales/quote_address"); 22 | $qshipping->importCustomerAddress(Mage::getModel("customer/address")->load($entry['shipping_address_id'])); 23 | $oshipping = Mage::getModel("sales/order_address"); 24 | Mage::helper("core")->copyFieldset( 25 | "sales_convert_quote_address", 26 | "to_order_address", 27 | $qshipping, 28 | $oshipping 29 | ); 30 | $entity->setShippingAddress($oshipping); 31 | 32 | $qbilling = Mage::getModel("sales/quote_address"); 33 | $qbilling->importCustomerAddress(Mage::getModel("customer/address")->load($entry['billing_address_id'])); 34 | $obilling = Mage::getModel("sales/order_address"); 35 | Mage::helper("core")->copyFieldset( 36 | "sales_convert_quote_address", 37 | "to_order_address", 38 | $qbilling, 39 | $obilling 40 | ); 41 | $entity->setBillingAddress($obilling); 42 | 43 | $num_items = $entry['total_item_count']; 44 | $qty = $entry['total_qty_ordered']; 45 | if($qty < $num_items) { 46 | $qty = $num_items; 47 | $entity->setTotalQtyOrdered($qty); 48 | } 49 | 50 | $items = Mage::getModel("catalog/product") 51 | ->getCollection() 52 | ->setPageSize($num_items); 53 | $items->getSelect()->order('rand()'); 54 | $items = array_values($items->getItems()); 55 | 56 | if(count($items) < $num_items) { 57 | throw new Exception("There aren't enough items to generate orders."); 58 | } 59 | 60 | for($i = 0; $i < $num_items; $i++) { 61 | $thisqty = ($i == ($num_items-1))?$qty:1; 62 | $qty -= $thisqty; 63 | 64 | $product = $items[$i]; 65 | $sitem = Mage::getModel("cataloginventory/stock_item") 66 | ->loadByProduct($product); 67 | $product->setStockItem($sitem); 68 | $qitem = Mage::getModel("sales/quote_item") 69 | ->setQuote($quote) 70 | ->setProduct($product) 71 | ->setOriginalPrice($product->getPrice()) 72 | ->setCalculationPrice($product->getPrice()) 73 | ->setQty($thisqty); 74 | 75 | $oitem = Mage::getModel("sales/order_item"); 76 | Mage::helper("core")->copyFieldset( 77 | "sales_convert_quote_item", 78 | "to_order_item", 79 | $qitem, 80 | $oitem 81 | ); 82 | $oitem->setProductId($product->getId()); 83 | $entity->addItem($oitem); 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /lib/fixtures/categories.php: -------------------------------------------------------------------------------- 1 | load($parent); 45 | return $parent_obj->getLevel() + 1; 46 | } 47 | 48 | function fixture_next_child_position() { 49 | $sqlst = "select max(position)+1 as position from catalog_category_entity"; 50 | $res = mysql_query($sqlst); 51 | if(!$res) { 52 | throw new Exception("Couldn't find a product"); 53 | } 54 | 55 | return $res['position']; 56 | } 57 | 58 | function fixture_url_key($entry) { 59 | return strtolower(str_replace(" ", "-", $entry['name'])); 60 | } 61 | 62 | function fixture_url_path($entry) { 63 | return strtolower(str_replace(" ", "-", $entry['name'])).".html"; 64 | } 65 | 66 | function post_process_category($entry, $context, $entity) { 67 | $parent_id = $entry['parent_id']; 68 | $parent = Mage::getModel("catalog/category")->load($entry['parent_id']); 69 | $path = $parent->getPath()."/".$entity->getId(); 70 | 71 | $sqlst = "update catalog_category_entity set level = {$entry['level']}, parent_id = {$entry['parent_id']}, path = '$path' where entity_id = ".$entity->getId(); 72 | mysql_query($sqlst); 73 | } 74 | 75 | function process_catalogevent($entry, $context, $entity) { 76 | if(strtotime($entry['date_start']) < strtotime($entry['date_end'])) { 77 | $end = $entry['date_end']; 78 | $entry['date_end'] = $entry['date_start']; 79 | $entry['date_start'] = $end; 80 | } 81 | } 82 | 83 | function post_fixture_category() { 84 | $sqlst = "select parent_id, count(*) ct from catalog_category_entity group by parent_id"; 85 | $res = mysql_query($sqlst); 86 | while($row = mysql_fetch_array($res)) { 87 | $sqlst = "update catalog_category_entity set children_count = {$row['ct']} where entity_id = {$row['parent_id']}"; 88 | mysql_query($sqlst); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lib/base.php: -------------------------------------------------------------------------------- 1 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | // 11 | 12 | if(!isset($_SERVER['argc'])) { 13 | // fuck it. hack me w/ the tools, 14 | $_SERVER['argc'] = count($_GET); 15 | $_SERVER['argv'] = $_GET; 16 | } 17 | 18 | $server = new stdClass(); 19 | $server->argc = $_SERVER['argc']; 20 | $server->argv = $_SERVER['argv']; 21 | $server->raw_argc = $_SERVER['argc']; 22 | $server->raw_argv = $_SERVER['argv']; 23 | 24 | // print something on stderr 25 | function print_error($str) { 26 | $fp = fopen("php://stderr", "w+"); 27 | fwrite($fp, $str); 28 | fclose($fp); 29 | } 30 | 31 | function print_help() { 32 | if(function_exists("putdocs")) { 33 | $res = putdocs(); 34 | if(is_array($res)) { 35 | foreach($res as $line) { 36 | print_error($line."\n"); 37 | } 38 | } 39 | print_error("\n"); 40 | } else { 41 | print_error("No docs available for this function. Yell at the developer. Sorry.\n"); 42 | } 43 | 44 | exit; 45 | } 46 | 47 | 48 | require_once(dirname(__FILE__)."/functions.php"); 49 | $lib_dir = dirname(__FILE__); 50 | $support_dir = dirname(__FILE__)."/../data"; 51 | require_once("$support_dir/defaults.php"); 52 | require_once(dirname(__FILE__)."/color.php"); 53 | 54 | // @throws Exception we're not inside of magento 55 | $magento = find_magento(); 56 | $magento_init = false; 57 | 58 | // dash-arguments 59 | $server->dash_args = array(); 60 | foreach($server->argv as $key => $value) { 61 | $matches = array(); 62 | if(preg_match("/^--([a-z_-]+)=(.*)$/", $value, $matches)) { 63 | $server->dash_args[$matches[1]] = $matches[2]; 64 | unset($server->argv[$key]); 65 | $server->argc -= 1; 66 | } 67 | 68 | } 69 | 70 | // helpdoc system 71 | if(isset($server->argv[1])) { 72 | $arg = $server->argv[1]; 73 | if(0 == strcmp($arg, "--help") || 0 == strcmp($arg, "-h")) { 74 | print_help(); 75 | } 76 | } 77 | 78 | function init_magento($store_code = 'default', $scope_code = 'store') { 79 | global $magento, $magento_init; 80 | 81 | if($magento_init) { return; } 82 | $magento_init = true; 83 | 84 | chdir("$magento"); 85 | require_once("$magento/app/Mage.php"); 86 | 87 | Mage::app()->init($store_code, $scope_code); 88 | } 89 | 90 | function find_magento() { 91 | $path = trim(`pwd`); 92 | while(false !== strpos($path, "/") && $path != "/") { 93 | $target = "$path/LICENSE.txt"; 94 | if(file_exists($target)) { 95 | return $path; 96 | } 97 | 98 | $path = dirname($path); 99 | } 100 | 101 | throw new Exception("There is no Magento to be found. My hands are tied!"); 102 | } 103 | 104 | // get a value that normally would be prompted for, but that 105 | // the user specified on the command line, as in --foo="bar baz" 106 | function cmd_switch($name) { 107 | global $server; 108 | return isset($server->dash_args[$name]) ? $server->dash_args[$name] : null; 109 | } 110 | -------------------------------------------------------------------------------- /lib/fixtures/general.php: -------------------------------------------------------------------------------- 1 | getStore()->getName(); 62 | } 63 | 64 | function fixture_long_store_name() { 65 | $store = fixture_website_name()."\n". 66 | fixture_store_group_name()."\n". 67 | fixture_store_name(); 68 | 69 | return $store; 70 | } 71 | 72 | function fixture_store_id() { 73 | return Mage::app()->getStore()->getId(); 74 | } 75 | 76 | function fixture_website_id() { 77 | return Mage::app()->getStore()->getWebsite()->getId(); 78 | } 79 | 80 | function fixture_website_name() { 81 | return Mage::app()->getStore()->getWebsite()->getName(); 82 | } 83 | 84 | function fixture_store_group_name() { 85 | return Mage::app()->getStore()->getGroup()->getName(); 86 | } 87 | 88 | function fixture_entity_type($entry, $context) { 89 | if(!isset($context->data['entity_type'])) { 90 | throw new Exception("Need to specify an entity type."); 91 | } 92 | 93 | $cfg = Mage::getSingleton("eav/config"); 94 | return $cfg->getEntityType($context->data['entity_type'])->getEntityTypeId(); 95 | } 96 | 97 | function get_flw($context) { 98 | if(!isset($context->four_letter_words) || !count($context->four_letter_words)) { 99 | $context->four_letter_words = get_four_letter_words(); 100 | } 101 | 102 | shuffle($context->four_letter_words); 103 | return array_shift($context->four_letter_words); 104 | } 105 | 106 | function get_four_letter_words() { 107 | global $support_dir; 108 | return explode("\n", file_get_contents("$support_dir/fourletterwords.txt")); 109 | } 110 | 111 | function get_lipsum($context) { 112 | global $support_dir; 113 | 114 | if(!isset($context->lipsum_sentences)) { 115 | $context->lipsum_sentences = explode("\n", trim(file_get_contents("$support_dir/lipsum.txt"))); 116 | } 117 | 118 | return $context->lipsum_sentences; 119 | } 120 | 121 | -------------------------------------------------------------------------------- /lib/bash_completion: -------------------------------------------------------------------------------- 1 | # Magento CD bash completion by Joseph Mastey 2 | # 3 | _mcd() 4 | { 5 | local cur words mwords 6 | COMPREPLY=() 7 | 8 | cur="${COMP_WORDS[COMP_CWORD]}" 9 | curlen=$(echo ${#cur}) 10 | words=`cat "$MAGENTO_TOOLS_PATH/data/cd-paths.php" | grep "^ '" | sed -e "s/^ '\([a-z-]*\).*/\1/"` 11 | 12 | mwords='' 13 | if [[ $cur =~ [a-z]{1,} ]]; then 14 | mwords=$(_magento_modules) 15 | fi 16 | 17 | COMPREPLY=( $(compgen -W "${words} ${mwords}" -- "$cur") ) 18 | return 0 19 | } 20 | complete -F _mcd magento-cd mcd 21 | 22 | _mc() 23 | { 24 | local cur words 25 | COMPREPLY=() 26 | 27 | cur="${COMP_WORDS[COMP_CWORD]}" 28 | words=`ls $MAGENTO_TOOLS_PATH/data/recipes | sed -e "s/.xml//"` 29 | COMPREPLY=( $(compgen -W "${words}" -- "$cur") ) 30 | return 0 31 | } 32 | complete -F _mc magento-config mc 33 | 34 | _magento_modules() 35 | { 36 | local cur words 37 | COMPREPLY=() 38 | 39 | cur="${COMP_WORDS[COMP_CWORD]}" 40 | words='local core community' 41 | COMPREPLY=( $(compgen -W "${words}" -- "$cur") ) 42 | return 0 43 | } 44 | complete -F _magento_modules magento-modules 45 | 46 | _magento_test_fixtures() 47 | { 48 | local cur words 49 | COMPREPLY=() 50 | 51 | cur="${COMP_WORDS[COMP_CWORD]}" 52 | words=`ls $MAGENTO_TOOLS_PATH/data/fixtures | sed -e "s/.yml//"` 53 | COMPREPLY=( $(compgen -W "${words}" -- "$cur") ) 54 | return 0 55 | } 56 | complete -F _magento_test_fixtures magento-test-fixture 57 | 58 | _magento_class() 59 | { 60 | local cur nm words first 61 | COMPREPLY=() 62 | cur="${COMP_WORDS[COMP_CWORD]}" 63 | nm=$COMP_CWORD 64 | 65 | case "$nm" in 66 | 1) 67 | words='block model' 68 | ;; 69 | 3) 70 | words=$(_magento_classtypes ${COMP_WORD[1]}) 71 | ;; 72 | 2|*) 73 | words=$(_magento_modules) 74 | ;; 75 | esac 76 | 77 | COMPREPLY=( $(compgen -W "${words}" -- "$cur") ) 78 | return 0 79 | } 80 | complete -F _magento_class magento-class 81 | 82 | _magento_otherclasses() 83 | { 84 | local cur nm words first 85 | COMPREPLY=() 86 | cur="${COMP_WORDS[COMP_CWORD]}" 87 | nm=$COMP_CWORD 88 | 89 | case "$nm" in 90 | 2) 91 | type=`echo ${COMP_WORDS[0]} | sed -e "s/magento-//"` 92 | words=$(_magento_classtypes $type) 93 | ;; 94 | 1|*) 95 | words=$(_magento_modules) 96 | ;; 97 | esac 98 | 99 | COMPREPLY=( $(compgen -W "${words}" -- "$cur") ) 100 | return 0 101 | } 102 | complete -F _magento_otherclasses magento-block magento-model 103 | 104 | 105 | refresh_magento_module() { magento-modules local simple > $MAGENTO_TOOLS_PATH/data/cached-modules.txt; } 106 | _magento_modules() { cat "$MAGENTO_TOOLS_PATH/data/cached-modules.txt"; } 107 | _magento_classtypes() { type=`perl -e "print ucfirst($1)"`; echo `ls $MAGENTO_TOOLS_PATH/data/$type | sed -e "s/.php//" | tr '[A-Z]' '[a-z]'`; } 108 | 109 | _magento_help() 110 | { 111 | local cur words 112 | COMPREPLY=() 113 | 114 | cur="${COMP_WORDS[COMP_CWORD]}" 115 | words=`ls $MAGENTO_TOOLS_PATH | grep magento- | sed -e "s/magento-//"` 116 | COMPREPLY=( $(compgen -W "${words}" -- "$cur") ) 117 | return 0 118 | 119 | } 120 | complete -F _magento_help magento-help 121 | 122 | _magento() 123 | { 124 | local cur words 125 | COMPREPLY=() 126 | 127 | cur="${COMP_WORDS[COMP_CWORD]}" 128 | words=`ls $MAGENTO_TOOLS_PATH | grep "magento-" | sed -e "s/magento-//"` 129 | COMPREPLY=( $(compgen -W "${words}" -- "$cur") ) 130 | return 0 131 | } 132 | complete -F _magento magento m 133 | -------------------------------------------------------------------------------- /magento-profile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 11 | // @author $Author$ 12 | // @version $Id$ 13 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 14 | 15 | require_once("lib/base.php"); 16 | require_once("lib/db.php"); 17 | 18 | $profiles = explode("\n", `ls $support_dir/profiles | grep -v .sql`); 19 | if($server->argc == 2) { 20 | $key = $server->argv[1]; 21 | if(!in_array($key, $profiles)) { 22 | print_error("Sorry, '$key' isn't a valid profile. Try again.\n"); 23 | exit; 24 | } 25 | } else { 26 | print "\nStore profiles\n"; 27 | foreach($profiles as $profile) { 28 | printf("%-10s\n", $profile); 29 | } 30 | print "\n"; 31 | 32 | $default = basename($magento); 33 | if(!in_array($default, $profiles)) { $default = null; } 34 | 35 | $key = user_array_choice("Select a profile to load for this store", $profiles, $default); 36 | } 37 | 38 | require_once("$support_dir/profiles/$key"); 39 | 40 | print "Loading site profile for $key.\n"; 41 | 42 | $query_stack = array(); 43 | 44 | // change config data 45 | foreach($profile['config'] as $key => $value) { 46 | $query_stack[] = "update core_config_data set value='$value' where path='$key'"; 47 | } 48 | 49 | // alter properties of CMS pages (like changing layout) 50 | if(isset($profile['cms_pages'])) { 51 | foreach($profile['cms_pages'] as $identifier => $values) { 52 | $keys = array(); 53 | foreach($values as $key => $value) { 54 | $keys[] = "$key = '$value'"; 55 | } 56 | $keys = implode(", ", $keys); 57 | 58 | $query_stack[] = "update cms_page set $keys where identifier = '$identifier'"; 59 | } 60 | } 61 | 62 | // delete all design changes 63 | if(isset($profile['delete_designs']) && $profile['delete_designs']) { 64 | $query_stack[] = "delete from design_change"; 65 | } 66 | 67 | // disable caches 68 | if(isset($profile['cache_all'])) { 69 | $on = $profile['cache_all'] ? "1" : "0"; 70 | $query_stack[] = "update core_cache_option set value = $on"; 71 | } 72 | 73 | print "Running profile transactions.\n"; 74 | start_db_transaction(); 75 | $query = ""; 76 | try { 77 | foreach($query_stack as $query) { 78 | $res = mysql_query($query); 79 | if(!$res) { throw new Exception(mysql_error()); } 80 | } 81 | commit_db_transaction(); 82 | } catch(Exception $e) { 83 | print $query; 84 | rollback_db_transaction(); 85 | print_error("There was an error during the database commit (".$e->getMessage()."). Couldn't load site profile."); 86 | } 87 | 88 | if(isset($profile['sql'])) { 89 | print "Running profile SQL loaders.\n"; 90 | foreach($profile['sql'] as $file) { 91 | if(!file_exists("$support_dir/profiles/$file")) { continue; } 92 | db_load_file("$support_dir/profiles/$file"); 93 | print " Loaded $file.\n"; 94 | } 95 | print " Done.\n"; 96 | } 97 | 98 | function putdocs() { 99 | return array( 100 | "Load profile data for an installation, including DB params.", 101 | "Usage: magento-profile [KEY]", 102 | "", "Useful for after you load a DB dump from a production system and", 103 | "need to change the hostname and payment info from that dump. Also", 104 | "supports .sql files as loaders for haphazard data.", 105 | ); 106 | } 107 | -------------------------------------------------------------------------------- /magento-class: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 9 | // @author $Author$ 10 | // @version $Id$ 11 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 12 | 13 | require_once("lib/base.php"); 14 | 15 | switch($server->argc) { 16 | case 3: 17 | $type = $server->argv[1]; 18 | $handle = $server->argv[2]; 19 | $override = ""; 20 | $template = "base"; 21 | break; 22 | case 4: 23 | $type = $server->argv[1]; 24 | $handle = $server->argv[2]; 25 | $override = $server->argv[3]; 26 | $template = "base"; 27 | break; 28 | case 5: 29 | $type = $server->argv[1]; 30 | $handle = $server->argv[2]; 31 | $override = $server->argv[3]; 32 | $template = $server->argv[4]; 33 | break; 34 | default: 35 | print_help(); 36 | } 37 | 38 | if(!preg_match("#^[a-z]+/[a-z_0-9]+$#", $handle)) { 39 | print_error("Proposed class handle fails hard ($handle)\n"); 40 | exit; 41 | } 42 | 43 | print "Creating $type for $handle\n"; 44 | 45 | // get the real override 46 | if(strlen($override)) { 47 | if(file_exists($override)) { $override = file_to_class($override); } 48 | else if(preg_match("/[a-zA-Z_\/]*/", $override)) { $override = handle_to_class($override, $type); } 49 | $override_handle = class_to_handle($override); 50 | print "This $type will be an override for $override\n"; 51 | } 52 | 53 | print "Using $template as a template.\n"; 54 | 55 | try { 56 | list($module, $class) = explode("/", $handle); 57 | if(0 == strcmp("-", $module)) { 58 | $module = strtolower(current_module("local")); 59 | if(!$module) { throw new Exception("You aren't in a local module. Fail"); } 60 | $handle = str_replace("-", $module, $handle); 61 | } 62 | 63 | $module_path = module_path($module); 64 | print "This $type will be created in module $module_path\n"; 65 | 66 | // do all the work 67 | $subs = get_file_substitution_values($handle, $type, $author, $override); 68 | $type_upcase = ucfirst($type); 69 | $template = ucfirst($template); 70 | 71 | // do the rest of the work 72 | print "Creating $type file.\n"; 73 | move_filtered_file( "$support_dir/$type_upcase/$template.php", $subs['output_file'], $subs ); 74 | print ucfirst($type)." created!\n\n"; 75 | 76 | # create config data as necessary 77 | if(user_yesno("Run recipe for {$type}s?")) { 78 | print "Running recipe for {$type}s.\n"; 79 | `magento-config $type $module`; 80 | } 81 | 82 | if($override) { 83 | $module = strtolower($module); 84 | $class = $subs['class']; 85 | list($ovv_mod, $ovv_class) = explode("/", $override_handle); 86 | $override = "magento-config override $module --classtype={$type}s --rewrite_module_lower=$ovv_mod --rewrite_handle=$ovv_class --rewrite_class=$class"; 87 | if(user_yesno("Run recipe for override of $override_handle?")) { 88 | print "Running recipe for override of $override_handle\n"; 89 | `$override`; 90 | } else { 91 | print "to override: \n"; 92 | print "$override"; 93 | } 94 | } 95 | } catch( Exception $e ) { 96 | print_error("{$e->getMessage()}\n"); 97 | print_error("{$e->getTraceAsString()}\n"); 98 | print "Aborted class creation."; 99 | } 100 | 101 | function putdocs() { 102 | return array( 103 | "Create a new Magento class file based on a type template", 104 | "Usage: magento-class type module/long_model_name [extends_model_name] [template]", 105 | ); 106 | } 107 | -------------------------------------------------------------------------------- /lib/taxes.php: -------------------------------------------------------------------------------- 1 | tax COUNTRY | 10 | | / | 11 | | TAX_CALCULATION_RATE -> tax REGION | 12 | | ^ | 13 | | | \ | 14 | | | \-> tax rate (pct) | 15 | | | | 16 | | | /-> product TAX_CLASS | 17 | | | / | 18 | | TAX_CALCULATION | 19 | | ^ \ | 20 | | (n) \-> customer TAX_CLASS | 21 | | | | 22 | | (1) | 23 | | TAX_RULE -> priority | 24 | | | 25 | =============================================== 26 | "; 27 | 28 | if($use_error) { 29 | print_error($str); 30 | } else { 31 | print($str); 32 | } 33 | } 34 | 35 | 36 | function tax_classes() { 37 | $ret = array(); 38 | $sqlst = "select class_id, class_name, class_type from tax_class"; 39 | $res = mysql_query($sqlst) or die(mysql_error()); 40 | if(mysql_num_rows($res)) { 41 | while($row = mysql_fetch_array($res)) { 42 | if(!isset($ret[$row['class_type']])) { $ret[$row['class_type']] = array(); } 43 | 44 | $ret[$row['class_type']][$row['class_id']] = $row['class_name']; 45 | } 46 | } 47 | 48 | return $ret; 49 | } 50 | 51 | function tax_rates() { 52 | $ret = array(); 53 | $sqlst = "select tax_country_id, tax_region_id, tax_postcode, code, rate from tax_calculation_rate"; 54 | $res = mysql_query($sqlst) or die(mysql_error()); 55 | if(mysql_num_rows($res)) { 56 | while($row = mysql_fetch_assoc($res)) { 57 | $ret[$row['code']] = $row; 58 | } 59 | } 60 | 61 | return $ret; 62 | } 63 | 64 | function tax_rules() { 65 | $ret = array(); 66 | $sqlst = "select tax_calculation_rule_id, code, position, priority, (select count(*) from tax_calculation tc where tc.tax_calculation_rule_id = tcr.tax_calculation_rule_id) num_rules from tax_calculation_rule tcr order by position asc, priority asc"; 67 | $res = mysql_query($sqlst) or die(mysql_error()); 68 | if(mysql_num_rows($res)) { 69 | while($row = mysql_fetch_assoc($res)) { 70 | $ret[$row['tax_calculation_rule_id']] = $row; 71 | } 72 | } 73 | 74 | return $ret; 75 | } 76 | 77 | function directory_countries() { 78 | $sqlst = "select country_id from directory_country order by country_id"; 79 | $res = mysql_query($sqlst) or die(mysql_error()); 80 | $ret = array(); 81 | 82 | if(!mysql_num_rows($res)) { 83 | return $ret; 84 | } 85 | 86 | while($row = mysql_fetch_array($res)) { 87 | $ret[] = $row['country_id']; 88 | } 89 | 90 | return $ret; 91 | } 92 | 93 | function directory_regions($country_id) { 94 | $sqlst = "select code, region_id from directory_country_region where country_id = '$country_id' order by code"; 95 | $res = mysql_query($sqlst) or die(mysql_error()); 96 | $ret = array(); 97 | 98 | if(!mysql_num_rows($res)) { 99 | return $ret; 100 | } 101 | 102 | while($row = mysql_fetch_array($res)) { 103 | $ret[$row['code']] = $row['region_id']; 104 | } 105 | 106 | return $ret; 107 | } 108 | -------------------------------------------------------------------------------- /magento-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/xml.php"); 13 | 14 | switch(count($server->argv)) { 15 | case 1: 16 | print_help(); 17 | case 2: 18 | $pattern = $server->argv[1]; 19 | $module = null; 20 | $values = array(); 21 | break; 22 | case 3: 23 | $pattern = $server->argv[1]; 24 | $module = $server->argv[2]; 25 | $values = array(); 26 | break; 27 | default: 28 | $pattern = $server->argv[1]; 29 | $module = $server->argv[2]; 30 | $args = $server->argv; 31 | $values = parse_opts($server->argv); 32 | break; 33 | } 34 | 35 | # attempt to auto-detect a module 36 | if(0 == strcmp("-", $module)) { 37 | $module = current_module("local"); 38 | } 39 | 40 | try { 41 | $pattern = $server->argv[1]; 42 | $recipe = "$support_dir/recipes/$pattern.xml"; 43 | if(!file_exists($recipe)) { 44 | throw new Exception("The recipe for \"$pattern\" doesn't exist. You'll have to try harder than that."); 45 | } 46 | 47 | if(!$module) { 48 | $plugin_path = user_module_path("Which plugin should be overridden", current_module("local")); 49 | } else { 50 | $plugin_path = module_path($module); 51 | } 52 | 53 | list($pool, $company, $module) = explode("/", $plugin_path); 54 | $values['module'] = $module; 55 | $values['module_lower'] = strtolower($module); 56 | $values['company'] = $company; 57 | $values['code_pool'] = $pool; 58 | $values['file'] = "config.xml"; 59 | 60 | $contents = file_get_contents($recipe); 61 | $xml_values = get_string_params($contents); 62 | $values = array_merge($values, $xml_values); 63 | $values['defaults'] = array_keys($xml_values); 64 | 65 | $target = "$magento/app/code/$plugin_path/etc/{$values['file']}"; 66 | if(!file_exists($target)) { 67 | if(user_yesno("Target file ({$values['file']}) doesn't exist. Create it?")) { 68 | move_filtered_file( "$support_dir/etc/{$values['file']}", $target, $values ); 69 | } else { 70 | throw new Exception("The target file ({$values['file']}) doesn't exist"); 71 | } 72 | } 73 | $target_contents = file_get_contents($target); 74 | 75 | $values = get_filter_values($contents, $values); 76 | $final_contents = filter_contents($contents, $values); 77 | $final_output = get_xml_output(merge_xml($target_contents, $final_contents)); 78 | $fp = fopen($target, "w"); 79 | fwrite($fp, $final_output); 80 | fclose($fp); 81 | } catch( Exception $em_all ) { 82 | print_error($em_all->getMessage()."\n"); 83 | } 84 | 85 | function print_recipes() { 86 | global $support_dir; 87 | 88 | $recipes = explode("\n", `ls $support_dir/recipes | sed -e 's/.xml//' -e 's/^/ /'`); 89 | foreach($recipes as $recipe) { 90 | $recipe = trim($recipe); 91 | if(!$recipe) { continue; } 92 | 93 | $description = trim(`grep "docstring" $support_dir/recipes/$recipe.xml | sed -e "s/.*docstring \([^@]*\)@.*/\\1/"`); 94 | if(!$description) { $description = ""; } 95 | print_error(sprintf(" %-25s\t%s\n", $recipe, $description)); 96 | } 97 | } 98 | 99 | function putdocs() { 100 | print_error("Usage: magento-config pattern [module] [options]\n\n"); 101 | print_error("Available patterns:\n"); 102 | print_recipes(); 103 | print_error("\n"); 104 | } 105 | -------------------------------------------------------------------------------- /lib/yaml/sfYaml.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | /** 12 | * sfYaml offers convenience methods to load and dump YAML. 13 | * 14 | * @package symfony 15 | * @subpackage yaml 16 | * @author Fabien Potencier 17 | * @version SVN: $Id: sfYaml.class.php 8988 2008-05-15 20:24:26Z fabien $ 18 | */ 19 | class sfYaml 20 | { 21 | static protected 22 | $spec = '1.2'; 23 | 24 | /** 25 | * Sets the YAML specification version to use. 26 | * 27 | * @param string $version The YAML specification version 28 | */ 29 | static public function setSpecVersion($version) 30 | { 31 | if (!in_array($version, array('1.1', '1.2'))) 32 | { 33 | throw new InvalidArgumentException(sprintf('Version %s of the YAML specifications is not supported', $version)); 34 | } 35 | 36 | self::$spec = $version; 37 | } 38 | 39 | /** 40 | * Gets the YAML specification version to use. 41 | * 42 | * @return string The YAML specification version 43 | */ 44 | static public function getSpecVersion() 45 | { 46 | return self::$spec; 47 | } 48 | 49 | /** 50 | * Loads YAML into a PHP array. 51 | * 52 | * The load method, when supplied with a YAML stream (string or file), 53 | * will do its best to convert YAML in a file into a PHP array. 54 | * 55 | * Usage: 56 | * 57 | * $array = sfYaml::load('config.yml'); 58 | * print_r($array); 59 | * 60 | * 61 | * @param string $input Path of YAML file or string containing YAML 62 | * 63 | * @return array The YAML converted to a PHP array 64 | * 65 | * @throws InvalidArgumentException If the YAML is not valid 66 | */ 67 | public static function load($input) 68 | { 69 | $file = ''; 70 | 71 | // if input is a file, process it 72 | if (strpos($input, "\n") === false && is_file($input)) 73 | { 74 | $file = $input; 75 | 76 | ob_start(); 77 | $retval = include($input); 78 | $content = ob_get_clean(); 79 | 80 | // if an array is returned by the config file assume it's in plain php form else in YAML 81 | $input = is_array($retval) ? $retval : $content; 82 | } 83 | 84 | // if an array is returned by the config file assume it's in plain php form else in YAML 85 | if (is_array($input)) 86 | { 87 | return $input; 88 | } 89 | 90 | require_once dirname(__FILE__).'/sfYamlParser.php'; 91 | 92 | $yaml = new sfYamlParser(); 93 | 94 | try 95 | { 96 | $ret = $yaml->parse($input); 97 | } 98 | catch (Exception $e) 99 | { 100 | throw new InvalidArgumentException(sprintf('Unable to parse %s: %s', $file ? sprintf('file "%s"', $file) : 'string', $e->getMessage())); 101 | } 102 | 103 | return $ret; 104 | } 105 | 106 | /** 107 | * Dumps a PHP array to a YAML string. 108 | * 109 | * The dump method, when supplied with an array, will do its best 110 | * to convert the array into friendly YAML. 111 | * 112 | * @param array $array PHP array 113 | * @param integer $inline The level where you switch to inline YAML 114 | * 115 | * @return string A YAML string representing the original PHP array 116 | */ 117 | public static function dump($array, $inline = 2) 118 | { 119 | require_once dirname(__FILE__).'/sfYamlDumper.php'; 120 | 121 | $yaml = new sfYamlDumper(); 122 | 123 | return $yaml->dump($array, $inline); 124 | } 125 | } 126 | 127 | /** 128 | * Wraps echo to automatically provide a newline. 129 | * 130 | * @param string $string The string to echo with new line 131 | */ 132 | function echoln($string) 133 | { 134 | echo $string."\n"; 135 | } 136 | -------------------------------------------------------------------------------- /lib/filters.php: -------------------------------------------------------------------------------- 1 | $value) { 8 | $filter_standin = strtoupper("%$filter%"); 9 | $filter_standin_upper = "%$filter%"; 10 | $string = str_replace(array($filter_standin, $filter_standin_upper), $value, $string); 11 | } 12 | 13 | return $string; 14 | } 15 | 16 | // do file substitution, then move a blank file into place 17 | function move_filtered_file( $source, $target, $subs ) { 18 | if(!file_exists($source)) { throw new Exception("Source file $source doesn't exist"); } 19 | if(file_exists($target)) { throw new Exception("Target file $target already exists"); } 20 | 21 | $contents = filter_contents(file_get_contents($source), $subs); 22 | create_path(dirname($target)); 23 | $fp = fopen($target, "w+"); 24 | if(!$fp) { throw new Exception("Couldn't open target $target for write"); } 25 | 26 | fwrite($fp, $contents); 27 | fclose($fp); 28 | } 29 | 30 | function get_filter_values( $source, &$values ) { 31 | $filters = array(); 32 | // :-] 33 | if(!preg_match_all("/%([a-z0-9_:-]*)%/", $source, $filters)) { 34 | return $values; 35 | } 36 | 37 | $filters = array_unique($filters[1]); 38 | foreach($filters as $filter_key) { 39 | if(isset($values[$filter_key]) && !in_array($filter_key, $values['defaults'])) { 40 | continue; 41 | } 42 | 43 | $default = null; 44 | if(isset($values[$filter_key])) { 45 | $default = $values[$filter_key]; 46 | } 47 | 48 | $filter_func = "filter_$filter_key"; 49 | if(function_exists($filter_func)) { 50 | $filter_func($values, $default); 51 | } else { 52 | filter_value($filter_key, $values, $default); 53 | } 54 | } 55 | 56 | return $values; 57 | } 58 | 59 | // specific filters called for required values 60 | 61 | function filter_value( $filter_key, &$values, $default = null ) { 62 | $values[$filter_key] = cmd_switch($filter_key); 63 | if(!$values[$filter_key]) { 64 | $values[$filter_key] = user_text("Enter a value for $filter_key", $default); 65 | } 66 | } 67 | 68 | function filter_classtype( &$values, $default = null ) { 69 | $values['classtype'] = cmd_switch('classtype'); 70 | if(!$values['classtype']) { 71 | $values['classtype'] = user_array_choice("Select a class type", array("block", "model"), $default); 72 | } 73 | } 74 | 75 | function filter_rewrite_module_lower( &$values ) { 76 | $default = current_module(); 77 | if(cmd_switch('rewrite_module')) { 78 | $values['rewrite_module'] = cmd_switch('rewrite_module'); 79 | $values['rewrite_module_lower'] = strtolower($module); 80 | } else { 81 | $module = user_module_path("Select a module to override", $default); 82 | list($codepool, $company, $module) = explode("/", $module); 83 | 84 | $values['rewrite_module'] = $module; 85 | $values['rewrite_module_lower'] = strtolower($module); 86 | } 87 | } 88 | 89 | function filter_rewrite_handle( &$values, $default ) { 90 | if(cmd_switch('rewrite_handle')) { 91 | $values['rewrite_handle'] = cmd_switch('rewrite_handle'); 92 | } else { 93 | $values['rewrite_handle'] = user_text("Select class handle to override (class only, no module)", $default); 94 | } 95 | } 96 | 97 | function filter_rewrite_class( &$values, $default ) { 98 | if(cmd_switch('rewrite_handle')) { 99 | $values['rewrite_class'] = cmd_switch('rewrite_handle'); 100 | } else { 101 | $class = user_text("Select class to override to", $default); 102 | $values['rewrite_class'] = $class; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /magento-test-expunge-data: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | 14 | $sqlsts = array(); 15 | $purges = array(); 16 | $edition = get_edition(); 17 | 18 | if(user_yesno("Purge sales order / quote data?")) { 19 | $purges[] = "Sales orders"; 20 | if(0 == strcmp("community", $edition)) { 21 | $sqlsts[] = "delete from sales_order"; 22 | $sqlsts[] = "delete from sales_order_entity"; 23 | } else { 24 | $sqlsts[] = "delete from sales_flat_order"; 25 | } 26 | 27 | $sqlsts[] = "delete from sales_flat_order_item"; 28 | $sqlsts[] = "delete from sales_flat_quote"; 29 | 30 | if(user_yesno("Reset order increment?")) { 31 | $increment = user_text("What should sales order increment be reset to", "100000000"); 32 | $sqlsts[] = "update eav_entity_store set increment_last_id = '$increment' where entity_type_id = (select entity_type_id from eav_entity_type where entity_type_code = 'order')"; 33 | } 34 | } 35 | 36 | if(user_yesno("Purge review data?")) { 37 | $purges[] = "Product reviews"; 38 | $sqlsts[] = "delete from review"; 39 | $sqlsts[] = "delete from review_entity_summary"; 40 | } 41 | 42 | if(user_yesno("Purge customer data?")) { 43 | $purges[] = "Customer data"; 44 | $sqlsts[] = "delete from customer_entity"; 45 | } 46 | 47 | if(user_yesno("Purge newsletter data?")) { 48 | print "\n"; 49 | 50 | if(user_yesno("Purge newsletter templates?")) { 51 | $purges[] = "Newsletter templates"; 52 | $sqlsts[] = "delete from newsletter_template"; 53 | } 54 | 55 | if(user_yesno("Purge newsletter subscribers?")) { 56 | $purges[] = "Newsletter subscribers"; 57 | $sqlsts[] = "delete from newsletter_subscriber"; 58 | } 59 | 60 | if(user_yesno("Purge newsletter queue?")) { 61 | $purges[] = "Newsletter queue"; 62 | $sqlsts[] = "delete from newsletter_queue"; 63 | } 64 | 65 | print "\n"; 66 | } 67 | 68 | if(user_yesno("Purge catalog data?")) { 69 | $purges[] = "Catalog data"; 70 | $sqlsts[] = "delete from catalog_product_entity"; 71 | $sqlsts[] = "delete from catalog_category_entity where level > 1"; 72 | } 73 | 74 | if(user_yesno("Purge search data?")) { 75 | $purges[] = "Catalog search data"; 76 | $sqlsts[] = "delete from catalogsearch_query"; 77 | } 78 | 79 | if(user_yesno("Purge tag data?")) { 80 | $purges[] = "Tag data"; 81 | $sqlsts[] = "delete from tag_relation"; 82 | 83 | if(user_yesno("Purge all product tags?")) { 84 | $purges[] = "Product tags"; 85 | $sqlsts[] = "delete from tag_relation"; 86 | $sqlsts[] = "delete from tag_summary"; 87 | } else { 88 | $sqlsts[] = "update tag_summary set customers = 0, products = 0, uses = 0, historical_uses = 0, popularity = 0"; 89 | } 90 | } 91 | 92 | print "\nPurges to be completed:\n"; 93 | foreach($purges as $purge) { 94 | print "* $purge\n"; 95 | } 96 | print "\n"; 97 | 98 | if(!user_yesno("Delete data from the database?")) { 99 | exit; 100 | } 101 | 102 | start_db_transaction(); 103 | try { 104 | foreach($sqlsts as $sqlst) { 105 | print "$sqlst\n"; 106 | $res = mysql_query($sqlst); 107 | if(!$res) { throw new Exception(mysql_error()); } 108 | } 109 | commit_db_transaction(); 110 | print "Cleared test data.\n\n"; 111 | } catch( Exception $e ) { 112 | print "Exception detected: ".$e->getMessage()."\n"; 113 | rollback_db_transaction(); 114 | print "Failed to expunge test data.\n"; 115 | } 116 | 117 | function putdocs() { 118 | return array( 119 | "Clear all test data from the system.", 120 | "Usage: magento-test-expunge-data", 121 | ); 122 | } 123 | -------------------------------------------------------------------------------- /magento-tax-rule: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 8 | // @author $Author$ 9 | // @version $Id$ 10 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 11 | 12 | require_once("lib/base.php"); 13 | require_once("lib/db.php"); 14 | require_once("lib/taxes.php"); 15 | init_magento(); 16 | 17 | $rules = tax_rules(); 18 | $vars = user_action_vars(array("rules" => $rules)); 19 | $actions = array( 20 | "l" => array("name" => "List tax rule", "callback" => "list_tax_rules"), 21 | "a" => array("name" => "Add a tax rule", "callback" => "add_tax_rule"), 22 | "d" => array("name" => "Delete a tax rule", "callback" => "delete_tax_rule"), 23 | "w" => array("name" => "Write changes", "callback" => "write_user_action_changes"), 24 | "x" => array("name" => "Abandon changes and exit", "callback" => "abandon_user_action_changes"), 25 | ); 26 | 27 | print_graph(); 28 | list_tax_rules($vars); 29 | user_action($actions, $vars); 30 | 31 | function list_tax_rules($vars) { 32 | print "\nTax Rules:\n"; 33 | $format_string = " %-5s\t%-50s\t%-10s\t%-10s\t%s\n"; 34 | printf($format_string, "ID", "CODE", "POSITION", "PRIORITY", "NUM_RULES"); 35 | foreach($vars->rules as $id => $rule) { 36 | printf($format_string, $id, $rule['code'], $rule['position'], $rule['priority'], $rule['num_rules']); 37 | } 38 | } 39 | 40 | function delete_tax_rule($vars) { 41 | print "\nDeleting an existing tax rule.\n"; 42 | 43 | $ids = array_keys($vars->rules); 44 | $choices = array("") + array_keys($ids); 45 | $id = user_array_choice("Select an id to delete or press enter to skip and cancel", $choices); 46 | if(0 == strcmp("", $id)) { return; } 47 | 48 | $code = $vars->rules[$id]['code']; 49 | unset($vars->rules[$id]); 50 | array_push($vars->query_stack, "delete from tax_calculation_rule where code = '$name' limit 1"); 51 | } 52 | 53 | function add_tax_class($vars) { 54 | print "\nAdding a new tax rule.\n"; 55 | 56 | $classes = tax_classes(); 57 | $customer_type = user_array_choice("Select a customer tax class", array_keys($classes['CUSTOMER'])); 58 | $product_type = user_array_choice("Select a product tax class", array_keys($classes['PRODUCT'])); 59 | 60 | $code = user_text("Enter a code for the rate rule", null, "/\w*/"); 61 | $priority = user_text("Enter a priority for the rate rule", 1, "/^\d+/"); 62 | $position = user_text("Enter a position for the rate rule", 1, "/^\d+/"); 63 | 64 | $rules = tax_rules(); 65 | $used_rules = array(); 66 | while(true) { 67 | $selection = user_text("Enter a tax rate code to use w/ this rule or enter 'q' to complete."); 68 | if(0 == strcmp("q", $rules[$selection])) { 69 | break; 70 | } else if(!isset($rules[$selection])) { 71 | print "That wasn't a valid rule. Didn't add anything.\n"; 72 | continue; 73 | } 74 | 75 | $used_rules[] = $selection; 76 | print "Using $selection for tax rules.\n"; 77 | } 78 | 79 | $vars->rules[rand(5000,9999)] = array("code" => $code, "position" => $position, "priority" => $priority, "num_rules" => count($used_rules)); 80 | array_push($vars->query_stack, "insert into tax_calculation_rule (code, priority, position) VALUES ('$code', $priority, $position)"); 81 | foreach($used_rules as $rule) { 82 | array_push($vars->query_stack, "insert into tax_calculation (tax_calculation_rule_id, customer_tax_class_id, product_tax_class_id) 83 | (select tax_calculation_rule_id, $customer_type, $product_type from tax_calculation_rule where code = '$code'"); 84 | } 85 | } 86 | 87 | function putdocs() { 88 | require_once("lib/taxes.php"); 89 | print_error("List magento tax rules and interactively allow the user to modify that list of rules.\n"); 90 | print_error("Usage: magento-tax-rule\n"); 91 | print_error("\n\n"); 92 | print_graph(true); 93 | } 94 | -------------------------------------------------------------------------------- /magento-email-create-templates: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 8 | // @author $Author$ 9 | // @version $Id$ 10 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 11 | 12 | require_once("lib/base.php"); 13 | require_once("lib/db.php"); 14 | init_magento(); 15 | 16 | $existing_templates = array(); 17 | $sqlst = "select orig_template_code from core_email_template"; 18 | $res = mysql_query($sqlst); 19 | if(mysql_num_rows($res)) { 20 | while($row = mysql_fetch_array($res)) { 21 | $existing_templates[] = $row['orig_template_code']; 22 | } 23 | } 24 | 25 | $email_templates = Mage::app()->getConfig()->getNode("global/template/email"); 26 | $to_load = array(); 27 | $templates = array(); 28 | foreach($email_templates[0] as $template => $params) { 29 | if(in_array($template, $existing_templates)) { print "Found loaded template: $template\n"; continue; } 30 | $to_load[$template] = "y"; 31 | $templates[$template] = $params; 32 | } 33 | 34 | if(!count($templates)) { 35 | print "All email templates are already loaded. Nothing to do.\n"; 36 | exit; 37 | } 38 | 39 | print "Loading the following templates:\n\t"; 40 | print implode("\n\t", array_keys($to_load))."\n\n"; 41 | verify_choices($to_load, "Load all of the listed templates?"); 42 | 43 | $replacements = array( 44 | "Demo Store" => "{{var store.getFrontendName()}}", 45 | "#bebcb7" => "#bebcb7", 46 | "#d9e5ee" => "#d9e5ee", 47 | "Monday - Friday, 8am - 5pm PST" => "Monday - Friday, 8am - 5pm PST", 48 | ); 49 | print "Some Magento templates contain 'Demo Store' data, and should be updated before entry into the database.\n"; 50 | print "\nHere are the default replacement choices for emails:\n"; 51 | foreach($replacements as $key => $value) { printf("%-50s: %s\n", $key, $value); } 52 | print "\n"; 53 | verify_choices($replacements, "Accept these replacements?"); 54 | print "\n"; 55 | 56 | foreach($to_load as $template => $load) { 57 | if(0 === stripos($load, "n")) { print "Skipping $template\n"; continue; } 58 | 59 | $file = $templates[$template]->file; 60 | $target_file = "$magento/app/locale/en_US/template/email/$file"; 61 | if(!file_exists($file)) { 62 | print "Couldn't find file template for $template\n"; 63 | continue; 64 | } 65 | 66 | $text = file_get_contents($target_file); 67 | $orig_params = get_string_params($text); 68 | $subject = (string)$templates[$template]->label; 69 | $type = (0 === strcmp("html", $templates[$template]->type))?2:1; 70 | 71 | $clean_text = trim(preg_replace(array("/{\*.*?\*}\n?/ism", "/\n?/ism"), "", $text)); 72 | $clean_text = str_replace(array_keys($replacements), array_values($replacements), $clean_text); 73 | 74 | if(!isset($orig_params['subject'])) { $orig_params['subject'] = $text; } 75 | if(!isset($orig_params['styles'])) { $orig_params['styles'] = ""; } 76 | if(!isset($orig_params['vars'])) { $orig_params['vars'] = "{}"; } 77 | 78 | $templ_obj = Mage::getModel("core/email_template"); 79 | $templ_obj->setTemplateSubject($orig_params['subject']) 80 | ->setTemplateCode($subject) 81 | ->setTemplateText($clean_text) 82 | ->setTemplateStyles($orig_params['styles']) 83 | ->setModifiedAt(Mage::getSingleton('core/date')->gmtDate()) 84 | ->setOrigTemplateCode($template) 85 | ->setTemplateType($type) 86 | ->setOrigTemplateVariables($orig_params['vars']); 87 | 88 | $templ_obj->save(); 89 | print "Loaded $template into the database.\n"; 90 | } 91 | 92 | function putdocs() { 93 | return array( 94 | "Selectively create database entries for Magento's transactional", 95 | "emails. You will be prompted regarding which templates you want to", 96 | "load in this fashion.", 97 | "Usage: magento-email-create-templates", 98 | ); 99 | } 100 | -------------------------------------------------------------------------------- /data/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Usage: ./install.sh /path/to/magento 3 | 4 | # get magento path. works either from plugin directory or the one above it 5 | STDIR=`pwd` 6 | cd ../../../../../ 7 | MAGENTO=`pwd` 8 | if [ 1 == $# ]; then MAGENTO=$1 9 | elif [ ! -f "$MAGENTO/LICENSE.html" ]; then cd $STDIR; cd ../../../../; MAGENTO=`pwd`; 10 | fi 11 | 12 | COMPANY="%COMPANY%" 13 | MOD="%PLUGIN%" 14 | MODL="%PLUGINL%" 15 | FRONTTHEME="default" 16 | 17 | MODULES=$MAGENTO/app/etc/modules 18 | LOCALE=$MAGENTO/app/locale/en_US 19 | SRC=code/local/$COMPANY/$MOD 20 | 21 | # file existence, part 1 22 | if [ ! -f "$MAGENTO/LICENSE.html" ]; then echo "Unable to locate magento directory at $MAGENTO. Please enter a valid path to the magento installation"; exit; 23 | elif [ ! -d $MODULES ] || [ ! -d $LOCALE ]; then echo "Unable to locate one of the required directories for module installation. Is $MAGENTO really the magento directory?"; exit; 24 | elif [ ! -d "$MAGENTO/app/$SRC" ]; then echo "Couldn't find plugin source. Looking for it at \"$MAGENTO/app/$SRC\". Can't continue."; exit; 25 | fi 26 | 27 | VERSION="default" 28 | if [ -f "$MAGENTO/LICENSE_EE.html" ]; then 29 | VERSION="enterprise" 30 | echo "Found Magento. Looks like you're using enterprise edition." 31 | echo "" 32 | fi 33 | 34 | #cd "app/design/frontend/${VERSION}" 35 | #THEMES=`ls -1 | grep -v "default$" | sed -e s/$/,\ / | xargs echo` 36 | #echo "Default frontend theme is: ${FRONTTHEME}. Press enter for this theme or enter another one from [${THEMES} default]:" 37 | #read THEME 38 | 39 | #if [ $THEME ] && [ -d $THEME ]; then 40 | # FRONTTHEME=$THEME 41 | #elif [ $THEME ]; then 42 | # echo "You entered an invalid theme ${THEME}. Can't continue." 43 | # exit 44 | #fi 45 | 46 | #echo "Using ${FRONTTHEME} as frontend theme." 47 | #echo "" 48 | 49 | #file existence, part 2 50 | #ALAYOUT="$MAGENTO/app/design/adminhtml/default/default/layout" 51 | #FLAYOUT="$MAGENTO/app/design/frontend/${VERSION}/${FRONTTHEME}/layout" 52 | #ATEMPLATE="$MAGENTO/app/design/adminhtml/default/default/template" 53 | #FTEMPLATE="$MAGENTO/app/design/frontend/${VERSION}/${FRONTTHEME}/template" 54 | #if [ ! -d ${ALAYOUT} ]; then echo "Can't find directory ${ALAYOUT} for admin layout. Unable to continue."; exit; 55 | #elif [ ! -d ${FLAYOUT} ]; then echo "Can't find directory ${FLAYOUT} for frontend layout. Unable to continue."; exit; 56 | #elif [ ! -d ${ATEMPLATE} ]; then echo "Can't find directory ${ATEMPLATE} for admin templates. Unable to continue."; exit; 57 | #elif [ ! -d ${FTEMPLATE} ]; then echo "Can't find directory ${FTEMPLATE} for frontend templates. Unable to continue."; exit; 58 | #fi 59 | 60 | echo "Found necessary directories. Installing $MOD at $MAGENTO" 61 | 62 | # proceed with install 63 | cd ${MODULES} 64 | if [ -f "${COMPANY}_${MOD}.xml" ] || [ -h "${COMPANY}_${MOD}.xml" ]; then 65 | rm "${COMPANY}_${MOD}.xml"; 66 | fi 67 | ln -s "../../$SRC/${COMPANY}_${MOD}.xml" . 68 | echo "Added module XML" 69 | 70 | #cd ${LOCALE} 71 | #if [ -f "${COMPANY}_${MOD}.csv" ] || [ -h "${COMPANY}_${MOD}.csv" ]; then 72 | # rm "${COMPANY}_${MOD}.csv" 73 | #fi 74 | #ln -s "../../$SRC/${COMPANY}_${MOD}.csv" . 75 | #echo "Added localization file" 76 | # 77 | #cd ${ALAYOUT} 78 | #if [ -f "$MODL.xml" ] || [ -h "$MODL.xml" ]; then 79 | # rm "$MODL.xml" 80 | #fi 81 | #ln -s "../../../../../$SRC/app/design/adminhtml/layout/$MODL.xml" . 82 | # 83 | #cd ${FLAYOUT} 84 | #if [ -f "$MODL.xml" ] || [ -h "$MODL.xml" ]; then 85 | # rm "$MODL.xml" 86 | #fi 87 | #ln -s "../../../../../$SRC/app/design/frontend/layout/$MODL.xml" . 88 | #echo "Added $MODL layouts" 89 | # 90 | #cd ${ATEMPLATE} 91 | #if [ -h "$MODL" ] || [ -d "$MODL" ]; then 92 | # rm -rf "$MODL" 93 | #fi 94 | #ln -s "../../../../../$SRC/app/design/adminhtml/template/$MODL" . 95 | # 96 | #cd ${FTEMPLATE} 97 | #if [ -h "$MODL" ] || [ -d "$MODL" ]; then 98 | # rm -rf "$MODL" 99 | #fi 100 | #ln -s "../../../../../$SRC/app/design/frontend/template/$MODL" . 101 | #echo "Added template directories" 102 | 103 | # should probably let the user know... 104 | echo "Installation script completed. Make sure to disable/refresh cache to view changes." 105 | -------------------------------------------------------------------------------- /magento-db-integrity: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | require_once("lib/base.php"); 12 | require_once("lib/db.php"); 13 | 14 | print "Order items with no valid product record..."; 15 | $row = db_row("select count(*) ct, min(created_at) mindate, max(created_at) maxdate from sales_flat_order_item where product_id not in (select entity_id from catalog_product_entity)"); 16 | if(!$row['ct']) { print "OK.\n\n"; } else 17 | { print "Found errors ({$row['ct']} rows between {$row['mindate']} - {$row['maxdate']}).\n\n"; } 18 | 19 | print "Configurable order items without child rows..."; 20 | $row = db_row("select count(*) ct, min(created_at) mindate, max(created_at) maxdate from sales_flat_order_item sfoi where product_type = 'configurable' and not exists (select 1 from sales_flat_order_item where parent_item_id = sfoi.item_id)"); 21 | if(!$row['ct']) { print "OK.\n\n"; } else 22 | { print "Found errors ({$row['ct']} rows between {$row['mindate']} - {$row['maxdate']}).\n\n"; } 23 | 24 | print "Configurable products w/ wrong simple quantity..."; 25 | $row = db_row("select count(*) ct, min(c.created_at) mindate, max(c.created_at) maxdate from sales_flat_order_item c join sales_flat_order_item s on s.parent_item_id = c.item_id where c.qty_ordered != s.qty_ordered"); 26 | if(!$row['ct']) { print "OK.\n\n"; } else 27 | { print "Found errors ({$row['ct']} rows between {$row['mindate']} - {$row['maxdate']}).\n\n"; } 28 | 29 | print "Orders with incorrect total quantity ordered..."; 30 | $row = db_row("select count(*) ct, min(created_at) mindate, max(created_at) maxdate from (select sfo.entity_id, sfo.created_at, sfo.total_qty_ordered, sum(qty_ordered) sum_line_items 31 | from sales_flat_order sfo join sales_flat_order_item sfoi on sfoi.order_id = sfo.entity_id where sfoi.parent_item_id is null 32 | group by sfo.entity_id, sfo.created_at, sfo.total_qty_ordered having sum_line_items != total_qty_ordered) t"); 33 | if(!$row['ct']) { print "OK.\n\n"; } else 34 | { print "Found errors ({$row['ct']} rows between {$row['mindate']} - {$row['maxdate']}).\n\n"; } 35 | 36 | print "Configurable products without any enabled simples..."; 37 | $row = db_row("select count(*) ct from (select cpec.sku, sum(case when cpi.value = 1 then 1 else 0 end) children, sum(case when cpi.value = 1 then 0 else 1 end) disabled_children from catalog_product_entity cpec left join catalog_product_relation cpr on cpr.parent_id = cpec.entity_id left join catalog_product_entity cpes on cpr.child_id = cpes.entity_id left join catalog_product_entity_int cpi on cpi.entity_id = cpes.entity_id where cpec.type_id = 'configurable' and cpi.attribute_id = 84 group by cpec.sku having children = 0) t"); 38 | if(!$row['ct']) { print "OK.\n\n"; } else 39 | { print "Found errors ({$row['ct']} rows).\n\n"; } 40 | 41 | print "Sales of 'simple' items for non-simple products..."; 42 | $row = db_row("select count(*) ct from sales_flat_order_item where product_type = 'simple' and product_id in (select entity_id from catalog_product_entity where type_id != 'simple')"); 43 | if(!$row['ct']) { print "OK.\n\n"; } else 44 | { print "Found errors ({$row['ct']} rows).\n\n"; } 45 | 46 | print "Duplicate SKU on catalog table..."; 47 | $row = db_row("select count(*) ct from (select sfo.entity_id, count(*) items from sales_flat_order sfo left join sales_flat_order_item sfoi on sfoi.order_id = sfo.entity_id group by sfo.entity_id having items = 0) t"); 48 | if(!$row['ct']) { print "OK.\n\n"; } else 49 | { print "Found errors ({$row['ct']} rows).\n\n"; } 50 | 51 | print "Total item count on order less and sum of items..."; 52 | $row = db_row("select count(*) ct from (select sfo.entity_id, count(*) items from sales_flat_order sfo left join sales_flat_order_item sfoi on sfoi.order_id = sfo.entity_id group by sfo.entity_id having items = 0) t"); 53 | if(!$row['ct']) { print "OK.\n\n"; } else 54 | { print "Found errors ({$row['ct']} rows).\n\n"; } 55 | 56 | print "Orders with no items..."; 57 | $row = db_row("select count(*) ct, min(created_at) mindate, max(created_at) maxdate from (select sfo.entity_id, sfo.created_at, count(*) items from sales_flat_order sfo left join sales_flat_order_item sfoi on sfoi.order_id = sfo.entity_id group by sfo.entity_id, sfo.created_at having items = 0) t"); 58 | if(!$row['ct']) { print "OK.\n\n"; } else 59 | { print "Found errors ({$row['ct']} rows between {$row['mindate']} - {$row['maxdate']}).\n\n"; } 60 | -------------------------------------------------------------------------------- /magento-users: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 8 | // @author $Author$ 9 | // @version $Id$ 10 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 11 | 12 | require_once("lib/base.php"); 13 | require_once("lib/db.php"); 14 | init_magento(); 15 | 16 | $users = get_users(); 17 | $resources = get_default_resources(); 18 | $vars = user_action_vars(array("users" => $users, "resources" => $resources)); 19 | $actions = array( 20 | "l" => array("name" => "List users", "callback" => "list_users"), 21 | "a" => array("name" => "Add a user", "callback" => "add_user"), 22 | "p" => array("name" => "Reset a password", "callback" => "reset_password"), 23 | "d" => array("name" => "Delete a user", "callback" => "delete_user"), 24 | "w" => array("name" => "Write changes", "callback" => "write_user_action_changes"), 25 | "x" => array("name" => "Abandon changes and exit", "callback" => "abandon_user_action_changes"), 26 | ); 27 | 28 | list_users($vars); 29 | user_action($actions, $vars); 30 | 31 | function get_users() { 32 | $sqlst = "select firstname, lastname, email, username from admin_user"; 33 | $res = mysql_query($sqlst) or die(mysql_error()); 34 | if(!mysql_num_rows($res)) { return array(); } 35 | 36 | $users = array(); 37 | while($row = mysql_fetch_array($res)) { 38 | $users[$row['username']] = array('firstname' => $row['firstname'], 'lastname' => $row['lastname'], 'email' => $row['email'], 'username' => $row['username']); 39 | } 40 | 41 | return $users; 42 | } 43 | 44 | function get_default_resources() { 45 | $sqlst = "select extra from admin_user order by user_id asc limit 1"; 46 | $res = mysql_query($sqlst) or die(mysql_error()); 47 | $row = mysql_fetch_array($res); 48 | 49 | return $row['extra']; 50 | } 51 | 52 | function list_users($vars) { 53 | print "\nUsers\n"; 54 | foreach($vars->users as $user => $user_data) { 55 | printf("%-20s\t%s (%s)\n", $user_data['firstname']." ".$user_data['lastname'], $user, $user_data['email']); 56 | } 57 | } 58 | 59 | function add_user($vars) { 60 | print "\nAdding a new user.\n"; 61 | 62 | $name = user_text("Enter name as (first last)", null, "/^[a-zA-Z]+ [a-zA-Z]+$/"); 63 | list($fname, $lname) = explode(" ", $name); 64 | $email = user_text("Enter an email address for this user"); 65 | $username = user_text("Enter username for this user"); 66 | 67 | $password = user_password("Enter the default password for this user"); 68 | $password = get_hash($password, 2); 69 | 70 | $lognum = 0; 71 | $reload_acl_flag = 0; 72 | $is_active = 1; 73 | $extra = $vars->resources; 74 | 75 | $vars->users[$username] = array('firstname' => $fname, 'lastname' => $lname, 'email' => $email, 'username' => $username); 76 | array_push($vars->query_stack, "insert into admin_user (firstname, lastname, email, username, password, created, modified, logdate, lognum, reload_acl_flag, is_active, extra) values ('$fname', '$lname', '$email', '$username', '$password', now(), now(), now(), $lognum, $reload_acl_flag, $is_active, '$extra')"); 77 | array_push($vars->query_stack, "insert into admin_role (parent_id, tree_level, sort_order, role_type, user_id, role_name) values (1, 2, 0, 'U', (select user_id from admin_user where username = '$username'), '$fname')"); 78 | } 79 | 80 | function delete_user($vars) { 81 | print "\nDeleting an existing user.\n"; 82 | $code = user_array_choice("Select a user to delete", array_keys($vars->users)); 83 | 84 | unset($vars->users[$code]); 85 | array_push($vars->query_stack, "delete from admin_user where username = '$code'"); 86 | } 87 | 88 | function reset_password($vars) { 89 | print "\nResetting a password.\n"; 90 | $code = user_array_choice("Select a user to reset", array_keys($vars->users)); 91 | 92 | $password = user_password("Enter a new password for this user"); 93 | $password = get_hash($password, 2); 94 | 95 | unset($vars->users[$code]); 96 | array_push($vars->query_stack, "update admin_user set password = '$password' where username = '$code'"); 97 | } 98 | 99 | function putdocs() { 100 | return array( 101 | "List magento administrative users and allow the user to modify", 102 | "that list of users interactively.", 103 | "Usage: magento-users", 104 | ); 105 | } 106 | -------------------------------------------------------------------------------- /lib/fixtures/base.php: -------------------------------------------------------------------------------- 1 | $sec_data) { 6 | print " starting import for $sec\n"; 7 | 8 | $context = new stdClass(); 9 | $context->data = $sec_data; 10 | $context->title = $sec; 11 | $context->bases = load_bases($context); 12 | 13 | foreach($sec_data['entries'] as $ent => $ent_data) { 14 | print " importing $ent\n"; 15 | $context->entry = $ent_data; 16 | $context->entry_title = $ent; 17 | $context->iterator = get_iterator($context); 18 | 19 | // perform import 20 | $iterator = $context->iterator; 21 | $iterator($context); 22 | } 23 | 24 | // run post-actions (index updates et al) 25 | if(isset($context->data['entity_type'])) { 26 | $postFunc = "post_fixture_".$context->data['entity_type']; 27 | if(function_exists($postFunc)) { 28 | print " running post-actions for $sec"; 29 | $postFunc(); 30 | } 31 | } 32 | } 33 | 34 | } 35 | 36 | function get_entity($context) { 37 | if(!isset($context->data) || !isset($context->data['entity'])) { 38 | throw new Exception("Can't get entity data for {$context->title}"); 39 | } 40 | 41 | $class_handle = $context->data['entity']; 42 | return Mage::getModel($class_handle); 43 | } 44 | 45 | // right now it looks like I should be able to ignore the bases themselves. 46 | // this method is for informational output and as a stub for initialization 47 | // of features later. 48 | function load_bases($context) { 49 | if(!isset($context->data) || !isset($context->data['bases'])) { 50 | return array(); 51 | } 52 | 53 | foreach($context->data['bases'] as $base => $base_data) { 54 | print " found base '$base'\n"; 55 | } 56 | 57 | return array(); 58 | } 59 | 60 | // get a function callback for the correct iterator 61 | function get_iterator($context) { 62 | if(!isset($context->entry) || !isset($context->entry['iterate'])) { 63 | $context->entry['iterate'] = 1; 64 | } 65 | 66 | $iterate = $context->entry['iterate']; 67 | 68 | if(is_numeric($iterate)) { 69 | return "iterate_numeric"; 70 | } else if(function_exists("iterate_$iterate")) { 71 | return "iterate_$iterate"; 72 | } else { 73 | throw new Exception("Unknown iterator: $iterate"); 74 | } 75 | } 76 | 77 | function get_fixture_data($type) { 78 | global $support_dir; 79 | 80 | if(!file_exists("$support_dir/fixtures/$type.yml")) { 81 | throw new Exception("No fixture data found for $type"); 82 | } 83 | 84 | return sfYaml::load("$support_dir/fixtures/$type.yml"); 85 | } 86 | 87 | function iterate_numeric($context) { 88 | $ct = $context->entry['iterate']; 89 | $tithe = $ct/10; 90 | print " "; 91 | for($i = 0; $i < $ct; $i++) { 92 | save_record($context->entry, $context); 93 | if($i%$tithe == 0) { print "."; } 94 | } 95 | print "\n\n"; 96 | } 97 | 98 | function iterate_numeric_prompt($context) { 99 | $num = (int)user_text(" How many entries for $context->entry_title", null, "/^\d+$/"); 100 | $context->entry['iterate'] = $num; 101 | iterate_numeric($context); 102 | } 103 | 104 | function save_record(array $entry, $context) { 105 | $entry = $entry + array(); //take an array copy 106 | $entity = get_entity($context); 107 | $context->entity = $entity; 108 | 109 | foreach($entry as $key => $value) { 110 | if($value && function_exists($value)) { 111 | $entry[$key] = $value($entry, $context); 112 | } else if(0 === strpos($value, "fixture_")) { 113 | throw new Exception("Please define a mock data method $value for {$context->title}"); 114 | } 115 | } 116 | 117 | if(isset($context->data['entity_type'])) { 118 | $process_func = "process_".$context->data['entity_type']; 119 | if(function_exists($process_func)) { 120 | $process_func($entry, $context, $entity); 121 | } 122 | } 123 | 124 | $entity->setData($entry); 125 | if(!$entity->save()) { 126 | throw new Exception("Save didn't happen"); 127 | } 128 | 129 | if(isset($context->data['entity_type'])) { 130 | $process_func = "post_process_".$context->data['entity_type']; 131 | if(function_exists($process_func)) { 132 | $process_func($entry, $context, $entity); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /magento-cd: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 7 | // @author $Author$ 8 | // @version $Id$ 9 | // @copyright Copyright (c) JRM Ventures LLC, 2010- 10 | 11 | try { 12 | require_once("lib/base.php"); 13 | require_once("$support_dir/cd-paths.php"); 14 | require_once("$support_dir/defaults.php"); 15 | } catch( Exception $e ) { 16 | require_once("$support_dir/cd-paths.php"); 17 | require_once("$support_dir/defaults.php"); 18 | $magento = $default_path; 19 | $theme = trim(`cd $default_path; magento-theme`); 20 | } 21 | 22 | if(2 != $server->argc) { 23 | print_error("Usage: magento-cd %somepath%\n"); 24 | print `pwd`; 25 | exit; 26 | } 27 | 28 | $target = $server->argv[1]; 29 | 30 | // it's a project! 31 | if(is_array($project_paths) && count($project_paths)) { 32 | foreach($project_paths as $path) { 33 | if(file_exists("$path/$target") and is_dir("$path/$target")) { 34 | print_error("Zing! Advancing to project $target.\n"); 35 | print "$path/$target"; 36 | exit; 37 | } 38 | } 39 | } 40 | 41 | // it's a developer specified shortcut! 42 | if(isset($cd_paths[$target])) { 43 | if(!isset($theme)) { $theme = trim(`magento-theme`); } 44 | $edition = get_edition(); 45 | if(0 == strcmp($edition, "community")) { 46 | $package = "default"; 47 | } else { 48 | $package = $edition; 49 | } 50 | $path = str_replace(array( 51 | "%magento%", "%theme%", "%edition%", "%edition_package%", 52 | ), array( 53 | $magento, $theme, $edition, $package, 54 | ), $cd_paths[$target]); 55 | 56 | print_error("Zap! Teleported to $target.\n"); 57 | print "$path"; 58 | exit; 59 | } 60 | 61 | // it's a module handle! 62 | try { 63 | $target_path = module_path($target); 64 | print_error("Whiz! Going to module $target.\n"); 65 | print "$magento/app/code/$target_path"; 66 | exit; 67 | } catch( Exception $e ) { 68 | // it wasn't a module name. keep moving. 69 | } 70 | 71 | // it's a company handle! 72 | try { 73 | $target_path = company_path($target); 74 | print_error("Bang! You're at company dir $target.\n"); 75 | print "$magento/app/code/$target_path"; 76 | exit; 77 | } catch( Exception $e ) { 78 | // it wasn't a company handle. keep moving. 79 | } 80 | 81 | // it's a model handle! 82 | try { 83 | $target_path = handle_to_path($target, "model"); 84 | $filename = handle_to_file($target, "model"); 85 | if(!file_exists("$target_path/$filename")) { 86 | throw new Exception("It's a fake! Bail!"); 87 | } 88 | 89 | print_error("Get thee to model $target.\n"); 90 | print "$target_path"; 91 | exit; 92 | } catch( Exception $e ) { 93 | // it wasn't a model handle. keep moving. 94 | } 95 | 96 | // it's a block handle! 97 | try { 98 | $target_path = handle_to_path($target, "block"); 99 | $filename = handle_to_file($target, "block"); 100 | if(!file_exists("$target_path/$filename")) { 101 | throw new Exception("It's a fake! Bail!"); 102 | } 103 | 104 | print_error("Kapow! You're at block $target.\n"); 105 | print "$target_path"; 106 | exit; 107 | } catch( Exception $e ) { 108 | // it wasn't a model handle. keep moving. 109 | } 110 | 111 | // it's a really poorly typed module handle! 112 | try { 113 | $target_path = fuzzy_module_path($target); 114 | print_error("Buh? Headed to FAKE local module '$target'. Put a little more effort in next time.\n"); 115 | print "$magento/app/code/$target_path"; 116 | exit; 117 | } catch( Exception $e ) { 118 | // it wasn't a poorly typed module name. keep moving. 119 | } 120 | 121 | // it's a really, incredibly sloppy file path... 122 | try { 123 | if(!preg_match("#([a-zA-Z]+[_\ \\\\/]+)+#", $target)) { 124 | throw new Exception("doesn't look right."); 125 | } 126 | 127 | $modpath = str_replace(array("_", " ", "\\"), "/", $target); 128 | $target_paths = horrible_path($modpath); 129 | print_error("You've got to be kidding... That's not even a real thing.\n"); 130 | 131 | if(count($target_paths) > 1) { 132 | print_error("For future reference, here are some real things:\n"); 133 | foreach($target_paths as $path) { 134 | print_error(" $path\n"); 135 | } 136 | } 137 | 138 | print array_shift($target_paths); 139 | exit; 140 | } catch( Exception $e ) { 141 | // what in the world? 142 | } 143 | 144 | print_error("Couldn't figure out where $target is. Meditate on uncertainty and try again.\n"); 145 | print `pwd`; 146 | 147 | 148 | function putdocs() { 149 | global $support_dir; 150 | require_once("$support_dir/cd-paths.php"); 151 | 152 | return array( 153 | "Load a path in the current Magento installation. Use tab completion to see available paths.", 154 | "Usage: mcd SHORTCUT", "", 155 | "Shortcuts may be specified in data/cd-paths, or can be one of the following:", 156 | "* A project in the project-dir specified in your profile\n\t(project -> /var/www/project)", 157 | "* A complete module name\n\t(core -> app/code/core/Mage/Core, loaded from [core,community,local])", 158 | "* A partial module name from the local codepool\n\t(foo -> app/code/local/Company/FooBarModule)", 159 | "* A class handle for a block, model or helper\n\t(core/template -> app/code/core/Mage/Core/Block)", 160 | "* An incredibly lazily typed path inside of app/code\n\t(sales/order/pdf -> app/code/core/Mage/Sales/Order/Pdf)", 161 | "", "Known Shortcuts:", 162 | ) + array_keys($cd_paths); 163 | } 164 | -------------------------------------------------------------------------------- /lib/fixtures/customers.php: -------------------------------------------------------------------------------- 1 | countries)) { 9 | $context->countries = array_values(Mage::getModel("directory/country")->getCollection()->getItems()); 10 | } 11 | 12 | $country = $context->countries[rand(0, count($context->countries)-1)]; 13 | 14 | // recurse if we didn't find a country w/ regions 15 | if(!count($country->getRegions())) { $country = fixture_country($entry, $context, true); } 16 | 17 | $context->entry_country = $country; 18 | return $return_obj? $country : $country->getCountryId(); 19 | } 20 | 21 | function fixture_region($entry, $context) { 22 | if(!isset($context->entry_country) && !$entry['country_id']) { 23 | throw new Exception("Couldn't get country code for entry - cannot find resulting regions."); 24 | } 25 | 26 | $country_id = $entry['country_id']; 27 | 28 | if(!isset($context->entry_country)) { 29 | $context->entry_country = Mage::getModel("directory/country")->loadByCode($country_id); 30 | } 31 | 32 | 33 | if(!isset($context->regions)) { $context->regions = array(); } 34 | if(!isset($context->regions[$country_id])) { 35 | $regions = $context->entry_country->getRegions()->getItems(); 36 | $regionData = array(); 37 | foreach($regions as $key => $value) { 38 | // this array is backwards to make access in fixture_region_id faster 39 | $regionData[$value->getName()] = $key; 40 | } 41 | $context->regions[$country_id] = $regionData; 42 | } 43 | 44 | if(!count($context->regions[$country_id])) { 45 | return fixture_string($entry, $context); 46 | } else { 47 | $keys = array_keys($context->regions[$country_id]); 48 | shuffle($keys); 49 | return array_shift($keys); 50 | } 51 | } 52 | 53 | function fixture_region_id($entry, $context) { 54 | if(!isset($entry['country_id']) || !isset($entry['region'])) { 55 | throw new Exception("Couldn't construct region_id from entity params."); 56 | } 57 | 58 | $country = $entry['country_id']; 59 | $regions = $context->regions[$country]; 60 | 61 | // some countries have no listed regions 62 | if(!count($regions) || !isset($regions[$entry['region']])) { 63 | return null; 64 | } 65 | 66 | return $regions[$entry['region']]; 67 | } 68 | 69 | 70 | function fixture_zip() { 71 | return rand(10000, 99999); 72 | 73 | } 74 | 75 | function fixture_street($entry, $context) { 76 | $streets = rand(1,2); 77 | $str = ""; 78 | for($i = 0; $i < $streets; $i++) { 79 | $str .= rand(10,99999)." ".fixture_capsed_string($entry, $context)."\n"; 80 | } 81 | 82 | return trim($str); 83 | } 84 | function fixture_address($entry, $context) { 85 | $sqlst = "select entity_id from customer_address_entity order by rand() limit 1"; 86 | $res = mysql_query($sqlst); 87 | if(!$res) { 88 | throw new Exception("Couldn't get an address"); 89 | } 90 | 91 | $row = mysql_fetch_array($res); 92 | return $row['entity_id']*1; 93 | } 94 | 95 | function fixture_customer_by_addresses($entry, $context) { 96 | # try to select by fewest addresses 97 | $sqlst = "select entity_id, 98 | (select count(*) from customer_address_entity a where a.parent_id = e.entity_id) addresses 99 | from customer_entity e order by addresses asc, rand() limit 1"; 100 | $res = mysql_query($sqlst); 101 | if(!$res) { 102 | throw new Exception("Couldn't get a customer entity"); 103 | } 104 | 105 | $row = mysql_fetch_array($res); 106 | $entity_id = $row['entity_id']*1; 107 | $context->customer_id = $entity_id; 108 | return $entity_id; 109 | } 110 | 111 | function fixture_customer($entry, $context) { 112 | $sqlst = "select entity_id from customer_entity e order by rand() limit 1"; 113 | $res = mysql_query($sqlst); 114 | if(!$res) { 115 | throw new Exception("Couldn't get a customer entity"); 116 | } 117 | 118 | $row = mysql_fetch_array($res); 119 | $entity_id = $row['entity_id']*1; 120 | $context->customer_id = $entity_id; 121 | return $entity_id; 122 | } 123 | 124 | function fixture_customer_group($entry, $context) { 125 | if(!isset($context->customer_id)) { 126 | throw new Exception("Can't get address for non-existent customer."); 127 | } 128 | 129 | $customer = Mage::getModel("customer/customer")->load($context->customer_id); 130 | return $customer->getGroupId(); 131 | } 132 | 133 | function fixture_customer_email($entry, $context) { 134 | if(!isset($context->customer_id)) { 135 | throw new Exception("Can't get address for non-existent customer."); 136 | } 137 | 138 | $customer = Mage::getModel("customer/customer")->load($context->customer_id); 139 | return $customer->getEmail(); 140 | } 141 | 142 | function fixture_customer_address($entry, $context) { 143 | if(!isset($context->customer_id)) { 144 | throw new Exception("Can't get address for non-existent customer."); 145 | } 146 | 147 | $customer = Mage::getModel("customer/customer")->load($context->customer_id); 148 | $addresses = $customer->getAddressesCollection(); 149 | if(!count($addresses)) { 150 | throw new Exception("Customer didn't have any addresses."); 151 | } 152 | 153 | $address = $addresses->getFirstItem(); 154 | return $address->getId(); 155 | } 156 | 157 | function fixture_email($entry, $context) { 158 | global $email; 159 | list($address, $domain) = explode("@", $email); 160 | $postfix = fixture_string($entry, $context); 161 | 162 | return "$address+$postfix@$domain"; 163 | } 164 | 165 | function fixture_group_id() { 166 | return Mage::getStoreConfig(Mage_Customer_Model_Group::XML_PATH_DEFAULT_ID); 167 | } 168 | 169 | function fixture_password_hash() { 170 | return get_hash("password", 2); 171 | } 172 | 173 | -------------------------------------------------------------------------------- /lib/interaction.php: -------------------------------------------------------------------------------- 1 | value array into a set of switches to append to a commandline command 136 | function array_to_switches($arr) { 137 | $str = ""; 138 | foreach($arr as $key => $value) { 139 | $value = str_replace("'", "", $value); 140 | $str .= " --$key='$value'"; 141 | } 142 | 143 | return $str; 144 | } 145 | 146 | // verify a set of values 147 | function verify_choices( array &$choices, $change_mind_question = null ) { 148 | if($change_mind_question && user_yesno($change_mind_question)) { return; } 149 | 150 | $keys = array_keys($choices); 151 | while(true) { 152 | print_error("\n"); 153 | $i = 0; 154 | foreach($choices as $key => $value) { 155 | $i++; 156 | print_error("$i. $key [{$value}]\n"); 157 | } 158 | print_error("Select value to change or enter to continue: "); 159 | $choice = trim(fgets(STDIN)); 160 | 161 | if(0 == strlen($choice)) { 162 | break; 163 | } else if(!array_key_exists(($choice-1), $keys)) { 164 | print_error("Invalid choice. Try again.\n\n"); 165 | continue; 166 | } 167 | 168 | $key = $keys[$choice-1]; 169 | print_error("Select a new value for $key: "); 170 | $choices[$key] = trim(fgets(STDIN)); 171 | } 172 | } 173 | 174 | // loop through actions repeatedly to let the user make selections 175 | function user_action($actions, $vars) { 176 | while(true) { 177 | _user_actions($actions, count($vars->query_stack)); 178 | $action = user_array_choice("Please select an action", array_keys($actions)); 179 | $actions[$action]['callback']($vars); 180 | } 181 | } 182 | 183 | function _user_actions($actions, $changes_waiting) { 184 | $title = "Choices"; 185 | if($changes_waiting) { $title .= " ($changes_waiting waiting)"; } 186 | print "\n\n$title:\n"; 187 | print "===============================\n"; 188 | foreach($actions as $code => $params) { 189 | printf(" (%s)\t%-20s\n", $code, $params['name']); 190 | } 191 | 192 | } 193 | 194 | function user_action_vars(array $params) { 195 | $vars = new stdClass(); 196 | $vars->query_stack = array(); 197 | foreach($params as $key => $value) { 198 | $vars->$key = $value; 199 | } 200 | 201 | return $vars; 202 | } 203 | 204 | function write_user_action_changes($vars) { 205 | print "Writing changes to the database.\n"; 206 | if(!count($vars->query_stack)) { 207 | return; 208 | } 209 | 210 | start_db_transaction(); 211 | try { 212 | foreach($vars->query_stack as $query) { 213 | $result = mysql_query($query); 214 | if(false === $result) { throw new Exception(mysql_error()); } 215 | } 216 | 217 | commit_db_transaction(); 218 | } catch(Exception $e) { 219 | rollback_db_transaction(); 220 | print "DB error while writing changes: ".$e->getMessage(); 221 | } 222 | 223 | $vars->query_stack = array(); 224 | } 225 | 226 | function abandon_user_action_changes() { 227 | print "Abandoning changes. Goodbye Dave...\n"; 228 | exit; 229 | } 230 | --------------------------------------------------------------------------------