Jump to content

bsandall

Member
  • Posts

    222
  • Joined

  • Last visited

  • Days Won

    11

Everything posted by bsandall

  1. Are you able to try other browsers? Firefox and Chrome have both worked well for me. If that's not an option and you are comfortable with HTML, you can edit the markup directly by using the 'Source' button in the top left of the toolbar and enter in the image that way, e.g.: <img alt="Flaming logo" src="/images/source/Flaming_M.jpg" style="width: 200px; height: 100px;">
  2. Indeed, as bsmither points out, this kind of operation can quickly break with limited precision, unless you are either extremely lucky or very deliberate in choosing your quantity pricing. Furthermore, since the unit price is always shown in the basket, any rounding that you do will result in the total not matching the apparent sum. Perhaps you could look into alternatives such as creating a separate product e.g. 'Batteries, pack of 12' with the discounted price set exactly? Another option would be to round off to 2 points of precision, so the battery would cost $0.88 in quantity and the customer overpays a few cents, whereas on others it would round down and the customer would underpay a few cents. I would not go this route if you have advertised pricing somewhere, e.g. you specifically advertise that you can buy 12 batteries for $10.50. If you really want to allow 3 decimal places in the price, though, you could try modifying the priceFormat method in tax.class.php by changing the `$decimal_places` variable, but there are some hard-coded formatting decisions elsewhere in the code, such as in cubecart.class.php's _receipt() function: $item['price_total'] = $GLOBALS['tax']->priceFormat(sprintf('%.2F', $item['price'] * $item['quantity']), true); You'd have to change the formatting to '%.3F' and also look through the rest of the code for similar practices. The easiest way to find all of those would be to search for '%.2F' using Linux grep or Windows findstr functions in your cubecart directory.
  3. Just out of curiosity, why do you need such a high level of precision, specifically in the store's database? For example, in my own store, I have a script that rounds up to the nearest cent when updating prices, even if on my spreadsheet it is something like $1.23456789.
  4. From your previous post, it sounded like you were trying to allow customers to pay by credit card, my mistake. If you only want Express Checkout, then no, you wouldn't want PayPal Pro (which has Express Checkout as an integrated component). Just use the regular PayPal module, which it sounds like you are.
  5. PayPal Pro provides 2 checkout buttons because each serves a different purpose: 1. Checkout, i.e. with a credit card - the customer enters their info on a form on your site, but this form is submitted to and processed by PayPal and the customer never leaves your site. This does NOT require the customer to have a PayPal account, and your server doesn't store any of the credit card information, just the results of the transaction as received from PayPal. 2. Check out with PayPal - the customer is taken to a PayPal login page with your store logo where they must login and choose a payment option, then they are returned to your site. Obviously, this requires the customer to have a valid PayPal account. I'm not sure what others mean by the 'gateway version' vs. the 'pro version', as a gateway is a generic term for any way of transferring data between e.g. your website and e.g. the payment processor. If they mean the 'Express Checkout' version, I'm pretty sure that only supports the 'Check out with PayPal' option as described above.
  6. Notepad++ should be fine, but it depends on your settings. Please try it with regular Notepad; if it still doesn't work, can you verify that you do have API credentials in your PayPal account as I described above, and that 'PayPal Payments Pro' is listed as 'Live' in your PayPal services? Also, what version of the PayPal Pro plugin are you using? I have v1.0.9 and can confirm that it is working both live and, when I swap the credentials, in sandbox mode. If after checking all of the above you still can't get it to work, you may need to contact PayPal support.
  7. While you should always follow best practices when you can, I wouldn't worry too much about going out of your way to do so unless you notice actual real-life speed issues. For example, your home page loads extremely fast for me (approx. 1-2 seconds) on my PC, so unless you are experiencing speed issues on mobile devices or on particular pages such as checkout, it's probably not worth your time unless you just want to make the most highly optimized site you possibly can just because. My 2 cents.
  8. Being unfamiliar with versions prior to v6, I can't tell you exactly what to add / change, but what I would so is the following: Make a backup of the live v3 database and import it into a local MySQL installation Compare the SQL structure of the v3 tables to the v6 tables Use ALTER TABLE on your local v3 database until it matches the v6 tables - paste each command you used into a text file Test the local database with a local install of CubeCart v6 - note that live 'CubeCart_config' values such as the store address may not work well locally, so you may need to delete that entry and start fresh for testing If that all worked out for you, then do the following: Take your store offline temporarily Make a FULL backup of your live site, just in case the upgrade doesn't work out Using PHPMyAdmin or whatever database interface you have for your store, paste all the ALTER TABLE commands you saved into the 'SQL' query box and run it to update the live database, or just import a dump of the local version (keeping in mind your store may not work with the local version of the 'CubeCart_config' settings). FTP the updated code base to the live site Test while still in offline mode If it works, great; if not, restore from your backups. I've found that pretty much every table other than CubeCart_config can be transferred between local and live without a hitch, but the values in that table can prevent your entire store from working with no way to access the admin panel to change them. The only remedy is to drop the table or delete all entries from it (there should only be one anyway) and recreate it with the default values from the CubeCart version you are using.
  9. Login to your PayPal account and click on 'Profile'. Do you have 'PayPal Payments Pro' listed in your 'Services'? If you do, under 'Account Information', click on 'Request API credentials'. Then, under Option 1, click the 'Set up PayPal API credentials and permissions' link, followed by 'View API Signature' under the NVP/SOAP API integration. Make sure your API Username, API Password, and Signature all match EXACTLY. The tricky part, which bhsmither clued me in on previously, is that the character encodings may screw you up if you copy/paste directly (specifically the '-' character, which has multiple hex representations), so paste the values into plain old Notepad, then re-copy them and paste them from there. Also, as others have mentioned, the live and sandbox modes use different credentials and are not interchangeable. The credentials above would be for the live version; sandbox credentials are created from PayPal's sandbox and/or developer sites (don't recall at the moment which).
  10. Yes, as long as the page containing the form you want to submit is the last one you opened. If you open any other admin tab page afterward, and you entered some data but didn't submit the form, all that data will be lost*. Thus, if you are planning to submit a form, I recommend you only have one tab open - it's easy to forget and open another tab by accident half-way through a form (I've done it lots... but maybe that's just me). * Unless you open yet another tab to the same page and copy/paste that data over and then submit that one, but if you tried to submit the first one, *poof*
  11. To clarify (though I may just be reading your response incorrectly), you can have multiple tabs open so long as only one of them is the admin panel. I usually have both the storefront and the admin open in the same window, along with a dozen or more other tabs.
  12. This type of security measure, known as the Synchronizer Token Pattern, is typically implemented to prevent Cross-Site Request Forgery attacks, which, while rare and usually difficult to pull off, can be very devastating when successful. EDIT: Note that you can avoid getting sent to the dashboard by working with the admin panel open in only one tab at a time, which is unfortunate because having multiple tabs open to different parts of the admin panel often makes a task easier to complete.
  13. It may just be that the OP didn't have an account: I'm using PayPal Pro (with an account) and it appears to be working fine (tested with the sandbox for now) - payment requests with items in quantities over 1 seem to be passing the correct total. PayPal request and response: Request Sent - https://api-3t.sandbox.paypal.com/nvp PAYMENTACTION=Authorization&IPADDRESS=127.0.0.1&RETURNFMFDETAILS=1&INVNUM=151229-120223-1173&AMT=107.09&ITEMAMT=107.09&CREDITCARDTYPE=Visa&ACCT=<redacted> Response received TIMESTAMP=2015%2d12%2d29T20%3a02%3a19Z&CORRELATIONID=h13201mar6910&ACK=Success&VERSION=112&BUILD=18308778&AMT=107%2e09&CURRENCYCODE=USD&AVSCODE=X&CVV2MATCH=M&TRANSACTIONID=1BV93017BF5915211Also see attached cart image. Still worth investigating, but I don't think there is an issue.
  14. I see you are working on your Git skills, nice I do still plan on creating a good tutorial for that, but time, you know... If you are on Windows, a handy trick to find all places in your code that certain string appers is to open a command window in your repository directory (shift-right-click the directory and select 'open command window') - once you've done that, you can do a search for 'cart_oder_id' or anything else using the Windows findstr command. Since that page can be a little dense, this is what my typical command looks like: findstr /i /s /n /c:"search_query" *.*
  15. Here's a little code snippet that would meet the UPS specs, at least: /** * Validates and formats the postal code based on the country following UPS specifications. * @param $postal_code the postal code to validate * @param $country_code the 2-letter country code * @throws InvalidArgumentException if the code is invalid * @return formatted postal code */ public function getFormattedPostalCode($postal_code, $country_code) { switch ($country_code) { case 'PR': // fall-through to US case 'US': // US and PR (Puerto Rico): 5 or 9 digits in the format xxxxx-xxxx $pattern = '/^([0-9]){5}(-| )?(([0-9]){4})?$/'; if (empty($postal_code) || !preg_match($pattern, $postal_code)) { throw new \InvalidArgumentException("Invalid postal code: $postal_code"); } if (strlen($postal_code) > 5 && $postal_code[5] != '-') { $postal_code = substr($postal_code, 0, 5) . '-' . substr($postal_code, -4); } return $postal_code; case 'CA': // CA (Canada): A#A#A# - upper case letter-digit-letter-digit-letter-digit $postal_code = strtoupper($postal_code); $pattern = '/^([A-Z][0-9]){3}$/'; if (empty($postal_code) || !preg_match($pattern, $postal_code)) { throw new \InvalidArgumentException("Invalid postal code: $postal_code"); } return $postal_code; default: // All other countries: code is optional; if present, may be up to 9 alphanumeric characters $pattern = '/^[a-z0-9]$/i'; if (!empty($postal_code) && (strlen($postal_code) > 9 || !preg_match($pattern, $postal_code))) { throw new \InvalidArgumentException("Invalid postal code: $postal_code"); } // postal code returned below } return $postal_code; }
  16. Perhaps a better pattern would be '/^([0-9]){5}(-| )?(([0-9]){4})?$/'- this would match 12345, 123456789, 12345-6789, and 12345 6789. EDIT: However, reviewing the UPS developer's guide: Neither of the above patterns is sufficient to meet the specification, and neither one automatically inserts a hyphen; though the API does say that a hyphen is optional, it doesn't specify whether a space is allowed. EDIT 2: Interestingly, the standard UPS module doesn't show any available shipping options for 9-digit codes with or without a hyphen included. It seems it can only accept exactly 5 digits, even though the API docs suggest that 9 digits should be acceptable.
  17. I raised a feature request on Github for this, and have implemented it in my own store. The implementation branch is a little outdated now, but if you are handy with code, you could use the changeset as a starting point. Of course, mods and plugins are the recommended way to add functionality - you should only consider modifying core code if you have a version control system in place that allows you to merge changes from the master CubeCart branch.
  18. One thing to note with the API credentials is that the character encoding can mess them up - even though they look like they are correct, if you copied and pasted them from your browser or any type of rich text editor, there is the chance that they are not exactly the same and PayPal will reject them with the 'Security header not valid' error. Also note that the live and sandbox credentials are not the same. I just had the encoding issue when moving a site live today. So if you're still having the issue, try pasting your credentials into regular old Notepad and then re-copying them from there before pasting them into the Admin panel plugin settings.
  19. I don't see why you are so vehemently opposed to me moving my credentials outside of the root directory, yet on Github you raise the issue of forcing users to rename the admin folder... well, anyone with a strong password shouldn't have to worry about that, right? Whether an attack vector is likely or not is irrelevant - no one is likely to break into my house, but I still lock the door, and advising people to do otherwise is sort of like malpractice for web security. Both moving the credentials out of the root directory and renaming the admin folder are simple steps that address fairly unlikely attacks. Unless you host your own server (which you do), then you never know what the people managing your server are going to do with it. Maybe they hire someone new, or some setting gets bungled in an upgrade, etc, so why not take a minute to take some simple precautions, and why argue against it?
  20. I totally agree, but this is not security by obscurity, it is preventing your credentials from having any URL at all so they are completely inaccessible* from the web no matter what. Here's a StackOverflow question I searched up for you that discusses this. However as you said, someone with root / direct access to the server would still be able to read your file, but there isn't a whole lot you can do about that. Security by obscurity would be renaming the admin folder to '21097590GOihEA907' or running your secure server from a non-standard port - they do add some measure of security in the sense that you are less likely to be attacked (which can be very significant), but you still need to have real security measures in place if you ever are attacked. * Unless someone can upload and run a .php file or other script to your server, at which point it is trivial to read the contents of any file in your home directory whether public or not, but then you have already been compromised.
  21. Security in layers, folks Moving the database credentials out of the public directory is just one more layer - what if there is ever a vulnerability found in your firewall software, for example? As for restricting database permissions, the principle of least privilege is a standard approach to a more secure system, so why the opposition? It's the same reason if you run a server you don't just give every user root access - maybe they wouldn't break anything on purpose, and maybe your other settings would prevent them if they tried, but why take the chance? Normally I would grant granular permissions at the table level so non-admin users can only affect tables that they would reasonably be accessing / modifying, but unfortunately my current hosting provider does not allow permissions at that level (even though MySQL supports it natively), so I have to make do with what I have. Besides, it hardly takes any changes at all to core code - literally a handful of lines in 2 files - so that's not an issue for me. EDIT: Actually, it also requires one more change to allow a new database instance: public static function getInstance($config = '', $create_new = false) { if (!(self::$_instance instanceof self) || $create_new) { self::$_instance = new self($config); } return self::$_instance; }Thanks @bhsmither for tracing the admin login path - saved me some time this morning!
  22. Typically when I'm working on a website with a database, I keep the database credentials in a file stored outside of the public web root directory so that it is impossible to access via URL, and I also set up different database users for regular users (e.g. customers) and those with elevated privileges (e.g. admins). The first part can be done simply by editing the global.inc.php file to include a different file stored somewhere else: <?php require CC_ROOT_DIR . '/../secret/path/my_hidden_db_credentials.php'; ?>For additional security, I prefer not to track global.inc.php or any hidden files with the rest of my version controlled files. However, for the second part, I'm wonder where the best place is to reestablish the database connection using elevated admin credentials; specifically, I would like to know when, exactly, it is determined that a user is an admin and that they are fully authenticated. As far as I can tell after a little investigation, this would be right after the call to Sanitize::checkToken() in controller.admin.pre_session.inc.php - is that correct? //Check security token Sanitize::checkToken(); // Re-initialize Database class with elevated privileges now that identity is established (is it?) //$GLOBALS['db']->close(); // this crashes for some reason $GLOBALS['db'] = Database::getInstance(array( 'dbhost' =>$glob['dbhost'], 'dbusername'=>DB_ADMIN_USER, // defined in hidden file 'dbpassword'=>DB_ADMIN_PASS, // defined in hidden file 'dbdatabase'=>$glob['dbdatabase'], 'dbprefix' =>$glob['dbprefix'], ) );Also, my default database user has only the 4 basic permissions required for CRUD operations: Select, Insert, Update, Delete - I presume this will be sufficient for anything that a normal user is capable of doing while shopping and managing their account, but does anyone happen to know otherwise?
  23. Yes, normally, but in the particular case of using a WYSIWYG type editor, the HTML markup is part of the data - it's not the same as an actual HTML page where the data is added separately. Do you know of any WYSIWYG type editors that store the markup and content separately?
  24. It's always good to have a test area Personally, I prefer to keep my testing mostly offline, so I use a local WAMP stack going with multiple test sites (various projects, not all CubeCart) on it each in a different directory, where each test site has its own git repo (most completely local, too - no online version of the repo). This way, I can catch most of my issues before they ever go live, as well as continue to work without internet - our internet connection is pretty bad, so that last point is especially important for me. Anyway, sounds like you are well on your way with Git already. Once you start thinking in terms of the git workflow, life gets much easier, but be prepared: I fought with Git plenty my first year, though I didn't use it much that first year, either. It can be very frustrating, but if you stick with it, it really pays off.
  25. When I have more time, I'll update the earlier post to be more helpful, i.e. full setup instructions using SourceTree, which is the only application I would recommend both for beginners and more advanced users alike. The interface is 100x more intuitive and useful than the Github app for Windows, not even exaggerating (okay, maybe a little...). Note that you can use SourceTree with repositories hosted on Github and vice versa, the Github app for repos on Bitbucket, and you can manage repos on both from the same application at the same time. Pretty nifty.
×
×
  • Create New...