Jump to content

creativejay

Members
  • Posts

    259
  • Joined

  • Last visited

Posts posted by creativejay

  1. Ah, thanks!

    Now... Could I please get some help with the hook?

    • I've written the following (site/ready.php) but see nothing in the logs and no email arrives
    • I suspect I'm starting wrong in how I retrieve the SnipWire/SnipCart order data
    • SnipCart is currently in TEST mode
    • I've confirmed the SMTP settings in the WireMail SMTP module configuration
    • I'm operating on the assumption that the $event returned for this Hook contains the subscription information as shown on: https://docs.snipcart.com/v2/webhooks/subscription-events
    $wire->addHookAfter('SnipWire::handleSubscriptionCreated', function($event) { 
    	
        $snip_input = $event->arguments(0); 
    	$event_json = json_decode($snip_input); 
        
        $mail = $wire->modules('WireMailSmtp'); // calling WireMail SMTP to send a notification since SnipCart doesn't
        $clientEmail = $snip_input->getChildByName('user')->email->value; // Fetching customer's email
        $clientName = $snip_input->getChildByName('user')->fullName->value; // Fetching customer's Full Name
        $products = $snip_input->getChildByName('items'); // Fetching an array of the items in the cart
        
        foreach($products as $p) {
    		// For each product in the cart, we send the corresponding coach an email
            $coach = $p->getChildByName('Coach')->value;  // The coach selected at checkout
       		$kvcoach = $wire->pages->get("title=$coach"); // Coach will have a matching page on the site
        	$coachEmail = $kvcoach->email; // get email from that page's fields
    
    		$to = array('user@domain.com'); // including the admin (me) in the TO for testing
    		array_push($to,$coachEmail); // add coach's email to array
                 
    	    $cart = $p->getChildByName('name'); // product name from this order item
    
    		try { 
    	        $body = $coach . ", you have a new client! " . $clientName . " (". $clientEmail.") has subscribed to: " . $cart . "<br /><br />" . "<pre>" . var_export($event_json, true) . "</pre>";
    	        $subject = $clientName . " (". $clientEmail.") has signed up for ". $cart;
    	        $mail->to($to);
    	        $mail->from('no-reply@domain.com');
    	        $mail->subject($subject);
    	        $mail->bodyHTML($body);
    	        $mail->send();
    		}
    		catch (\Exception $e) {
    	     $error = "Email not sent: " . $e->getMessage();
    	     $mail->log($error);   
    		} 
        } 
    });

     

  2. Has anyone here worked with SnipCart's webhooks yet?

    I can't find an example in their docs of a fully formed webhook file, nor am I quite sure how I would imitate their examples along with the PW API to call things so I don't have to manually enter every product, for example. Their webhook examples also seem to contain hardcoded info that should be drawn from the session?

    I'm trying to set up both gift cards, and extra notifications for subscription events.

    https://snipcart.com/blog/creating-a-gift-card-application-with-snipcart-php

    https://docs.snipcart.com/v2/webhooks/subscription-events

  3. Thanks!

    Will SnipWire allow for multiple product templates?

    Right now I have several products that are subscriptions, several that are short-term access, and others that are one-time purchases. These are all for services, with nothing to ship. They are each a different (non "snipcart-") template at the moment but if SnipWire would only allow one, I can go back in and build a lot of dependent fields based on checkboxes or select dropdowns.

    Thanks for your pre-launch guidance on this!

  4. 5 hours ago, Gadgetto said:

    Important: SnipCart is not yet ready for production environments!

    Just to be clear, SnipWire is not yet ready, correct? As long as I develop with SnipCart's code and don't rely on your module, I can safely plan to add SnipWire to the site after its stable release, correct? 

    I'm just trying to plan ahead for that date. ?

  5. @Gadgetto this module looks fantastic! I'm looking at using SnipCart to create an ecommerce site because it seems very user friendly (important for when I pass this site off) and it has support for some of the features I need.

    One of those features is subscriptions. Do you have advice for setting up monthly subscriptions vs one-time purchases? I'm new to both your module and SnipCart and I didn't see anything obvious after the initial install and a bit of poking about in the admin but I do see it in the Module's page under Setup and references to subscriptions in the module files.

    Am I overlooking something, or do I just need to add custom fields to the snipcart-product template (and output them in the markup) to correspond to the button attributes listed in https://docs.snipcart.com/v3/setup/products ?

    Thanks!

  6. Thank you, Pixrael! That got me to the solution!

     

    				$loadLogo = $getKV->exhibitor_logo;
    				$logoresize = $loadLogo->pim2Load('ig')->canvas(1600,895,array(0, 0, 0, 0),'c',0)->setOutputFormat("png")->pimSave()->httpUrl;
    					
    				$exlogo = $logoresize;
    				$filename = $getKV->name . "_instagram.png";
    				
    				$background = "https://domain.com/site/templates/images/Exhibitor-Graphic-BG-Platinum.jpg";
    				
    				
    				$logo =
    				file_get_contents("$exlogo");
    				$bg =
    				file_get_contents("$background");
    				
    				$im = new \Imagick(); 
    				$im->readImageBlob($bg);
    				$im2 = new \Imagick();
    				$im2->readImageBlob($logo);
    				
    				$im->compositeImage($im2, \Imagick::COMPOSITE_ATOP, 100, 350);   
    				
    				
    				$im->setImageFormat("png24");
    				$im->scaleImage(1024,
    				1024, true);
    				$im->writeImage("../downloads/$filename");
    				$im->clear();
    				$im->destroy();
    				
    				$file =
    				"https://domain.com/site/downloads/$filename";
    				echo "<img src='$file' alt='$getKV->name' />";

    Now I just need to bring in the code to start with a different background graphic based on the order history in Padloper. In THEORY, I'm almost there! ?

     

    Thanks so much for your help!

    • Like 1
  7. 1 hour ago, Pixrael said:

    It work for me. Try to assign the image path manually to verify that the Imagick is working:

    
    $im->readImageBlob("https://www.domain.com/site/templates/images/image.svg");

    If you are able to open the picture in the browser using the path, this should render the picture on the page.

    				header("Content-Type: image/jpg");	
    				$im = new
    				\Imagick(); 
    				$im->readImageBlob("https://www.ketocon.org/site/assets/files/1130/ketovangelist-lockup-w-tag_glc-lg.1500x0.png");
    				

    Still getting a blank square. (doesn't work if I put 'png' for the header, either, or try the other half of the image I'm trying to composite, which is a jpg)

    Here's my imagick install (from phpinfo):

    548007845_ScreenShot2019-10-14at5_05_49PM.png.0200c92231b0830338e57a0c10666ee5.png

     

  8. On 10/3/2019 at 10:54 AM, Pixrael said:

    No idea... try this alternative:

    
    $im = new \Imagick(); 
    $im->readImageBlob($imageurl);

     

    Thanks. This displays an empty image object (which renders as a small empty square). ? 

    I also tried changing the source images in $ex_logo and $background from path to url but that didn't have a positive effect.

  9. Ah, thank you, that corrects the path. Both image variable paths now output starting from the server root.

    				if($getKV->exhibitor_logo->width >= $getKV->exhibitor_logo->height) {
    					 $logoresize =  $getKV->exhibitor_logo->width(1500);
    					} else {
    					 $logoresize =  $getKV->exhibitor_logo->height(500);
    				}
    				$ex_logo = $logoresize->path . $logoresize->filename;
    				$background = $config->path('templates') . "images/Exhibitor-Graphic-BG-Silver.jpg";
    				$imagick = new \Imagick($background);
    				$imagick2 = new \Imagick($ex_logo);
    				  
    				$imagick->compositeImage($imagick2, \Imagick::COMPOSITE_ATOP, 0, 0);   
    				$imagick->setImageFormat('jpg');
    									
    				header("Content-Type: image/jpg");
    				echo $imagick->getImageBlob(); 	

    The above seems as though it should work, but the page silently fails (no logs, no content). Is this the bug I've seen people discuss where it times out before the allotted time when there's more than one Imagick thread? Or could something else be causing it?

  10. I thought this would be simple. I want to make a composite image from a background I provide and a logo (jpg or png) provided by a user, where the logo is resized and placed (retaining its transparency) on top of the background.

    Being completely unfamiliar with the API of Imagick, I can't even get it off the ground. But it seems as though this should be fairly straightforward:

    $exhibitors = $users->find("roles=exhibitor, limit=1");
    			
    			foreach($exhibitors as $getKV) {
    				$ex_logo = $getKV->exhibitor_logo->path . $getKV->exhibitor_logo->filename;
    				$background = $config->urls->templates . "images/Exhibitor-Graphic-BG-Silver.jpg";
    				   $imagick = new \Imagick($background);
    				   $imagick2 = new \Imagick($ex_logo);
    				   $imagick1->compositeImage($imagick2, $type, 0, 0);
    				   $imagick1->setImageFormat('jpg');
    				
    				   $image->setImageFormat("jpg");
    				   header("Content-Type: image/jpg");
    				   echo $imagick->getImageBlob();			
    				}

    However it results in:

    Quote

     

    ImagickException #435

    unable to open image `/site/templates/images/Exhibitor-Graphic-BG-Silver.jpg': No such file or directory @ error/blob.c/OpenBlob/2614

     

    I realize not everything I want to do (including the resize) is covered in the script above, but first we need the script to even find the images, and that is failing. The examples I find for Imagick often place their source images in the same directory, which doesn't help me figure out what's wrong with the formatting of my path. 

    I have already tried using static strings for $imagick and $imagick2, starting from the server's user directory and starting from the public_html directory, with the same result.

    Has anyone used Imagick for composite images, who can see what I'm doing wrong here? 

    Is there a better way to go about this?

     

    Thanks!

  11. 20 minutes ago, louisstephens said:

    This.. I run into little things like this all the time. It is one reason I moved away from outputting html in code/text blocks (unless it it really small), and moved to:

    
    <?php foreach ($services as $service) : ?>
        <div class="service">
            <h1>Sample Text</h1>
            <p><a href="<?php echo $service->url; ?>"><?php echo $service->title; ?></a></p>
        </div>
    <?php endforeach; ?>

    At least to me, it is much easier to find an issue since Visual Studio Code doesn't highlight the different syntax in code/text blocks (unless there is a way and I cant find it)

    Yes that’s a very good argument for switching to that method!

  12. 3 minutes ago, netcarver said:

    @creativejay Have you tried turning off all your browser extensions, then closing and reloading your browser?

     In the past, I've spent hours fruitlessly trying to track down insertions into a page. I looked in my templates, modules and js. I eventually found out it was the Grammerly browser extension.

    Thanks for this! I've tried it now, and still the same problem.

    I've also viewed the page in both Safari and Chrome with the same effect.

  13. Yes, of course! 

    As I said, when I view the Page Source in my browser, it looks as it should. It's only in the Inspect Element that I see the unwanted <a> tags.

     

    if($user->isSuperuser()) {
    	$speakblock = '';
    	$speakers = $users->find("roles=speaker, sort=created, speaker_portrait!=null, speaker_topics.event_picker=$page, limit=4");
    	$s = 0;
    	foreach($speakers as $speaker){
    		
    			$s++;
    			$portrait = null;
    			$portrait = $speaker->speaker_portrait->first();
    			
    			$simg = $portrait->size(267,358)->url;
    			$simgsrc = "<img src='" . $simg . "' alt='{$speaker->pad_firstname} {$speaker->pad_lastname}' width=\"267\" height=\"358\"/>";
    			
    		    $topicfield = $speaker->speaker_topics->find("event_picker=$page");
        
    			
    			// There is now a template for schedules within each event that draws from time slots defined under the main site structure.
    			// Figure out where the speaker is scheduled to speak and add that to the entry-meta area.
    			
    			$speakblock .= "
    			<div class=\"col-md-6 col-sm-6 col-xs-12\">
    				<article class=\"type-post\">
    					<div class=\"col-md-6 col-sm-6 col-xs-6\">
    						<div class=\"entry-cover\">
    							<a href=\"schedule/speakers/\">{$simgsrc}</a>
    						</div>
    					</div>
    					<div class=\"col-md-6 col-sm-6 col-xs-6\">
    						<div class=\"entry-meta\">
    							<div class=\"post-date\">
    								<a href=\"#\" title=\"\"><i class=\"fa fa-calendar\" aria-hidden=\"true\"></i><span>10 Dec, 2015 </span></a>
    							</div>
    							<div class=\"post-admin\">
    								<i class=\"fa fa-user\" aria-hidden=\"true\"></i><span>by</span><a href=\"#\" title=\"Admin\">Admin</a>
    							</div>
    							<div class=\"post-like\">
    								<a href=\"#\" title=\"Likes\"><i class=\"fa fa-heart-o\" aria-hidden=\"true\"></i></a><span>03 Likes</span>
    							</div>
    						</div>
    						<div class=\"entry-title\">
    							<a href=\"schedule/speakers/\" title=\"Topic\">";
    							foreach ($topicfield as $topic){
    						        $speakblock .= "<h3>" . $topic->presentation_topic_1 . "</h3>";
    						    }
        					$speakblock .= "</a>
    						</div>
    						<div class=\"entry-content\">
    							<p>{$speaker->speaker_bio}</p>
    						</div>
    						<a href=\"schedule/speakers/\" class=\"learn-more\" title=\"See All Speakers\">See All Speakers</a>
    					</div>
    				</article>
    			</div>";
    
    		if ($s%2 == 0) {
    			$speakblock .= "</div>
    			<div class=\"row\"> ";
    		}
    	
    	}
    	
    	if($s > 0){
    			
    		
    	echo "<!-- Latest Speakers -->
    	<div class=\"container-fluid latest-blog latest-blog-section no-padding\">
    		<div class=\"section-padding\"></div>
    		<div class=\"container\">
    			<div class=\"section-header\">
    				<h3>New Speakers Announced!</h3>
    				<span>Experts and Enthusiasts of a Keto Lifestyle</span>
    			</div>
    			<div class=\"row\">";
    	echo $speakblock;				
    	echo "</div></div>
    		<div class=\"section-padding\"></div>
    	</div>
    	<!-- Latest Speakers /- -->";
    	
    	}
    }

     

  14. I don't even know where to begin with this plea for help. Is this a PWire issue? Or just CSS/js? I have no idea.

    I guess I'm looking for help pinpointing suspects for this strange behavior.

    I have a block of markup with some API mixed in, but nothing that should result in this. My "View Source" when viewing the page is correct, but when I inspect element, I found these empty "<a>            </a>" tags that are being inserted into just the first instance of a foreach loop. If I repeat the same code in the same loop (double-output per $item), only the first is affected.

    1214751919_ScreenShot2019-09-17at1_24_34PM.png.40a5add499bcd5a78f708d0b92171ef6.png

    See all those <a> tags? The output should be:

    897671354_ScreenShot2019-09-17at3_23_28PM.png.e7b0e2bcf149f5a2d56dc073231b60aa.png

     

    I checked the css files that Inspect Element says are interacting with this output, but I've found nothing. I turned off my css calls in the header one by one, and my javascript calls, but I can't pinpoint the problem. My first suspect was the EmailObfuscation module but deactivating it/debug-moding it/putting it on manual/etc. had no effect. 

    So if this were you, how would you go about locating the source of the problem?

    I'm hoping one of you has seen this before and knows what my problem is right away. ? 

  15. 13 hours ago, kongondo said:

    Do you have a specific need to run both the old and new versions?

    Just that the site will need to go live before PadLoper2 is ready. We sell tickets to an annual event, so if 2021's event sales (which launch immediately after the event in 2020) could be on the new system, I could set it up within the same site. Sounds like there'll be a lot of fiddling to changeover, so since there's a conflict I'll probably clone the site and work on it then switchover for 2021.

     

    Thanks! Really looking forward to the new version!

  16. @kongondo So excited to see you actively working on this (I had only been watching the private access forum, whoops!). 

    I'm developing a shop with the current full release of PadLoper and will need to launch it without waiting for your new release. We run an annual event and backup/purge the previous years' data so I know I'll at least be able to work with PadLoper 2 eventually!

    When it does come out, will I be able to run the PadLoper 2 module alongside the current module or will that cause conflicts?

    • Like 1
  17. Apologies if this has been covered. I tried a search but didn't hit the usecase I'm after.

    I currently have category pages listing their children products. Someone asked me to put a product in multiple categories, so I created a Page Reference field called prod_othercategories which lets a user pick multiple product category pages.

    When I try to output a list of products for a category page, I came around to the following selector:

    $pages->find("prod_othercategories|parent=$page, template=prod_series, sort=title, prod_status_pages!=1554|1559|1560|4242");

    Only the first selector item is giving me trouble, but I'm including the entire string in case something is conflicting and I'm not realizing it.

    The output is currently only outputting matches for "parent" and ignoring prod_othercategories. I tried listing parent first in the selector but it had no effect.

    Appreciate if someone could help me with this! Thanks!

  18. Just now, szabesz said:

    Should not matter too much as far as I know.

    That's what I figured. It's faster than it was before the Apache/PHP upgrades but it's still long enough that I get a script warning from jquery on the page for the first run.  The page loads like a dream with ProCache. I just want to improve it for the poor sucker that hits it for the first time each expire. (or is there a 'never expire' setting in ProCache I've missed that will allow me to reload it manually and be that sucker, myself?)

  19. Yes, roughly. There is also a Page reference (single value) field that defines the product per our company's stages of production (preliminary, new release, worldwide, NA only, EMEA only, and obsoleted). So the 255 is further refined by the page id values of those fields. But I still wouldn't expect it to be a serious draw on resources to double check those. But if you think it would save PWire brainjuice, I could switch to a standard Options field, instead.

     

    The call is:

    ///in my header.inc...
    $productCatList="prod_series|prod_series_ethernet|prod_series_access|prod_series_accessories|prod_series_fiber|prod_series_pwr_supplies|prod_series_pwr_systems|prod_series_wireless";
    $getCurrentProdOptions="template=$productCatList, prod_status_pages!=1554|1559|1560|4242";
    // and then wherever I need it...
    $products = $pages->find("$getCurrentProdOptions"); 

     

×
×
  • Create New...