Codeigniter Rest Api Delete using parameter ID - rest

I'm Learning CRUD operation with Codeigniter and Rest Api for my app Flutter.But I'm get some problem with Delete operation. I'm want delete data using parameter ID , but the message show me ID Null.
It's my Get Operation using parameter
http://192.168.43.159/wpu-rest-server/apii/mahasiswa/get?id=5
Possible i'm make delete operation like this ?
http://192.168.43.159/wpu-rest-server/apii/mahasiswa/delete?id=5
I already try
http://192.168.43.159/wpu-rest-server/apii/mahasiswa/delete/5
http://192.168.43.159/wpu-rest-server/apii/mahasiswa/delete/id/5
But Nothing change , still ID null.
It's my Controller And Model Rest Api :
Controller
public function delete_delete()
{
$id = $this->delete('id');
$msgDelete = ['id' => $id, 'message' => 'Deleted the resource'];
$msgEmpty = ['status' => false, 'message' => 'ID Not Found'];
$msgBadRequest = ['status' => false, 'message' => 'Provide an ID'];
if ($id === null) {
$this->set_response($msgBadRequest, 400);
} else {
if ($this->mahasiswa->deleteMahasiswa($id) > 0) {
$this->set_response($msgDelete, 204);
} else {
$this->set_response($msgEmpty, 404);
}
}
}
Model
public function deleteMahasiswa($id)
{
$this->db->delete('mahasiswa', ['id' => $id]);
return $this->db->affected_rows();
}

I am seeing some ambigius things in your code for example the api url is :
http://192.168.43.159/wpu-rest-server/apii/mahasiswa/delete/5
and your controller method name is delete_delete .
If you are using the get method you should respect the following :
base_url/controller_name/method_name?id=3
and then you can get the value with :
$this->input->get('id')
otherwise if you are passing the id as a method argument like the following :
http://your_domain/controller_name/delete/5
you can get the value like this :
class controller_name extends CI_Controller {
.
.
.
public function delete($id=null){
}
}

If Possible do like this
192.168.43.159/wpu-rest-server/apii/mahasiswa/delete_delete?id=5
Controller
public function delete_delete() {
$id = $this->input->get('id');
$this->mahasiswa->deleteMahasiswa($id);
redirect('http://192.168.43.159/wpu-rest-server/apii/mahasiswa');
}
Model
function deleteMahasiswa() {
$this->db->where('id', $id);
$this->db->delete('mahasiswa');
}

Related

CodeIgniter Suddenly Cannot Upload Image and says Cannot Be Null

