Jump to content

TWIG


benanamen

Recommended Posts

Trying to learn TWIG. I can do a basic template but having a problem with Mysql results. {{ dump() }}  displays the mysql array but no data shows in the TWIG for loop. No error, just nothing. Expected result is person_id and first_name rows from Mysql. Dump Array seems awfully big for two rows. I suspect the problem is here. Cant find any info on the net for TWIG and Mysql. (Unbelievably)

 

What I have tried:

<?php
$hostdb   = 'localhost';
$dbname   = 'test';
$username = 'root';
$password = '';

$pdo = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql  = "SELECT person_id, first_name FROM people";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();

require_once 'Twig/Autoloader.php';

Twig_Autoloader::register();
try
    {
    $loader = new Twig_Loader_Filesystem('./templates');
    $twig   = new Twig_Environment($loader, array(
        'debug' => true
    ));
    $twig->addExtension(new Twig_Extension_Debug());
    echo $twig->render('people.twig', $result);
    }
catch (Exception $e)
    {
    die('ERROR: ' . $e->getMessage());
    }
?>

people.twig

<pre>
{{ dump() }}
</pre>

<ul>
    {% for row in result %}
        <li>{{ row.person_id }} {{ row.first_name }}</li>
    {% endfor %}
</ul>

Results

array(2) {
  [0]=>
  array(4) {
    ["person_id"]=>
    string(1) "1"
    [0]=>
    string(1) "1"
    ["first_name"]=>
    string(3) "Bob"
    [1]=>
    string(3) "Bob"
  }
  [1]=>
  array(4) {
    ["person_id"]=>
    string(1) "2"
    [0]=>
    string(1) "2"
    ["first_name"]=>
    string(3) "Sam"
    [1]=>
    string(3) "Sam"
  }
}
 
Edited by benanamen
Link to comment
Share on other sites

The second argument of render() is supposed to be an associative array so that you can access the variables by name:

$twig->render('people.twig', ['test' => 'foo', 'people' => $result]);
<p>{{ test }}</p>
<ul>
    {% for person in people %}
        <li>{{ person.person_id }} {{ person.first_name }}</li>
    {% endfor %}
</ul>
Link to comment
Share on other sites

Thanks.

 

In some of my existing Php templates there is one or more dynamic dropdowns that get their data from the DB. What would be the proper setup for those dropdowns? The query for the dropdown currently resides in the Php template as so.... What is the proper way to TWIG this?  ($person_id is the POST value.) This would be a second query for the template page.

<div class="form-group <?= !empty($error['person_id'] ) ? 'has-error' : '' ?>">
   <label class="col-md-4 control-label" for="person_id">People</label>
   <div class="col-md-4">
      <select id="person_id" name="person_id" class="form-control">
         <option value="" style="display:none">Select Person</option>
         <?php
            $sql = "SELECT person_id, first_name FROM people";
            $stmt = $pdo->prepare($sql);
            $stmt->execute();
            $result = $stmt->fetchAll();

            foreach ($result as $row)
            {
            $selected = '';
            if ((isset($person_id)) && $person_id == $row['person_id'])
                {
                $selected = "selected=\"selected\"";
                }

            echo "<option value=\"{$row['person_id']}\" $selected>{$row['first_name']}</option>\n";
            }
            ?>
      </select>
   </div>
</div>
Edited by benanamen
Link to comment
Share on other sites

The proper way (not just for Twig) is to untangle the business logic and presentation. Executing queries is business logic and belongs into the underlying PHP script; the template is only responsible for rendering, so it shouldn't do anything but receive the result set and generate the corresponding HTML markup.

 

What I personally find helpful is to imagine that there must be multiple output formats like HTML for humans and XML for bots. Right now, this is unthinkable, because everything is one big block of PHPSQLHTMLCSS. You can't just switch to XML. But if you separate the different layers and use templates exclusively for rendering, you can provide any output format simply by using a different template.

Edited by Jacques1
Link to comment
Share on other sites

In your PHP script you'd run the query and generate an array with the data you need in as simple of a form as possible. For example an options array with value, label, and selected keys.

<?php
$sql = "SELECT person_id, first_name FROM people";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$options = [];
foreach ($stmt as $row){
	$options[] = [
		'selected' => isset($person_id)) && $person_id == $row['person_id']
		, 'value' => $row['person_id']
		, 'label' => $row['first_name']
	];
}
//Pass $options to the template

