update rows in mysql with codeigniter - php

so. i've been trying to update the password. randomly generated. but. if i refresh the database, nothing happens. what's wrong with my code?
this is my controller:
function create_password()
{
$this->load->model('members_model');
$newRow = array(
'name' => $this->input->post($a);
'value' =>
);
$this->membership_model->passchange($newRow);
}
this is my model:
function passchange()
{
$this->db->select();
$this->db->from('membership');
$this->db->where('security_answer',$this->session->userdata('security_answer'));
$q=$this->db->get();
if($q->num_rows() > 0) {
$data = array();
foreach($q->result() as $row) {
$data['result']=$row;
$this->db->where('email_address', $this->session->userdata('email_address'));
$this->db->update('membership', 'password');
}
return $data;
}
}
and this is my view:
<?php echo form_open('login/create_password')?>
<?php $this->load->view('includes/header');
$CI =& get_instance();
$CI->load->model('membership_model');
$result = $CI->membership_model->passchange();
foreach($result as $row) {
}
?>
Your Email Address is: <?php echo $row->email_address;?> <br/>
<?php
$a = random_string('alnum', 6);
?>
Your password is: <?php echo $a; "<br/>"?>
<p align="right"><?php echo anchor('login/signin', 'Back to Login Page'); ?></p>
the password in my database is blank. it is not updating. please help. thank you in advance! :)

Marishka you really really need to watch those tutorials I gave you before continuing this process. You're going to get to a point where your application is so badly messed up it will be nearly impossible to fix.
Almost everything you're doing there shows bad practices, not the least of which is stop loading the CI instances and getting data from the model in the view.
Here are the problems with your code as it stands.
You're creating an array of $newRow using a post value you're not getting because you aren't posting anything. Creating a variable in a view does not automatically post it back, to post data to a controller it needs to be in a form and that form needs to have an action to call the controller function.
$a isn't going to equal anything because random_string isn't a php function that I know of, it looks like something you just pulled out of the middle of a tutorial without reading how it was created, so $a is going to be null, even if it were posted back to the controller it would still have no value to insert into the database.
In your model that you're passing the $newRow to you're never actually getting the $newRow into the function.
This has nothing to do with it not working but you're basing which record to update on the security answer? The possibility of numerous users having the same answer makes this a horrendous idea.
As was previously said the second parameter in active records update function should be an array. So to understand what that function is doing it breaks down like this.
$this->db->update ($tableToUpdate, $arrayOfValuesToUpdate);
The array of values are key pairs so for password you'd have an array like the following:
$arrayOfValuesToUpdate = array(
'nameOfPasswordFieldInYourDB' => 'value you want to set the password to'
);
I really get the feeling you're trying to learn CI from various examples and tutorials and you really do need to just stop and look at the nettuts tutorials I linked you before from step one. Your practices are terrible and your understanding of what you're actually doing is low enough that you're just copying and pasting and not getting what it is that's supposed to actually be happening. The Nettuts tutorials will give you that base understanding you need to do these things properly.

The error lies here
$this->db->update('membership', 'password');
This method gets array as second parameter
$data['password'] = $newpassword;
$this->db->update('membership', $data);
Also use this method
echo $this->db->last_query();
to see what query has been run recently. And dont forget to use where instruction with update instruction. Read the userguide again it is very helpful
https://www.codeigniter.com/userguide2/database/active_record.html

Related

CodeIgniter flashdata incoerence

So, I've been struggling with this for some time, but to no avail. My research didn't help much, either. Here it is: I built a test to prevent people to go to the alter page of an module by typing the address directly in the url without the id of the registry to be altered (therefore causing trouble in the DB). Simply put, it searches for the id passed as parameter in the url in the DB; if it has a match, it proceeds, if not, I redirect to the main module page with an error message passed via flashdata. I use a similar process to impede the insertion/alteration of registries if a field from a different table is not defined (as it is required in both in order to work, as the tables are related). A rough example of what I'm doing in the Controller is:
if(is_numeric($id)) $search=$this->model_foo->search($id);
else
{
$this->session->set_flashdata('error_message','not numeric');
redirect('myurl/index','refresh');
}
if($search->num_rows()==0)
{
$this->session->set_flashdata('error_message','not found');
redirect('myurl/index','refresh');
}
$search=$this->model_foo2->list();
if ($search->num_rows()==0)
{
$this->session->set_flashdata('error_message','other table empty');
redirect('myurl/index','refresh');
}
And my view (index) is like this:
<?php
$error=$this->session->flashdata('error_message');
$success=$this->session->flashdata('success_message'); /*success_message goes after a successful inset/update*/
if ($error!="")echo $error;
?>
So here is the issue: the success messages show up normally (I checked and double checked, they are being declared in the Controller the exact same way the error ones), as well as the 'not numeric' one, but not the 'not found' and 'other table empty' ones. I'm really confused by this one, since the flashdata seems to work in some instances and not in others, which is specially weird given the flashdata are being declared in pretty much the same way... =/ Sorry if I wasn't clear enough, this is my first post here, so (try to) be patient ;D Thanks in advance for any help in this matter.
EDIT: Found out the source of the issue. It was something with my browsers cache storage. Rebooted my machine and cleaned the cache and the output worked like a charm. Thanks for all the help.
So, i just improved your code a little bit so you can try and debug...
Controller:
$arr = array('error_message' => '');
if(!empty($id) && is_numeric($id)) {
$search=$this->model_foo->search($id);
if($search->num_rows()==0) {
$arr['error_message'] = 'not found';
} else {
$search=$this->model_foo2->list();
if ($search->num_rows()==0) {
$arr['error_message'] = 'other table empty';
}
}
} else {
$arr['error_message'] = 'not numeric';
}
$this->session->set_flashdata($arr);
redirect('myurl/index');
View (same):
<?php
$error=$this->session->flashdata('error_message');
$success=$this->session->flashdata('success_message'); /*success_message goes after a successful inset/update*/
if ($error!="")echo $error;
?>
Give a try with this and before check if the message appears, make sure the flashdata is set.

