Incorporating functions in oop - php

I'm trying to write a code for one of my schools assignments, yet I cannot find the reason for it not working. It's probably something simple that i'm yet unaware of. Could anyone point me in the right direction. I'm trying to make a class generate 3 dropdown boxes for selecting the day, month and year. Also there seems to be an infinite loop with the 3rd function. The code is as follows and is split between two files.
File 1: datselect.php
<?php
include ("datselect_functions.php");
$cls = new Dropdown();
$monthname = array(1 => "January", "February", "March", "April", "May", "June",
"July","August", "September", "October", "November", "December");
$today = time();
$f_today = date("M-d-Y",$today);
$func = insert_day();
$func = insert_month($monthname);
//$func = insert_year($today);
echo html_head($f_today);
echo $cls -> getHTML();
echo html_foot();
?>
File 2: datselect_functions.php
<?php
function html_head($f_today) {
return "<html>
<head>
<title>Select a date</title>
</head>
<body>
<div>
Today is ".$f_today."
</div>";
}
class Dropdown {
private $name = "";
private $options = array();
private $selected = "";
public function __construct($name = "") {
$this->name=$name;
}
public function setOption($var,$label) {
$this->options[$var]=$label;
}
public function getHTML() {
$html = "<select name='".$this->name."'>";
var_dump($this->name);
foreach($this->options as $var => $label) {
if ($this->selected=$var) {
$html.= "<option selected value='".$var."'>.$label.</option>";
} else {
$html.= "<option value='".$var."'>.$label.</option>";
}
}
$html.= "</select>";
return $html;
}
}
function html_foot() {
return "</body></html>";
}
function insert_day(){
$ddd = new Dropdown("day");
for($i=1; $i<=31; $i++){
$ddd -> setOption($i, $i);
}
}
function insert_month($monthname){
$ddm = new Dropdown("month");
foreach($monthname as $key => $value) {
$ddm -> setOption($key, $value);
}
}
function insert_year($today){
$currentyear = date("Y", $today);
$ddy = new Dropdown("year");
for($n=$currentyear;$n=$currentyear+3;$n++) {
$ddy -> setOption($n, $n);
}
}
?>

There are a bunch of things where it goes wrong.
//this is unnecessary, you now create an empty dropdown and echo it here.
$cls = new Dropdown();
echo $cls -> getHTML();
//instead of this
$func = insert_day();
$func = insert_month($monthname);
//$func = insert_year($today);
//do this
$days = insert_day();
$months = insert_month($monthname);
$years = insert_year($today);
//then make the dropdows appear like this.
echo $days;
echo $months;
echo $years;
//These 3 functions require an extra line of code.
function insert_day(){
$ddd = new Dropdown("day");
for($i=1; $i<=31; $i++){
$ddd -> setOption($i, $i);
}
//add this line to all of these three functions, but change the var name
return $ddd->getHTML();
}
This should resolve most of your errors, but now a few others might appear though.

Your Dropdown class is just a helper that generates the dropdown html code. You need to store that generated code or output it somewhere, for "it to work".
$func = insert_day(); // 1
$func = insert_month($monthname); // 2
//$func = insert_year($today);
echo html_head($f_today); // 3
echo $cls -> getHTML(); // 4
echo html_foot(); // 5
You are doing the following here, step by step:
You assign the dropdown html code for the day selection to $func
You assign the dropdown html code for the month selection to $func, overwriting everything from 1. You should use a new variable for that or append it with $func .= insert... if that's what you want
You output your header html
You output an empty dropdown, as the Dropdown instance $cls isn't configured anywhere with an options array
You output the footer html
What's missing is that you should also output the results from 1. and 2. after 3.
Also the infinite loop in insert_year is because you assign the current year + 3 in the for loop, not compare it (= vs. ==).
Also it's good style to have one file per class and nothing else in that, but that shouldn't be the problem here.
Hope that helps.