Greeting everyone and especially to Senior of CodeIgniter Developer.
I have a problem with website that was built from CodeIgniter (I am not the developer inherited by previous epmployer). This website cannot working properly, especially when upload the image and shows warning about
Error Number: 1048 Column 'article_image' cannot be null
I did try with find the problem on the script and database, but nothing change and because no one change the codes & contents. Today, i try again with changing the "Null into yes" (previously is "No"), and tried to upload the article. It is miracle that it is working but the next problem is the image is gone (broken). I search at other and looking people with same problem with me says that i need to upgrade the CodeIgniter. Mine is 3.0.0 while the latest is 3.1.10. I copy paste the content inside /System and /views/error/cli not making better but make it worse, the image at the web page is gone(missing).
This is my Article_model
defined('BASEPATH') OR exit('No direct script access allowed');
class Article_model extends CI_Model {
public function get_all()
{
// $this->db->order_by('article_date', 'desc');
// $this->db->order_by('article_view', 'desc');
// $query = $this->db->get_where('article', array('flag !=' => 3));
// return $query->result_array();
$query = $this->db->query("SELECT A.*,B.*, A.id AS id_article FROM article AS A JOIN category B ON A.article_category = B.id WHERE A.flag != 3 ORDER BY article_date DESC, article_view DESC ");
return $query->result_array();
}
public function check($article_id)
{
$query = $this->db->get_where('article', array('flag !=' => 3, 'id' => $article_id));
return $query->row_array();
}
public function get_category()
{
$query = $this->db->order_by('category_name', 'ASC')->get_where('category', array('flag' => 1));
return $query->result_array();
}
public function get_tag()
{
$query = $this->db->order_by('tag_name', 'ASC')->get_where('tag', array('flag' => 1));
return $query->result_array();
}
public function get_selected_tag($article_id)
{
$query = $this->db
->select('tag.id, tag_name')
->join('article_tag', 'tag_id = tag.id')
->where(array('tag.flag' => 1, 'article_id' => $article_id))
->get('tag');
return $query->result_array();
}
public function insert()
{
$this->load->helper('upload');
$this->load->library('image_moo');
$image = file_upload('article_image', 'upload/article');
$this->image_moo->load($image['full_path']);
$this->image_moo->resize(924, 527)->save($image['path'] . '/' . $image['file_name'], TRUE);
$this->image_moo->resize_crop(100, 69)->save($image['path'] . '/thumb/' . $image['file_name']);
$this->image_moo->resize_crop(367, 232)->save($image['path'] . '/cover/' . $image['file_name']);
$insert_data = array(
'article_author' => $this->session->admin_id,
'article_title' => $this->input->post('article_title'),
'article_slug' => url_title($this->input->post('article_title'), '-', TRUE),
'article_category' => $this->input->post('article_category'),
'article_image' => $image['file_name'],
'article_content' => $this->input->post('article_content'),
'is_popup' => $this->input->post('is_poup'),
'article_date' => $this->input->post('article_date'),
);
$this->db->insert('article', $insert_data);
$article_id = $this->db->insert_id();
foreach ($this->input->post('article_tag') as $tag)
{
// Check apakah tag itu udah ada di database?
if (is_numeric($tag))
{
$tag_id = $tag;
}
else
{
$this->db->insert('tag', array('tag_name' => strtolower(trim($tag)), 'tag_slug' => url_title(trim($tag), '-', TRUE)));
$tag_id = $this->db->insert_id();
}
if ( ! $this->db->get_where('article_tag', array('article_id' => $article_id, 'tag_id' => $tag_id))->row_array())
{
$this->db->insert('article_tag', array('article_id' => $article_id, 'tag_id' => $tag_id));
}
}
}
public function update($id)
{
$this->load->helper('upload');
$this->load->library('image_moo');
$image = file_upload('article_image', 'upload/article');
$this->image_moo->load($image['full_path']);
$this->image_moo->resize(924, 527)->save($image['path'] . '/' . $image['file_name'], TRUE);
$this->image_moo->resize_crop(100, 69)->save($image['path'] . '/thumb/' . $image['file_name']);
$this->image_moo->resize_crop(367, 232)->save($image['path'] . '/cover/' . $image['file_name']);
$insert_data = array(
'article_author' => $this->session->admin_id,
'article_title' => $this->input->post('article_title'),
'article_slug' => url_title($this->input->post('article_title'), '-', TRUE),
'article_category' => $this->input->post('article_category'),
'is_popup' => $this->input->post('is_popup'),
'article_content' => $this->input->post('article_content'),
'article_date' => $this->input->post('article_date'),
);
if ($image)
{
$insert_data['article_image'] = $image['file_name'];
}
$article_id = $id;
$this->db->where('id', $id);
$this->db->update('article', $insert_data);
$this->db->where('article_id', $id);
$this->db->delete('article_tag');
foreach ($this->input->post('article_tag') as $tag)
{
// Check apakah tag itu udah ada di database?
if (is_numeric($tag))
{
$tag_id = $tag;
}
else
{
$this->db->insert('tag', array('tag_name' => strtolower(trim($tag)), 'tag_slug' => url_title(trim($tag), '-', TRUE)));
$tag_id = $this->db->insert_id();
}
if ( ! $this->db->get_where('article_tag', array('article_id' => $article_id, 'tag_id' => $tag_id))->row_array())
{
$this->db->insert('article_tag', array('article_id' => $article_id, 'tag_id' => $tag_id));
}
}
}
}
What should i do guys? i did backup but it remain same like after upgraded. Thank you. Web Url (http://www.hidupseimbangku.com/)
First. If you want to upgrade CI Version you must follow Upgrading Guide one by one. There may be break changes and you need to correct them, you can find this guide here:
https://www.codeigniter.com/userguide3/installation/upgrading.html
I suggest you rollback upgrade changes and start again doing one by one. It is not hard, it is just time consuming.
The error you're getting is probably related to an error of uploading process. What is file_upload?
I also suggest you read this, for properly file upload.

yii2 rest api implement custom actions

For some reason i am getting :
{
"name": "Not Found",
"message": "Object not found: search",
"code": 0,
"status": 404,
"type": "yii\web\NotFoundHttpException"
}
when I try to access a custom action (http://localhost/project/api/web/v1/userfunctions/search) in my yii2 rest api app.
This is what I have in the main.php configuration file
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/userfunction',
'extraPatterns' => ['GET search' => 'search'],
'tokens' => [
'{id}' => '<id:\\w+>'
]
]
And the UserFunctionController class has a actionSearch method.
Am I missing something here?
When I add a blank action method :
public function actions()
{
$actions = parent::actions();
return $actions;
}
method the 404 goes away but i get a blank response (status code 200) [This is irrespective of whether the actionSearch is defined or not] Where does the control go in this case?
Here is the actionSearch() code
public function actionSearch()
{
$output = UserStatus::findAll();
return $output;
}
By default Yii pluralize controller names for use in endpoints. So if you did not configure the yii\rest\UrlRule::$pluralize property to not do so, then your action should be available within :
http://localhost/project/api/web/v1/userfunctions/search
UPDATE:
public function actionSearch()
{
$output = UserStatus::findAll();
return $output;
}
This should throw this PHP error : Missing argument 1 for yii\db\BaseActiveRecord::findAll() as the findAll() method is expecting a mixed argument holding your filtering conditions.
You should use this instead :
public function actionSearch()
{
$output = UserStatus::find()->all();
return $output;
}
I think your server is not showing error messages correctly. Check its configs, errors log files and be sure to have those lines in your Entry Script while the app is in dev state :
// remember to remove them all when deploying to production
error_reporting(E_ALL);
ini_set('display_errors', 'on');
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

symfony 2 "This form should not contain extra fields." validation error and issues in binding REST request data

I am trying to use Symfony forms to handle REST requests.
I was facing issue with binding request data in symfony form. While going through Symfony's code, I found it uses
HttpFoundationRequestHandler->handleRequest
In that, for POST,
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();
} elseif ($request->request->has($name) || $request->files->has($name)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = $request->request->get($name, $default);
$files = $request->files->get($name, $default);
} else {
// Don't submit the form if it is not present in the request
return;
}
If you see above code, if there is form name in Our form type class, it tries to get values from request as
$request->request->get($name) // $name is form name.
This may work if we render form as HTML but if we post request through REST, it doesnt find data.
To make it work we either have to namespace it like below in request (I haven't tested personally this but have read it somewhere)
{
'form_name': {
'field1' => 'value1'
}
}
Only below requst doesnt't bind data
{
'field1' => 'value1'
}
or we will have to return form name as null from getName from form type so that it use root namespace.
public function getName()
{
return null;
}
If we return null, then it creates other problem, if there are any extra parameters in request other than form fields it gives validation errors.
"This form should not contain extra fields."
Ideally form should just fetch the feild values from request which are configured in form and should ignore any other request parameters which are unknowne to it.
e.g. if this is the form
class SampleFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('field1', 'text', array('constraints' => new NotBlank()))
->add('field2', 'password', array('constraints' => new NotBlank()));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'csrf_protection' => false,
));
}
public function getName()
{
return null;
}
}
but in request if I am sending
{
'field1' => 'value1',
'field2' => 'value2',
'field3' => 'value3'
}
It gives above validation errors. It should ideally simply ignore field3 and fetch feild1 & field2 from request.
If we compare code in NativeRequestHandler & HttpFoundationRequestHandler,
NativeRequestHandler seem to have handled it properly
if ('' === $name) {
$params = $_POST;
$files = $fixedFiles;
} elseif (array_key_exists($name, $_POST) || array_key_exists($name, $fixedFiles)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = array_key_exists($name, $_POST) ? $_POST[$name] : $default;
$files = array_key_exists($name, $fixedFiles) ? $fixedFiles[$name] : $default;
} else {
// Don't submit the form if it is not present in the request
return;
}
where as HttpFoundationRequestHandler doesn't
if ('' === $name) {
$params = $request->request->all();
$files = $request->files->all();
} elseif ($request->request->has($name) || $request->files->has($name)) {
$default = $form->getConfig()->getCompound() ? array() : null;
$params = $request->request->get($name, $default);
$files = $request->files->get($name, $default);
} else {
// Don't submit the form if it is not present in the request
return;
}
So either we need to be able to use NativeRequestHandler or we need fix in HttpFoundationRequestHandler ?
I see below works though only in case of content-type text request (doesnt work with application/json),
$form->submit(array('field1' => $request->request->get('field1'), 'field2' => $request->request->get('field2')))
But using $form->handleRequest($request) looks more simpler and abstract.
If there is any other better and simpler solution please do suggest.