Simplifying php code

I'm working on revamping my CMS right now. Currently, I'm trying to minimize the front end code to make theming easier. To display the latest posts, this is the code I am using:
<?php
$query = mysql_query("SELECT * FROM posts order by id desc") or die(mysql_error());
while($row = mysql_fetch_array($query)) :
?>
<h3><?php echo $row['title'] ?></h3>
<?php endwhile; ?>
What would be the best way to simplify this for the front end user? I'm thinking about using a functions.php file but I not sure exactly how to do that. Is there a way I could make the first two lines of php into a function and then the user would only have to call the function?
Typically you use two layers.
Database access layer: Query function accepts arbitrary queries, verifies return value, logs to file on error, dies if needed. You can create separate functions for querying+retrieving data in one step (query_one_row(), query_dataset_as_array(), ...).
Data model layer: Separate functions for each major query, each calling the lower layer. eg: get_recent_posts(),
Try to rewrite #Sascha's answer to use these two layers.
Here is the function you could use:
function getPosts() {
$query = mysql_query("SELECT * FROM posts order by id desc") or die(mysql_error());
$result = array();
while($row = mysql_fetch_object($query)) {
$result[] = $row;
}
return $result;
}
and in the template:
<?php foreach(getPosts() as $post) : ?>
<h3><?php echo $row->title ?></h3>
<?php endforeach; ?>
note: i know I'm not answering your question, but just wanted to give you a heads up.
you might want to split the different concerns of the code. on one hand there is the render of the data, on the other hand, the business logic and the persistance layer. it seems you're coding everything in one file and this may make matters complex in the future. try using an mvc like yii, zend framework, or symfony2.
also, the "or die" is pretty much a bad practice. notice how you are loosing the chance of logging the error properly and outputing the error directly to the user instead of giving them a nice error page to look at, and maybe give you some feedback about the error.
edit: for the persistance layer, you could try doctrine2
To improve a little on Sascha's answer above, you could do this...
<?php
foreach(getPosts() as $post)
{
printf( '<h3>%s</h3>', $post->id, $row->title );
}
?>
Works exactly the same, but a bit easier to read, imo.

php refactoring and better coding for php?

