moddle change in table summary of exam - php

I use Moodle 3.9.1+ . I want to change summary exam table to div to be able to show the each question and its situation beside each-other like below. I want to have each 5 question in a row in fact. As I know it's not possible to do so with table and because of that I want to use div to be able to do so with css.
I found the file /mod/quiz/renderer.php has a function with below code that makes the summary exam table.
public function summary_table($attemptobj, $displayoptions) {
// Prepare the summary table header.
$table = new html_table();
$table->attributes['class'] = 'generaltable quizsummaryofattempt boxaligncenter';
$table->head = array(get_string('question', 'quiz'), get_string('status', 'quiz'));
$table->align = array('left', 'left');
$table->size = array('', '');
$markscolumn = $displayoptions->marks >= question_display_options::MARK_AND_MAX;
if ($markscolumn) {
$table->head[] = get_string('marks', 'quiz');
$table->align[] = 'left';
$table->size[] = '';
}
$tablewidth = count($table->align);
$table->data = array();
// Get the summary info for each question.
$slots = $attemptobj->get_slots();
foreach ($slots as $slot) {
// Add a section headings if we need one here.
$heading = $attemptobj->get_heading_before_slot($slot);
if ($heading) {
$cell = new html_table_cell(format_string($heading));
$cell->header = true;
$cell->colspan = $tablewidth;
$table->data[] = array($cell);
$table->rowclasses[] = 'quizsummaryheading';
}
// Don't display information items.
if (!$attemptobj->is_real_question($slot)) {
continue;
}
// Real question, show it.
$flag = '';
if ($attemptobj->is_question_flagged($slot)) {
// Quiz has custom JS manipulating these image tags - so we can't use the pix_icon method here.
$flag = html_writer::empty_tag('img', array('src' => $this->image_url('i/flagged'),
'alt' => get_string('flagged', 'question'), 'class' => 'questionflag icon-post'));
}
if ($attemptobj->can_navigate_to($slot)) {
$row = array(html_writer::link($attemptobj->attempt_url($slot),
$attemptobj->get_question_number($slot) . $flag),
$attemptobj->get_question_status($slot, $displayoptions->correctness));
} else {
$row = array($attemptobj->get_question_number($slot) . $flag,
$attemptobj->get_question_status($slot, $displayoptions->correctness));
}
if ($markscolumn) {
$row[] = $attemptobj->get_question_mark($slot);
}
$table->data[] = $row;
$table->rowclasses[] = 'quizsummary' . $slot . ' ' . $attemptobj->get_question_state_class(
$slot, $displayoptions->correctness);
}
// Print the summary table.
$output = html_writer::table($table);
return $output;
}
Can anyone help me to change this code and show desired information in div format?