How can I replace this _forward() with something that can exit?

I use the following code over and over in my zend framework application. It is used in action() to check if an article exists. If not, the user shall see an error message:
$article = ArticleQuery::create()->findOneByUrl($this->_getParam('url', ''));
if (!$article) {
$this->getResponse()
->setRawHeader('HTTP/1.1 404 Not Found');
return $this->_forward('error', null, null, array(
'message' => 'Article not found',
));
}
I was wondering how to factor this out into an own method to reduce the code load in all actions.
I came to something like this:
protected function myAction() {
$article = $this->getArticleIfExists($this->_getParam('url', ''));
if ($article == null) {
return;
}
}
protected function getArticleIfExists($url) {
$article = ArticleQuery::create()->findOneByUrl($this->_getParam('url', ''));
if ($article) {
return $article;
} else {
$this->getResponse()
->setRawHeader('HTTP/1.1 404 Not Found');
$this->_forward('error', null, null, array(
'message' => 'Article not found',
));
return nulL;
}
}
I still would like to get rid of the if case in myAction(), but _forward() does not allow to exit the execution (of course, because it still needs to execute the other actions).
Another possibility (I have implemented in some other controllers) is this:
protected function myAction() {
$article = ArticleQuery::create()->findOneByUrl($this->_getParam('url', ''));
if (!$article) {
return $this->notFound('Article does not exist');
}
}
protected function notFound($message) {
$this->getResponse()
->setRawHeader('HTTP/1.1 404 Not Found');
return $this->_forward('error', null, null, array(
'message' => $message,
));
}
Again we have this if check in the action. It’s already better than before, but can we make it even better?
How can I circumvent this? Is there a possibility to do it without losing the current URL? With a Redirector I can of course exit, but then I would lose the current URL (/controller/myaction/url/hello -> /error/error/message/Article%20not%20found)
A possible approach would be to throw an Exception. Because of the Zend_Controller_Plugin_ErrorHandler this will automatically redirect you to the ErrorController without any further code being executed.
If you don't want to get to the ErrorController but only to the current controller's error actions, you can simply modify the plugin in the controller's init method:
public function init()
{
$plugin = Zend_Controller_Front::getInstance()->getPlugin('Zend_Controller_Plugin_ErrorHandler');
$plugin->setErrorHandlerModule('default')
->setErrorHandlerController('MyController')
->setErrorHandlerAction('error');
}
But of course you can also write your own ErrorHandler plugin for a more fine grained error handling. This is described in the Zend Framework Manual on Plugins
For something as simple as just displaying a "* does not exist" against a user request I prefer to leave the user in the application and just hit them with a flashmessenger notice and leave them on the page to make another request (if appropriate):
public function indexAction() {
//get form and pass to view
$form = new Form();
$this->view->form = $form;
try {
//get form values from request object
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost())) {
$data = $form->getValues();
// Do some stuff
}
}
} catch (Zend_Exception $e) {
$this->_helper->flashMessenger->addMessage($e->getMessage());//add message to flashmessenger
$this->_redirect($this->getRequest()->getRequestUri());//perform redirect to originating page so the messenger will flash
}
}
This is simple and works well when the possibility for incorrect user input exists.

