How to - Insert / Update - using the same form?

Hello all,

Without using MVC,
I do have a place were my database queries reside.
I do have another place where my form inputs go and interact with the database.
I do have another place where my html form are.

Now:
I have a insertForm.php file that contains the html form;
I have a something.Controller (where I process the form data, and I call methods like insert())
I do have something.Model (where those methods deal with the database).

I would like to change the insertForm.php to a AddEditForm.php, so that I can profit from the same validations erros and all, based on a condition: if a value is passed, try the update, if no value is passed, then do an insert.

Any ideas in order to have them both working on the same form?

K. Regards,
Márcio

ps - you can do those kind of kill comments really. I don’t know how to get better without them. :slight_smile:

If your using MySQL, then there is a REPLACE query as an option, if your not using MySQL, check the manual for the database server that your using, there might be an equivalent query syntax.

OMG :bouncy2::bouncy2::bouncy2:

I was able to do an insert edit on the same page, have anyone hear of it!! :goof::goof::goof:

The working “think”:

I will try to clean it, care to provide me some advices?


/**
 * Inserir / Editar Notícia
 */
 
$val = new Validacao();

$noticiaVo = new NoticiaVo();

$noticiaDao = new NoticiaDao();

//$id = (isset($_GET['id'])) ? (int)$_GET['id'] : 0;

if (isset($_GET['id']))
{
    $id = $_GET['id'];

    $noticiaVo->setId($_GET['id']);
    //passa o value object para o Dao e deixa os dados prontos para serem fetchados na view: $noticia->titulo_noticia;
    $noticia = $noticiaDao->mostraNoticiaPorId($noticiaVo);
}
else
{
    $id=0;
}

    if(isset($_POST['inserirEditarNoticia']) || isset($_POST['inserirEditarNoticia_x']))
    {
        $tituloNoticia              = stripslashes($_POST['inputTituloNoticia']);
        $primeiroParagrafoNoticia   = stripslashes($_POST['inputPrimeiroParagrafoNoticia']);
        $corpoNoticia               = stripslashes($_POST['inputCorpoNoticia']);
        $idNoticia                  = $_POST['hiddenId']; //is_numeric($_POST['hiddenId']);

        //var_dump($idNoticia);

        //limpeza e validacao:
        $val->requerido($tituloNoticia);
        $val->limpaString($tituloNoticia);

        //to do - parece não validar devido ao ckeditor - verificar se, quando limpar, se os links e bold se preservam.
        $val->requerido($primeiroParagrafoNoticia);
        $val->limpaString($primeiroParagrafoNoticia);

        $val->requerido($corpoNoticia);
        $val->limpaString($corpoNoticia);


        if (!$val->errosValidacao())
        {
            
            try
            {
                
               
                $noticiaVo->setTitulo($tituloNoticia);
                $noticiaVo->setPrimeiroParagrafo($primeiroParagrafoNoticia);
                $noticiaVo->setCorpo($corpoNoticia);

                if ($idNoticia != 0)
                {
                    //só seta o ID depois de sabermos que não é zero. Senão vai setar 0 e nós não queremos isso.
                    $noticiaVo->setId($idNoticia);

                    $noticiaDao->actualizar($noticiaVo);

                    //o $titulo Noticia vem do post. O ultimoId vem do parametro passado.
                    $mensagem = $tituloNoticia.' - http://www.example.com=noticia'.$_POST['hiddenId'];

                    $resultado['sucessoInserirEditar'] = 'Noticia Editada. Obrigado.';
                }
                else
                {
                    $noticiaDao->adicionar($noticiaVo);
                  
                    $ultimoIdInserido = $noticiaDao->ultimoIdInserido();

                    //o $titulo Noticia vem do post. O ultimoId vem da base de dados.
                    $mensagem = $tituloNoticia.' - http://www.example.com/Noticias.php?expanddiv=noticia'.$ultimoIdInserido;

                    $resultado['sucessoInserirEditar'] = 'Noticia Adicionada. Obrigado.';
                }
                
                // Cria o tweet
                //tweet($mensagem, $twitterUser, $twitterPassword);

                
            }
            catch(PDOException $e)
            {
                echo "Erro na inserção na base de dados: " .$e->getMessage();
                $resultado['insucessoInserirEditar'] = 'Lamentamos. Ocorreu um problema e a informação não foi enviada. Tente novamente mais tarde por favor. Se o erro persistir, queira contactar-nos através dos meios disponíveis. Obrigado.';
            }
        }
        else
        {
            $resultado['insucessoValidacao'] = 'Por favor, preencha todos os campos adequadamente. Obrigado';
        }
    }