In your template you loop over that array and generate the select options based on the array data.

<select id="person_id" name="person_id" class="form-control">
	<option value="">Select Person</option>
	{% for opt in options %}
		<option value="{{ opt.value }}" {{ opt.selected?'selected="selected"':'' }}>{{ opt.label }}</option>
	{% endfor %}
</select>
If you have a particular bit of HTML you need to use site-wide that needs to be generated you could look into creating a twig function that will render the necessary HTML, then just call it from your template (like how dump() works).
Link to comment
Share on other sites

You do not pre-generate the HTML form elements, because now you're back mixing business logic with rendering.

 

You simply pass the people array and the selected person (or $_POST) to the template and let it generate the options.

<?php

$people = $pdo->query('SELECT person_id, first_name FROM people')->fetchAll();

// pass $people and $people_id (or $_POST) to the template
<select id="person_id" name="person_id" class="form-control">
    <option value="">Select Person</option>
    {% for person in people %}
        <option value="{{ person.person_id }}" {% if post.person_id is defined and post.person_id == person.person_id %}selected{% endif %}>{{ person.first_name }}</option>
    {% endfor %}
</select>

Or you create a macro (not a function) to build the menu from an array of values.

Edited by Jacques1
Link to comment
Share on other sites

Problem with TWIG ternary with TWIG value

 

 

{{ id }} # This works, output is record id 1
 
{{ id ? '{{ id }}' : '' }} # This just outputs {{ id }}
 
{{ id ? 'Some text' : '' }} # This Works, output Some text
 
I want the TWIG ternary of if isset id, output id else nothing.
 
 
The actual line I am attempting
 
    {{ id  ? '<input type="hidden" name="id" value="{{ id }}">' : '' }} 
Edited by benanamen
Link to comment
Share on other sites

Thanks @Jaques1. I have almost completed a TWIG conversion for one edit action. I will be able to do all the rest once I get this one done right.

 

I am not sure how transform the server validation part. Here are all the parts as they currently are. The only parts left to convert to TWIG is the validation and the drop down in the template.

 

* Connection info is actually a separate file. Only here for testing.

* This same template is used for ADD and EDIT

 

edit_membership_types.php

<?php
//----------------------------------------------------------------------------------------
// Update Data
//----------------------------------------------------------------------------------------

if (isset($_POST['update']))
    {
    //------------------------------------------------------------------------------------
    // Trim Data, Check Missing Fields
    //------------------------------------------------------------------------------------

    include './includes/validate_membership_types.php';

    //------------------------------------------------------------------------------------
    // Check for errors
    //------------------------------------------------------------------------------------

    if ($error)
        {
        show_form_errors($error);
        }
    else
        {
        $sql = "UPDATE membership_types SET membership_category_id =?, membership_type =?, membership_type_description =?, is_promo =?, is_active =? WHERE membership_type_id=?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute(array(
            $_POST['membership_category_id'],
            $_POST['membership_type'],
            $_POST['membership_type_description'],
            $_POST['is_promo'],
            $_POST['is_active'],
            $_POST['id']
        ));
        die(header("Location: {$_SERVER['SCRIPT_NAME']}?p=list_membership_types&edit"));
        } // End Else
    } // End POST

//----------------------------------------------------------------------------------------
// Get Update Data
//----------------------------------------------------------------------------------------

$hostdb   = 'localhost';
$dbname   = 'test';
$username = 'root';
$password = '';

$pdo = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

require_once 'Twig/Autoloader.php';
Twig_Autoloader::register();


$_POST['id'] = 1;// Temp Dev
$sql  = "SELECT membership_category_id, membership_type, membership_type_description, is_promo, is_active FROM membership_types WHERE membership_type_id=?";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(
    $_POST['id']
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);

try
    {
    $loader = new Twig_Loader_Filesystem('./templates');
    $twig   = new Twig_Environment($loader, array('debug' => true));
    $twig->addExtension(new Twig_Extension_Debug());
    echo $twig->render('form_membership_types.php', ['action' => 'Edit', 'form_action' => $_SERVER['SCRIPT_NAME'], 'p' => $_GET['p'], 'id' => $_POST['id'], 'membership_types' => $row]);
    }
catch (Exception $e)
    {
    die('ERROR: ' . $e->getMessage());
    }

?>