I could at last solve the problem but it may not be very professional:
* Create the summary page
*
* #param quiz_attempt $attemptobj
* #param mod_quiz_display_options $displayoptions
*/
public function summary_page($attemptobj, $displayoptions) {
$output = '';
$output .= $this->header();
$output .= $this->heading(format_string($attemptobj->get_quiz_name()));
$output .= $this->heading(get_string('summaryofattempt', 'quiz'), 3);
$output .= $this->summary_table($attemptobj, $displayoptions);
$output .= $this->summary_page_controls($attemptobj);
$output .= $this->footer();
return $output;
}
/**
* Generates the table of summarydata
* sara
* #param quiz_attempt $attemptobj
* #param mod_quiz_display_options $displayoptions
*/
public function summary_table($attemptobj, $displayoptions) {
// Prepare the summary table header.
$table = new html_table();
$table->attributes['class'] = 'generaltable quizsummaryofattempt boxaligncenter';
$table->head = array(get_string('question', 'quiz'), get_string('status', 'quiz'));
$table->align = array('left', 'left');
$table->size = array('', '');
$markscolumn = $displayoptions->marks >= question_display_options::MARK_AND_MAX;
if ($markscolumn) {
$table->head[] = get_string('marks', 'quiz');
$table->align[] = 'left';
$table->size[] = '';
}
$tablewidth = count($table->align);
$table->data = array();
// Get the summary info for each question.
$slots = $attemptobj->get_slots();
foreach ($slots as $slot) {
// Add a section headings if we need one here.
$heading = $attemptobj->get_heading_before_slot($slot);
if ($heading) {
$cell = new html_table_cell(format_string($heading));
$cell->header = true;
$cell->colspan = $tablewidth;
$table->data[] = array($cell);
$table->rowclasses[] = 'quizsummaryheading';
}
// Don't display information items.
if (!$attemptobj->is_real_question($slot)) {
continue;
}
// Real question, show it.
$flag = '';
if ($attemptobj->is_question_flagged($slot)) {
// Quiz has custom JS manipulating these image tags - so we can't use the pix_icon method here.
$flag = html_writer::empty_tag('img', array('src' => $this->image_url('i/flagged'),
'alt' => get_string('flagged', 'question'), 'class' => 'questionflag icon-post'));
}
if ($attemptobj->can_navigate_to($slot)) {
$row = array(html_writer::link($attemptobj->attempt_url($slot),
$attemptobj->get_question_number($slot) . $flag),
$attemptobj->get_question_status($slot, $displayoptions->correctness));
} else {
$row = array($attemptobj->get_question_number($slot) . $flag,
$attemptobj->get_question_status($slot, $displayoptions->correctness));
}
if ($markscolumn) {
$row[] = $attemptobj->get_question_mark($slot);
}
$table->data[] = $row;
$table->rowclasses[] = 'quizsummary' . $slot . ' ' . $attemptobj->get_question_state_class(
$slot, $displayoptions->correctness);
$counter=0;
foreach($row as $r)
{
if($counter ==0)
{
$output .= html_writer::start_tag('div', array('class' => 'qsummary'.' '.'questionNo' .' q'. $slot. ' '.$attemptobj->get_question_status($slot, $displayoptions->correctness)));
$output .= $r;
$output .= html_writer::end_tag('div');
$counter=1;
}
else{
if($counter ==1)
{
$output .= html_writer::start_tag('div', array('class' => 'qsummary' .' '.'questionStat'.' q'. $slot. ' '.$attemptobj->get_question_status($slot, $displayoptions->correctness)));
$output .= $r;
$output .= html_writer::end_tag('div');
$counter=1;
}
}
}
}
// Print the summary table.
// $output = html_writer::table($table);
return $output;
}

Related

How to place HTML tags in a CSV?

