Searching keys of multi-dimensional array and returning true, then getting values without looping.

I have a multi-dimensional array that is created when a user dynamically adds options to a form.

When the form is posted, I have been tasked with matching their dynamic inputs with static options on a PDF.

I'm not sure how to go about tackling this one.

My array looks like this:

Array
(
    [1] => Array
        (
            ['type_of_work'] => Storm Lift Stations
            ['hours'] => 8
            ['qty'] => 1
        )

    [2] => Array
        (
            ['type_of_work'] => Hydrant Install/Adjust
            ['hours'] => 5
            ['qty'] => 3
        )

)

Open in new window


I now have a static HTML table that will be converted to a PDF that appears like this:

$html .= '<tr>
			<td>20AF</td>
			<td>Storm Lift Stations</td>
			<td>Hours Here</td>
			<td>Cost Here</td>
			<td>N/A</td>		
		</tr>';
		
$html .= '<tr>
			<td>30AA</td>
			<td>Water Main Construction</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>LF</td>		
		</tr>';

Open in new window


If the term "Storm Lift Stations" appears in that array, I need to get the cost and the number of hours stored in the array and place them in the appropriate columns. Since "Water Main Construction" was not in the array posted, nothing would get filled in here.

I tried making a function that would return true if a specific array key was found, but nothing gets printed..and even if it did, I'm still left in the dark matching the hours and quantity of this array.

I realize that this would be better off it built the HTML tables dynamically based on what the user selects from the form, but my client is asking me manipulate their inputs so it matches a PDF form I was given.

I appreciate any guidance!  Thank you.
LVL 1
t3chguyAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
First of all, just drop the idea about "without looping."  That's an idea that is likely to be an impediment to your design.

The mix-in of HTML and PDF is a difficult one.  HTML is a semantic markup language, designed to attach meaning to elements of data.  It's not used in document layout. PDF is a document layout language, designed to place specific elements of data at exact locations on the printed page.  It has no knowledge of the semantic meaning of the data.  So when you're talking about getting data from a resource such as an API or database, and you want to take this data and use it in both HTML and PDF -- well you're really talking about using the data in two completely different applications.  You'll be better off and your work will be done faster if you approach the design and programming as if it is two small jobs, rather than one large job with the inherent complexity of tying semantic meaning and document layout into a single application.

Since both the HTML and PDF construction are matters of taking data from your resource and placing it into appropriate places in a template, I'll try to show you the general design of this for HTML.  For PDF, you will probably want to explore FPDF or TCPDF.  Both are open source, free, PHP5+ compatible and reasonably well documented.  Look those up and while you do that, I'll get some code samples together that show how to do HTML templates in PHP.
0
Ray PaseurCommented:
A general design might go something like this.
http://iconoun.com/demo/temp_t3chguy.php

A few notes on the code...

1. Lines 28-45: PHP is well suited to generating HTML, but not so well suited for reading it.  It's probably better to use a different data abstraction for this (See line 69).

2. Lines 48-66: This is probably similar to what you might get back from a data base query or an API.

3. Line 88: Be very careful if you use extract() on external data - it can cause unwanted variable injections.  Here it's OK because we created the data inside our script.  PHP extract() creates the variables that get inserted into our HTML rows via the use of HEREDOC notation.

<?php // demo/temp_t3chguy.php

/**
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28626411.html
 */
error_reporting(E_ALL);

/**
 * SOME TEST DATA
Array
(
    [1] => Array
        (
            ['type_of_work'] => Storm Lift Stations
            ['hours'] => 8
            ['qty'] => 1
        )

    [2] => Array
        (
            ['type_of_work'] => Hydrant Install/Adjust
            ['hours'] => 5
            ['qty'] => 3
        )

)

/**
 * SOME HTML TO MATCH
$html .= '<tr>
			<td>20AF</td>
			<td>Storm Lift Stations</td>
			<td>Hours Here</td>
			<td>Cost Here</td>
			<td>N/A</td>
		</tr>';

$html .= '<tr>
			<td>30AA</td>
			<td>Water Main Construction</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>LF</td>
		</tr>';
*/


// ORGANIZE THE TEST DATA INTO ARRAYS THAT CAN BE MATCHED TO THE HTML
$dat = array
( array
  ( 'key' => '20AF'
  , 'nom' => 'Storm Lift Stations'
  , 'hrs' => '8'
  )
, array
  ( 'key' => 'XXXX'
  , 'nom' => 'Hydrant Install/Adjust'
  , 'hrs' => '5'
  )
, array
  ( 'key' => '30AA'
  , 'nom' => 'Water Main Construction'
  , 'hrs' => ' '
  )
)
;