i have this process that is the heart of my app, that im creating, but for some reason i feel like its the worst way to do it(instinct) , and i wanted to see if thier is something wrong with this process, and am i approaching it in a bad way! p.s. the code works fine, just refactoring problem.
the process is:
users go to homepage, they see thier latest activities, by other site memebers(home.php),
//function to bring the latest activities from database
$results=function getUserUpdates($_SESSION['user_id'];
while($row = mysql_fetch_array($results))
{
//another function to format the activities in a social stream
echo formatUpdate($row['user_note'],$row['dt'],$row['picture'],$row['username'],$row['id'],$row['reply_id'],$row['reply_name'],$row['votes_up'],$row['votes_down']);
}
i have put the function codes in pastie.
formatUpdate function http://pastie.org/1213958
getUserUpdates function http://pastie.org/1213962
EDIT both functions are from different files they are included in home.php,
formatUpdate from functions.php
getUserUpdates from queries.php
First of all, it's good that you have separate functions for getting the data and for formatting the data. It's a good start toward refactoring your code. It makes it easier in the future: if you ever want to format your data differently, you can just expand your formatter.
Second, this is what coreyward meant by a lambda:
$results=function getUserUpdates($_SESSION['user_id'];
Remove the function keyword. You use function when you're defining a function. But here you're only calling one. (You defined it in queries.php.)
Third, I agree with webbiedave about the echo statements. A good way to avoid that: In the "heart" of your app, collect all the HTML into one place. Then, when you've collected everything you're going to display on the page, you can echo it all at once. This makes it a lot easier to keep track of what you're doing, and to remember the order of everything. It also makes it easier to add headers and footers, or do more formatting. Otherwise, if you have echo statements scattered around your code, it's a lot easier to let something slip that shouldn't be there.
Here's a very basic example of what I mean:
$html = '';
$results = getUserUpdates($_SESSION['user_id'];
while($row = mysql_fetch_array($results)) {
$fields = array(
'user_note' => $row['user_note'],
'dt' => $row['dt'],
'picture' => $row['picture'],
'username' => $row['username'],
'id' => $row['id'],
'reply_id' => $row['reply_id'],
'reply_name' => $row['reply_name'],
'votes_up' => $row['votes_up'],
'votes_down' => $row['votes_down'],
);
$html .= formatUpdate($fields);
}
// This way you can do whatever you want to $html here.
echo $html;
Also notice that I put all the fields from $row into an array and passed it to formatUpdate(). That has two advantages:
It's easier to read.
If you ever
want to change the fields that
formatUpdate deals with, you don't
have to worry about searching
through your code to change the
arguments every time you call it.
Firstly, I think you mean:
$results = getUserUpdates($_SESSION['user_id']);
In your getUserUpdates() function there is a redundant branch:
if ($username == $_SESSION['u_name']){
// return something
}
if ($username != $_SESSION['u_name']){
// return something else
}
You don't need the second if statement as any code run at that point will only be run if $username != $_SESSION['u_name'].
In my opinion, it's usually better not to have different functions directly echoing HTML up the stack (such as echoVote()). It's preferred to have functions return data and have the original caller echo it. This allows the caller to perform additional data massaging if desired.
Other than that, your code is fetching data, looping through and acting on the results which is pretty much standard fare.
I think your instinct is to be a little too harsh on yourself ;) There are improvements to be made but it's certainly not the worst way to do anything.

Make links clickable in PHP with twitterlibphp?

Hey guys, I'm using Twitter's PHP API, called twitterlibphp, and it works well, but there's one thing that I need to be able to initiate, which is the linking of URLs and #username replies. I already have the function for this written up correctly (it is called clickable_link($text);) and have tested it successfully. I am not too familiar with parts of twitterlibphp (link goes to source code), and I am not sure where to put the function clickable_link() in order to make URLs and #username's clickable. I hope that is enough information, thanks a lot.
EDIT:
In addition, I would like only one status to come up in the function GetFriendsTimeline(), right now 20 come up, is there any easy way to limit it to one?
I would extend the Twitter class and put the functionality in my own getUserTimeline method.
class MyTwitter extends Twitter
{
public function getUserTimeline()
{
$result = parent::getUserTimeline();
// Your functionality ...
return $result;
}
}
You don't need to put clickable_link() in twitterlibphp. Instead, call it right before you output a status message. Example:
$twitter = new Twitter('username', 'password');
$result = $twitter->getUserTimeline();
... parse the $result XML here ...
echo 'Status : '.clickable_link($status);

Loading 'modules' Data Into Views on a Per User Basis Dynamically From One Controller Using CodeIgniter

I am trying to load views for a set of 'modules' for a user who has selected any number of available 'modules'. I can get the name of the modules, or any column from the database.
load->view($name . '_view');
I can't seem to figure a way to load the data for the view based on the 'module' name though.
//Loads the rows (selected modules) I need for this user into an array
$modules['modulearr'] = $this->module_model->getModuleUser();
for($i = 0; $i < count($modules['modulearr']); $i++){
//Get the variable from the array
$name = $modules['modulearr'][$i]->mod_name;
//The below works.
$this->load->view($name.'_view');
//The below would not work. (this is the crux of my problem)
$data = $this->$name.'_model'->get();
$this->load->view($name.'_view', $data);
}
There is also an issue with loading the models in the controller based on the fact I can't change $this->load->THIS_PART dynamically.
I am new to everything, so there may be a basic concept I am not grasping. If you could point me in the right direction; that would be awesome. I could do a whole bunch of if statements, but that seems messy. Surely there is a better way. Thanks in advance!
maybe you wanted
$data = $this->$name.'_model'->get();
you forgot to concatenate the strings
but can't seem to figure a way to load
the data for the view based on the
'module' name.
The module name seems to be defined from the line
$name = $modules['modulearr'][$i]->mod_name;
if this works...
$this->load->view($name.'_view');
maybe you want to do this?
$data = $name.'_model'->get();
instead of $this->name ?
If that doesn't work (i don't really know what you have going on) try echoing $this->name and making sure the output makes sense attached to '_model'
It was a capitalization issue: The fields from the database (in array form)
$name = $modules['modulearr'][$i]->mod_name;
were sometimes in capitals. I fixed it by using
$name = strtolower($name);
$nameMod = $name.'_model';
then
//it doesn't seem to like combinations of things where nameMod is below.
$data[$name.'_result'] = $this->$nameMod->get()
$this->load->view($name.'_view', $data);
I don't know why it originally worked in the view loading part and not the loading data by calling model function part, but it does now. I am using it for a main landing (after sign up or login) page function that selects and displays the modules added by each user to their profile, I am probably going about this in a completely gammy way, but I am learning heaps by making mistakes, Thanks for the help answerers you definitely put me on the right track

Categories