K. Regards,
Márcio

I thank you all for your feedback.

I’m now having something like this:

if (isset($_GET['id']) && is_numeric($_GET['id']))
{
  //run displayDataById method (to be used on my form page)

    if(isset($_POST['inserirEditarNoticia']) || isset($_POST['inserirEditarNoticia_x']))
    {

       //run updateDataBasedOnId

    }
} 
else //if there is no url param  
{
   if(isset($_POST['inserirEditarNoticia']) || isset($_POST['inserirEditarNoticia_x']))
    {

       //run insertData

    }
}

However, when I try it, I only get the data inserted, never the update. :nono:

Any help? Must be a logic issue perhaps…

Thanks in advance,
Márcio

OK.

Now I can edit or insert.

However, I’m now having an issue that oddz (more or less) was talking about.

After validation errors, I get an insert instead of an update. :s

Is this related with the fact that the URL has no values?
Answer: No.

Why?
Because:
I’m making update or insert based on two conditions:
A post has been made.
And hidden field has same value.

The get doesn’t play a role on this decision.

So, why is it doing an update?
I don’t know yet.

Maybe if we preserve the data on the hidden field, the same way I do for the others, I can get my update?

I will give it a try, if I’m missing the track, please let me know.

Márcio

I’m on mysql yes. ON DUPLICATE KEY will do the same yes?
Any reason to pick one instead of another?

So, basically , all this can just be throw away, but then I will need to find a way to tell to the user: your insert as been successful. Your update as been made.

Or you just output, “The data as been saved”. Anyway.
But is there any best practice we may adopt to distinguish them?

Two issues that I’ve detected:
I was showed on my page “Edit page” or “Insert page” titles, based on the get value. So, if we had URL param the “Edit page” title will appear, if not, the “insert will appear”.

This doesn’t work when we see our page after the “Edit” as been made, the “Insert title” shows up. (because no URL is set at that time).

If we validate, and the validation throws an error, then the URL param will disappear as well, and we can the “Insert Title” again.

I presume we cannot base this on the hidden field because this verification should be made prior any post.

Any help?

Thanks for the feedback,
Márcio

What about an error on the form? In that case if your not checking the GET and POST you would end up with an empty id hidden field when the form fails due to invalid fields. That is one of major reasons I have strictly been using the URL to host the update flag. That way only one place needs to be checked for the flag vs. two. The rules surrounding all the different HTTP protocols are so construed you might as well use what works best for situation.