// MAKE A LIST OF THE INFORMATION TYPES WE WANT IN THE TABLE
$inf = array( '20AF', '30AA' );


// CREATE AN HTML TABLE
$table = '<table>';

// CREATE THE HEADERS FOR THE TABLE
$table .= <<<EOD
	<tr>
	  <th>KEY</th>
	  <th>NAME</th>
	  <th>HOURS</th>
	</tr>
EOD;

// CREATE THE ROWS FOR THE TABLE
foreach ($dat as $row)
{
    // BRING THE VARIABLES INTO THE CURRENT SCOPE
    extract($row);

    // SKIP IF THIS ROW IS NOT IN THE LIST OF INFORMATION TYPES
    if (!in_array($key, $inf)) continue;

    // COPY THE VARIABLES INTO HEREDOC FRAGMENTS THAT MATCH THE TEST DATA
	$htm = <<<EOD
	<tr>
	  <td>$key</td>
	  <td>$nom</td>
	  <td>$hrs</td>
	</tr>
EOD;

    $table .= PHP_EOL . $htm;
}
$table .= PHP_EOL . '</table>';

// SHOW THE WORK PRODUCT
echo $table;

Open in new window

0
t3chguyAuthor Commented:
I had planned on using dompdf to generate the PDF, which will reads HTML data, but I've reading on the TCPDF library and it looks pretty solid as well..

This is awesome, thank you!  The only question I have is that it seems as if we are hardcoding the values for the number of hours the user has entered, is this the case, or am I not understanding that portion?

$dat = array
( array
  ( 'key' => '20AF'
  , 'nom' => 'Storm Lift Stations'
  , 'hrs' => '8'
  )
, array
  ( 'key' => 'XXXX'
  , 'nom' => 'Hydrant Install/Adjust'
  , 'hrs' => '5'
  )
, array
  ( 'key' => '30AA'
  , 'nom' => 'Water Main Construction'
  , 'hrs' => ' '
  )
)
;

Open in new window

0
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

Ray PaseurCommented:
Yes, I hardcoded those.  I don't know where that data comes from, but I can imagine that it came from a database or from client input.  It could be a PHP variable, too.
0
t3chguyAuthor Commented:
Those would be coming from user input, a form I have on the prior page.  So In order to not hard-code those, do I need to loop through the values and add they key as a hidden input type ('10AF') for example to the form?  And create new arrays within the loop?
0
t3chguyAuthor Commented:
I suppose more information would be helpful.  I have attached a screenshot of the form.  The user can add new rows as they pertain to the job they are working, so not all rows possible get posted through the form.

The user wants final product to show all possibilities with hours/quantity filled in for the type of work the user selects [second screenshot].
2-28-2015-9-29-45-AM.png
pdf.png
0
Ray PaseurCommented:
That makes sense.  The input from the external form will be indeterminate, so we use iterators like "foreach" to walk through the external inputs.  Here's an example with checkboxes.  Unchecked checkbox elements do not appear in the request data, so they are functionally like text elements that are not present because they were not added to the form (via JavaScript).
http://iconoun.com/demo/temp_t3chguy.php

<?php // demo/temp_t3chguy.php

/**
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28626411.html
 * Process external form data when we do not know how much we have
 */
error_reporting(E_ALL);

// IF THERE IS A REQUEST
if (!empty($_POST))
{
    // ONLY CHECKED BOXES COME THROUGH IN THE REQUEST
    foreach ($_POST['boxes'] as $key => $value)
    {
        echo PHP_EOL . "<br>Key: $key, Value: $value";
    }
}

// CREATE A CHECKBOX FORM WITH KEYS AND VALUES
$form = <<<EOD
<form method="post">
<input type="checkbox" name="boxes[1]"  value="One" />One
<br>
<input type="checkbox" name="boxes[2]"  value="Two" />Two
<br>
<input type="checkbox" name="boxes[3]"  value="Three" />Three
<br>
<input type="checkbox" name="boxes[42]" value="Life, The Universe and Everything" />Forty two
<br>
<input type="submit" />
</form>
EOD;

echo $form;

Open in new window

0
t3chguyAuthor Commented:
I need them to appear though...even though only two may be selected in the form, the html page should show all possible options, with hours and quantity appearing, if they were selected in the form, or, in other words, matches one of the rows in the static html table.
0
Ray PaseurCommented:
That's certainly doable.  The important element of the "must appear" design pattern is to know the possible answers in advance, on the PHP side of things, so that you know them before your script generates the form.  Then after the client makes selections, you know what was selected and what was not selected.