Template form_membership_types.php

<form class="form-horizontal" action="{{ form_action }}?p={{ p }}" method="post">
<fieldset>
<legend><p>{{ action }} Membership Types</p>  </legend>

<!-- Select Basic -->
<div class="form-group <?= !empty($error['membership_category_id'] ) ? 'has-error' : '' ?>">
   <label class="col-md-4 control-label" for="membership_category_id">Membership Category <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <select id="membership_category_id" name="membership_category_id" class="form-control">
         <option value="" style="display:none">Select Category</option>
         <?php
            $sql = "SELECT membership_category_id, membership_category FROM membership_category";
            $stmt = $pdo->prepare($sql);
            $stmt->execute();
            $result = $stmt->fetchAll();

            foreach ($result as $row)
            {
            $selected = '';
            if ((isset($membership_category_id)) && $membership_category_id == $row['membership_category_id'])
                {
                $selected = "selected=\"selected\"";
                }

            echo "<option value=\"{$row['membership_category_id']}\" $selected>{$row['membership_category']}</option>\n";
            }
            ?>
      </select>
   </div>
</div>

<!-- Text input-->
<div class="form-group <?= !empty($error['membership_type'] ) ? 'has-error' : '' ?>">
   <label class="col-md-4 control-label" for="membership_type">Membership Type <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <input id="membership_type" name="membership_type" type="text" placeholder="Membership Type" class="form-control input-md" value="{{ membership_types.membership_type }}">
   </div>
</div>

<!-- Text input-->
<div class="form-group <?= !empty($error['membership_type_description'] ) ? 'has-error' : '' ?>">
   <label class="col-md-4 control-label" for="membership_type_description">Membership Type Description <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <input id="membership_type_description" name="membership_type_description" type="text" placeholder="Membership Type Description" class="form-control input-md" value="{{ membership_types.membership_type_description }}">
   </div>
</div>


<!-- Multiple Checkboxes (inline) -->
<div class="form-group">
  <label class="col-md-4 control-label" for="checkboxes"></label>
  <div class="col-md-4">
    <label class="checkbox-inline" for="is_promo">
      <input type="checkbox" name="is_promo" id="is_promo" value="1"  {{ membership_types.is_promo ? 'checked="checked"' : '' }} >
      Promotional
    </label>
    <label class="checkbox-inline" for="is_active">
      <input type="checkbox" name="is_active" id="is_active" value="1" {{ membership_types.is_active ? 'checked="checked"' : '' }}  >
      Active
    </label>
  </div>
</div>


<div class="form-group">
   <div class="col-md-offset-4 col-md-4">
    <input type="hidden" name="update">
    {% if id is not null %}<input type="hidden" name="id" value="{{ id }}">{% endif %}
    <input type="submit" name="submit" value="Submit" class="btn btn-primary">
   </div>
</div>
</fieldset>
</form>

validate_membership_types.php - The part I am currently at.

//----------------------------------------------------------------------------------------
// Trim $_POST Array
//----------------------------------------------------------------------------------------

$_POST = array_map('trim', $_POST);

//----------------------------------------------------------------------------------------
// Validate Form Input
//----------------------------------------------------------------------------------------

$error = array();

if (empty($_POST['membership_category_id']))
    {
    $error['membership_category_id'] = 'Membership Category Id Required.';
    }

if (empty($_POST['membership_type']))
    {
    $error['membership_type'] = 'Membership Type Required.';
    }

if (empty($_POST['membership_type_description']))
    {
    $error['membership_type_description'] = 'Membership Type Description Required.';
    }
Edited by benanamen
Link to comment
Share on other sites

Ok, error handling is good to go now. One last problem with that..

 

On error (i.e: missing field), the other fields should retain the post values so as to not have to re-type the info again on every error.  How to do the TWIG equivalent of 

value="<?= !empty($_POST['membership_type']) ? $_POST['membership_type'] : '';?>"
Edited by benanamen
Link to comment
Share on other sites

Neither one outputs anything. * See the random text just above <!-- Multiple Checkboxes (inline) -->

 

Here is the current files.

 

edit_membership.php

<?php
echo "<pre>";
print_r($_POST);
echo "</pre>";

//----------------------------------------------------------------------------------------
// Update Data
//----------------------------------------------------------------------------------------

$error = array();

