I am in the process of turning my standard PHP project into something built on Symfony2. One part I have is this function
function viewAvailability(){
$db = Database::get();
$active = "Active";
// Fetch all the active alert IDs.
$idListSql = $db->prepare("SELECT DISTINCT id
FROM availability_alert
WHERE alert_status = :active");
$idListSql->bindParam(':active', $active);
$idListSql->execute();
$alerts = array();
// Go through each ID.
while ($idListRow = $idListSql->fetch(PDO::FETCH_ASSOC)) {
$alertId = (int)$idListRow["id"];
// Create the first dimension of the array, using the alert ID as the key.
$alerts[$alertId] = array();
// Fetch all the availability values for this alert.
$availabilitySql = $db->prepare("
SELECT availability, last_updated, class_letter, alert_pseudo, flight_number
FROM availability_alert_availability
WHERE availability_alert_id = {$alertId}
ORDER by class_letter, last_updated");
$availabilitySql->execute();
// Go through each availability result.
while ($aRow = $availabilitySql->fetch(PDO::FETCH_ASSOC)) {
// Fetch the date and hour for this availability row as a string.
$dateString = new DateTime($aRow["last_updated"]);
$dateString = $dateString->format('d M Y H:00');
// Create the second dimension of the array, using the alert pseudo as the key.
if (empty($alerts[$alertId][$aRow["alert_pseudo"]])) {
$alerts[$alertId][$aRow["alert_pseudo"]] = array();
}
// Create the third dimension of the array, using the flight number as the key.
if (empty($alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]])) {
$alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]] = array();
}
// Create the fourth dimension of the array, using the date string as the key.
if (empty($alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]][$dateString])) {
$alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]][$dateString] = array();
}
// Create the fifth dimension of the array, using the class letter as a key, and the
// availability value as the value.
$alerts[$alertId][$aRow["alert_pseudo"]][$aRow["flight_number"]][$dateString][$aRow["class_letter"]] = $aRow["availability"];
}
}
}
This is only part of the function, I then go onto a lot of loops to output the data in a table. Anyways, I have moved my database calls above into my Entities custom repository (using DQL instead).
I then do most of the above working in my controller
public function availabilityAction()
{
$em = $this->getDoctrine()->getEntityManager();
$alerts = $em->getRepository('NickAlertBundle:AvailabilityAlert')->getActiveAlertIds();
$alertsArray = array();
if (!$alerts) {
throw $this->createNotFoundException('Unable to find Availability.');
}
foreach($alerts as $alert){
$alertId = (int)$alert['id'];
$alertsArray[$alertId] = array();
$allAvailability = $em->getRepository('NickAlertBundle:AvailabilityAlert')->getAlertAvailability($alertId);
foreach($allAvailability as $alertAvailability)
{
$dateString = $alertAvailability['lastUpdated'];
$dateString = $dateString->format('d M Y H:00');
if (empty($alerts[$alertId][$alertAvailability['alertPseudo']])) {
$alertsArray[$alertId][$alertAvailability['alertPseudo']] = array();
}
if (empty($alerts[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']])) {
$alertsArray[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']] = array();
}
if (empty($alerts[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']][$dateString])) {
$alertsArray[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']][$dateString] = array();
}
$alertsArray[$alertId][$alertAvailability['alertPseudo']][$alertAvailability['flightNumber']][$dateString][$alertAvailability['classLetter']] = $alertAvailability['availability'];
}
}
return $this->render('NickAlertBundle:Page:availability.html.twig', array(
'alertsArray' => $alertsArray,
));
}
Now it is a lot neater, but I feel there is too much going on in my controller (not sure if this is good or not). The other problem is that I am then passing this filled up array I have to my view. Now I have a complex table layout to create from this array, and I really dont think it should be the job of the view to do this. As an example, this is part of the code I would need to convert within the view
if (!empty($pseudos)) {
foreach ($pseudos as $pseudo => $flights) {
foreach ($flights as $flight => $dates) {
$firstDate = array_pop(array_keys($dates));
echo '<div class="availability_table_container">';
echo "<table class='availability_table'>";
echo "<tr>";
if ($i == 0) {
echo "<th></th>";
}
echo "<th class='pseudo-header'>{$flight}</th>";
echo "</tr>";
echo "<tr>";
foreach (array_keys($dates[$firstDate]) as $classLetter) {
if ($j == 0) {
echo "<th></th>";
}
$j++;
echo "<th class='class-header'>{$classLetter}</th>";
}
echo "</tr>";
foreach ($dates as $date => $classes) {
echo "<tr>";
if ($i == 0) {
echo "<td class='time_row'>{$date}</td>";
}
foreach ($classes as $classLetter => $availability) {
if ($availability >= 0) {
$className = $availability > 0 ? "green" : "red";
}
if ($availability == "." || $availability == "-") {
$className = "purple";
}
echo "<td class='number_row {$className}'>{$availability}</td>";
}
echo "</tr>";
}
$i++;
echo "</table>";
echo "</div>";
}
}
}
So what's the best way to handle this code? I think I am right in not allowing my view to handle the above code, but then where should I do it?
Any advice on the design is appreciated.
Related
I have a registration system where there are several fields. One of the registration fields is Segments and they come from the database:
public function comboSegmentos($key)
{
$sqlMostrar = mysqli_query($this->conexao, "SELECT * FROM loja_segmentos;");
if (mysqli_num_rows($sqlMostrar) == 0)
{
$mostrar = "<div style='color: red'>Nenhuma segmento cadastrado até o momento.</div>";
}
else
{
$mostrar = "<select name='Segments[]' id='segmentos' class='form-control select2' multiple='multiple' style='width: 35%'>";
while ($jmMostrar = mysqli_fetch_object($sqlMostrar))
{
$mostrar .= "<option value='".$jmMostrar->Segmentos."' ".$selected.">".$jmMostrar->Segmentos."</option>";
}
$mostrar .= "</select>";
}
return $mostrar;
}
So that the method doesn't have too many parameters, I did it like this:
<?php
...
$dados = array_filter($_POST);
echo $metodos->cadastrarProdutos($dados);
Method cadastrarProdutos($dados)
But I'm not able to get the values of the Segments even using foreach().
<?php
public function cadastrarProdutos(array $dados)
{
...
$segments = $dados["Segments"];
foreach($segments as $seg)
{
$segm = $seg;
}
...
}
How can I get the values of the select2 field and get them using a PHP method without Jquery?
I managed to solve it as follows:
<?php
public function cadastrarProdutos(array $dados)
{
...
$segments = $dados["Segments"];
$segm = array();
foreach($segments as $seg)
{
$segm[] = $seg;
}
$segments = implode(',',$segm);
...
}
I need two print the same rows which retrieved from the db, in two different locations in same php file.
I know it is better to have a function. It tried, It doesn't work properly.
I am using the below code print the said rows/
$get_g = "SELECT * FROM profile_groups";
$get_gr = mysqli_query($condb ,$get_g);
if(mysqli_num_rows($get_gr) > 0)
{
while($groups = mysqli_fetch_array($get_gr))
{
echo "<option value='".$groups['profile_gid']."'>".$groups['profile_gname']."</option>";
}
}
else
{
echo '<option value="">Empty - No Groups!!</option>';
}
I need to print exactly the same code twice in two different location in a php file.
I think it is not a good idea to retrieve data twice from the server by pasting the above code twice.
Is there any way to recall or reprint the retrieved data in second place which I need to print.
Edit : Or else, if someone can help me to convert this to a function?
I converted this into a function. It prints only first row.
Edit 2 : Following is my function
unction getGroup($dbconn)
{
$get_g = "SELECT * FROM profile_groups";
$get_gr = mysqli_query($dbconn ,$get_g);
if(mysqli_num_rows($get_gr) > 0)
{
while($groups = mysqli_fetch_array($get_gr))
{
$groupData = "<option value='".$groups['profile_gid']."'>".$groups['profile_gname']."</option>";
}
}
else
{
echo '<option value="">Empty - No Groups!!</option>';
}
return $groupData;
You can store the records coming from the DB in array and use a custom function to render the element
$get_g = "SELECT * FROM profile_groups";
$get_gr = mysqli_query($condb ,$get_g);
$options = []; //store in an array
if(mysqli_num_rows($get_gr) > 0)
{
while($groups = mysqli_fetch_array($get_gr))
{
$options[$groups['profile_gid']] = $groups['profile_gname'];
}
}
Now you can use the $options array many times in your page
echo renderElement($options);
function renderElement($ops){
$html = '';
foreach($ops as $k => $v){
$html .= "<option value={$k}>{$v}</option>";
}
return $html;
}
If the data is same for both places, put the entire string into variable, then echo it on those two places.
instead of
echo "here\n";
echo "there\n";
do
$output = "here\n";
$output .= "there\n";
then somewhere
echo $output
on two places....
Values are being stored in groups array, hence you can use a foreach loop elsewhere to get values from the array:
$groups = array();
$get_g = "SELECT * FROM profile_groups";
$get_gr = mysqli_query($condb ,$get_g);
if(mysqli_num_rows($get_gr) > 0)
{
while($groups = mysqli_fetch_array($get_gr))
{
echo "<option value='".$groups['profile_gid']."'>".$groups['profile_gname']."</option>";
}
}
else
{
echo '<option value="">Empty - No Groups!!</option>';
}
// use here
foreach($groups as $group)
{
echo $group['profile_gid'] . " ". $group['profile_gname'] . "<br/>";
}
class ProfileGroups
{
public $profile_groups_options;
public static function get_profile_groups_options($condb) {
$get_g = "SELECT * FROM profile_groups";
if( isset( $this->profile_groups_options ) && $this->profile_groups_options != '') {
return $this->profile_groups_options;
}
$get_gr = mysqli_query($condb ,$get_g);
if(mysqli_num_rows($get_gr) > 0)
{
while($groups = mysqli_fetch_array($get_gr))
{
$this->profile_groups_options .= "<option value='".$groups['profile_gid']."'>".$groups['profile_gname']."</option>";
}
}
else
{
$this->profile_groups_options .= '<option value="">Empty - No Groups!!</option>';
}
return $this->profile_groups_options;
}
}
ProfileGroups::get_profile_groups_options($condb);
I have write a code to create a select with PHP Object which is:
<?php
class Modulo {
var $nD;
var $nC;
var $nA;
function __construct($nD,$nC,$nA) {
$this->nD=$nD;
$this->nC=$nC;
$this->nA=$nA;
}
function toString(){
return $this->nD."-".$this->nC."-".$this->nA."<br>";
}
}
?>
Here is the method to build the select:
function loadModuleValid(){
$mod1 = new Modulo(4,3,3);
$mod2 = new Modulo(5,3,2);
$mod3 = new Modulo(4,4,2);
$mod4 = new Modulo(5,4,1);
$mod5 = new Modulo(4,5,1);
$mod6 = new Modulo(3,5,2);
$mod7 = new Modulo(3,4,3);
$mods = array($mod1,$mod2,$mod3,$mod4,$mod5,$mod6,$mod7);
$i = 0;
print "<h3>Seleziona il modulo</h3>";
print "<select id=\"d1\">";
foreach ($mods as $key ) {
print "<option value=\"{$i}\">{$key->toString()}</option>";
$i++;
}
print "</select>";
}
Now I have to retrive the selected object by the user when the she/he presses a button. How can I do ? I want the actual object not just it's value !
You can't pass an object through a form... well you could if you were to serialize it, pass the string and then unserialize it but you don't want to do that.
What you want to do is reference the object with an identifier:
function loadModuleValid(){
array(
'mod1' => new Modulo(4,3,3),
'mod2' => new Modulo(5,3,2),
// your other objects
)
$i = 0;
print "<h3>Seleziona il modulo</h3>";
print "<select id=\"d1\">";
foreach ($mods as $key => $object ) {
print "<option value=\"{$key}\">{$object->toString()}</option>";
$i++;
}
print "</select>";
}
Then on the backend you would fetch the object based on mod1 or whatever the array key is. However this requires creating this array of objects in a place where they can be fetched again.
So let's do an example of that:
function getModulos($id = null) {
$mods = array(
'mod1' => new Modulo(4,3,3),
'mod2' => new Modulo(5,3,2),
// your other objects
);
if (null !== $id) {
return isset($mods[$id]) ? $mods[$id] : false;
} else {
return $mods;
}
}
function loadModuleValid(){
$mods = getModulos();
$i = 0;
print "<h3>Seleziona il modulo</h3>";
print "<select id=\"d1\" name=\"modulo\">";
foreach ($mods as $key => $object ) {
print "<option value=\"{$key}\">{$object->toString()}</option>";
$i++;
}
print "</select>";
}
// this would be an example of your form handling
if (isset($_POST['modulo'])) {
$modulo = getModulos($_POST['modulo']);
}
There is a dark tricks, you can serialize your object :
print "<option value=\"" . serialize($key) . "\">{$key->toString()}</option>";
Then unserialize it to retrieve your object :
$mod = unserialize($_POST['yourSelectName']);
I have a database with lots of courses in for example, breakfast_cereal, breakfast_toast, lunch_salad, lunch_main etc etc
Im using this to put the data they enter into a variable containing there results, for example:
breakfast_toast = Wholemeal;Brown;50/50;
and
breakfast_hotdrinks = Tea;Coffee;Milk;
This is the script im using to gather that information:
if(!empty($_POST['toast_selection'])) {
foreach($_POST['toast_selection'] as $toast) {
$toast = trim($toast);
if(!empty($toast)) {
$toastchoices .= "$toast;";
}
}
}
This works absolutely fine, But i have about a lot of entries to collect and if they add more to the database i want them to automatically gather.
I had a go at trying to think of a way but i just can't figure it out, This is what i tried:
All the inputs are called the same as the $course_menuname, for example breakfast_cereal[]
$query = "SELECT * FROM course";
$result = mysql_query($query);
while($row = mysql_fetch_array($result))
{
$course_menuname = $row['course_menuname']; #E.G breakfast_cereal, breakfast_toast, lunch_main
$course_item = $row['course_jsname']; #E.G cereal, toast, jacketpotato
$postResults = $_POST[''.$course_menuname .''];
if(!empty($postResults)) {
echo $postResults."<br />";
foreach($postResults as $course_item) {
$course_item = trim($course_item);
if(!empty($course_item)) {
$course_item1 .= "$course_item;";
}
}
}
echo $course_item1."<br />";
}
This is what the end result should look for
if(!empty($_POST['toast'])) {
foreach($_POST['toast'] as $toast) {
$toast = trim($toast);
if(!empty($toast)) {
$toastchoices .= "$toast;";
}
}
}
if(!empty($_POST['toastextra_selection'])) {
#Gather Toast EXTRAs Choices
foreach($_POST['toastextra_selection'] as $toastextra) {
$toastextra = trim($toastextra);
if(!empty($toastextra)) {
$toastextrachoices .= "$toastextra;";
}
}
}
if(!empty($_POST['toastextra_selection'])) {
#Gather Cold Drinks Choices
foreach($_POST['colddrinks_selection'] as $colddrinks) {
$colddrinks = trim($colddrinks);
if(!empty($colddrinks)) {
$colddrinkschoices .= "$colddrinks;";
}
}
}
if(!empty($_POST['hotdrinks_selection'])) {
#Gather Hot Drinks Choices
foreach($_POST['hotdrinks_selection'] as $hotdrinks) {
$hotdrinks = trim($hotdrinks);
if(!empty($hotdrinks)) {
$hotdrinkschoices .= "$hotdrinks;";
}
}
}
First of all you should not use the mysql_* functions anymore. These functions are marked as deprecated. Alternativly you can use PDO or the mysqli_* functions.
I guess group change is what you need. Let 's start with a simple example.
try {
$data = array();
$pdo = new PDO(...);
foreach ($pdo->query("SELECT * FROM course") as $row) {
if (!isset($data[$row['course_menuname'])) {
$data[$row['course_menuname']] = array();
}
if (!empty($row['course_item'] && in_array($row['course_item'], $_POST[$row['course_menuname'])) {
$data[$row['course_menuname'][] = $row['course_item'];
}
}
} catch (PDOException $e) {
// error handling
}
// Output all choices by menuname
foreach ($data as $key => $value) {
echo "Choices for " . $key . "\n";
echo implode(";", $value) . "\n";
}
i am generating a invoice generation application. In that, i have a table that stores individual items of invoice with flags buyer and invoice_no. These flags help me get a aggregate invoice construct from rows. This is the function:
public function invoice_get()
{
$data=array();
$this->db->group_by('invoice_no');
$this->db->order_by('invoice_no','asc');
$Q=$this->db->get('sales');
echo $Q->num_rows();
if($Q->num_rows()>0)
{
foreach($Q->result_array() as $row)
{
if(!isset($data[$row['invoice_no']]))
{
$data[$row['invoice_no']]['date']=$row['date'];
$this->db->where('id',$row['buyer']);
$q=$this->db->get('ledgers');
$data[$row['invoice_no']]['buyer']=$q->row();
}
else
{
$this->db->where('id',$row['item_id']);
$i=$this->db->get('inventory');
$data[$row['invoice_no']]['items'][$row['item_id']]=$i->row();
}
}
print_r($data);
//$this->response($data);
}
}
The problem is that i am not getting item details
What may be the mistake?
$i = 1;
foreach ($q->result_array() as $row){
$data[$row['invoice_number']]['date'] = $row['date'];
$data[$row['invoice_number']]['buyer']['id'] = $row['id'];
$data[$row['invoice_number']]['item'][$i]['name'] = $row['name'];
$data[$row['invoice_number']]['item'][$i]['description'] = $row['description'];
//and more if you want to add....
$i++;
}
This should give you the desired result.