"=" is not a comparison but a setting (use "==" instead):
if ($this->selected=$var) {
Endless-Loop:
for($n=$currentyear;$n=$currentyear+3;$n++) {
Use this:
for($n=$currentyear;$n < $currentyear+3;$n++) {

Your insert_day, insert_month functions do not serve any purpose. Below I have updated your code to display the days, although really you dont need so much code.
//dateselect.php
<?php
include ("datselect_functions.php");
$cls = new Dropdown();
$monthname = array(1 => "January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December");
$today = time();
$f_today = date("M-d-Y",$today);
$func = $cls->insert_day();
//$func = insert_month($monthname);
//$func = insert_year($today);
echo html_head($f_today);
echo $cls -> getHTML();
//echo html_foot();
?>
//datselect_functions
<?php
function html_head($f_today) {
return "<html>
<head>
<title>
Select a date
</title>
</head>
<body>
<div>
Today is ".$f_today."
</div>";
}
class Dropdown {
private $name = "";
private $options = array();
private $selected = "";
public function __construct($name = "") {
$this->name=$name;
}
public function setOption($var,$label) {
$this->options[$var]=$label;
}
public function getHTML() {
$html = "<select>";
//var_dump($this->options);
foreach($this->options as $var => $label) {
if ($this->selected==$var) {
$html.= "<option selected value='".$var."'>.$label.</option>";
}
else {
$html.= '<option value="'.$var.'">'.$label."</option>";
}
}
$html.= "</select>";
//print_r($html);
return $html;
}
function insert_day(){
for($i=1; $i<=31; $i++){
$this -> setOption($i, $i);
}
}
function html_foot() {
return "</body></html>";
}
}
function insert_month($monthname){
$ddm = new Dropdown("month");
foreach($monthname as $key => $value) {
$ddm -> setOption($key, $value);
}
}
function insert_year($today){
$currentyear = date("Y", $today);
$ddy = new Dropdown("year");
for($n=$currentyear;$n<=$currentyear+3;$n++) {
$ddy -> setOption($n, $n);
}
}
?>

Related

Translating date into spanish Wordpress

I have the followwing site on Wordpress where you can find different schedules with the month in english and i need to change it to spanish:
http://comproautosusados.com/centrolerner2016/horarios/
I tried Loco Translate, trying editing the .pó files and now i'm looking into the theme's php files. I've been able to translate lots of stuff, but i can't translate the months. You can see at the left side of the table that it says "Lunes 28th April" for example. I need to change it to "Lunes 28 Abril".
In the theme's "core"there's this file: timetable.php where this function is found:
public function getDays() {
if (!isset(self::$cache['days'])) {
$days = array();
foreach ($this->get('calendar.period') as $time) {
$object = new VTCore_Wordpress_Objects_Array(array(
'id' => strtolower($time->format('l')),
'timestamp' => $time->getTimeStamp(),
'formatted' => $time->format($this->get('calendar.format')),
'iso' => $time->format('Y-m-d\TH:i:sO'),
'label' => $this->get('days.' . strtolower($time->format('l'))),
));
$days[] = $object;
}
self::$cache['days'] = $days;
}
return self::$cache['days'];
}
There is where the theme generates the date? i don't know what to do.
I have had the same problem, maybe something like this will help you:
<?php
// Get the numeric representation of the current month
$m = date('n');
// Get a full textual representation of the month ( in norwegian )
if ($m==1) { $t = "Januar"; }
if ($m==2) { $t = "Februar"; }
if ($m==3) { $t = "Mars"; }
if ($m==4) { $t = "April"; }
if ($m==5) { $t = "Mai"; }
if ($m==6) { $t = "Juni"; }
if ($m==7) { $t = "Juli"; }
if ($m==8) { $t = "August"; }
if ($m==9) { $t = "September"; }
if ($m==10) { $t = "Oktober"; }
if ($m==11) { $t = "November"; }
if ($m==12) { $t = "Desember"; }
// Display the date
echo date('m').".".$t.".".date('Y'); // returns: 05.Mai.2016
?>

Symfony2 - Am I handling things in the correct place?

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.

Repeating output of an array

$timein_out = $this->time_model->get_timein_out($this->input->get('i'));
$total_diff= array();
$hours = array();
$mins =array();
foreach($timein_out as $timetest)
{
$total_diff[] = strtotime($timetest["Time_out"]) - strtotime($timetest["Time_in"]);
for($key=0;$key<count($total_diff);$key++)
{
$hours[] = intval(floor($total_diff[$key]/3600));
$mins[] = intval(($total_diff[$key]-$hours[$key]*3600)/60);
}
};
echo json_encode($total_diff); // output: [33600,34560,35160]
echo json_encode($hours); // [9,9,9,9,9,9]
echo json_encode($mins); //[20,20,36,20,36,46]
The actual output should be
echo json_encode($hours); // [9,9,9,]
echo json_encode($mins); //[20,36,46]
Question: Why is the output repeating? what is the problem in my code? :( thanks.
may be you want the inner loop outside. try this.
foreach($timein_out as $timetest)
{
$total_diff[] = strtotime($timetest["Time_out"]) - strtotime($timetest["Time_in"]);
}
for($key=0;$key<count($total_diff);$key++)
{
$hours[] = intval(floor($total_diff[$key]/3600));
$mins[] = intval(($total_diff[$key]-$hours[$key]*3600)/60);
}
may be try unset()'ting the $total_diff like:
foreach($timein_out as $timetest) {
$total_diff[] = strtotime($timetest["Time_out"]) - strtotime($timetest["Time_in"]);
for($key=0;$key<count($total_diff);$key++) {
$hours[] = intval(floor($total_diff[$key]/3600));
$mins[] = intval(($total_diff[$key]-$hours[$key]*3600)/60);
}
unset($total_diff);
}

PHP: How to use the Twitter API's data to convert URLs, mentions, and hastags in tweets to links?

I'm really stumped on how Twitter expects users of its API to convert the plaintext tweets it sends to properly linked HTML.
Here's the deal: Twitter's JSON API sends this set of information back when you request the detailed data for a tweet:
{
"created_at":"Wed Jul 18 01:03:31 +0000 2012",
"id":225395341250412544,
"id_str":"225395341250412544",
"text":"This is a test tweet. #boring #nbc http://t.co/LUfDreY6 #skronk #crux http://t.co/VpuMlaDs #twitter",
"source":"web",
"truncated":false,
"in_reply_to_status_id":null,
"in_reply_to_status_id_str":null,
"in_reply_to_user_id":null,
"in_reply_to_user_id_str":null,
"in_reply_to_screen_name":null,
"user": <REDACTED>,
"geo":null,
"coordinates":null,
"place":null,
"contributors":null,
"retweet_count":0,
"entities":{
"hashtags":[
{
"text":"boring",
"indices":[22,29]
},
{
"text":"skronk",
"indices":[56,63]
}
],
"urls":[
{
"url":"http://t.co/LUfDreY6",
"expanded_url":"http://www.twitter.com",
"display_url":"twitter.com",
"indices":[35,55]
},
{
"url":"http://t.co/VpuMlaDs",
"expanded_url":"http://www.example.com",
"display_url":"example.com",
"indices":[70,90]
}
],
"user_mentions":[
{
"screen_name":"nbc",
"name":"NBC",
"id":26585095,
"id_str":"26585095",
"indices":[30,34]
},
{
"screen_name":"crux",
"name":"Z. D. Smith",
"id":407213,
"id_str":"407213",
"indices":[64,69]
},
{
"screen_name":"twitter",
"name":"Twitter",
"id":783214,
"id_str":"783214",
"indices":[91,99]
}
]
},
"favorited":false,
"retweeted":false,
"possibly_sensitive":false
}
The interesting parts, for this question, are the text element and the entries in the hashtags, user_mentions, and urls arrays. Twitter is telling us where in the text element the hastags, mentions, and urls appear with the indices arrays... so here's the crux of the question:
How do you use those indices arrays?
You can't just use them straight up by looping over each link element with something like substr_replace, since replacing the first link element in the text will invalidate all the index values for subsequent link elements. You also can't use substr_replace's array functionality, since it only works when you give it an array of strings for the first arg, rather than a single string (I've tested this. The results are... strange).
Is there some function that can simultaneously replace multiple index-delimited substrings in a single string with different replacement strings?
All you have to do to use the indices twitter provides straight up with a simple replace is collect the replacements you want to make and then sort them backwards. You can probably find a more clever way to build $entities, I wanted them optional anyway, so I KISS as far as that went.
Either way, my point here was just to show that you don't need to explode the string and character count and whatnot. Regardless of how you do it, all you need to to is start at the end and work to the beginning of the string, and the index twitter has is still valid.
<?php
function json_tweet_text_to_HTML($tweet, $links=true, $users=true, $hashtags=true)
{
$return = $tweet->text;
$entities = array();
if($links && is_array($tweet->entities->urls))
{
foreach($tweet->entities->urls as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = "<a href='".$e->expanded_url."' target='_blank'>".$e->display_url."</a>";
$entities[] = $temp;
}
}
if($users && is_array($tweet->entities->user_mentions))
{
foreach($tweet->entities->user_mentions as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = "<a href='https://twitter.com/".$e->screen_name."' target='_blank'>#".$e->screen_name."</a>";
$entities[] = $temp;
}
}
if($hashtags && is_array($tweet->entities->hashtags))
{
foreach($tweet->entities->hashtags as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = "<a href='https://twitter.com/hashtag/".$e->text."?src=hash' target='_blank'>#".$e->text."</a>";
$entities[] = $temp;
}
}
usort($entities, function($a,$b){return($b["start"]-$a["start"]);});
foreach($entities as $item)
{
$return = substr_replace($return, $item["replacement"], $item["start"], $item["end"] - $item["start"]);
}
return($return);
}
?>
Ok so I needed to do exactly this and I solved it. Here is the function I wrote. https://gist.github.com/3337428
function parse_message( &$tweet ) {
if ( !empty($tweet['entities']) ) {
$replace_index = array();
$append = array();
$text = $tweet['text'];
foreach ($tweet['entities'] as $area => $items) {
$prefix = false;
$display = false;
switch ( $area ) {
case 'hashtags':
$find = 'text';
$prefix = '#';
$url = 'https://twitter.com/search/?src=hash&q=%23';
break;
case 'user_mentions':
$find = 'screen_name';
$prefix = '#';
$url = 'https://twitter.com/';
break;
case 'media':
$display = 'media_url_https';
$href = 'media_url_https';
$size = 'small';
break;
case 'urls':
$find = 'url';
$display = 'display_url';
$url = "expanded_url";
break;
default: break;
}
foreach ($items as $item) {
if ( $area == 'media' ) {
// We can display images at the end of the tweet but sizing needs to added all the way to the top.
// $append[$item->$display] = "<img src=\"{$item->$href}:$size\" />";
}else{
$msg = $display ? $prefix.$item->$display : $prefix.$item->$find;
$replace = $prefix.$item->$find;
$href = isset($item->$url) ? $item->$url : $url;
if (!(strpos($href, 'http') === 0)) $href = "http://".$href;
if ( $prefix ) $href .= $item->$find;
$with = "$msg";
$replace_index[$replace] = $with;
}
}
}
foreach ($replace_index as $replace => $with) $tweet['text'] = str_replace($replace,$with,$tweet['text']);
foreach ($append as $add) $tweet['text'] .= $add;
}
}
It's an edge case but the use of str_replace() in Styledev's answer could cause issues if one entity is contained within another. For example, "I'm a genius! #me #mensa" could become "I'm a genius! #me #mensa" if the shorter entity is substituted first.
This solution avoids that problem:
<?php
/**
* Hyperlinks hashtags, twitter names, and urls within the text of a tweet
*
* #param object $apiResponseTweetObject A json_decoded() one of these: https://dev.twitter.com/docs/platform-objects/tweets
* #return string The tweet's text with hyperlinks added
*/
function linkEntitiesWithinText($apiResponseTweetObject) {
// Convert tweet text to array of one-character strings
// $characters = str_split($apiResponseTweetObject->text);
$characters = preg_split('//u', $apiResponseTweetObject->text, null, PREG_SPLIT_NO_EMPTY);
// Insert starting and closing link tags at indices...
// ... for #user_mentions
foreach ($apiResponseTweetObject->entities->user_mentions as $entity) {
$link = "https://twitter.com/" . $entity->screen_name;
$characters[$entity->indices[0]] = "<a href=\"$link\">" . $characters[$entity->indices[0]];
$characters[$entity->indices[1] - 1] .= "</a>";
}
// ... for #hashtags
foreach ($apiResponseTweetObject->entities->hashtags as $entity) {
$link = "https://twitter.com/search?q=%23" . $entity->text;
$characters[$entity->indices[0]] = "<a href=\"$link\">" . $characters[$entity->indices[0]];
$characters[$entity->indices[1] - 1] .= "</a>";
}
// ... for http://urls
foreach ($apiResponseTweetObject->entities->urls as $entity) {
$link = $entity->expanded_url;
$characters[$entity->indices[0]] = "<a href=\"$link\">" . $characters[$entity->indices[0]];
$characters[$entity->indices[1] - 1] .= "</a>";
}
// ... for media
foreach ($apiResponseTweetObject->entities->media as $entity) {
$link = $entity->expanded_url;
$characters[$entity->indices[0]] = "<a href=\"$link\">" . $characters[$entity->indices[0]];
$characters[$entity->indices[1] - 1] .= "</a>";
}
// Convert array back to string
return implode('', $characters);
}
?>
Jeff's solution worked well with English text but it got broken when the tweet contained non-ASCII characters. This solution avoids that problem:
mb_internal_encoding("UTF-8");
// Return hyperlinked tweet text from json_decoded status object:
function MakeStatusLinks($status)
{$TextLength=mb_strlen($status['text']); // Number of UTF-8 characters in plain tweet.
for ($i=0;$i<$TextLength;$i++)
{$ch=mb_substr($status['text'],$i,1); if ($ch<>"\n") $ChAr[]=$ch; else $ChAr[]="\n<br/>"; // Keep new lines in HTML tweet.
}
if (isset($status['entities']['user_mentions']))
foreach ($status['entities']['user_mentions'] as $entity)
{$ChAr[$entity['indices'][0]] = "<a href='https://twitter.com/".$entity['screen_name']."'>".$ChAr[$entity['indices'][0]];
$ChAr[$entity['indices'][1]-1].="</a>";
}
if (isset($status['entities']['hashtags']))
foreach ($status['entities']['hashtags'] as $entity)
{$ChAr[$entity['indices'][0]] = "<a href='https://twitter.com/search?q=%23".$entity['text']."'>".$ChAr[$entity['indices'][0]];
$ChAr[$entity['indices'][1]-1] .= "</a>";
}
if (isset($status['entities']['urls']))
foreach ($status['entities']['urls'] as $entity)
{$ChAr[$entity['indices'][0]] = "<a href='".$entity['expanded_url']."'>".$entity['display_url']."</a>";
for ($i=$entity['indices'][0]+1;$i<$entity['indices'][1];$i++) $ChAr[$i]='';
}
if (isset($status['entities']['media']))
foreach ($status['entities']['media'] as $entity)
{$ChAr[$entity['indices'][0]] = "<a href='".$entity['expanded_url']."'>".$entity['display_url']."</a>";
for ($i=$entity['indices'][0]+1;$i<$entity['indices'][1];$i++) $ChAr[$i]='';
}
return implode('', $ChAr); // HTML tweet.
}
Here is an updated answer that works with Twitter's new Extended Mode. It combines the answer by #vita10gy and the comment by #Hugo (to make it utf8 compatible), with a few minor tweaks to work with the new api values.
function utf8_substr_replace($original, $replacement, $position, $length) {
$startString = mb_substr($original, 0, $position, "UTF-8");
$endString = mb_substr($original, $position + $length, mb_strlen($original), "UTF-8");
$out = $startString . $replacement . $endString;
return $out;
}
function json_tweet_text_to_HTML($tweet, $links=true, $users=true, $hashtags=true) {
// Media urls can show up on the end of the full_text tweet, but twitter doesn't index that url.
// The display_text_range indexes show the actual tweet text length.
// Cut the string off at the end to get rid of this unindexed url.
$return = mb_substr($tweet->full_text, $tweet->display_text_range[0],$tweet->display_text_range[1]);
$entities = array();
if($links && is_array($tweet->entities->urls))
{
foreach($tweet->entities->urls as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = " <a href='".$e->expanded_url."' target='_blank'>".$e->display_url."</a>";
$entities[] = $temp;
}
}
if($users && is_array($tweet->entities->user_mentions))
{
foreach($tweet->entities->user_mentions as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = " <a href='https://twitter.com/".$e->screen_name."' target='_blank'>#".$e->screen_name."</a>";
$entities[] = $temp;
}
}
if($hashtags && is_array($tweet->entities->hashtags))
{
foreach($tweet->entities->hashtags as $e)
{
$temp["start"] = $e->indices[0];
$temp["end"] = $e->indices[1];
$temp["replacement"] = " <a href='https://twitter.com/hashtag/".$e->text."?src=hash' target='_blank'>#".$e->text."</a>";
$entities[] = $temp;
}
}
usort($entities, function($a,$b){return($b["start"]-$a["start"]);});
foreach($entities as $item)
{
$return = utf8_substr_replace($return, $item["replacement"], $item["start"], $item["end"] - $item["start"]);
}
return($return);
}
Here is a JavaScript version (using jQuery) of vita10gy's solution
function tweetTextToHtml(tweet, links, users, hashtags) {
if (typeof(links)==='undefined') { links = true; }
if (typeof(users)==='undefined') { users = true; }
if (typeof(hashtags)==='undefined') { hashtags = true; }
var returnStr = tweet.text;
var entitiesArray = [];
if(links && tweet.entities.urls.length > 0) {
jQuery.each(tweet.entities.urls, function() {
var temp1 = {};
temp1.start = this.indices[0];
temp1.end = this.indices[1];
temp1.replacement = '' + this.display_url + '';
entitiesArray.push(temp1);
});
}
if(users && tweet.entities.user_mentions.length > 0) {
jQuery.each(tweet.entities.user_mentions, function() {
var temp2 = {};
temp2.start = this.indices[0];
temp2.end = this.indices[1];
temp2.replacement = '#' + this.screen_name + '';
entitiesArray.push(temp2);
});
}
if(hashtags && tweet.entities.hashtags.length > 0) {
jQuery.each(tweet.entities.hashtags, function() {
var temp3 = {};
temp3.start = this.indices[0];
temp3.end = this.indices[1];
temp3.replacement = '#' + this.text + '';
entitiesArray.push(temp3);
});
}
entitiesArray.sort(function(a, b) {return b.start - a.start;});
jQuery.each(entitiesArray, function() {
returnStr = substrReplace(returnStr, this.replacement, this.start, this.end - this.start);
});
return returnStr;
}
You can then use this function like so ...
for(var i in tweetsJsonObj) {
var tweet = tweetsJsonObj[i];
var htmlTweetText = tweetTextToHtml(tweet);
// Do something with the formatted tweet here ...
}
Regarding vita10gy's helpful json_tweet_text_to_HTML(), I found a tweet that it could not format correctly: 626125868247552000.
This tweet has a nonbreaking space in it. My solution was to replace the first line of the function with the following:
$return = str_replace("\xC2\xA0", ' ', $tweet->text);
Performing a str_replace() on is covered here.

PHP Undefined index error. How to fix? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP: “Notice: Undefined variable” and “Notice: Undefined index”
I am getting this notice:
PHP Notice: Undefined index: votefor in /home/.../savevote.php on line 2
How can I fix this?
Here is my line 2 in savevote.php:
<?php
$votefor = $_REQUEST["votefor"];
Thank you
Here is the code:
<?php
$votefor = $_REQUEST["votefor"];
// Returns a random RGB color (used to color the vote bars)
function getRandomColor()
{
$r = rand(128,255);
$g = rand(128,255);
$b = rand(128,255);
$color = dechex($r) . dechex($g) . dechex($b);
echo "$color";
}
//Get the IP of the user
$domain = $_SERVER["REMOTE_ADDR"];
$today = date("m/d/Y");
echo "<table id=\"tblResults\" align=\"center\">";
//If votefor is null, then we're just viewing results, so don't log the IP
if ($votefor != "")
{
//Load the addresses XML file
$doc = new DOMDocument();
$doc->load("../vote_dir/xml/addresses.xml");
$addresses = $doc->getElementsByTagName("address");
$pVoted = false;
$pFound = false;
//Loop through the addresses nodes and see if the person has voted before
foreach( $addresses as $address )
{
$lastvisits = $address->getElementsByTagName("lastvisit");
$lastvisit = $lastvisits->item(0)->nodeValue;
$ips = $address->getElementsByTagName("ip");
$ip = $ips->item(0)->nodeValue;
if ($ip == $domain)
{
$pFound = true;
if ($lastvisit == $today)
$pVoted = true;
else
{
$lastvisits->item(0)->nodeValue = $today;
$doc->save("../vote_dir/xml/addresses.xml");
}
break;
}
else
continue;
}
if ($pVoted == true) //Already voted
{
echo "<tr><td colspan=\"3\" class=\"message\">Έχετε ήδη ψηφίσει!</td></tr>";
}
else //Update the XML files
{
if ($pFound == false) //Add new node for IP and date to addresses.xml
{
echo "<tr><td colspan=\"3\" class=\"message\">Ευχαριστούμε που ψηφίσατε!</td></tr>";
$newAddy = $doc->getElementsByTagName('addresses')->item(0);
$newAddressElement = $doc->createElement('address');
$newLastVisitElement = $doc->createElement('lastvisit');
$newAddressElement->appendChild($newLastVisitElement);
$newIPElement = $doc->createElement('ip');
$newAddressElement->appendChild($newIPElement);
$dayvalue = $doc->createTextNode($today);
$dayvalue = $newLastVisitElement->appendChild($dayvalue);
$ipvalue = $doc->createTextNode($domain);
$ipvalue = $newIPElement->appendChild($ipvalue);
$newAddy->appendChild($newAddressElement);
$doc->save("../vote_dir/xml/addresses.xml");
}
else
{
echo "<tr><td colspan=\"3\" class=\"message\">Ευχαριστούμε για την ψήφο σας.</td></tr>";
}
// Update the vote
$doc = new DOMDocument();
$doc->load("../vote_dir/xml/results.xml");
$pollitems = $doc->getElementsByTagName("pollitem");
foreach( $pollitems as $pollitem )
{
$entries = $pollitem->getElementsByTagName("entryname");
$entry = $entries->item(0)->nodeValue;
if ($entry == $votefor)
{
$votes = $pollitem->getElementsByTagName("votes");
$count = $votes->item(0)->nodeValue;
$votes->item(0)->nodeValue = $count + 1;
break;
}
}
$doc->save("../vote_dir/xml/results.xml");
}
}
else
{
echo "<tr><td colspan=\"3\" class=\"message\">Αποτελέσματα Ψηφοφορίας Μέχρι Στιγμής</td></tr>";
}
// Get max vote count
$doc = new DOMDocument();
$doc->load("../vote_dir/xml/results.xml");
$maxvotes = 0;
$pollitems = $doc->getElementsByTagName("pollitem");
foreach( $pollitems as $pollitem )
{
$votes = $pollitem->getElementsByTagName("votes");
$vote = $votes->item(0)->nodeValue;
$maxvotes = $maxvotes + $vote;
}
// Generate the results table
$doc = new DOMDocument();
$doc->load("../vote_dir/xml/results.xml");
$pollitems = $doc->getElementsByTagName("pollitem");
foreach( $pollitems as $pollitem )
{
$entries = $pollitem->getElementsByTagName("entryname");
$entry = $entries->item(0)->nodeValue;
$votes = $pollitem->getElementsByTagName("votes");
$vote = $votes->item(0)->nodeValue;
$tempWidth = $vote / $maxvotes;
$tempWidth = 300 * $tempWidth;
$votepct = round(($vote / $maxvotes) * 100);
echo "<tr><td width=\"20%\" class=\"polls\">$entry</td>";
echo "<td width=\"30%\" class=\"resultbar\"><div class=\"bar\" style=\"background-color: ";
getRandomColor();
echo "; width: $tempWidth px;\">$votepct%</div></td><td width=\"20%\">($vote votes)</td></tr>";
}
echo "<tr><td class=\"total\" colspan=\"3\">$maxvotes άτομα ψήφισαν μέχρι τώρα.</td>";
echo "</table>";
?>
#Brian
<script language="javascript">
function setVote(voteName)
{
document.getElementById("votefor").value = voteName;
}
function confirmSubmit()
{
if (document.getElementById("votefor").value == "")
{
var agree=confirm("Παρακαλώ επιλέξτε μια απάντηση, για να ψηφίσετε");
return false;
}
}
</script>
The request parameter isn't being passed. If you know why it might be missing and just want to prevent the notice, you can say:
$votefor = isset( $_REQUEST["votefor"] ) ? $_REQUEST["votefor"] : null;
It is not safe to use $_REQUEST because it can be $_GET or $_POST, better is specify which you want.
At second you need to check if the array key exists. This can officially be done with array_key_exists(). But unfortunately this function is a little bit slow. You can replace it by using the isset() function, but this says a null value is not set and returns false when it is null. The best approach is to use them both, first the isset and then the array_key_exists:
<?php
if (isset($_POST['votefor']) || array_key_exists($_POST['votefor'])) {
// do something
}
?>
Or use only isset if you are sure the value won't be null.
If you are almost 100% sure the index votefor exists in the array you need to debug it. var_dump the $_REQUEST array to see which items (and indexes) are in there and look what you did wrong.
1/ Check you have a request parameter named votefor
2/ Check you didn't misspelt it
Handle it like so:
if(array_key_exists("votefor", $_REQUEST)) {
...
}
You may ignore notice reports by setting error_reporting no to show them
error_reporting(E_ALL & ~E_NOTICE);

Categories