I have an excel sheet. In this excel sheet it contains Parts Number, Summary, Brand, Status. I would like to be able to import CSV data which contains text that already has html so I don’t have to apply all the formatting after import.
In this new csv, it should only contain 3 columns, Parts Number, Summary and html table. In this html table, it contains Parts Number, Summary, Brand, Status.
I have already created a table using php and it worked, now I am having difficulty trying to bring the table to csv.
Here is my code:
<?php
$file = fopen("Book1.csv","r");
$file2 = fopen("Book2.csv","w");
$data = [];
$description = '<table class="table">';
while($row = fgetcsv($file)) {
$data[] = $row; //Get all the data
}
if($data){
$n_columns = count($data[0]); //Get number of columns
}
$description .= '<table border="1">';
for ($col = 0; $col < $n_columns; $col++) {
$description .= '<tr>';
foreach ($data as $row_k => $row) {
if ($row_k == 0) {
$description .= '<th>';
} else {
$description .= '<td>';
}
$description .= $row[$col] ?? '';
if ($row_k == 0) {
$description .= '</th>';
} else {
$description .= '</td>';
}
}
$description .= '</tr>';
fputcsv($file2, $data); // line 50
}
$description .= '</table>';
fclose($file);
fclose($file2);
?>
I am desperate, any help is appreciated.
If I understood you correctly, this should accomplish the task. It uses 3 functions, array_to_csv, csv_to_array and build_table.
<?php
function csv_to_array($filename, $header_row=true)
{
$handle = fopen($filename, 'r');
if ($header_row === true)
$header = fgetcsv($handle);
$data = [];
while ($row = fgetcsv($handle)) {
if ($header_row)
$data[] = array_combine($header, $row);
else
$data[] = $row;
}
return $data;
}
function array_to_csv($data, $filename, $header_row=true)
{
$handle = fopen($filename, 'w');
if ($header_row == true) {
$header = array_keys($data[0]);
fputcsv($handle, $header);
}
foreach ($data as $line) {
fputcsv($handle, $line);
}
fclose($handle);
}
function transpose_array($array)
{
$headers = array_keys($array[0]);
$transposed = [];
foreach ($array as $row) {
foreach ($headers as $header) {
if (!isset($transposed[$header]))
$transposed[$header] = [];
$transposed[$header][] = $row[$header];
}
}
return $transposed;
}
function build_table($array)
{
$transposed = transpose_array($array);
$table = '<table><tbody>';
foreach ($transposed as $heading => $row) {
$table .= '<tr><th>' . $heading .'</th>';
foreach ($row as $element) {
$table .= '<td>' . $element . '</td>';
}
$table .= '</tr>';
}
$table .= '</tbody></table>';
return $table;
}
$book1 = csv_to_array('Book1.csv');
$book2 = [];
foreach ($book1 as $row) {
$key = $row['Parts Number'];
if (!isset($book2[$key])) {
$book2[$key] = [
'Parts Number' => $key,
'Summary' => $row['Summary']
];
}
$book2[$key]['rows'][] = $row;
}
foreach ($book2 as &$product) {
$product['html table'] = build_table($product['rows']);
unset($product['rows']);
}
unset($product);
$book2 = array_values($book2);
array_to_csv($book2, 'Book2.csv');
Book1.csv contains:
Parts Number,Summary,Brand,Status,Country
6SE1200-1EA70-1,SIMOVERT P 6,Siemens,Discontinued,Germany
6SE1200-1EA70-1,SIMOVERT P 6,Siemens,Discontinued,France
6SE1200-1EA70-1,SIMOVERT P 6,Siemens,In Stock,England
6SE3012-0BA00,SIMOVERT P M,Siemens,Discontinued,-
Book2.csv output:
"Parts Number",Summary,"html table"
6SE1200-1EA70-1,"SIMOVERT P 6","<table><tbody><tr><th>Parts Number</th><td>6SE1200-1EA70-1</td><td>6SE1200-1EA70-1</td><td>6SE1200-1EA70-1</td></tr><tr><th>Summary</th><td>SIMOVERT P 6</td><td>SIMOVERT P 6</td><td>SIMOVERT P 6</td></tr><tr><th>Brand</th><td>Siemens</td><td>Siemens</td><td>Siemens</td></tr><tr><th>Status</th><td>Discontinued</td><td>Discontinued</td><td>In Stock</td></tr><tr><th>Country</th><td>Germany</td><td>France</td><td>England</td></tr></tbody></table>"
6SE3012-0BA00,"SIMOVERT P M","<table><tbody><tr><th>Parts Number</th><td>6SE3012-0BA00</td></tr><tr><th>Summary</th><td>SIMOVERT P M</td></tr><tr><th>Brand</th><td>Siemens</td></tr><tr><th>Status</th><td>Discontinued</td></tr><tr><th>Country</th><td>-</td></tr></tbody></table>"

youtube class video limit not working