if (isset($_POST['update']))
    {
    //------------------------------------------------------------------------------------
    // Trim Data, Check Missing Fields
    //------------------------------------------------------------------------------------

    include './includes/validate_membership_types.php';

    //------------------------------------------------------------------------------------
    // Check for errors
    //------------------------------------------------------------------------------------

    if ($error)
        {
        //show_form_errors($error);
        }
    else
        {
        die;
        $sql  = "UPDATE membership_types SET membership_category_id =?, membership_type =?, membership_type_description =?, is_promo =?, is_active =? WHERE membership_type_id=?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute(array(
            $_POST['membership_category_id'],
            $_POST['membership_type'],
            $_POST['membership_type_description'],
            $_POST['is_promo'],
            $_POST['is_active'],
            $_POST['id']
        ));
        die(header("Location: {$_SERVER['SCRIPT_NAME']}?p=list_membership_types&edit"));
        } // End Else
    } // End POST

//----------------------------------------------------------------------------------------
// Get Update Data
//----------------------------------------------------------------------------------------

$hostdb   = 'localhost';
$dbname   = 'test';
$username = 'root';
$password = '';

$pdo = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

require_once 'Twig/Autoloader.php';

Twig_Autoloader::register();


$_POST['id'] = 1; // Temp Dev
$sql         = "SELECT membership_category_id, membership_type, membership_type_description, is_promo, is_active FROM membership_types WHERE membership_type_id=?";
$stmt        = $pdo->prepare($sql);
$stmt->execute(array(
    $_POST['id']
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);


$sql  = "SELECT membership_category_id, membership_category FROM membership_category";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$options = array();
foreach ($stmt as $row)
    {
    $options[] = [
        'selected' => isset($row['membership_category_id']) && $row['membership_category_id'] == $row['membership_category_id'],
        'value' => $row['membership_category_id'],
        'label' => $row['membership_category']
    ];
    }

try
    {
    $loader = new Twig_Loader_Filesystem('./templates');
    $twig   = new Twig_Environment($loader, array(
        'debug' => true
    ));
    $twig->addExtension(new Twig_Extension_Debug());
    echo $twig->render(
        'form_membership_types.php', [
        'action' => 'Edit',
        'form_action' => $_SERVER['SCRIPT_NAME'],
        'p' => $_GET['p'],
        'id' => $_POST['id'],
        'membership_types' => $row,
        'options' => $options,
        'error' => $error
    ]);
    }
catch (Exception $e)
    {
    die('ERROR: ' . $e->getMessage());
    }

?>

Template: form_membership_types.php

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<form class="form-horizontal" action="{{ form_action }}?p={{ p }}" method="post">
<fieldset>
<legend><p>{{ action }} Membership Types</p>  </legend>

<!-- Select Basic -->
<!--<div class="form-group <?= !empty($error['membership_category_id'] ) ? 'has-error' : '' ?>">
   <label class="col-md-4 control-label" for="membership_category_id">Membership Category <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <select id="membership_category_id" name="membership_category_id" class="form-control">
         <option value="" style="display:none">Select Category</option>
         {% for opt in options %}
		<option value="{{ opt.value }}" {{ opt.selected?'selected="selected"':'' }}>{{ opt.label }}</option>
	    {% endfor %}
      </select>
   </div>
</div>-->

<!-- Text input-->
<div class="form-group {{ error.membership_type ? 'has-error' : '' }}">
   <label class="col-md-4 control-label" for="membership_type">Membership Type <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <input id="membership_type" name="membership_type" type="text" placeholder="Membership Type" class="form-control input-md" value="{{ membership_types.membership_type }}">
   </div>
</div>

<!-- Text input-->
<div class="form-group  {{ error.membership_type_description ? 'has-error' : '' }}">
   <label class="col-md-4 control-label" for="membership_type_description">Membership Type Description <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <input id="membership_type_description" name="membership_type_description" type="text" placeholder="Membership Type Description" class="form-control input-md" value="{% if membership_types.membership_type_description is not null %} {{ membership_types.membership_type_description }} {% endif %}">
   </div>
</div>




{% if membership_type_description is not null %}HEllo{{ membership_type_description }}{% endif %}

value="{{ post.membership_type ?? '' }}"


<!-- Multiple Checkboxes (inline) -->
<div class="form-group">
  <label class="col-md-4 control-label" for="checkboxes"></label>
  <div class="col-md-4">
    <label class="checkbox-inline" for="is_promo">
      <input type="checkbox" name="is_promo" id="is_promo" value="1"  {{ membership_types.is_promo ? 'checked="checked"' : '' }} >
      Promotional
    </label>
    <label class="checkbox-inline" for="is_active">
      <input type="checkbox" name="is_active" id="is_active" value="1" {{ membership_types.is_active ? 'checked="checked"' : '' }}  >
      Active
    </label>
  </div>
</div>

<div class="form-group">
   <div class="col-md-offset-4 col-md-4">
    <input type="hidden" name="update">
    {% if id is not null %}<input type="hidden" name="id" value="{{ id }}">{% endif %}
    <input type="submit" name="submit" value="Submit" class="btn btn-primary">
   </div>
</div>
</fieldset>
</form>
Edited by benanamen
Link to comment
Share on other sites

That works. But in EDIT mode, value should be initially set to the DB value. On post, if there is an error, value should be set by POST. How would I TWIG that? (In ADD mode, value is empty unless there is an error POST)

 

The way it was being handled is like so:

if (!empty($row['membership_type_description']))
    {
    $membership_type_description = $row['membership_type_description'];
    }
    if (!empty($_POST['membership_type_description']))
    {
    $membership_type_description = $_POST['membership_type_description'];
    }
Edited by benanamen
Link to comment
Share on other sites

I usually assign a Defaults variable to twig that contains all the default values for the form fields. Within the PHP code I will populate this either from the existing database record or $_POST depending on whether the request was a submission or not.

 

if ($_SERVER['REQUEST_METHOD'] == 'POST'){
   $Defaults = $_POST;
   //further processing
} else {
   $Defaults = LoadRecordFromDB();
}

$twig->render('template', ['Defaults' => $Defaults]);
<input type="text" name="membership_type_description" value="{{ Defaults.membership_type_description }}">
Link to comment
Share on other sites

Not sure what you are talking about, but setting a default is not the answer. This single template is used for adding AND editing records. 

 

When adding a record, there is nothing to possibly default to. The record does not exist. Only when there is an error such as a missing field will the values of other fields be populated by the post data already entered so you don't have to re-type everything to enter data to the missing field.

 

When editing, the values data initially comes from the DB. You are editing an existing record. On a missing field post error, the field values will be the post values which may or may not be the same as the original row data depending on if you edited the existing data.

 

Its really not complicated when you look at the code. The problem is converting it to twig. Look at the Php setup that works perfectly for adding or editing using a single template. I need EXACTLY as below but in TWIG.

 

if (!empty($row['membership_type_description']))
    {
    $membership_type_description = $row['membership_type_description'];
    }
    if (!empty($_POST['membership_type_description']))
    {
    $membership_type_description = $_POST['membership_type_description'];
    }


<!-- Text input-->
<div class="form-group <?= !empty($error['membership_type_description'] ) ? 'has-error' : '' ?>">
   <label class="col-md-4 control-label" for="membership_type_description">Membership Type Description <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <input id="membership_type_description" name="membership_type_description" type="text" placeholder="Membership Type Description" class="form-control input-md" value="<?= !empty($membership_type_description) ? htmlspecialchars($membership_type_description, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') : '';?>">
   </div>
</div>
Edited by benanamen
Link to comment
Share on other sites

you're still pre-rendering your HTML options

 

I re-read the linked post. I dont know what you mean by pre-rendering html. If you are refering to post #17 that is not how the template file is. So we can be on the same page in getting this right, here is the current code. Please advise on what you see here. Thanks for your help on this.

 

This works exactly as expected:

 

edit_membership_types.php

<?php
echo "<pre>";
print_r($_POST);
echo "</pre>";

//----------------------------------------------------------------------------------------
// Update Data
//----------------------------------------------------------------------------------------

$error = array();

if (isset($_POST['update']))
    {
    //------------------------------------------------------------------------------------
    // Trim Data, Check Missing Fields
    //------------------------------------------------------------------------------------

    include './includes/validate_membership_types.php';

    //------------------------------------------------------------------------------------
    // Check for errors
    //------------------------------------------------------------------------------------

    if ($error)
        {
        //show_form_errors($error);
        }
    else
        {
        die;
        $sql  = "UPDATE membership_types SET membership_category_id =?, membership_type =?, membership_type_description =?, is_promo =?, is_active =? WHERE membership_type_id=?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute(array(
            $_POST['membership_category_id'],
            $_POST['membership_type'],
            $_POST['membership_type_description'],
            $_POST['is_promo'],
            $_POST['is_active'],
            $_POST['id']
        ));
        die(header("Location: {$_SERVER['SCRIPT_NAME']}?p=list_membership_types&edit"));
        } // End Else
    } // End POST

