Jump to content


  • Content count

  • Joined

  • Last visited

1 Follower

Profile Information

  • Real Name
    P. Scheepens

Recent Profile Visitors

9,207 profile views
  1. Guest99999999

    Google XML Sitemap SEO

    Hi Jack (and others interested of course), Here is some code I changed to give the idea (so in this example 3 languages nl, en and de) . 1) The changed code for generating a sitemap based on your contribution, you may find it some pages back in this forum (or check in my profile to find it quicker), but I removed the language parameters like .html?language=en etc. 2) Changed code in .htacces : RewriteRule ^(.*)-p-(.*).html$ product_info.php?language=nl&products_id=$2&%{QUERY_STRING} RewriteRule ^(.*)-ep-(.*).html$ product_info.php?language=en&products_id=$2&%{QUERY_STRING} RewriteRule ^(.*)-dp-(.*).html$ product_info.php?language=de&products_id=$2&%{QUERY_STRING} RewriteRule ^(.*)-c-(.*).html$ index.php?language=nl&cPath=$2&%{QUERY_STRING} RewriteRule ^(.*)-ec-(.*).html$ index.php?language=en&cPath=$2&%{QUERY_STRING} RewriteRule ^(.*)-dc-(.*).html$ index.php?language=de&cPath=$2&%{QUERY_STRING} RewriteRule ^(.*)-m-([0-9]+).html$ index.php?language=nl&manufacturers_id=$2&%{QUERY_STRING} RewriteRule ^(.*)-em-([0-9]+).html$ index.php?language=en&manufacturers_id=$2&%{QUERY_STRING} RewriteRule ^(.*)-dm-([0-9]+).html$ index.php?language=de&manufacturers_id=$2&%{QUERY_STRING} 3) Changed code in header.php (but could be in your case in /boxes/languages.php), in my case I have the language flags in the header of the page : if (!isset($lng) || (isset($lng) && !is_object($lng))) { include(DIR_WS_CLASSES . 'language.php'); $lng = new language; } $languages_string = ''; reset($lng->catalog_languages); $i = 1; while (list($key, $value) = each($lng->catalog_languages)) { if (($PHP_SELF == '/product_info.php') or (($PHP_SELF == '/index.php') and (isset($_GET['cPath']))) or (($PHP_SELF == '/index.php') and (isset($_GET['manufacturers_id'])))) { $save_languages_id = $languages_id; if ($i == 1) { $languages_id = 4; unset($seo_urls); // initiate new class for language (now) } elseif ($i == 2) { $languages_id = 5; unset($seo_urls); // initiate new class for language (now) } elseif ($i == 3) { $languages_id = 6; unset($seo_urls); // initiate new class for language (now) } $languages_string .= ' <a href="' . tep_href_link(basename($PHP_SELF), tep_get_all_get_params(array('language', 'currency')), $request_type) . '">' . tep_image(DIR_WS_LANGUAGES . $value['directory'] . '/images/' . $value['image'], $value['name']) . '</a> '; $languages_id = $save_languages_id; unset($seo_urls); // initiate new class for language (next time) } else { $languages_string .= ' <a href="' . tep_href_link(basename($PHP_SELF), tep_get_all_get_params(array('language', 'currency')) . 'language=' . $key, $request_type) . '">' . tep_image(DIR_WS_LANGUAGES . $value['directory'] . '/images/' . $value['image'], $value['name']) . '</a> '; } $i++; } 3) Changed code in seo_class.php (here only for the products pages, same for manufacturer and category pages): function make_url($page, $string, $anchor_type, $id, $extension = '.html', &$separator){ // Right now there is but one rewrite method since cName was dropped // In the future there will be additional methods here in the switch switch ( $this->attributes['SEO_REWRITE_TYPE'] ){ case 'Rewrite': // FS start if ($anchor_type == 'products_id') { if ($this->languages_id == 4) { return $string . '-p-' . $id . $extension; } elseif ($this->languages_id == 5) { return $string . '-ep-' . $id . $extension; } elseif ($this->languages_id == 6) { return $string . '-dp-' . $id . $extension; } } if ($anchor_type == 'cPath') { if ($this->languages_id == 4) { return $string . '-c-' . $id . $extension; } elseif ($this->languages_id == 5) { return $string . '-ec-' . $id . $extension; } elseif ($this->languages_id == 6) { return $string . '-dc-' . $id . $extension; } } if ($anchor_type == 'manufacturers_id') { if ($this->languages_id == 4) { return $string . '-m-' . $id . $extension; } elseif ($this->languages_id == 5) { return $string . '-em-' . $id . $extension; } elseif ($this->languages_id == 6) { return $string . '-dm-' . $id . $extension; } } // FS stop return $string . $this->reg_anchors[$anchor_type] . $id . $extension; break; default: break; } # end switch } # end function function get_product_name($pID){ // FS start stop - [(int)$this->languages_id] added (constants per language) // - . (int)$this->languages_id . '_' switch(true){ case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && defined('PRODUCT_NAME_' . (int)$this->languages_id . '_' . $pID)): $this->performance['CACHE_QUERY_SAVINGS']++; $return = constant('PRODUCT_NAME_' . (int)$this->languages_id . '_' . $pID); $this->cache['PRODUCTS'][$pID][(int)$this->languages_id] = $return; break; case ($this->attributes['USE_SEO_CACHE_GLOBAL'] == 'true' && isset($this->cache['PRODUCTS'][$pID][(int)$this->languages_id])): $this->performance['CACHE_QUERY_SAVINGS']++; $return = $this->cache['PRODUCTS'][$pID][(int)$this->languages_id]; break; default: $this->performance['NUMBER_QUERIES']++; $sql = "SELECT products_name as pName FROM ".TABLE_PRODUCTS_DESCRIPTION." WHERE products_id='".(int)$pID."' AND language_id='".(int)$this->languages_id."' LIMIT 1"; $result = $this->DB->FetchArray( $this->DB->Query( $sql ) ); $pName = $this->strip( $result['pName'] ); $this->cache['PRODUCTS'][$pID][(int)$this->languages_id] = $pName; $this->performance['QUERIES']['PRODUCTS'][] = $sql; $return = $pName; break; } # end switch return $return; } # end function function generate_products_cache(){ $this->is_cached($this->cache_file . 'products', $is_cached, $is_expired); if ( !$is_cached || $is_expired ) { $sql = "SELECT p.products_id as id, pd.products_name as name FROM ".TABLE_PRODUCTS." p LEFT JOIN ".TABLE_PRODUCTS_DESCRIPTION." pd ON p.products_id=pd.products_id AND pd.language_id='".(int)$this->languages_id."' WHERE p.products_status='1'"; $product_query = $this->DB->Query( $sql ); $prod_cache = ''; while ($product = $this->DB->FetchArray($product_query)) { // FS start stop - [(int)$this->languages_id] added (constants per language) // - . (int)$this->languages_id . '_' $define = 'define(\'PRODUCT_NAME_' . (int)$this->languages_id . '_' . $product['id'] . '\', \'' . $this->strip($product['name']) . '\');'; $prod_cache .= $define . "\n"; eval("$define"); } $this->DB->Free($product_query); $this->save_cache($this->cache_file . 'products', $prod_cache, 'EVAL', 1 , 1); unset($prod_cache); } else { $this->get_cache($this->cache_file . 'products'); } } # end function You see only a few changes in seo_class and it works.
  2. Guest99999999

    Google XML Sitemap SEO

    Hi Jack, Long time ago. As how oscommerce works now with languages there are to many pages (when you click on the flags) who leades to the same page (e.g. page-lang1?language=en, page-lang2?language=en etc.). Google looks also to the contents of a page (domain independed) and when there are too many pages with the same contents they all get a low rank, you have to say to them who's is most important with a canonial link. But because these pages are virtual (seo names) you can't apply such canonial link. Besides the other pages (e.g. productslist) are all pointing to the default language because there is no session when google visits the website (if you switch that off in the admin settings to prevent the session_id parameter in the url's). So all that pages in the different languages also point to the same contents (default language). So I removed my language parameter in my solution for generating sitemaps for more languages (see before). In stead of I changed it like that so all pages are unique in name and contents. E.g. languge en : page-ep-, language ge : page-gp- etc. etc. and changed the .htacces file to apply the language parameter, so e.g. page-ep- will change to products_info.php?language=en etc. So every seo name is an unique page by name (no language parameters) and also by contents, there are no 2 product, category or manufacturer pages anymore leading to the same content. This brings also with it that you have to use different languages in one page for your language flags url's (seo names in different languages in 1 page). I changed this in header.php and seo_class.php that I build all my names for every language flag after each other by creating the seo_class object every time again (so the constructor will be executed every time again). This works now too. I got no indexed pages for some languages before, but now I get them slowly for all languages ...
  3. Guest99999999

    Google XML Sitemap SEO

    Hi Jack, I did not forget you but there are problems in google. So I am involved in a long discussion in google but maybe I find a solution that other languages will also be indexed from sitemaps (not now how oscommerce works with languages). If I have the final answer (soon I guess) I report you all my findings (learned a lot).
  4. Guest99999999

    Concept Multistore

    It will finally be an admin by choice where you can switch to another admin. Other things will be as described above. So every admin gets the same program for login and showing orders from all other webshops. Even an not superadmin can switch to admin's for webshops he/she is authorized for. Why this change ? Because directories for cache etc. (or for the pdf invoice) are domain depended, so you can't in a domain (admin) call the pdf invoice in another domain. Advantage: as well as the version of the webshop/admin may be different as long as the login/switch program is the same and works in all that versions ....
  5. Guest99999999

    Concept Multistore

  6. Guest99999999

    Concept Multistore

    Ok, I understand now better that the concept of a multistore is in fact more stores, one admin and same products, so the stock is shared. So this is in fact a lot of work always for a solution. In fact my customers wants only a panel to control all their stores (different products) with one admin but separate databases (otherwise one database will be too big). So my solution for that problem is as follows : - all webshops have separate domains and separate databases but all on one server - their is only one admin (so in the first domain) and has one login - images can not be uploaded anymore, so programs have to be changed that only the name will be filled in (browse is still possible for names), with FTP images have to be transfer - one config file with all database login data - with login all databases will be checked, if a user is no superadmin, he/she will be connected to the right webshop - when a user is a superadmin, the first screen will be a kind of control panel where you see new orders from all webshops, with a button you can go to another database from a webshop, so you have not to login again - so you can easily control all your webshops from one place - in the case you have shared products in different webshops, you could create products double with a special written program from admin (keep relations) but you could update them in their own admins (database), stock could be the same in all (same case when you sell products from a wholesaler, stock is never correct exactly) and you could create a cronjob to update the stock for that products every hour - in this case you have a little bit a multistore too but without to change many programs (for the rest use your creativity as an programmer) Do I forget something ?
  7. Guest99999999

    Concept Multistore

    Sorry I placed this topic in v3 by mistake! Because the description for the multistore contribution is limited and I can't not see which problems I could get with many other contributions (some payment methods are only working for one domain) I think it could be simple like follows (maybe it is the same concept, but this is no contribution only a way to work for the expeirenced ones because of future/other contributions), what is your opinion (only all queries have to be changed in the same way, so easily to change in a heavely modified webshop) ? Concept multistore : - add store_id (default 1) to the tables where necessary and change indexes - every webshop has in it's configurationfile an extra field store_id (unique id for each store) - change all queries for each webshop for store_id (or maybe some tables are the same for all webshops to make it more simple) - change all queries for admin for store_id (or maybe some tables are the same for all webshops to make it more simple) - define entries from admin configuration and webshop depended like url webshop, in configuration table (remove some from admin configurationfile) - extend the login for admin with store_id (dropdown webshop names) (this program does not use stores_id, only for the login and to put it into a session field) - in the top of admin (only after login as superadmin user) the possibility to change between stores - in the top of admin (only after login as superadmin user) the possibility to choose to see orders from all stores or only one store (default) - only orders get an unique number so not webshop depended (view extended with webshopname) - enter products and categories for each webshop (are mostly different, but this is to change later what an owner wishes) - languagesfiles al the same in admin, depended webshop definitions in table configuration (new group) extended with languagecode in the definition, separte function to retrieve contents definition - only the names of images can be added (upload via Easy Populate), images itself must be added by FTP at once (more efficient) - if you want to see the images too in admin, store the images in admin/image_websops (extended with stores_id) and define this path in the configuration table (has key store_id too) (you may not put only the images in admin for all webshops, because of SSL warnings, must be the same domain and admin lies in another domain e.g. of the first webshop) - image name logo webshop in admin extended with store_id (and adapt program where necessary like header, for pdf invoices you can put this name into the configuration field) - each contribution can be easily adapted in this way I think no error/problems senseable .... do I forgot something ?
  8. Guest99999999

    Google XML Sitemap SEO

    It can not be a problem because the links are seo-links, so all the text for every language is different, so there is not 1 duplicated link for all languages together (except the productnumber/categorynumber inside the link)! And I think they can't see the link to the same product_info.php pages for example, that's happening in the .htaccess translation inside the server ... it looks for them different pages I guess ... In fact they lead all to the default language because the language is not part of the seo link. But I don't think they compare the contents (text) of the pages, otherwise the language must be made a part of the seo-link like -en or -ge or -du etc. so being translated to product_info?language= in stead of only product_info. I let you know my own experiences within 3-4 days ... that's the time it normally takes Google will handle the sitemaps (my experience)...
  9. Guest99999999

    Google XML Sitemap SEO

    Hi Jack, Thanks for your answer and I understand now what you meant. Because a cron job does not understand parameters like ?language=4. So you have to create in my case e.g. index_4.php, index_5.php and index_6.php and each with hard coded $language_id=4 etc. So you have to change inside index_4.php (or 5 or 6) : 1) // FS start $languages_id = 4; or 5 or 6 //include_once(DIR_WS_CLASSES . 'language.php'); //$lng = new language(); //$languages_id = $lng->language['id']; // FS stop In my case it was enough to change to first statement chdir (in index_4.php etc.) to the full path for the catalog (because for my options I have not to deal with fopen in the programs, so I got no extra errors).
  10. Guest99999999

    Google XML Sitemap SEO

    Additional explanation (I forgot) : - this contribution use e.g. sitemapproducts.xml and sitemapcategories.xml (I used this ones only in my case) - so for every language you have to create before (in my case) sitemap_4_products.xml, sitemap_5_products.xml etc. (so you can remove sitemapproducts.xml and sitemapcategories.xml)
  11. Guest99999999

    Google XML Sitemap SEO

    Hi Jack, Thanks (and others) for the excellent contribution. It works too for many languages. I fixed it for myself as follows : for index.php 1) // FS start $languages_id = (int)$_GET['language']; if ($languages_id == 0) { exit(); } //include_once(DIR_WS_CLASSES . 'language.php'); //$lng = new language(); //$languages_id = $lng->language['id']; // FS stop 2) // FS start //$google = new GoogleSitemap(DB_SERVER, DB_SERVER_USERNAME, DB_DATABASE, DB_SERVER_PASSWORD); $google = new GoogleSitemap(DB_SERVER, DB_SERVER_USERNAME, DB_DATABASE, DB_SERVER_PASSWORD, $languages_id); // FS stop for sitemap_class.php 1) // FS start //function GoogleSitemap($host, $user, $db, $pass){ function GoogleSitemap($host, $user, $db, $pass, $lang){ // FS stop $this->DB = new MySQL_Database($host, $user, $db, $pass); // FS start //$this->filename = "sitemap"; $this->filename = "sitemap_" . $lang . '_'; // FS stop 2) function SaveFile($data, $type){ $filename = $this->savepath . $this->filename . $type; // FS start if ($type == 'index') { $filename = $this->savepath . 'sitemap' . $type; } // FS stop 3) // FS start //foreach ( glob($this->savepath . $pattern, GLOB_BRACE) as $filename ) { // if ( eregi('index', $filename) ) continue; // if ( eregi('manufacturers', $filename) && GOOGLE_XML_SITEMAP_CREATE_MANU != 'true' ) continue; // if ( eregi('pages', $filename) && GOOGLE_XML_SITEMAP_CREATE_PAGES != 'true' ) continue; // if ( eregi('specials', $filename) && GOOGLE_XML_SITEMAP_CREATE_SPECIALS != 'true' ) continue; $filename = DIR_FS_CATALOG . 'sitemap_4_products.xml'; if (file_exists($filename)) { // FS stop $content .= "\t" . '<sitemap>' . "\n"; $content .= "\t\t" . '<loc>'.$this->base_url . basename($filename).'</loc>' . "\n"; $content .= "\t\t" . '<lastmod>'.date ("Y-m-d", filemtime($filename)).'</lastmod>' . "\n"; $content .= "\t" . '</sitemap>' . "\n"; } # end foreach // FS start $filename = DIR_FS_CATALOG . 'sitemap_5_products.xml'; if (file_exists($filename)) { $content .= "\t" . '<sitemap>' . "\n"; $content .= "\t\t" . '<loc>'.$this->base_url . basename($filename).'</loc>' . "\n"; $content .= "\t\t" . '<lastmod>'.date ("Y-m-d", filemtime($filename)).'</lastmod>' . "\n"; $content .= "\t" . '</sitemap>' . "\n"; } $filename = DIR_FS_CATALOG . 'sitemap_6_products.xml'; if (file_exists($filename)) { $content .= "\t" . '<sitemap>' . "\n"; $content .= "\t\t" . '<loc>'.$this->base_url . basename($filename).'</loc>' . "\n"; $content .= "\t\t" . '<lastmod>'.date ("Y-m-d", filemtime($filename)).'</lastmod>' . "\n"; $content .= "\t" . '</sitemap>' . "\n"; } $filename = DIR_FS_CATALOG . 'sitemap_4_categories.xml'; if (file_exists($filename)) { $content .= "\t" . '<sitemap>' . "\n"; $content .= "\t\t" . '<loc>'.$this->base_url . basename($filename).'</loc>' . "\n"; $content .= "\t\t" . '<lastmod>'.date ("Y-m-d", filemtime($filename)).'</lastmod>' . "\n"; $content .= "\t" . '</sitemap>' . "\n"; } $filename = DIR_FS_CATALOG . 'sitemap_5_categories.xml'; if (file_exists($filename)) { $content .= "\t" . '<sitemap>' . "\n"; $content .= "\t\t" . '<loc>'.$this->base_url . basename($filename).'</loc>' . "\n"; $content .= "\t\t" . '<lastmod>'.date ("Y-m-d", filemtime($filename)).'</lastmod>' . "\n"; $content .= "\t" . '</sitemap>' . "\n"; } $filename = DIR_FS_CATALOG . 'sitemap_6_categories.xml'; if (file_exists($filename)) { $content .= "\t" . '<sitemap>' . "\n"; $content .= "\t\t" . '<loc>'.$this->base_url . basename($filename).'</loc>' . "\n"; $content .= "\t\t" . '<lastmod>'.date ("Y-m-d", filemtime($filename)).'</lastmod>' . "\n"; $content .= "\t" . '</sitemap>' . "\n"; } // FS stop Explanation: So I am working with 3 languages 4, 5 and 6. I run the index program for each language with parameter language, so index.php?language=4 (or 5 or 6). When I run the last language my sitemapindex.xml is complete. Like you said is not easy to do it quite automatically, costs time and I don't have because it is not a hobby for me. But so it works quickly with a few changes. When this program (index.php) is run as a cronjob (for me 3x) you get the errors with paths for some statements. So that has to fixed also. Best is maybe to start with a chgdir for the catalog path and after to change extra where necessary. For statements like fopen, I thought you have to use always the full path, so not a relative path (in a cronjob).
  12. Guest99999999

    IP trap Version 3 released

    Hi Fimble, Excellent contribution, thank you. For me the whitelist was not working because the end of line characters can be different on servers. So I fixed it in personal/index.php to remove the added end of line character "\n" to the ip address of the curious visiter and used rtrim to remove the end of line characters from the array elements from file. Now it worked for me.
  13. Guest99999999


    Hi Jack, As you already know your Sitemonitor found my hack in contact_us.php (language part) because your program searches for base64 (often used by hackers). Thank you. But I have problems with Sitemonitor as cronjob and because I builded many cronjobs (connections with suppliers) I know that if you use e.g. fopen you have always to use the full path (my experience, why I don't know), a relative path did't work in all my cases in cronjobs (even when I work with chgdir). So when I changed your program with full paths ($admin_dir in front of) it works (and still of course direct from admin). Ok I have still another problem but that's one for the provider (no writable connection allowed, maybe because of the su php settings). But first Sitemonitor could not found sitemonitor files like reference etc. with only the name (relative path).
  14. Hallo

    Niet zeker of dit de juiste plaats is voor mijn vraag, ik zal zien.

    Ik verstuur (bijna) alleen maar registered/aangetekend per TNT naar het buitenland en in sommige gevallen binnen nederland. Zal/moet ik dan nog een extra line in de dB aanbrengen of kan/moet ik dat dan per artikel invoeren.

    Bedankt alvast voor je reaktie.

    vr groeten

    Johan de Groot


  15. Guest99999999

    Why works ipn in test, why not in production ?

    Problem fixed : http://addons.oscommerce.com/info/2679 Ordernumber was not always send to paypal so ipn notification could not update order.