Symfony2 Choice : Expected argument of type "scalar", "array" given

I'm making a form with a choice list. Here's the content of my FormType (only as a test):
$builder->add('regionUser');
$builder->add('roles' ,'choice' ,array('choices' => array(
"ROLE_ADMIN" => "ROLE_ADMIN",
"ROLE_USER" => "ROLE_USER",
),
'required' => true,
'multiple' => false,
));
When I execute this, I get the following error:
Expected argument of type "scalar", "array" given
What goes wrong? How to solve it?
There is 3 solutions:
Use a multiple choices field to show the roles field. Multiple
choices returns a array.
In your form, don't show the "roles" field.
Put a new field "role" only in your buildform, not in your entity.
(You can fill autmaticaly it with the role hierarchy if you want).
In the onSuccess method, get the "role" to set roles for your user.
$user->addRole( $role );
When you create your user class, don't use the UserInterface from
the FOSUserBundle. Copy it and change the prototype of the method.
// FOSUserBundle/UserInterface
function setRoles(array $roles);
// YourUserBundle/UserInterface
function setRoles($roles);
And change the method in your User Class
// FOSUserBundle/UserInterface
public function setRoles(array $roles)
{
$this->roles = array();
foreach ($roles as $role) {
$this->addRole($role);
}
}
// YourUserBundle/UserInterface
public function setRoles($roles)
{
if (is_string()) {
$this->addRole($roles);
} else {
$this->roles = array();
foreach ($roles as $role) {
$this->addRole($role);
}
}
}
You can find more information here: https://groups.google.com/group/symfony2/browse_thread/thread/3dd0d26bcaae4f82/4e091567abe764f9
http://blog.aelius.fr/blog/2011/11/allow-user-to-choose-role-at-registration-in-symfony2-fosuserbundle-2/
https://github.com/FriendsOfSymfony/FOSUserBundle