//----------------------------------------------------------------------------------------
// Get Update Data
//----------------------------------------------------------------------------------------

$hostdb   = 'localhost';
$dbname   = 'test';
$username = 'root';
$password = '';

$pdo = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

require_once 'Twig/Autoloader.php';

Twig_Autoloader::register();


try
    {
$_POST['id'] = 1; // Temp Dev
$sql         = "SELECT membership_category_id, membership_type, membership_type_description, is_promo, is_active FROM membership_types WHERE membership_type_id=?";
$stmt        = $pdo->prepare($sql);
$stmt->execute(array(
    $_POST['id']
));
$row = $stmt->fetch(PDO::FETCH_ASSOC);

$membership_category_id = '';
$membership_type = '';
$membership_type_description ='';
$is_promo = '';
$is_active = '';

if (!empty($row['membership_category_id']))
    {
    $membership_category_id = $row['membership_category_id'];
    }
    if (!empty($_POST['membership_category_id']))
    {
    $membership_category_id = $_POST['membership_category_id'];
    }

//-------------------------------------------------------------------------------------

if (!empty($row['membership_type']))
    {
    $membership_type = $row['membership_type'];
    }
    if (!empty($_POST['membership_type']))
    {
    $membership_type = $_POST['membership_type'];
    }

//-------------------------------------------------------------------------------------

if (!empty($row['membership_type_description']))
    {
    $membership_type_description = $row['membership_type_description'];
    }
    if (!empty($_POST['membership_type_description']))
    {
    $membership_type_description = $_POST['membership_type_description'];
    }

//-------------------------------------------------------------------------------------

if (!empty($row['is_promo']))
    {
    $is_promo = $row['is_promo'];
    }
    if (!empty($_POST['is_promo']))
    {
    $is_promo = $_POST['is_promo'];
    }

//-------------------------------------------------------------------------------------

if (!empty($row['is_active']))
    {
    $is_active = $row['is_active'];
    }
    if (!empty($_POST['is_active']))
    {
    $is_active = $_POST['is_active'];
    }

 //-------------------------------------------------------------------------------------

$sql  = "SELECT membership_category_id, membership_category FROM membership_category";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$options = array();
foreach ($stmt as $row2)
    {
    $options[] = [
        'selected' => isset($membership_category_id) && $membership_category_id == $row2['membership_category_id'],
        'value' => $row2['membership_category_id'],
        'label' => $row2['membership_category']
    ];
    }

    $loader = new Twig_Loader_Filesystem('./templates');
    $twig   = new Twig_Environment($loader, array(
        'debug' => true
    ));
    $twig->addExtension(new Twig_Extension_Debug());
    echo $twig->render(
        'form_membership_types.php', [
        'action' => 'Edit',
        'form_action' => $_SERVER['SCRIPT_NAME'],
        'p' => $_GET['p'],
        'id' => $_POST['id'],
        /*'membership_types' => $row, */
        'options' => $options,
        'error' => $error,

        /*'row' => $row, */
        /*'post' => $_POST, */

        'membership_category_id' => $membership_category_id,
        'membership_type' => $membership_type,
        'membership_type_description' => $membership_type_description,
        'is_promo' => $is_promo,
        'is_active' => $is_active
    ]);
    }