I want to change the video limit on my home page (getpopularvideos), but when I change the limit, it always only shows 20 videos.
What am I doing wrong?
protected function getPopularVideos($limit = NULL){
// Set Limit
if(!is_null($limit)) $this->limit = $limit;
// Construct URL
$part = "snippet,contentDetails,statistics";
$this->url = "https://www.googleapis.com/youtube/v3/videos?key={$this->key}&part=$part&chart=mostPopular&maxResults={$this->limit}";
if(!is_null($this->page)) $this->url = $this->url."&pageToken={$this->page}";
// Get Data
$data = Main::cache_get("popular_{$this->page}");
if($data == NULL){
$data = $this->http(TRUE);
Main::cache_set("popular_{$this->page}", $data); $limit = 24;
}
$i = 1;
$html = "<ul class='media'>";
foreach ($data->items as $yt) {
$html .= $this->listVideo($yt);
if($i%24 == 0) {
$html .= "</ul>{$this->ads(728)}<ul class='media'>";
}
$i ++;
}
$html .= "</ul>";
$this->pagination = "<ul class='list-inline'>";
if(isset($data->prevPageToken)){
$this->pagination .= "<li ><a href='{$this->config["url"]}/popular/{$data->prevPageToken}' class='btn btn-ghost'><i class='btn-icon btn-icon--left ninety9lives-youtube-play'></i> Previous</a></li>";
}
if(isset($data->nextPageToken)){
$this->pagination .= "<li ><a href='{$this->config["url"]}/popular/{$data->nextPageToken}' class='btn btn-ghost'><i class='btn-icon btn-icon--left ninety9lives-youtube-play'></i> Next</a></li>";
}
$this->pagination .= "</ul>";
return $html;
}
protected function getUserVideos4Home($q, $limit = NULL){
if(!is_null($limit)) $this->limit = $limit;
$part = "snippet";
$this->url = "https://www.googleapis.com/youtube/v3/search?key={$this->key}&part=$part&order=date&type=video&channelId={$q}&maxResults={$this->limit}";
if(!is_null($this->page)) $this->url = $this->url."&pageToken={$this->page}";
$data = $this->http(TRUE);
$i = 1;
$return = new stdClass();
$return->title = $data->items[0]->snippet->channelTitle;
$html .= "";
$vids = array();
foreach ($data->items as $yt){
$vids[] = $yt->id->videoId;
}
$videos2 = implode(",", $vids);
$part = "snippet,contentDetails,statistics";
$this->url = "https://www.googleapis.com/youtube/v3/videos?key={$this->key}&part={$part}&id={$videos2}";
$data2 = $this->http(TRUE);
$durations = Main::durations($vids);
foreach ($data->items as $yt) {
$html .= $this->listSearchVideo12($yt,$durations[$yt->id->videoId]);
if($i%6 == 0) {
$html .= "</div><div class='adblock'><div class='img'>Google AdSense<br>336 x 280</div></div><div class='list'>";
}
$i ++;
}
$html .= "";
return $html;
}

what are the different ways for this code to work

The following is part of a personal budgeting program I'm writing.
This code pulls line item information from multiple tables and writes it into an array and then displays the information by transid => family => category => lineItems. Everything works, and I get the results I want out of it. My question is if there is a more efficient way to accomplish this task?
Since this is a personal program, I'm only asking so that I can improve my coding abilities.
<?php
include ('../cfg/connect.php');
$s = " : ";
$br = "<br>";
$ul = "<ul>";
$li = "<li>";
$_ul = "</ul>";
$_li = "</li>";
$data = [];
$itemCount = 0;
$arrayItemCount = 0;
$categoryQry = "SELECT a.itemQty, b.transDate, b.transID, b.amount, a.itemPrice, a.itemCategory, c.catFamily, a.itemName, a.itemSource FROM budget.lineItems AS a JOIN budget.quickEntry AS b ON a.transID = b.transID JOIN budget.categories AS c ON a.itemCategory = c.catName WHERE b.processed = 'y' ORDER BY c.catFamily, c.catName, b.transDate";
$categories = $conn->prepare ($categoryQry);
$categories->execute ();
$categories->store_result ();
$categories->bind_result ($itemQty, $transDate, $transID, $totalPrice, $itemPrice, $category, $family, $itemName, $source);
while ($categories->fetch ()) {
if (!isset($data[$transID]['amount'])) {
$data[$transID]['amount'] = 0;
}
if (!isset($data[$transID]['line'])) {
$data[$transID]['line'] = '';
}
if (!isset($data[$transID]['line'][$family]['amount'])) {
$data[$transID]['line'][$family]['amount'] = 0;
}
if (!isset($data[$transID]['line'][$family]['line'])) {
$data[$transID]['line'][$family]['line'] = '';
}
if (!isset($data[$transID]['line'][$family]['line'][$category]['amount'])) {
$data[$transID]['line'][$family]['line'][$category]['amount'] = 0;
}
if (!isset($data[$transID]['line'][$family]['line'][$category]['line'])) {
$data[$transID]['line'][$family]['line'][$category]['line'] = '';
}
$itemCount++;
$qtyPrice = $itemPrice * $itemQty;
$data[$transID]['amount'] += $qtyPrice;
$data[$transID]['transDate'] = $transDate;
$data[$transID]['source'] = $source;
$data[$transID]['line'][$family]['amount'] += $qtyPrice;
$data[$transID]['line'][$family]['line'][$category]['amount'] += $qtyPrice;
$data[$transID]['line'][$family]['line'][$category]['line'][$itemName] = ['itemQty' => $itemQty, 'itemPrice' => $itemPrice];
}
foreach ($data as $transID => $transValue) {
echo $transID .$s.$transValue['transDate'].$s.$transValue['source'].$s.$transValue['amount']. $ul;
foreach ($transValue['line'] as $category => $categoryValue) {
echo $li . $category .$s.$categoryValue['amount']. $ul;
foreach ($categoryValue['line'] as $line => $lineValue) {
echo $li . $line .$s.$lineValue['amount']. $ul;
foreach ($lineValue['line'] as $item => $details) {
echo $li . $item .$s . $details['itemQty'] . $s . $details['itemPrice'] . $_li;
}
echo $_ul . $_li;
}
echo $_ul . $_li;
}
echo $_ul . $br;
}