<?php // demo/temp_t3chguy.php

/**
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28626411.html
 * Process external form data when we know the options but might not know how many were selected
 */
error_reporting(E_ALL);

// THINGS YOU MUST KNOW BEFORE GENERATING A FORM
$info = array
( (object) array( 'nameinfo' => 1,  'valueinfo' => 'One',                               'textinfo' => 'One' )
, (object) array( 'nameinfo' => 2,  'valueinfo' => 'Two',                               'textinfo' => 'Two' )
, (object) array( 'nameinfo' => 3,  'valueinfo' => 'Three',                             'textinfo' => 'Three' )
, (object) array( 'nameinfo' => 42, 'valueinfo' => 'Life, The Universe and Everything', 'textinfo' => 'Forty two' )
)
;
// var_dump($info);

// IF THERE IS A REQUEST
if (!empty($_POST))
{
    echo 'RESULTS: <br>' . PHP_EOL;
    // ONLY CHECKED BOXES COME THROUGH IN THE REQUEST
    foreach ($info as $obj)
    {
        $ndx = $obj->nameinfo;
        if (empty($_POST['boxes'][$ndx]))
        {
            echo "Empty: $ndx <br>";
        }
        else
        {
            echo "Valid: $ndx "  . $_POST['boxes'][$ndx] . " Client Selected <i>$obj->textinfo</i> <br>";
        }
    }
}

// CREATE A CHECKBOX FORM WITH KEYS AND VALUES
$inputs = NULL;
foreach ($info as $obj)
{
    $inputs .= PHP_EOL
            . '<input type="checkbox" name="boxes['
            . $obj->nameinfo
            . ']" value="'
            . $obj->valueinfo
            . '" />'
            . $obj->textinfo
            . '<br>'
            ;
}
$form = <<<EOD
<form method="post">
$inputs
<input type="submit" />
</form>
EOD;

echo $form;

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
t3chguyAuthor Commented:
Thanks, Ray!  That wasn't 100% what I needed to do, but it gave me the fuel to get it done!

What I ended up doing was creating an array of all possible types after the form was submitted.

$workTypes = array (
	array('code' => '10AA', 'type_of_work' => 'Sanitary Main Construction', 'hours' => '', 'qty' => '', 'uom' => 'LF'),
	array('code' => '10AB', 'type_of_work' => 'Sanitary Structures', 'hours' => '', 'qty' => '', 'uom' => 'EA'),
	array('code' => '10AC', 'type_of_work' => 'Sanitary Services', 'hours' => '', 'qty' => '', 'uom' => 'EA'),
	array('code' => '10AE', 'type_of_work' => 'Sanitary Connections', 'hours' => '', 'qty' => '', 'uom' => 'EA'),
	array('code' => '10AF', 'type_of_work' => 'Sanitary Lift Stations', 'hours' => '', 'qty' => '', 'uom' => 'N/A')
);

Open in new window


From there, I merged what was posted from the user, with the array I created above, and looped through that the merged array to create a new array that combined like terms so to speak.

##Merge Posted Work Types w/ given work types
$mergedArray = array_merge($workTypes, $_POST['work_records']);
$workTypeArray = array();

foreach ($mergedArray as $work) {
    if (isset($workTypeArray[$work['type_of_work']])) {
        $workTypeArray[$work['type_of_work']]['code'] .= $work['code'];
        $workTypeArray[$work['type_of_work']]['hours'].= $work['hours'];
		$workTypeArray[$work['type_of_work']]['qty']  .= $work['qty'];
		$workTypeArray[$work['type_of_work']]['qty']  .= $work['uom'];
    } else {
        $workTypeArray[$work['type_of_work']] = $work;
    }
}

Open in new window


From, there, I just looped through that new array to display the tables in the HTML table as per the client's request!

foreach($workTypeArray AS $key => $type) {
	$html .= '<tr>';
	foreach($type AS $k => $lineVal) {
		if(!empty($lineVal)) {
			$html .='<td>' . $lineVal . '</td>';
		} else {
			$html .='<td>&nbsp;</td>';
		}
	}
	$html .= '</tr>';
}

Open in new window


Thanks again for all your help and explanations!
0
t3chguyAuthor Commented:
Thanks for all the help once again!
0
Ray PaseurCommented:
Thanks for the points -- it's a great question!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.