catch (Exception $e)
    {
    die('ERROR: ' . $e->getMessage());
    }

?>

form_membership_types.php

<pre>
{#{ dump() }#}
</pre>

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<form class="form-horizontal" action="{{ form_action }}?p={{ p }}" method="post">
<fieldset>
<legend><p>{{ action }} Membership Types</p>  </legend>

<!-- Select Basic -->
<div class="form-group {{ error.membership_category_id ? 'has-error' : '' }}">
   <label class="col-md-4 control-label" for="membership_category_id">Membership Category <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <select id="membership_category_id" name="membership_category_id" class="form-control">
         <option value="" style="display:none">Select Category</option>
         {% for opt in options %}
        <option value="{{ opt.value }}" {{ opt.selected?'selected="selected"':'' }}>{{ opt.label }}</option>
        {% endfor %}
      </select>
   </div>
</div>

<!-- Text input-->
<div class="form-group {{ error.membership_type ? 'has-error' : '' }}">
   <label class="col-md-4 control-label" for="membership_type">Membership Type <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <input id="membership_type" name="membership_type" type="text" placeholder="Membership Type" class="form-control input-md" value="{{ membership_type ?? '' }}">
   </div>
</div>

<!-- Text input-->
<div class="form-group  {{ error.membership_type_description ? 'has-error' : '' }}">
   <label class="col-md-4 control-label" for="membership_type_description">Membership Type Description <span style="color: #FF0000;">*</span></label>
   <div class="col-md-4">
      <input id="membership_type_description" name="membership_type_description" type="text" placeholder="Membership Type Description" class="form-control input-md" value="{{ membership_type_description ?? '' }}">
   </div>
</div>

<!-- Multiple Checkboxes (inline) -->
<div class="form-group">
  <label class="col-md-4 control-label" for="checkboxes"></label>
  <div class="col-md-4">
    <label class="checkbox-inline" for="is_promo">
      <input type="checkbox" name="is_promo" id="is_promo" value="1"  {{ is_promo ? 'checked="checked"' : '' }} >
      Promotional
    </label>
    <label class="checkbox-inline" for="is_active">
      <input type="checkbox" name="is_active" id="is_active" value="1" {{ is_active ? 'checked="checked"' : '' }}  >
      Active
    </label>
  </div>
</div>

<div class="form-group">
   <div class="col-md-offset-4 col-md-4">
    <input type="hidden" name="update">
    {% if id is not null %}<input type="hidden" name="id" value="{{ id }}">{% endif %}
    <input type="submit" name="submit" value="Submit" class="btn btn-primary">
   </div>
</div>
</fieldset>
</form>
Edited by benanamen
Link to comment
Share on other sites

With pre-rendering I mean your $options array at the bottom of the script (which you adopted from reply #5). This is unnecessary and blurs the line between business logic and presentation. See #6 for an alternative.

 

Besides that, I don't see any fundamental problems. A couple of suggestions:

  • You can make the code a lot shorter if you replace all the if(!empty($row...)) ... elseif (!empty($_POST...)) checks with a loop that goes through this procedure once for every field.
  • I would replace the {{ is_promo ? 'checked="checked"' : '' }} with a simple {% if is_promo %}checked{% endif %}. The checked="checked" syntax is an obsolete XHTMLism.
  • You should get rid of the try-catch statement.
Link to comment
Share on other sites

  • You can make the code a lot shorter if you replace all the if(!empty($row...)) ... elseif (!empty($_POST...)) checks with a loop that goes through this procedure once for every field.

 

Not sure how you are meaning to do this.

 

I would replace the {{ is_promo ? 'checked="checked"' : '' }} with a simple {% if is_promo %}checked{% endif %}

 

Code has been updated. Thanks.

 

  • You should get rid of the try-catch statement.

 

 

It is just there for testing twig. The app actually uses set_exception handler

Edited by benanamen
Link to comment
Share on other sites

Not sure how you are meaning to do this.

 

When you get the default values for your membership fields, you repeat the exact same pair of if statements over and over again with the only difference being the field name.

 

This screams for a loop:

$membership_fields = [
    'membership_category_id',
    'membership_type',
    'membership_type_description',
    'is_promo',
    'is_active',
];

$membership_data = [];
foreach ($membership_fields as $membership_field)
{
    if (!empty($_POST[$membership_field]))
    {
        $membership_data[$membership_field] = $_POST[$membership_field];
    }
    elseif (!empty($row[$membership_field]))
    {
        $membership_data[$membership_field] = $row[$membership_field];
    }
    else
    {
        $membership_data[$membership_field] = '';
    }
}

This cuts the code volumne in half and allows you to easily add field without having to repeat the if statements yet again.

 

 

 

It is just there for testing twig. The app actually uses set_exception handler

 

And why not just leave the exception alone?

Link to comment
Share on other sites

And why not just leave the exception alone?

 

 

I am. The app uses a single index file and includes each page from the $_GET value along with several other includes (db connection, functions).

 

It was easier for testing to pull an edit "page" out of the app as a stand alone page while I learn TWIG.

Edited by benanamen
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.