idssphp duping array in a foreach

OK...
your answer is fine #Random, however it's still duping the ids, so i integrated your code to my dev code... so here's my final code....
$gr = mysql_query("select id from permission_sets");
$permission_arr = array(
'start_perms' => isset($_POST['START_'.$id]),
'reply_perms' => isset($_POST['REPLY_'.$id]),
'read_perms' => isset($_POST['READ_'.$id]),
'upload_perms' => isset($_POST['UPLOAD_'.$id]),
'show_perms' => isset($_POST['SHOW_'.$id]),
'download_perms' => isset($_POST['DOWNLOAD_'.$id]));
// saving the beginning of the line : "group: 1,2,3"
$header = 'PID: ';
$read = "";
$reply = "";
$start = "";
$upload = "";
$download = "";
$show = "";
$subPIDs = "";
while($row = mysql_fetch_array($gr)){
foreach($row as $pid){
//-----------------------------
// Get perm id and set it..
//-----------------------------
$pid = $pid.",";
if($permission_arr['start_perms'] == 1){
$start .= $pid;
$subPIDs .= $start;
}
if($permission_arr['read_perms'] == 1){
$read .= $pid;
$subPIDs .= $read;
}
if($permission_arr['reply_perms'] == 1){
$reply .= $pid;
$subPIDs .= $reply;
}
if($permission_arr['upload_perms'] == 1){
$upload .= $pid;
$subPIDs .= $upload;
}
if($permission_arr['download_perms'] == 1){
$download .= $pid;
$subPIDs .= $download;
}
if($permission_arr['show_perms'] == 1){
$show .= $pid;
$subPIDs .= $show;
}
$header .= $subPIDs;
}
} // End while
//------------------------------------
// Store the data in a new array..
//------------------------------------
$perm_arr = array(
'start_perms' => $start,
'reply_perms' => $reply,
'read_perms' => $read,
'upload_perms' => $upload,
'show_perms' => $show,
'download_perms' => $download);
$head = $header.' = ';
foreach($perm_arr as $key => $val){
if($val){
$head .= $key.'<br>'.$head;
}
}
print $head;
echo '<pre>';
print_r($perm_arr);
this does everything yours does... we just need to stop dupes in the output, in the array is no dupe, only in output... also when i mark only 1 box ihe array gets all or no ids...
try this :
// list of permissions with boolean
$permission_arr = array(
'start_perms' => isset($_POST['START_'.$id]),
'reply_perms' => isset($_POST['REPLY_'.$id]),
'read_perms' => isset($_POST['READ_'.$id]),
'upload_perms' => isset($_POST['UPLOAD_'.$id]),
'show_perms' => isset($_POST['SHOW_'.$id]),
'download_perms' => isset($_POST['DOWNLOAD_'.$id]));
echo 'sql';
$gr = mysql_query("select id from permission_sets");
// saving the beginning of the line : "group: 1,2,3"
$header = 'group: ';
$separator = '';
while($row = mysql_fetch_array($gr)) {
foreach($row as $g){
$header .= $separator.$g;
$separator = ',';
}
}
$header = $header.' = ';
foreach($permission_arr as $k => $p){
if($p) {
// the permission is OK, we print this permission
// output like "group: 1,2,3 = start_perms, <br>"
print $header.$k.", <br>";
}
}

Hot to feed php function

