[eluser]jpcody[/eluser]
I'm still getting undefined variable errors, as well as a new "missing argument" error. I was able to remove the "Missing argument" error by inserting the tweet as an argument from the controller method instead of the model method, like such:
Code: <?php
class Feed extends Controller {
function index()
{
$this->load->model('Twitter_model');
$tweet = $this->Twitter_model->get_tweet();
$this->Twitter_model->insert_tweet($tweet);
}
}
So up until this point, I have loaded the model and run the get_tweet method from Twitter_model, which is as follows:
Code: function get_tweet(){
$tweet = $this->twitter->auth('user','pass');
return $this->twitter->user_timeline('jpcody',10);
}
This simply authenticates me, returns the past X status updates from user Y. And then this is stored, by the controller, in the $tweet variable. (I don't understand why the $tweet variable is necessary within the method to store the user authentication information, but it was necessary in my tests of simply returning the timeline arrays. Are my naming conventions causing a problem?)
Next, my controller runs insert_tweet($tweet), which I believe, should take the value stored in $tweet in the line above and insert it into the auto-loaded database using the following:
Code: function insert_tweet(){
foreach($tweet as $t) {
$messages = array(
'user' => $t->user->name ,
'pic' => $t->user->profile_image_url ,
'time' => $t->user->created_at ,
'tweet' => $t->text
);
}
$this->db->insert('updates', $messages);
}
Which says for each $tweet returned (Or is it saying for the whole chunk of 10?), access $tweet with $t, store the messages in an array with the variables as assigned, and then insert them all into the "updates" table.
I'm still getting "Undefined variable" errors on the $tweet value in the foreach line (which also triggers an invalid foreach) as well as an undefined $messages variable on the insertion line.
Am I writing sloppy code here or practicing poor naming conventions that are messing me up? Or am I doing something different wrong?
I can't thank you enough for guiding me through this process so far. I hope the information I'm picking me up will mean less questions in the future
[eluser]jedd[/eluser]
[quote author="jpcody" date="1253063799"]
I'm still getting "Undefined variable" errors on the $tweet value in the foreach line (which also triggers an invalid foreach) as well as an undefined $messages variable on the insertion line.
[/quote]
Instead of what you have:
Code: function insert_tweet(){
foreach($tweet as $t) {
$messages = array(
...
Try this instead:
Code: function insert_tweet ($tweet ) {
foreach($tweet as $t) {
$messages = array(
...
[eluser]jpcody[/eluser]
Thanks so much!
When I insert $tweet both in the controller method and the model method, I get a blank page with no errors, and my info is inserted into the database. I don't really understand why I do this though.
I understand that I define $tweet as the returned status update, and I pass it as an argument of the method insert_tweet in the controller, but why do I have to pass it as an argument again within the model?
I think this is about to get more complicated than I anticipated in the beginning.
• This is only returning one result into the database rather than the full array of the last 10.
• Next, I need to update this to take an input of multiple users.
• Do I need to set a specific time interval to cache the data in accordance with Twitter's rate limits? Or can it update automatically on refresh?
• I need to stop the caching of duplicate data into the database.
• Finally, I will display the data sorted by created_at, which I will need to modify to a more user-friendly timestamp.
I trust I'll be back for more help.
Update:
Yep, looks like I hit trouble on the first bullet point. This could be a long road ahead.
So it seems I've been returning data into the view at $data['tweets'] then accessing it within the view as foreach $tweet as $t. This worked lovely, and when I ran an is_array, it came back affirmative, and I could print_r the entire contents of the array to go in and get them, returning values for all 10 instances in the array.
The following code renders me 8 errors, 2 per line, that I am trying to get the property of a non-object in my model array.
Code: <?php
class Feed extends Controller {
function index()
{
$this->load->model('Twitter_model');
$data['tweet'] = $this->Twitter_model->get_tweet();
$this->Twitter_model->insert_tweet($data);
}
}
Code: <?php
class Twitter_model extends Model {
function Twitter_model(){
parent::Model();
}
function get_tweet(){
$tweet = $this->twitter->auth('cmsucks','c7cclab5');
return $this->twitter->user_timeline('jpcody',10);
}
function insert_tweet($tweet){
foreach($tweet as $t) {
$messages = array(
'user' => $t->user->name ,
'pic' => $t->user->profile_image_url ,
'time' => $t->user->created_at ,
'tweet' => $t->text
);
}
$this->db->insert('updates', $messages);
}
}
Update 2:
Yeah, very confused now. I keep getting the "Trying to get property of non-object" error. But a print_r shows each array item as "stdClass object." Each "->" within the $messages array generates its own error message. But this is the exact same way I'm accessing the same data successfully in my view. Where is my error here?
[eluser]n0xie[/eluser]
The reason you only get one result into your database is because the 'insert' statement is not in your foreach loop
Code: // change to:
foreach($tweet as $t) {
$messages = array(
'user' => $t->user->name ,
'pic' => $t->user->profile_image_url ,
'time' => $t->user->created_at ,
'tweet' => $t->text
);
$this->db->insert('updates', $messages);
}
This should take care of the inserts.
The reason you get the object errors is because you pass an array to your model instead of the object.
Code: // Your code
$data['tweet'] = $this->Twitter_model->get_tweet();
$this->Twitter_model->insert_tweet($data);
// My code
$tweet = $this->Twitter_model->get_tweet();
$this->Twitter_model->insert_tweet($tweet);
Hope this will get you on your way.
[eluser]jpcody[/eluser]
Thanks so much n0xie, that one is the first thing that has made me feel really dumb! That makes total sense, and now the database is returning all 10 results.
I was really hoping to get this next part on my own, but alas, I'm missing something somewhere:
Code: function index()
{
$this->load->model('Twitter_model');
$users = array('user1','user2','user3');
foreach($users as $u){
$tweet = $this->Twitter_model->get_tweet($u);
$this->Twitter_model->insert_tweet($tweet);
}
}
This is returning 3 sets of 10 updates, but all are coming from user1. Any ideas?
Thanks again everyone for your help. I have got this pretty much up and running with the exception of two issues:
• The code will only iterate through one user, albeit multiple times.
• I think I have an error in my SQL query to INSERT IGNORE, as that's throwing me errors like crazy. (I've tried to troubleshoot this and done a var_dump on both the array and a variable. All of these are successfully returning a string, yet when I attempt to run the query, I'm getting "Object of class stdClass could not be converted to string." Perhaps the arrow operator is not allowed or recognized in a SQL query?)
MODEL
Code: <?php
class Twitter_model extends Model {
function Twitter_model(){
parent::Model();
}
function get_tweet($u){
$auth = $this->twitter->auth('user','pass');
return $this->twitter->user_timeline($u,5);
}
function insert_tweet($tweet){
foreach($tweet as $t) {
$messages = array(
'user' => $t->user->name ,
'sn' => $t->user->screen_name ,
'pic' => $t->user->profile_image_url ,
'time' => $t->created_at ,
'tweet' => $t->text
);
$this->db->query("INSERT IGNORE INTO updates (user, sn, pic, time, tweet) VALUES ('$t->user->name', '$t->user->screen_name', '$t->user->profile_image_url', '$t->created_at', '$t->text')");
}
}
function return_tweet(){
return $this->db->query('SELECT * FROM updates ORDER BY time DESC');
}
}
VIEW:
Code: <ul>
<?php foreach($query->result() as $row): ?>
<li><img >pic; ?>" alt="Profile Picture"><h1><?php echo $row->user; ?></h1><h2><?php echo $row->sn; ?></h2><p><?php echo $row->tweet; ?></p><span><?php echo $row->time; ?></span></li>
<?php endforeach; ?>
</ul>
</p>
CONTROLLER:
Code: <?php
class Feed extends Controller {
function index()
{
$this->load->model('Twitter_model');
$users = array('user1','user2','user3');
foreach($users as $u){
$tweet = $this->Twitter_model->get_tweet($u);
$this->Twitter_model->insert_tweet($tweet);
}
$data['query'] = $this->Twitter_model->return_tweet();
$this->load->view('tweets',$data);
}
}
I would love if someone could lend a little help with these final two issues, and I'd also love any suggestions or recommendations about cleaning up or optimizing my code. I'm brand new at this, so anything is welcomed.
Thanks again for all your help folks.
[eluser]jpcody[/eluser]
I thought I would post my progress for the sake of posterity as well as ask for a little more help at this point.
• I got it to cycle through more than one user by adding a $this->twitter->user_timeline = null to the beginning of the function get_tweet. Apparently, the library was convincing itself that after using the first user instance from the array, that the function was empty, then was setting the user_timeline variable to the first user again and fetching the same data when re-looping.
• I fixed my SQL by storing the data in $sql and running this->db->query($sql, array(value1, value2, etc.));
Now, I'm getting a strange foreach error. It doesn't happen immediately, it only happens after a period of time, and I can't determine what period of time or what triggers it.
Here is my model:
Code: <?php
class Twitter_model extends Model {
function Twitter_model(){
parent::Model();
}
function get_tweet($u){
$this->twitter->user_timeline = null;
$auth = $this->twitter->auth('cmsucks','c7cclab5');
return $this->twitter->user_timeline($u,5);
}
function insert_tweet($tweet){
foreach($tweet as $t) {
$user = $t->user->name;
$sn = $t->user->screen_name;
$pic = $t->user->profile_image_url;
$time = strtotime($t->created_at);
$tweet = $t->text;
$sql = "INSERT IGNORE INTO updates (user, sn, pic, time, tweet) VALUES (?, ?, ?, ?, ?)";
$this->db->query($sql, array($user, $sn, $pic, $time, $tweet));
}
}
function insert_profile($profile){
foreach($profile as $p){
$user = $p->user->name;
$sn = $p->user->screen_name;
$bio = $p->user->description;
$pic = $p->user->profile_image_url;
$tweet = $p->text;
$time = strtotime($p->created_at);
$sql = "INSERT IGNORE INTO profiles (user, sn, bio, pic, tweet, time) VALUES (?, ?, ?, ?, ?, ?)";
$this->db->query($sql, array($user, $sn, $bio, $pic, $tweet, $time));
}
}
function return_tweet($offset, $row_count){
$sql = 'SELECT * FROM updates ORDER BY time DESC LIMIT ' . $row_count . ' OFFSET ' . $offset;
return $this->db->query($sql);
}
function return_profile(){
$sql = 'SELECT * FROM profiles ORDER BY sn';
return $this->db->query($sql);
}
}
And my controller:
Code: <?php
class Feed extends Controller {
function index()
{
$this->load->model('Twitter_model');
$users = array('cmsucks','kevinhendricks','jpcody','holycowcreative','kemmeyer','timschraeder');
foreach($users as $u){
$tweet = $this->Twitter_model->get_tweet($u);
$this->Twitter_model->insert_tweet($tweet);
}
$data['users_array'] = $users;
if(!$this->uri->segment(3)){
$offset = 0;
}
else{
$offset = $this->uri->segment(3);
};
$row_count = 5;
$data['query'] = $this->Twitter_model->return_tweet($offset, $row_count);
$this->load->library('pagination');
$rows = $this->db->count_all('updates');
$config['base_url'] = "http://localhost:8888/twitter/index.php/feed/index";
$config['total_rows'] = $rows;
$config['per_page'] = "5";
$this->pagination->initialize($config);
$this->load->view('tweets',$data);
}
function profiles()
{
$this->load->model('Twitter_model');
$users = array('cmsucks','kevinhendricks','jpcody','holycowcreative','kemmeyer','timschraeder');
foreach($users as $u){
$profile = $this->Twitter_model->get_tweet($u);
$this->Twitter_model->insert_profile($profile);
}
$data['query'] = $this->Twitter_model->return_profile();
$this->load->view('list', $data);
}
}
Depending on which view I am loading, the error occurs on either foreach($tweets as $t) or foreach ($profiles as $p). Any ideas where I could be going wrong?
(And apparently it goes away after a certain interval. No idea what's going on here.)
[eluser]n0xie[/eluser]
What is the error message you get?
[eluser]jpcody[/eluser]
I get "invalid argument supplied foreach" on line 88 of the Twitter library as well as line 15 of my model.
And if it's any help whatsoever, which it won't be, I can't tell if it's toggling between broken and fine based on number of refreshes or time period. It usually lasts for around 30 minutes working or non.
I'm also developing locally using the latest version of MAMP.
[eluser]n0xie[/eluser]
The error implies that your insert function doesn't get an array or object supplied which it needs to do it's job.
This could be a result of a timeout when requesting information from the twitter api. (it is known to go down quite regularly which I personally find hilarious since it's supposed to be the PoC that RoR scales ;-) )
What you could do is test the return value from your twitter or log it to see what goes wrong. Personally I would just var_dump the return value until saw something which looks out of the ordinary. Since I'm not familiar with this particular Twitter library I don't know if it has some form of error handling/ error messaging which could tell you more.
Code: // controller
foreach($users as $u){
$tweet = $this->Twitter_model->get_tweet($u);
var_dump($tweet);
[eluser]jpcody[/eluser]
Hmmm...looks like it's giving me a false boolean return. But this has nothing to do with Twitter actually going down. Could this be some sort of issue with exceeding a rate limit? Is there any way instead of running the database on a page refresh I can have it run in the background every so often? Every 10 minutes or so?
The API limits to 150 requests per hour, and I am making requests very often as I'm refreshing the page to test different things. I could very easily see this being the issue.
|