Twitter RSS feed, [domdocument.load]: failed to open stream: - dom

i'm using the following:
<?php
$doc = new DOMDocument();
$doc->load('http://twitter.com/statuses/user_timeline/XXXXXX.rss');
$arrFeeds = array();
foreach ($doc->getElementsByTagName('item') as $node) {
$itemRSS = array (
'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue
);
array_push($arrFeeds, $itemRSS);
}
for($i=0;$i<=3;$i++) {
$tweet=substr($arrFeeds[$i]['title'],17);
$tweetDate=strtotime($arrFeeds[$i]['date']);
$newDate=date('G:ia l F Y ',$tweetDate);
if($i==0) { $b='style="border:none;"'; }
$tweetsBox.='<div class="tweetbox" ' . $b . '>
<div class="tweet"><p>' . $tweet . '</p>
<div class="tweetdate">#' . $newDate .'</div>
</div>
</div>';
}
return $tweetsBox;
?>
to return the 4 most recent tweets from a given timeline (XXXXX is the relevant feed)
It seems to work fine but i've recently been getting the following error sporadically:
PHP error debug
Error: DOMDocument::load(http://twitter.com/statuses/user_timeline/XXXXXX.rss) [domdocument.load]: failed to open stream: HTTP request failed! HTTP/1.1 502 Bad Gateway
I've read that the above code is dependant on Twitter beign available and I know it gets rather busy sometimes. Is there either a better way of receiving twits, or is there any kind of error trapping i could do to just to display "tweets are currently unavailable..." ind of message rather than causing an error. I'm usnig ModX CMS so any parse error kills the site rather than just ouputs a warning.
thanks.

I know this is old, but I was just searching for the same solution for a nearly identical script for grabbing a twitter timeline. I ended up doing this, though I haven't been able to thoroughly test it.
I defined the twitter url as a variable ($feedURL), which I also used in $doc_load. Then, I wrapped everything except for the $feedURL into this conditional statement:
$feedURL = "http://twitter.com/statuses/user_timeline/XXXXXXXX.rss"
$headers = #get_headers($feedURL);
if (preg_match("/200/", $headers[0])){
//the rest of you original code in here
}
else echo "Can't connect user-friendly message (or a fake tweet)";
So, it's just checking the headers of the the feed's page, and if its status is 200 (OK), then the rest of the script will execute. Otherwise, it'll echo a message of your choice.
(reference: http://www.phptalk.com/forum/topic/3940-how-to-check-if-an-external-url-is-valid-andor-get-file-size/ )
ETA: Or even better, save a cached version of the feed (which will also ensure you don't go over your API limit of loads):
<?php
$cache_file = dirname(__FILE__).'/cache/twitter_cache.rss';
// Start with the cache
if(file_exists($cache_file)){
$mtime = (strtotime("now") - filemtime($cache_file));
if($mtime > 600) {
$cache_rss = file_get_contents('http://twitter.com/statuses/user_timeline/75168146.rss');
$cache_static = fopen($cache_file, 'wb');
fwrite($cache_static, $cache_rss);
fclose($cache_static);
}
echo "<!-- twitter cache generated ".date('Y-m-d h:i:s', filemtime($cache_file))." -->";
}
else {
$cache_rss = file_get_contents('http://twitter.com/statuses/user_timeline/75168146.rss');
$cache_static = fopen($cache_file, 'wb');
fwrite($cache_static, $cache_rss);
fclose($cache_static);
}
//End of caching
?>
Then use $cache_file in your $doc->load($cache_file) statement instead of the actual feed url.
(Adapted from here: http://snipplr.com/view/8156/twitter-cache/).

Related

dompdf form not working properly in secure server (ssl)

I created a form using dompdf and when I uploaded it to the regular server the website belongs to, it worked fine. However, when I moved it to a secure server (ssl) it didn't work and didn't send the form. The server runs Linux. The webserver is Nginx with FastCGI. Any ideas about what could be going on? I just get an error message from the form saying that not all the mandatory fields have been filled, but there's only two and I filled them.
2015/09/10 22:07:35 [error] 14522#0: *1509 FastCGI sent in stderr: "PHP
message: PHP Warning: strip_tags() expects parameter 1 to be string,
array given in
/var/www/nuweights.net/html/patient_registration_form/form.php on line 13
PHP message: PHP Warning: strip_tags() expects parameter 1 to be
string, array given in
/var/www/nuweights.net/html/patient_registration_form/form.php on line 13
PHP message: PHP Notice: Undefined property: stdClass::$prim_phone in
/var/www/nuweights.net/html/patient_registration_form/pdf.php on line
180" while reading response header from upstream, client: 72.83.230.123,
server: nuweights.net, request: "POST
/patient_registration_form/form.php HTTP/1.1", upstream:
"fastcgi://unix:/var/run/php5-fpm.sock:", host: "ssl.nuweights.net",
referrer: "https://ssl.nuweights.net/patient_registration_form/form.php"
This is the code for the php file. If I need more validation, how can I add it? what would be the code for that?
<?php
if (!empty($_POST)) {
// Used for later to determine result
$success = $error = false;
// Object syntax looks better and is easier to use than arrays to me
$post = new stdClass;
// Usually there would be much more validation and filtering, but this
// will work for now.
foreach ($_POST as $key => $val)
$post->$key = trim(strip_tags($_POST[$key]));
// Check for blank fields
if (empty($post->first_name) OR empty($post->last_name))
$error = true;
else {
// Get this directory, to include other files from
$dir = dirname(__FILE__);
// Get the contents of the pdf into a variable for later
ob_start();
require_once($dir.'/pdf.php');
$pdf_html = ob_get_contents();
ob_end_clean();
// Load the dompdf files
require_once($dir.'/dompdf/dompdf_config.inc.php');
$dompdf = new DOMPDF(); // Create new instance of dompdf
$dompdf->load_html($pdf_html); // Load the html
$dompdf->render(); // Parse the html, convert to PDF
$pdf_content = $dompdf->output(); // Put contents of pdf into variable for later
// Get the contents of the HTML email into a variable for later
ob_start();
require_once($dir.'/html.php');
$html_message = ob_get_contents();
ob_end_clean();
// Load the SwiftMailer files
require_once($dir.'/swift/swift_required.php');
$mailer = new Swift_Mailer(new Swift_MailTransport()); // Create new instance of SwiftMailer
$message = Swift_Message::newInstance()
->setSubject('Patient Registration Form') // Message subject
->setTo(array('info#hotmail.com' => 'Sam')) // Array of people to send to
->setFrom(array('no-reply#net.tutsplus.com' => 'PRF')) // From:
->setBody($html_message, 'text/html') // Attach that HTML message from earlier
->attach(Swift_Attachment::newInstance($pdf_content, 'reg_form.pdf', 'application/pdf')); // Attach the generated PDF from earlier
// Send the email, and show user message
if ($mailer->send($message))
$success = true;
else
$error = true;
}
}
?>
Your secure server is separate from your non-secure one, correct? It looks like maybe display_errors (in the PHP configuration) is set to "on" for the secure server. Because of this you're seeing messages from PHP related to code notices and errors. Unless you're on a dev server you should pretty much always disable that setting to avoid information disclosure.
Before you worry about what dompdf is doing you should address the configuration issues and add some exception handling and/or validation to your code.
Some thoughts on what you've posted.
You're generally validating without regard to the data type in your foreach loop. You should at least check whether the variable is parseable by strip_slashes(), e.g.:
foreach ($_POST as $key => $val) {
if (is_array($_POST[$key])) {
// assuming this is an array of values
$post->$key = array_map('trim', array_map('strip_slashes', $_POST[$key]));
}
else
{
$post->$key = trim(strip_tags($_POST[$key]));
}
}
2 - You're trying to validate properties that may or may not exist on your object. Since you're not making any definite assignments you need to check that these properties even exist before you validate against them:
if (!property_exists($post, 'first_name') || !property_exists($post, 'last_name') || empty($post->first_name) || empty($post->last_name))
{
$error = true;
}
3 - Why are you assigning properties to a generic object in the first place? If you want to use an object you should probably go ahead and define the class so that you can populate and validate the values during instantiation. If you don't want to do that assign them to variables so you know, really know, what data you have. If you want to short-cut it you could do something like this (or write your own):
$first_name = filter_var($_POST['first_name'], FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE);
To simplify this for a large number of you could even set up an array of expected params and parse that array to set your values:
$post = array();
foreach (array('first_name','last_name') as $key)
{
$post[$key] = filter_var($_POST[$key], FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE);
}
4 - Use curly braces for clarity ... always
You might want to take this over to https://codereview.stackexchange.com/ to get a more thorough critique.

Instagram Real-time API duplicate requests

I have an issue where when I create a real-time subscription I get duplicate notifications from different Instagram IP addresses. I have it set up so that when I get a notification, I send a request for latest updates using the min_tag_id setting. I store that in my db to use it for the next request. I don't always get duplicates, but when I do, everything about the notification is the same (time, object,changed_aspect), except I can tell they are different from my debugging output which lists two almost identical requests... the only differing info being a different IP address and the REQUEST_TIME_FLOAT is different by about 1/10th of a second. They even have the same HTTP_X_HUB_SIGNATURE value.
My general algorithm is:
process_subscription_update($data){
# get old min_id
$min_tag_id = mysqli_fetch_object(mysqli_query($dbconnecti,sprintf("SELECT instagram_min_id+0 as instaid FROM xxxx WHERE xxxx=%d",$_GET['xxxx'])));
$min_id = $min_tag_id->instaid;
# make api call
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, 'https://api.instagram.com/v1/tags/'.$_GET['tag'].'/media/recent?client_id=xxxx&min_tag_id='.$min_id.($min_id==0?'&count=1':''));
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$result = curl_exec($ch);
curl_close($ch);
$i = json_decode($result);
if ($min_id == $i->pagination->min_tag_id) { exit; }
# write new min_id to db
record_min_id($i->pagination->min_tag_id);
$data2 = $i->data;
foreach($data2 as $d) {
process_instagram($d);
}
// debugging output: ****************
$file = file_get_contents($_SERVER['DOCUMENT_ROOT'].'instagram/updates.txt');
$foo = "\n";
foreach($_SERVER as $key_name => $key_value) {
$foo .= $key_name . " = " . $key_value . "\n";
}
$fulldata = $file . "\n\n\n" . $result . "\n min_id = " . $min_id . $foo;
$fulldata .= "\nTIME:".$data[0]->time;
$fulldata .= "\nOBJECT:".$data[0]->object;
$fulldata .= "\nCHANGED_ASPECT:".$data[0]->changed_aspect;
file_put_contents($_SERVER['DOCUMENT_ROOT'].'instagram/updates.txt', $fulldata);
// end debugging output *************
}
I'd like to avoid checking if the instagram message id already exists in my db within the process_instagram function, and with the duplicates only coming 1/10th of a second apart, I don't know if that would work anyway.
Anybody else experience this and/or have a solution?
I solved this. I don't think there is anything I can do about receiving the duplicate notifications. So, when writing the Instagram to my db, I have a field for the Instagram id and put a unique constraint on the field. After doing the mysqli INSERT, I check to see if the errno = 1062, and if it does, I exit.
mysqli_query($dbconnecti,"INSERT INTO xxx (foo, etc, instagram_id ...")
if ($dbconnecti->errno==1062) { exit; }
...
// more script runs here if we don't have a duplicate.

php form processing issue when processing script returns to the calling script

Problem:
form processing script throws error when returning back to the calling script which is the user entry form.
error message
Notice: A session had already been started - ignoring session_start() in /inc/utilities.inc.php on line 3 Fatal error: Cannot redeclare class Connection in /inc/dbconn.php on line 5
The code is a bit too large to copy past all of it so im just going to focus on the problem area.
newproject.php calls -> savenewproject.php. if savenewproject.php finds error it returns back to newproject.php to display error message.
//newproject.php - parts of the code that i believe is the problem area.
<?php
include('../inc/utilities.inc.php');
include('header.php');
if (!empty($errorString))
{ echo '<div class="error">' . $errorString . '</div>'; }
if (!empty($successString))
{ $emailaddress = '';
$budget = '';
$projecttitle ='';
$projectdescription = '';
echo '<div id="divfadeout" class="success">' . $successString . '</div>';
}
?>
<form name ='newProject' action="../inc/savenewproject.php" enctype="multipart/form-data" method="POST">
the rest are form fields
</form>
// include('../inc/utilities.inc.php'); - appears in both script
<?php
session_start();
$user = (isset($_SESSION['user'])) ? $_SESSION['user']: null;
include("../inc/dbconn.php");
?>
// savenewproject.php - copy/pasting what i believed to be the problem area.
if(count($fieldErrors) > 0)
{ $errorString = '<p>There was an error processing the form.</p>';
$errorString . 'ul>';
foreach($fieldErrors as $errorVal)
{ $errorString .= "<li>$errorVal</li>"; }
$errorString .= '</ul>';
include ('../layout/newproject.php');
}
else
{
looks like i answered my own question..
instead of include i used request once and it seems to have fixed the probelm..

CodeIgniter: Cannot redirect after $this->email->send()

i have the following code which sends an email from a posted form:
$this->load->library('email');
$config['charset'] = 'iso-8859-1';
$config['mailtype'] = 'html';
$this->email->initialize($config);
$this->email->from('info#mysite.com', 'Scarabee');
$this->email->to('info#mysite.com');
$this->email->subject('Message via website');
$data['msg'] = nl2br($this->input->post('msg'));
$data['msg'] .= '<br><br><b>Verstuurd door:</b><br>';
if($this->input->post('bedrijf')){
$data['msg'] .= $this->input->post('bedrijf').'<br>';
}
$data['msg'] .= $this->input->post('naam').'<br>';
$data['msg'] .= $this->input->post('adres').' - '.$this->input->post('postcode').', '.$this->input->post('gemeente').'<br>';
$data['msg'] .= $this->input->post('tel').'<br>';
$data['msg'] .= $this->input->post('email');
$message = $this->load->view('email', $data, TRUE);
$this->email->message($message);
if($this->email->send()){
$success = 'Message has been sent';
$this->session->set_flashdata('msg', $success);
redirect('contact/'.$this->input->post('lang'));
}
else{
show_error('Email could not be sent.');
}
Problem: the email gets sent with proper formatting (from the email view template), but the page then goes blank. For instance, if I try to echo out $message just below the $this->email->send() call, nothing shows up. Redirecting, as I’m attempting above, obviously doesn’t work either. Am I missing something? Thanks for any help…
Update
Traced the problem down to a function inside /system/libraries/Email.php (CI's default email library). Commenting out the code inside this function allows the mail to get sent, as well as a proper redirect:
protected function _set_error_message($msg, $val = '')
{
$CI =& get_instance();
$CI->lang->load('email');
if (substr($msg, 0, 5) != 'lang:' || FALSE === ($line = $CI->lang->line(substr($msg, 5))))
{
$this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
}
else
{
$this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
}
}
The line that caused the error is: $CI->lang->load('email');
Go figure...
UPDATE 2: SOLVED
I had this in my controller's construct:
function __construct() {
parent::__construct();
$this->lang = $this->uri->segment(2, 'nl');
}
I guess there was a conflict between $this->lang and the _set_error_message function which also returns a "lang" variable (see var_dump further down).
Solution: changed $this->lang to $this->language, and everything's hunky dory!
Thought I'd post the answer here in case anyone else is ever losing hair with a similar problem :-)
It's likely that an error is occurring when you attempt to send an e-mail which is then killing your script during execution. Check your apache and PHP error logs ( /var/log/apache/ ) and enable full error reporting.
You could, for debugging purposes, try doing this:
...
$this->email->message($message);
$this->email->send();
redirect('contact/'.$this->input->post('lang'));
This should redirect you, regardless of your mail being sent or not (if you still recieve it, you can assume that the redirect would be the next thing that happens).
My own solution looks like this:
...
if ( $this->email->send() )
{
log_message('debug', 'mail library sent mail');
redirect('contact/thankyou');
exit;
}
log_message('error', 'mail library failed to send');
show_error('E-mail could not be send');
$ref2 = $this->input->server('HTTP_REFERER', TRUE);
redirect($ref);
By using the above code you can redirect to the current page itself
and you can set your flash message above the redirect function.

Triggering conversion tracking code on form submit

I have a PHP form that mail()s the form data on submit and then if successful returns them to the referring page (in other words keeping them on the same page as the form) and appends ?success=TRUE to the URL.
The question is, how would I implement the AdWords and Yahoo Search Marketing conversion code snippets to trigger only when the form is submitted? For functionality purposes, it is unfortunately not feasible to send them to another page on submit which would have been the easiest way to do it.
The relevant code from the form submit action that mails the results and sends them back to the homepage is below. I have a hunch it might be as simple as outputting the conversion tracking code snippets in the if statement at the end there but I'm not sure if that is correct or the syntax to properly do that.
if ( isset($_POST['sendContactEmail']) )
{
$fname = $_POST['posFName'];
$lname = $_POST['posLName'];
$phone = $_POST['posPhone'];
$email = $_POST['posEmail'];
$note = $_POST['posText'];
$to = $yourEmail;
$subject = $yourSubject;
$message = "From: $fname $lname\n\n Phone: $phone\n\n Email: $email\n\n Note: $note";
$headers = "From: ".cleanPosUrl($_POST['posFName']. " " .$_POST['posLName'])." \r\n";
$headers .= 'To: '.$yourName.' '."\r\n";
$mailit = mail($to,$subject,$message,$headers);
if ( #$mailit ) {
header('Location: '.$referringPage.'?success=true');
}
else {
header('Location: '.$referringPage.'?error=true');
}
}
Outputting it in the if-Statement would be a possibility, but the script you posted adds another way to do it as it redirects to the $referringPage - if the mail was successfully sent. And that's the only event you want to track a conversion.
So edit the code of $referringPage (the page that holds the form fields) and add:
<?php
if($_GET['success'] == 'true') {
echo "...";
}
?>
"..." ofcourse has to be replaced by the Adwords conversion Code Google gave you.
If you add it to your question, I could even add it to my answer.