Hi I am try to display icecat product data and I am a complete php newbie, I have tracked down a code snippet that I believe should do the job, It says that It requires that you feed the function with an EAN product number.
Could someone please give me an example of what this means as I have no idea, here is a EAN Product number EAN/UPC code:0885909481842
Here is the snippet code I am trying to use.
function getICEcatProductSpecs($ean, $drawdescription = 0, $drawpicture = 0)
{
// Username and password for usage with ICEcat
$username = "Your ICEcat username goes here";
$password = "Your ICEcat password goes here";
// Return 0 and exit function if no EAN available
if($ean == null)
{
return 0;
}
// Get the product specifications in XML format
$context = stream_context_create(array(
'http' => array(
'header' => "Authorization: Basic " . base64_encode($username.":".$password)
)
));
$data = file_get_contents('http://data.icecat.biz/xml_s3/xml_server3.cgi?ean_upc='.$ean.';lang=nl;output=productxml', false, $context);
$xml = new SimpleXMLElement($data);
// Create arrays of item elements from the XML feed
$productPicture = $xml->xpath("//Product");
$productDescription = $xml->xpath("//ProductDescription");
$categories = $xml->xpath("//CategoryFeatureGroup");
$spec_items = $xml->xpath("//ProductFeature");
//Draw product specifications table if any specs available for the product
if($spec_items != null)
{
$categoryList = array();
foreach($categories as $categoryitem) {
$catId = intval($categoryitem->attributes());
$titleXML = new SimpleXMLElement($categoryitem->asXML());
$title = $titleXML->xpath("//Name");
$catName = $title[0]->attributes();
//echo $catId . $catName['Value']. "<br />";
$categoryList[$catId] = $catName['Value'];
}
$specs = "<table class='productspecs'>";
$i = 0;
$drawnCategories = array();
foreach($spec_items as $item) {
$specValue = $item->attributes();
$titleXML = new SimpleXMLElement($item->asXML());
$title = $titleXML->xpath("//Name");
$specName = $title[0]->attributes();
$specCategoryId = intval($specValue['CategoryFeatureGroup_ID']);
if($specName['Value'] != "Source data-sheet")
{
$class = $i%2==0?"odd":"even";
$specs .= "<tr class='".$class."'>
<td>
<table>";
if(!in_array($specCategoryId, $drawnCategories))
{
$specs .= " <tr class='speccategory'>
<th><h3>".$categoryList[$specCategoryId]."</h3></th>
</tr>";
$drawnCategories[$i] = $specCategoryId;
}
$specs .= " <tr>
<th>".utf8_decode($specName['Value']).":</th>
</tr>
<tr>
<td>";
if($specValue['Presentation_Value'] == "Y")
{
$specs .= "Ja <img src='".SCRIPT_ROOT."images/check_green.png' alt='Ja' />";
}
else if($specValue['Presentation_Value'] == "N")
{
$specs .= "Nee <img src='".SCRIPT_ROOT."images/check_red.png' alt='Nee' />";
}
else
{
$specs .= str_replace('\n', '<br />', utf8_decode($specValue['Presentation_Value']));
}
$specs .= "</td>
</tr>
</table>
</td>
</tr>";
}
$i++;
}
$specs .= "</table>";
//Draw product description and link to manufacturer if available
if( $drawdescription != 0)
{
foreach($productDescription as $item) {
$productValues = $item->attributes();
if($productValues['URL'] != null)
{
$specs .= "<p id='manufacturerlink'><a href='".$productValues['URL']."'>Productinformation from manufacturer</a></p>";
}
if($productValues['LongDesc'] != null)
{
$description = utf8_decode(str_replace('\n', '', $productValues['LongDesc']));
$description = str_replace('<b>', '<strong>', $description);
$description = str_replace('<B>', '<strong>', $description);
$description = str_replace('</b>', '</strong>', $description);
$specs .= "<p id='manudescription'>".$description."</p>";
}
}
}
//Draw product picture if available
if( $drawdescription != 0)
{
foreach($productPicture as $item) {
$productValues = $item->attributes();
if($productValues['HighPic'] != null)
{
$specs .= "<div id='manuprodpic'><img src='".$productValues['HighPic']."' alt='' /></div>";
}
}
}
return $specs;
}
else
{
return 0;
}
}
Any advice will be very appreciated thx in advance Peter
My understanding is that it's saying that if you call this function you should pass EAN parameter to it, like this:
getICEcatProductSpecs("0885909481842", 0, 0);

Categories