Jump to content

SoccerGuy3

Members
  • Posts

    47
  • Joined

  • Last visited

Posts posted by SoccerGuy3

  1. 7 minutes ago, rastographics said:

    @SoccerGuy3 Would you be able to post the relevant code that got this working for you? Been struggling for a couple days getting this to work. After I call for the WireUpload->execute(), the files array that it returns is always empty. 

    		// form was submitted so we process the form
    		if($this->input->requestMethod('POST')) {
    
    			//Set directory for photos
    			$target_dir = $this->wire('config')->paths->files . '_listings/';
    
    			// user submitted the form, process it and check for errors
    		    $form->processInput($this->input->post);
    
    			// do with the form what you like
    			if($_POST['prop_delete'] == 'N') {
    
    				//create the listing_id or pull from hidden field on update
    				if(isset($_POST['listing_id'])) {
    					$propNum = mysqli_real_escape_string($dbCon, $_POST['listing_id']);
    				} else {
    					$propNum = 'CDR'.uniqid(true);
    				}
    
    				// Database Table Insert Stuff goes here
    
    			} else {
    				//Delete box checked, removed listing first...
    			}
    
    			//Process photos
    			function convertImage($originalImage, $outputImage, $quality) {
    			    // jpg, png, gif or bmp?
    			    $exploded = explode('.',$originalImage);
    			    $ext = $exploded[count($exploded) - 1];
    
    			    if (preg_match('/jpg|jpeg/i',$ext)) {
    			        $imageTmp=imagecreatefromjpeg($originalImage);
    					$outputImage = str_ireplace('jpeg','jpg',$outputImage);
    			    } else if (preg_match('/png/i',$ext)) {
    			        $imageTmp=imagecreatefrompng($originalImage);
    					$outputImage = str_ireplace('png','jpg',$outputImage);
    			    } else if (preg_match('/gif/i',$ext)) {
    			        $imageTmp=imagecreatefromgif($originalImage);
    					$outputImage = str_ireplace('gif','jpg',$outputImage);
    			    } else if (preg_match('/bmp/i',$ext)) {
    			        $imageTmp=imagecreatefrombmp($originalImage);
    					$outputImage = str_ireplace('bmp','jpg',$outputImage);
    			    } else {
    			        return 0;
    				}
    
    			    // quality is a value from 0 (worst) to 100 (best)
    			    imagejpeg($imageTmp, $outputImage, $quality);
    			    imagedestroy($imageTmp);
    				unlink($originalImage);
    
    			    return 1;
    			}
    
    			$oldumask = umask(0);
    			mkdir($target_dir.$propNum, 0777); // or even 01777 so you get the sticky bit set
    			umask($oldumask);
    
    			foreach ($form->get('prop_pix')->value as $pix) {
    				//ensure image is jpg image and delete original upload
    				convertImage($target_dir.$pix,$target_dir.$propNum.'/'.$pix,70);
    			}
    
    			//Update Database Table
    			if(mysqli_query($dbCon, $sql)){
    				$this->wire('session')->redirect("/site-admin/setup/add-a-listing/");
    				$success = "Record added successfully.";
    			} else{
    				$success = "ERROR: Not able to execute $sql. " . mysqli_error($link);
    				echo "ERROR: Not able to execute $sql. " . mysqli_error($link); exit();
    			}
    
    			//echo $success; exit();
    
    			// Close connection
    			mysqli_close($dbCon);
    
    			//Return to controller
    			return $success;
    		} else {
    			return $form->render();
    		}

    I think this is what you are looking for. Holler if not. Note: I removed all the DB interaction stuff as it was 100 lines long and not on topic.

  2. 1 hour ago, Robin S said:

    Does the module need to read data back from the external database and display it in an interface for editing, or is PW only used for creating new data and inserting it into the database?

    Because if it's the latter you could still use Page Edit as the interface for data creation. You'd use a saveReady hook to get, prep and insert the data from the page into the external database, then clear out the page ready for new data. Maybe you'd add an extra submit button to Page Edit ("Send to database") so that the normal save buttons can be used to temporarily save data locally and only the "Send" button finally inserts and clears the data when the user is ready.

    Yes, the data has to be editable. It is real estate data, so things change (price, description, etc).

  3. On 7/20/2019 at 10:02 PM, Robin S said:

    Why not use pages and proper Fieldtype fields to store the data? Seems like it would be much easier, and anything out-of-the-ordinary that you want to show within your Process module you could show within Page Edit by hooking the render of a markup inputfield, or by using one of the runtime field modules from kongondo, bernhard, kixe, or me.

    I can't use pages (would have been much easier if I could!) as the data has to be stored in an outside database so that it can be merged with other data.

  4. Wow! Is it really that easy? I changed the maxFiles to 0 and was able to upload 10 photos in the one dialog at the same time. But it only listed the first file in the window. Saving worked, although it didn't give them the formatted name I would desire, but I am sure I can address that.

    Is there an input type/setting that would allow the use of the image type you normally find on a page with drag and drop and previews of the uploads?

  5. I have created a module for a client that allows them to insert real estate listings into a larger 'global' database (external to PW). The module works great for the text (address, city, property info, etc), but I am getting stuck wrapping my head around the images. The customer wants to upload a lot of images (think 20-30 in some cases). Currently (see code below) I am allowing 8 images to be uploaded, which works fine - BUT not the way it should.

    Let me explain. The form is a simple file upload dialog (you know, "click here to choose file"). What's missing is the ability to display what has been uploaded previously (when they come back to edit a listing), the ability to delete an image previously uploaded and the ability to replace images. The images are currently stored in a special folder at: site/assets/files/_listings and saved as "listingID-1", "listingID-2", "listingID-3", etc.

    I tried reading the code for the inputimagefield tag, but that just got me more confused (new to this level of using processwire). I am looking for some pointers or help in moving this forward if anyone is willing!

    What I think would be great would be functionality like you get on pages using the images field. That would give the client the ability to add, delete, drag-n-drop, change the order, delete, etc. But I have no clue how you implement something like that inside a module.

    What I have now (in part, obviously this is a much larger file):

    The input part:

    		//Add Property Description
    		$f = $this->modules->get("InputfieldTextarea");
    		$f->label = 'Property Description';
    		$f->attr('name','prop_desc');
    		$f->columnWidth = 100;
    		$f->required = false;
    		$f->value = $row['description'];
    		$form->add($f);
    
    		//Add pictures
    		for ($x = 1; $x <= 8; $x++) {
    			$f = $this->modules->get("InputfieldFile");
    			$f->label = 'Property Picture #'.$x.' Import';
    			$fieldName = 'prop_pix_'.$x;
    			$f->attr('name',$fieldName);
    			$f->extensions = 'jpg jpeg png gif';
    			$f->maxFiles = 1;
    			$f->descriptionRows = 0;
    			$f->columnWidth = 25;
    			$f->overwrite = true;
    			$f->required = false;
    			$f->destinationPath = $dPath;
    			$form->add($f);
    			}
    
    		$f = $this->modules->get('InputfieldSubmit');
    		$f->attr('name', 'submit_save');
    		$f->attr('value', $this->_('Save'));
    		$f->addClass('head_button_clone');
    		$f->icon = 'save';
    		$form->add($f);

    The "saving" part:

    			//Process photos
    
    			function convertImage($originalImage, $outputImage, $quality) {
    			    // jpg, png, gif or bmp?
    			    $exploded = explode('.',$originalImage);
    			    $ext = $exploded[count($exploded) - 1];
    
    			    if (preg_match('/jpg|jpeg/i',$ext))
    			        $imageTmp=imagecreatefromjpeg($originalImage);
    			    else if (preg_match('/png/i',$ext))
    			        $imageTmp=imagecreatefrompng($originalImage);
    			    else if (preg_match('/gif/i',$ext))
    			        $imageTmp=imagecreatefromgif($originalImage);
    			    else if (preg_match('/bmp/i',$ext))
    			        $imageTmp=imagecreatefrombmp($originalImage);
    			    else
    			        return 0;
    
    			    // quality is a value from 0 (worst) to 100 (best)
    			    imagejpeg($imageTmp, $outputImage, $quality);
    			    imagedestroy($imageTmp);
    				unlink($originalImage);
    
    			    return 1;
    			}
    
    			for ($i = 1; $i <= 8; $i++) {
    				if($form->get('prop_pix_'.$i)->value > '') {
    					$uploadedFile = $form->get('prop_pix_'.$i)->value;
    					//ensure image is jpg image and delete original upload
    					convertImage($target_dir.$uploadedFile,$target_dir.$propNum.'-'.$i.'.jpg',70);
    				}
    			}

    Any pointers or references to the correct tags would be much appreciated.

    Screen Shot 2019-07-12 at 4.38.46 PM.png

  6. Again, thanks for your help, the form is working great. I would like to do an upgrade of sorts and add to the image upload box. I would like to show the image if it exists. I can determine the file name, but how to insert it into the form builder? Here's my form builder code for the image field:

    		$f = $this->modules->get("InputfieldFile");
    		$f->label = 'Property Picture #1 Import';
    		$f->attr('name','prop_pix_1');
    		$f->extensions = 'jpg jpeg png gif';
    		$f->maxFiles = 1;
    		$f->descriptionRows = 0;
    		$f->columnWidth = 25;
    		$f->overwrite = true;
    		$f->required = false;
    		$f->destinationPath = $dPath;
    		$form->add($f);

    I tried putting an image tag into to the "description" tag, but all I got in return was the code displayed on screen. Any hints/ideas?

  7. @bernhard @MrSnoozles

    Thanks for your help. Your pointers along with a 7 year old post by @Soma got it for me. The piece that I was missing I believe is that I had it in my head that the building of the form and the processing of the form needed to be in separate functions. Once I combined the two functions into one, did some further debugging (yes with Tracy), I was able to get a photo uploaded, named and saved where I wanted it!! Whew! Waaaayyyyyyy too many hours spent on this, but finally got it. Thanks again.

  8. 12 hours ago, bernhard said:

    PS: Don't you use TracyDebugger? It's a lot better than using print_r() ? 

    Tried installing TracyDebugger and while it did give me some things to clean up it won't let my form process at all. Keeps throwing an error for missing vars, etc. I use the same form to edit and enter new listings. Earlier in the code I check for a value in a $_GET and if there I populate $row (which was previously defined as an array).

               //Add Property Street Address
    100:            $f = $this->modules->get("InputfieldText");
    101:            $f->label = 'Property Address';
    102:            $f->attr('name','prop_add');
    103:            $f->columnWidth = 40;
    104:            $f->requiredLabel = '*';
    105:            $f->required = true;
    106:            $f->requiredAttr = true;
    107:            $f->placeholder = 'Example: 123 Main Street';
    108:            $f->value = $row['st_address'];    
    109:            $form->add($f);

    This block of code is throwing an error with Tracy turned on: Undefined index: st_address

    I've always done things this way. Is a best practices kind of thing?

     

    Figured it out! Too many iterations of testing and deleted one too many lines.

  9. Creating a module to add records to an external database. All the "text" form fields work perfectly. Now I am at the point of trying to do file uploads for the listing. I want to upload and save the images into a directory inside the Files directory. In part I have:

    		//Add pictures
    		$f = $this->modules->get("InputfieldFile");
    		$f->label = 'Property Picture #1 Import';
    		$f->attr('name','prop_pix_1');
    		$f->extensions = 'jpg jpeg png gif';
    		$f->maxFiles = 1;
    		$f->descriptionRows = 0;
    		$f->columnWidth = 25;
    		$f->overwrite = true;
    		$f->required = false;
    		$f->destinationPath = $dPath;
    		$form->add($f);

    And then in the processor section:

    print_r($image);

    and am only getting:

    Array ( [0] => IMG_2752.JPG )

    Shouldn't I get a lot more data? Obviously with only that little bit of info I can't save the file:

    move_uploaded_file($_FILES["prop_pix_1"]["tmp_name"], $dPath.'test.jpg');

     

  10. Beautiful!! That was it exactly. Still have some other logic/syntax problems to work out, but they are of the php/mysql variety and I can (hopefully) handle that part! ?

    Now the big question, can you tell me or point in the direction of WHY that code change you suggested was the solution? What I had before is working in another module I did last year (far simpler and writing to a table within the PW database).

  11. I am creating (or at least trying) a module to collect some data from a form in the admin that saves that data into a table/database that is not the PW database. Data has to be inserted into a table that is shared among several sites. I have successfully added a menu item, created and displayed the form in the admin, but when I click save, nothing happens, it just returns to the blank form without saving the data. I am new to this and probably missing something obvious, can you help?!

    <?php
    
    class AddSpecialPropertyListing extends Process {
    
    	public function init() {
    		parent::init(); // always remember to call the parent init
    	}
    
    	/** Executed when root url for module is accessed */
    	public function ___execute() {
    		$form = $this->buildForm();
    		if($this->input->post->submit) {
    			$result = $this->processForm($form);
    			return $result;
    		} else {
    			return $form->render();
    		}
    	}
    
    	/** Build the "Listing Input" form */
    	protected function buildForm() {
    		$form = $this->modules->get("InputfieldForm");
    		$form->method = 'post';
    
    		//Add Property Street Address
    		$f = $this->modules->get("InputfieldText");
    		$f->label = 'Property Address';
    		$f->attr('name','prop_add');
    		$f->columnWidth = 40;
    		$f->requiredLabel = '*';
    		$f->required = true;
    		$f->requiredAttr = true;
    		$f->placeholder = 'Example: 123 Main Street';
    		$form->add($f);
    
    		//Add Lot Size
    		$f = $this->modules->get("InputfieldText");
    		$f->description = "Input numbers only (ie 1234, not 134 acres). Enter as number of acres.";
    		$f->label = 'Lot Size';
    		$f->attr('name','prop_acres');
    		$f->columnWidth = 25;
    		$f->type = number;
    		$f->placeholder = 'Example: 1234';
    		$f->required = false;
    		$form->add($f);
    
    		$f = $this->modules->get('InputfieldSubmit'); 
    		$f->attr('name', 'submit_save'); 
    		$f->attr('value', $this->_('Save')); 
    		$f->addClass('head_button_clone');
    		$f->icon = 'save';
    
    		$form->add($f);
    
    		return $form;
    	}
    
    	/** Process the form **/
    	protected function processForm(InputfieldForm $form) {
    
    		// Connection details
    		$dbhost = 'localhost';
    		$dbuser = 'xxx';
    		$dbpass = 'xxx';
    		$db = 'prop_data';
    		$conn = mysqli_connect($dbhost,$dbuser,$dbpass,$db);
    
    		// Check connection
    		if($conn === false){
    			die("ERROR: Could not connect. " . mysqli_connect_error());
    		} else {
    			die('success');
    		}
    
    		// Attempt insert query execution
    		$sql = 'INSERT INTO listings_res (num_acres, st_address) VALUES (';
    		$sql .= '"'.mysqli_real_escape_string($conn, $_POST['prop_acres']).'",';
    		$sql .= '"'.mysqli_real_escape_string($conn, $_POST['prop_add']).'"';
    		$sql .= ');';
    		
    		echo $sql; exit();
    
    		if(mysqli_query($conn, $sql)){
    			$success = "Records added successfully.";
    		} else{
    			$success = "ERROR: Could not able to execute $sql. " . mysqli_error($link);
    		}
    
    		// Close connection
    		mysqli_close($conn);
    
      		return $success;
    	}
    
    }

    This is my module.php file. I am running in PW 3.0.123.

  12. 14 minutes ago, WillyC said:

    if usesing $pages say shits bout array it mean yoU write-over it some where 
    >>> u did a $pages = array some.where !

    BINGO!! That was it. I had picked up some code from a (former) employee for generating the nav bar and he had used $pages as a array/var. Changed his code from $pages to $navPages and my code now works!!!

    Thanks for pointing me in the right direction!

    • Like 1
  13. I've used this same code on lots of sites, but for some reason this new site is giving me grief!

    So with this page tree:

    Home
    	Page
    	Page
    	Category
    		2nd Level Page
    		2nd Level Page
    	Blog
    		Article
    		Article

    On the home page I have:

    foreach ($page->find("parent=/blog/, limit=3, include=all") AS $oneBlog) {
    	echo $oneBlog->output_field;
    }

    And it works fine.

    But when I put that same code on a 2nd Level Page, it finds nothing and therefore the 2nd level page is blank.

    One other issue on this site. On all previous uses of this code I have used $pages-> instead of $page-> and it worked fine. On this site I am getting an error when using $pages: "Error: Uncaught Error: Call to a member function find() on array in /home..."

    Could this be a bad install of PW or something? I am missing something obvious? Help!

  14. GOT IT!! ?

    See the commented out "save" on the fourth to last line of code. That was the ticket.

    	// Parse the CSV data
    	$handle = fopen('data/inventorylist.csv', 'r') or die('Cannot open file.');
    
    	$prevportname = '';
    
    	while(($row = fgetcsv($handle)) !== false) {
    
    	    list($port_name, $port_num, $plate_num, $plate_name, $year, $price) = $row;
    
    	    // Get the portfolio name for this $group_name
    	    $group_item = $page->portfolio_repeater->get("port_num=$port_num");
    	    // If no such item exists, create one
    	    if(!$group_item) {
    	        $group_item = $page->portfolio_repeater->getNewItem();
    	        $group_item->text = $port_name;
    	        $group_item->port_num = $port_num;
    	        $group_item->save();
    	        $page->portfolio_repeater->add($group_item);
    	    }
    
    	    // Create a photo item for this row
    	    $photo_item = $group_item->print_info->getNewItem();
    	    $photo_item->title = $plate_name;
    	    $photo_item->port_name = $port_name;
    	    $photo_item->port_num = $port_num;
    	    $photo_item->plate_num = $plate_num;
    	    $photo_item->print_year = $year;
    	    $photo_item->print_price = $price;
    //	    $photo_item->save();
    	    $group_item->print_info->add($photo_item);
    	    $group_item->save();
    	}

     

  15. Making some progress on this. Two issues:

    1) It only runs through the loop once and then errors: 

    Error: Uncaught Error: Call to a member function getNewItem() on null in /Library/WebServer/Documents/edwardscurtis/_site/site/templates/page-portfolio-import.php:27
    Stack trace:
    #0 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/TemplateFile.php(287): require()
    #1 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(380): ProcessWire\TemplateFile->___render()
    #2 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___render', Array)
    #3 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\TemplateFile), 'render', Array)
    #4 /Library/WebServer/Documents/edwardscurtis/_site/wire/modules/PageRender.module(514): ProcessWire\Wire->__call('render', Array)
    #5 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(383): ProcessWire\PageRender->___renderPage(Object(ProcessWire\HookEvent))
    #6 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/WireHooks.p (line 27 of /Library/WebServer/Documents/edwardscurtis/_site/site/templates/page-portfolio-import.php) 

    2) If I put in the ->save commands in your original code, then I get this error: 

    Error: Exception: Can’t save page 10368: /prints/large-prints/: Call $page->of(false); before getting/setting values that will be modified and saved. [portfolio_repeater] (in /Library/WebServer/Documents/edwardscurtis/_site/wire/core/PagesEditor.php line 515)
    
    #0 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Pages.php(411): ProcessWire\PagesEditor->save(Object(ProcessWire\Page), Array)
    #1 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(386): ProcessWire\Pages->___save(Object(ProcessWire\Page), Array)
    #2 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___save', Array)
    #3 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Pages), 'save', Array)
    #4 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Page.php(2409): ProcessWire\Wire->__call('save', Array)
    #5 /Library/WebServer/Documents/edwardscurtis/_site/site/templates/page-portfolio-import.ph

    Here's my current code, what am I missing?

    	// Parse the CSV data
    	$handle = fopen('data/inventorylist.csv', 'r') or die('Cannot open file.');
    
    	$prevportname = '';
    
    	while(($row = fgetcsv($handle)) !== false) {
    
    	    list($port_name, $port_num, $plate_num, $plate_name, $year, $price) = $row;
    
    	    // Get the portfolio name for this $group_name
    	    /* @var RepeaterPage $group_item */
    	    $group_item = $page->portfolio_repeater->get("text=$port_name");
    	    // If no such item exists, create one
    
    	    if($prevportname != $port_name) {
    	        $group_item = $page->portfolio_repeater->getNewItem();
    	        $group_item->text = $port_name;
    	        $group_item->save();
    	        $page->portfolio_repeater->add($group_item);
    	        $page->save();
    	    }
    
    	    // Create a photo item for this row
    	    /* @var RepeaterPage $photo_item */
    	    $photo_item = $group_item->print_info->getNewItem();
    	    $photo_item->title = $plate_name;
    	    $photo_item->port_name = $port_name;
    	    $photo_item->port_num = $port_num;
    	    $photo_item->plate_num = $plate_num;
    	    $photo_item->print_year = $year;
    	    $photo_item->print_price = $price;
    	    // If there are more columns deal with them here
    	    $photo_item->save();
    	    $group_item->print_info->add($photo_item);
    	    $group_item->save();
    
    	    $prevportname = $port_name;
    	}

     

  16. I am trying to import data to a repeating field. Searching these forums have lead me to various solutions and I think I have a decent grasp of that aspect of what I need to do. Where I am stuck is that the repeater I am importing into is actually a repeater WITHIN another repeater on a page. Looking for some help or direction to get me unstuck. Here's a sample of what I am working with (simplified):

    Large Images (page)
    	Group Name (Repeater)
    		Photo (Repeater)
    			Image (um, image field)
    			Image Name (text)
    			Price (text)
    

    Data looks like (one row): Group, image name, price

    So the big question is how to create the outer repeater and then the sub-repeaters. Can it be done? I could manually create the outer repeaters (there are only like 10-15 of them) if that makes it easier, but then, how to address the repeater inside for the import?

    Any suggestions (or code samples) welcome. Thanks in advance,

    Marc

  17. @adrian - Thank you for your offer to help.... You know there are days I really like programming, then there are other days! This is one of those others. I moved the site from my local machine to our dev server so I could give you access. Guess what? When I did that the extra fields for language URL showed up!!

    Thanks again. Looks like we are all good now.

    • Like 1
×
×
  • Create New...