Doing it any other way would be abusing HTTP. Without wanting to take this too off-topic - check out this, and [URL=“http://en.wikipedia.org/wiki/Representational_State_Transfer#RESTful_web_services”]this.

Kinda lost on the details for accomplish it.

Here is the details I’m trying to accomplish.

I will have a list of records, on that list of records, if the users clicks on a specific record link it will be redirected to the insertEdit form page.

I’m not sure were/how Post fits here…

Please advice,
Márcio

You are not coming late. :frowning: I will try this tomorrow and post back any frustrations.

Thanks for your feedback,
Márcio

Thank you all, about the ID I will then do what best works, now that I’ve seen some of the possibilities.

After the id as been passed, In order to display the data into our form, for edition, we will need to
a) have a method on or model to fetch data based on ID, and then, on or form, b) we will echo that data using isset($_GET[‘id’]

Is this a way for doing it?

If so, I must say that, on my form, I already have this, in order to preserve form data:

<?php echo (isset($_POST['inputCorpoNoticia'])) ? $_POST['inputCorpoNoticia'] : ''; ?>

I will then need to add in front of it, something like this:

<?php echo (isset($_GET['id'])) ? $noticia->id_noticia : ''; ?>

But if something is wrong after the POST, what will appear, the data just inserted, or the data from the database?

I’m on a mass confusing situation I realise that.
Better doing step by step, and close this topic perhaps.

reply if you feel like.

K. Regards,
Márcio

That would work, but why not do it like this?

if (isset($_GET['id'])) {
  // update
} else {
  // insert
}

So that I don’t have to write what is basically the same method twice.

Thanks a lot,

Actually I was thinking on having something like:
if (isset($_GET[‘id’])) {

if the variable id is set on the URL it means we want to edit a record…

If not, it means we want to added…

What do you think?

Thanks again,
Márcio

That works to.

To use the same method to update and insert for your model you would than add a on duplicate key update when the primary key exists.

Here is an example of how you could use the same method to update and insert:


	public function saveBlog($arrBlog) {
		
		$boolUpdate = false;
		$arrUpdate = array();
		
		$arrValues = array();
		$arrColumns = array();
		
		foreach($arrBlog as $strField=>$mixValue) {
			
			if(strcmp('blogs_id',$strField) == 0) {
				$boolUpdate = true;
			} else {
				$arrUpdate[] = "$strField = VALUES($strField)";
			}
			
			if(in_array($strField,array(
				'blog_url'
				,'blog_title'
				,'blog_subtitle'
				,'blog_content'
				,'content_type'
				,'blog_type'
				,'intro_type'
				,'intro_content'
			))) {
				$mixValue = "'".$this->_objMCP->escapeString($mixValue)."'";
			} else {
				$mixValue = $this->_objMCP->escapeString($mixValue);
			}
			
			$arrColumns[] = $strField;  
			$arrValues[] = $mixValue;
			
		}
		
		if(!array_key_exists('created_on_timestamp',$arrColumns)) {
			$arrColumns[] = 'created_on_timestamp';
			$arrValues[] = 'NOW()';
		}
		
		$strSQL = sprintf(
			'INSERT INTO BLOGS (&#37;s) VALUES (%s) %s'
			,implode(',',$arrColumns)
			,implode(',',$arrValues)
			,$boolUpdate === true?' ON DUPLICATE KEY UPDATE '.implode(',',$arrUpdate):''
		);
		
		return $this->_objMCP->query($strSQL);
		
	}

You can examine that at your discretion and apply the logic in the best way fit for your system.

Just render a hidden input to the form with a value of 0 when adding, or the id of the entity when you are editing. The model can use it to either INSERT or UPDATE.

I’d rather use the hidden form field than a GET flag, simply because I think inserting or updating should be a POST action, and conceptually it makes more sense for all the data to be in POST together.

Why? I thought that we have some reasons to not using GET methods, for example, on passing sensitive information through the URL and the lengths constrains, but the “security issues” are easily overcome either on GET or POST, so, despite the URL lengths constrains, I’m wondering what reasons we may have for NOT doing it using GET.

I’m using POST for inserting btw, I’m just asking.

Thanks a lot,
Márcio

note: oddz, I will give a read, but I will need to think a way of doing that on a abstract crud class perhaps. It’s simpler for me to do the Update and the Insert on separate methods.

I know I’m coming in late…

Nowadays I always do what you’re looking to do, and I call the page add_edit_something.php, in fact.

The key for me is to use a $_SESSION variable: $_SESSION[‘add_edit’] (the value of which is either ‘add’ or ‘edit’).

Using some conditional scripting, the page knows, for example, whether to display a checkbox for “Delete” (only for edit; duhh) and which function to call (update or insert). When the page is initially called without a $_GET argument, the page knows it’s doing an add/insert.

HTH.