Jump to content

requinix

Administrators
  • Posts

    15,086
  • Joined

  • Last visited

  • Days Won

    415

Posts posted by requinix

  1. At first glance it seems fine - except for the fact that you're using backticks for some of your PHP strings, and they mean something completely different from regular ' and " quotes.

  2. I'll try to explain a little better about the approach I'm thinking of.

    It's recursive. You start looking at the outermost values - the "test" keys in your example - and you decide whether they should be included in the common array. Should they? Only if they're present in the other arrays.
    So you look at the other arrays. If they don't have a "test" then you already know the answer (no) and you can skip ahead to the next key. If so, you know that the key is present but you don't know if the corresponding value (the vehicle information) is the same; if it's partly the same, you just keep the common parts.
    Next you look at that array's values - the "make" and "vehicle_info" keys - and you decide whether they should be included in this inner common array. Should they? Only if they're present in the other "test" sub-arrays.
    So you look at the other sub-arrays. If they don't have the "make"/"vehicle_info"/whatever then you already know the answer (no) and you can skip ahead to the next sub-key. If so, you know that the key is present but you don't know if the corresponding value (the make, or vehicle info array) is the same; the make is a string so you can compare that, while if the vehicle info is partly the same, you just keep the common parts.

    See how that's working? The same overall approach applies to the "test" parts, as well as the "make" and "vehicle_info" parts, as well as the actual vehicle parts themselves, as well as the data about the vehicle parts. At each of those different "layers", when you have an array to compare, you need to delve into that array to see what may be common with the other usages.

    The main point to illustrate was the ability to stop early: if you're looking for some particular key, like the "make", then you naturally have to check the other arrays to see if they have it, but if they don't then you don't have to keep looking any further. And the technique for "stopping early" is that you (a) have this array of "common" parts you build up, as you confirm that each piece of data exists in the other arrays, and (b) at the end of whatever loop, you take that common array and add it to whatever the "parent" thing is (be that the big common array of data, or some sub-array of vehicles or parts or whatever), and you can use a continue as you're checking things to skip over that and immediately start checking the next key.

    However,

    Working through this now, I'm seeing that it's not as effective as I thought it might be, and that the code will be nicer if it took a slightly different approach: do the whole "stop early" thing, but instead of building up the common data, try tearing down the uncommon data.
    There's also not so much a need to continue; anymore - as in, do something to skip past some code and restart a loop - because there's no dangling code. Could break; though, but I opted for using if/else blocks instead to make it easier to follow.

    $vehicleGroups = [...];
    
    $firstGroup = array_shift($vehicleGroups);
    $commonGroup = $firstGroup;
    
    foreach ($firstGroup as $id => $vehicle) {
    	foreach ($vehicleGroups as $otherGroup) {
    		// layer 1: the vehicle IDs
    
    		// check if $id exists in all the other groups
    		if (!isset($otherGroup[$id])) {
    			// if not, tear down
    			unset($commonGroup[$id]);
    		} else {
    			// if so, go deeper
    
    			$otherVehicle = $otherGroup[$id]; // for convenience, to pair with $vehicle
    
    			// layer 2: the make and vehicle_info
    
    			// check if make exists and is in all the other groups
    			if (isset($vehicle["make"])) {
    				if (!isset($otherVehicle["make"])) {
    					// if not, tear down
    					unset($commonGroup[$id]["make"]);
    				} else {
    					// nothing to potentially go deeper into
    				}
    			}
    			// same for vehicle_info
    			if (isset($vehicle["vehicle_info"])) {
    				if (!isset($otherVehicle["vehicle_info"])) {
    					// if not, tear down
    					unset($commonGroup[$id]["vehicle_info"]);
    				} else {
    					// layer 3: the vehicle_infos
    
    					foreach ($vehicle["vehicle_info"] as $infoid => $info) {
    						// check if $infoid exists in all the other groups
    						if (!isset($otherVehicle["vehicle_info"][$infoid])) {
    							// if not, tear down
    							unset($commonGroup[$id]["vehicle_info"][$infoid]);
    						} else {
    							// if so, go deeper
    
    							// layer 4: the bits of data in the vehicle_infos
    
    							// I'm going to assume that "brake" is only one of many possible values
    							// rather than handle each one like make/vehicle_info did individually, do another foreach
    
    							foreach ($vehicle["vehicle_info"][$infoid] as $partid => $part) {
    								// check if $partid exists in all the other groups
    								if (!isset($otherVehicle["vehicle_info"][$infoid][$partid])) {
    									// if not, tear down
    									unset($commonGroup[$id]["vehicle_info"][$infoid][$partid]);
    								} else {
    									// nothing to potentially go deeper into...?
    								}
    							}
    						}
    
    						// don't keep the info if there was nothing in common
    						if (!$commonGroup[$id]["vehicle_info"][$infoid]) {
    							unset($commonGroup[$id]["vehicle_info"][$infoid]);
    						}
    					}
    				}
    
    				// don't keep vehicle_info if there was nothing in common
    				if (!$commonGroup[$id]["vehicle_info"]) {
    					unset($commonGroup[$id]["vehicle_info"]);
    				}
    			}
    
    			// don't keep it if there was nothing in common
    			if (!$commonGroup[$id]) {
    				unset($commonGroup[$id]);
    			}
    		}
    	}
    }
    
    print_r($commonGroup);

    Note the similarities in the different "layers", and how they all repeat the same idea more or less the same way: if the thing is not present then remove, otherwise check it in more detail.

    Is it better, or even shorter or simpler, than what you have? Not really. Could it be improved? Undoubtedly. But the point was to show the "you can stop early if you know it won't work" concept.

  3. All you really need is some sort of "array_intersect_recursive", because the exact structure of the $products doesn't actually change how you compare the different parts of it to others, but unfortunately PHP doesn't have that built-in and implementing it yourself is a bit complicated.

    A quick improvement is that you can array_shift($products) to remove the first one from the array and return it back to you. Means you don't need to skip $index 0 anymore.

    A more complicated improvement would be to adjust your approach: rather than count how many times something appears before adding it, it would save some processing time if you immediately bailed out when you discovered that something did not appear. As in:

    $commonArray = [];
    $first = array_shift($products);
    foreach ($first as $key => $vehicle) {
    	$commonVehicle = [];
    
    	// check if $key exists in all the other $products
    	// if not, use continue (likely a continue 2; or continue 3;) to skip ahead of this loop here and go to the next $key
    	// if so, build up the contents of $commonVehicle...
    
    	if ($commonVehicle) {
    		// only add this $key if there is something to add
    		$commonArray[$key] = $vehicle;
    	}
    }

    And like I said, while the keys of $products changes as you dig into it, you're repeating the same "check if <key> exists in other <arrays>" all the way down, so you'd basically just repeat the above code a couple more times with different variable names.

  4. 5 hours ago, Chrisj said:

    However, in the paypal.com API Event logs I see, under API Calls, from an attempt today: http status 201, and under debug ID I see Request, and I see Response.

    That's the initial call from your site to PayPal to begin the transaction. What's missing is the second one from PayPal to your site after the transaction has completed.

    Do you see anything in your access logs for the URL https://websitename.com/aj/wallet/get_paid and that also includes a token=?

  5. 4 hours ago, Chrisj said:

    I've looked many places I do not see any notification of a transaction.

    It's not a notification. I'm talking about a record in your [whatever the value of that T_VIDEOS_TRSNS constant is] table.

    4 hours ago, Chrisj said:

    "integration that caused the payment capture call not to be invoked after the customer approved the payment"

    I can't tell for sure but it sounds like the code that handles the callback from PayPal, which I believe is the code starting from

    if ($first == 'get_paid') {

    Do you have access to server access logs? They would tell you what URLs are being hit on your site - to confirm that this "get_paid" URL (maybe /get_paid/???) is being hit by PayPal, and likely also whether it returned a successful 200 or something else like a 3xx redirect or a 500 error.

  6. :psychic:

    There's no logging of errors in here so it's going to be hard to know why something isn't working... They should have been able to confirm that your side was correctly checking the results after they call your site back, so if that's working then I assume the issue is going to be after.

    Can you at least see that a transaction has been recorded?

  7. It appears a missing cookie is the problem? You should be able to check this easily yourself by looking in the browser to see if the cookie is there.

    But database information isn't something that should be in a cookie, so I wouldn't expect cookie problems to result in that error - more likely, they'd result in forgetting you were logged in or what step of an installation wizard you were on.

  8. 4 minutes ago, EuroLee said:

    My train of thought was if I get affiliates linking directly to /XXXXXX/ and that just has the index.php page in for the site, when the visitor clicks a link, it will take them to the join page where the affiliates ID will be presented along with transaction information to credit them with a sale.

    Users aren't going to care about what the URL looks like. The only purpose of creating friendly URLs like this is so that if a human being looks at it then they can understand what it means, and that matters if you're giving them these links in something like an email.

    Have you ever looked at Amazon URLs with referrer codes? If one of the biggest sites on the internet isn't doing friendly affiliate IDs then it's just not going to matter much.

    So take your intentions with a grain of salt, and consider that having a page with an "unfriendly" URL is going to be 1000x better than having no page at all.

    4 minutes ago, EuroLee said:

    The other pluses of having it redirect to https://www.domain.com/XXXXXX/ would be that i should, in theory help with search engine rankings to that specific domain name and, its a lot easier for affiliates to remember a short link such as that one, than the one provided by the payment processor to track their affiliate sales.

    1. Search engines don't care about URLs either. They did once long ago, but technology and practices have advanced far since then. Concepts like semantic page markup and mobile friendliness are far more important.
    2. Why would you want search engines to index these URLs/pages in the first place? One of the main points of an affiliate link is that the affiliate alone controls it - if it starts showing up in search results then you lose a lot of the benefits.
    3. You haven't mentioned yet what these URLs/pages actually do. Are you redirecting? Then SEO is mostly irrelevant. Are you displaying content? If the content is the same for different affiliates then your site will lose in SEO because they're going to think you're a content farm.

    4 minutes ago, EuroLee said:

    Ill take a look at htaccess redirect stuff and see if I can figure out the code needed to add that to the server on all of the domains where I want to implement this.

    Forget the .htaccess stuff for the moment and implement the PHP page first.

  9. You need both .htaccess (to tell the web server how it should handle these custom URLs) as well as PHP (to know what to do with the code in that URL).

    The exact details of how you do that varies between applications. Nowadays, most sites already have the .htaccess stuff in place because they're already using URL redirecting - such as this page, whose URL is /topic/$number-$string which "redirects" to some internal PHP script.
    If you don't have that already then fine, you just need to add something for these URLs specifically.

    But there's some preliminary work you have to go through first: create a PHP script which is capable of taking a "XXXXXX" code and doing whatever is necessary. You can just hardcode it into your script to test with,

    <?php
    
    // todo: $code = value from $_GET
    $code = "XXXXXX";
    
    // ...

    URL rewriting will transform /XXXXXX into something like /path/to/script.php?code=XXXXXX.

    Speaking of, /XXXXXX isn't a great choice as it will be ambiguous with any other page at the root of your website - how do you tell whether the "XXXXXX" thing is an actual page or a tracking code?
    So I suggest giving it a "directory" of something like /track/XXXXXX. The "/track/" makes it unique so it won't conflict with anything else.

  10. By the way, if it wasn't clear, when your browser says "not redirecting properly" what it really means is that you created a redirect loop: the page was redirecting back to itself over and over again until the browser decided enough was enough.

    Conditionally redirecting would solve this, of course, by virtue of the fact that it won't redirect at all. But it does mean that you aren't completing a POST/Redirect/GET cycle. Which could be fine for you...

  11. Looking through their docs myself, I can't tell either...

    So what will probably be the easiest way to get an answer is to get the answer yourself: set the return URL and have that page log $_GET and $_POST somewhere for you to look at. That data will probably match up with something in the docs.

  12. "Resource id #X" means you have code that is trying to echo a resource - that's a type of value, like strings and integers and arrays are.

    Two things:

    1. Code doesn't just randomly start behaving differently. What changed recently?
    2. "Resource id #34" has to be coming from somewhere. If it's not those two var_exports then where is it?

  13. You can "yield from" another generator.

        private function getTextFiles(File $file):\Generator
        {
            foreach($file->getChildren() as $child) {
                if($child instanceof IsTextFile) {
                    yield $child;
                }
                else {
                    yield from $this->getTextFiles($child);
                }
            }
        }

     

    • Great Answer 1
  14. "Make the button go away and open another button" isn't exactly the most descriptive thing ever...

    As long as something isn't visible, it doesn't really matter much whether it exists or not. The simplest thing here is going to be a sort of toggle: start with the first button visible and the second not, then "toggle" the two so the first is not visible and the second is.

    1. Start with the HTML that includes both buttons.
    2. Figure out how you want to hide the unwanted button and apply it now so that the second one is hidden.
    3. When the first button is clicked, do whatever it takes to hide the first button and show the second.

    Okay, so reading that now it doesn't seem helpful, but I'm trying to word it in a way that makes it flexible. Because when it comes to HTML and CSS and Javascript, there's always 100 ways to accomplish a task... however 95 of them are terrible.

    Here's what I would do.

    1. Create a CSS class for these types of button. It doesn't have to do anything (unless you want it to) and only really exists to mark these buttons as being particular types of buttons. So in that sense there's nothing to "create" per se.
    2. Create a CSS class for "the active button". Apply it to the first button now, and use CSS to make "these types of buttons" which are not "the active button" be hidden. This means you control visible vs. hidden using a CSS class and not the direct style.* attributes.
    3. Add Javascript for the first button that will remove its own "the active button" class and add it to the second button.
    4. Add Javascript for the second button that will remove its own "the active button" (assuming you want it to be removed when clicked as well) and make the DIV you want visible; the latter should be through CSS too but it's not really that important.

    Personally, if I'm dealing with behaviors that are tied to Javascript, I prefer to deal with data attributes instead of class names, but that's not very important either.

    All together you get something like this:

    <style>
    	#step-container .step-button:not(.active-step) {
    		display: none;
    	}
    </style>
    
    <!-- This is a nice thing that "scopes" the buttons - using step-button or active-step outside this won't get the CSS applied -->
    <div id="step-container">
    	<button id="step1" name="button" class="btn step-button active-step">Click to Verify Information</button>
    	<button id="step2" name="button" class="btn step-button">Show Div</button>
    </div>
    
    <div id="thediv" style="display: none;">...</div>
    
    <script>
    // Creating and running this anonymous function immediately means you can use variables without making them global
    (function() {
    	// Grab these three ahead of time to make the function code nicer
    	const btn1 = document.getElementById("step1");
    	const btn2 = document.getElementById("step2");
    	const thediv = document.getElementById("thediv");
    
    	// Add event listeners through code instead of putting them inline with onclick attributes
    	btn1.addEventListener("click", () => {
    		// Use .classList to add and remove classes instead of going through the .className string
    		btn1.classList.remove("active-step");
    		btn2.classList.add("active-step");
    	});
    	btn2.addEventListener("click", () => {
    		btn2.classList.remove("active-step");
    		// Literally removing the "display" override is better than forcing it to be block/inline/whatever it's naturally supposed to be
    		thediv.style.removeProperty("display");
    	});
    })();
    </script>

    This is closer to the sort of modern stuff that we can do nowadays; the above isn't actually quite ideal, but it's a good step-up from the sorts of stuff we had to do 10 and 20 years ago with inline event handlers and quick-and-dirty Javascript.

  15. 8 minutes ago, XCalibre3 said:

    lol to both of you :D I'm 51 and ancient...  Hven't coded in a long time. I will find another way.  Thanks.

    I mean, it still works (except the ADODB thing), so... I'm not exactly the youngest web developer either and I find myself falling back on outdated practices occasionally.

    The IndexedDB thing isn't especially hard, but does make you work a bit more to get some basic stuff. Fortunately the MDN has a reasonable example to reference.

  16. 22 minutes ago, kicken said:

    It will not work on any modern browser.

    Between the inline onclick, script with a type attribute, and use of var to define variables, I'm going to guess some of this wasn't necessarily written in a time when we had our modern browsers.

  17. Bonus fact: the default min value is 0 and the default max value is unbounded/infinity, so if you use that comma (to indicate it's not an {exact} count but a {min,max} range) then you can leave out the min value itself to get the same "up to X" count.

    \d{,5}

     

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.