Пример #1
0
 /**
  * Send x copies of the registered item to a user.
  *
  * @param integer|Model_User $user
  * @param integer            $amount
  * @param string             $location
  *
  * @throws Item_Exception
  */
 public function to_user($user, $origin = "app", $amount = 1, $location = 'inventory')
 {
     if (!Valid::digit($amount)) {
         throw new Item_Exception('The supplied amount should be a number.');
     }
     if (Valid::digit($user)) {
         $user = ORM::factory('User', $user);
     } elseif (!is_a($user, 'Model_User')) {
         throw new Item_Exception('The supplied user does not come from a model.');
     }
     if (!$user->loaded()) {
         throw new Item_Exception('The supplied user does not exist.');
     } else {
         $user_item = ORM::factory('User_Item')->where('user_id', '=', $user->id)->where('item_id', '=', $this->_item->id)->where('location', '=', $location)->find();
         $action = $amount > 0 ? '+' : '-';
         if ($user_item->loaded()) {
             // update item amount
             $user_item->amount($action, $amount);
         } elseif ($action == '+') {
             $id = $this->_item->id;
             // create new copy
             $user_item = ORM::factory('User_Item')->values(array('user_id' => $user->id, 'item_id' => $id, 'location' => $location, 'amount' => $amount))->save();
         }
         return Journal::log('item.in.' . $origin, 'item', 'Player received :amount :item_name @ :origin', array(':amount' => $amount, ':item_name' => $user_item->item->name($amount, FALSE), ':origin' => str_replace('.', ' ', $origin)));
     }
 }
Пример #2
0
 protected function validate($value)
 {
     if (!Valid::digit($value)) {
         return 'digit';
     }
     if (!$this->repo->exists($value)) {
         return 'exists';
     }
 }
Пример #3
0
 public static function validate_material_amounts($validation, $materials, $amount_key = 'amount', $name_key = 'name')
 {
     $status = TRUE;
     foreach ($materials as $material) {
         if (!Valid::digit($material[$amount_key])) {
             $status = $false;
             $validation->error('materials', $material[$name_key] . '\'s amount should be a number.');
         }
     }
     return $status;
 }
Пример #4
0
 protected function validate($value)
 {
     if (!Valid::digit($value)) {
         return 'digit';
     }
     if (!$this->repo->exists($value)) {
         return 'exists';
     }
     $post = $this->repo->get($value);
     if (is_int($this->config['input']['form']) && $post->form_id !== $this->config['input']['form']) {
         return 'invalidForm';
     }
 }
Пример #5
0
 public static function check_data($value, $data)
 {
     switch ($data['type']) {
         case 'static':
             return TRUE;
         case 'module':
             return Valid::not_empty($value) and Valid::alpha_dash($value) and $value != '-';
         case 'page':
             return Valid::not_empty($value) and Valid::digit($value) and $value != '-' and $data['id'] != $value;
         case 'url':
             return Valid::not_empty($value) and Model_Page::check_link($value) and $value != '-';
     }
     return FALSE;
 }
Пример #6
0
 /**
  * Initialise the plugin and register all events that were defined in $this->_events.
  *
  * @return Kohana_Plugin
  * @throws Kohana_Exception
  */
 public final function init()
 {
     if ($this->_init() == true) {
         if (count($this->_events) > 0) {
             foreach ($this->_events as $id => $event) {
                 $class_event = Valid::digit($id) ? str_replace('.', '_', $event) : $id;
                 Plug::listen($event, array($this, 'on_' . $class_event));
             }
         }
         return $this;
     } else {
         throw new Kohana_Exception('Failed to initialise the ":plugin" plugin', array(':plugin' => $this->info['name']));
     }
 }
Пример #7
0
 /**
  * Top buttons
  *
  * @param array $links
  *
  * @return string
  */
 public static function btns_top(array $links = [])
 {
     $class = ['class' => 'btn btn-default btn-sm'];
     $html = PHP_EOL;
     foreach ($links as $url => $title) {
         if (!$title) {
             continue;
         }
         $action = explode('/', $url);
         $count = count($action) - 1;
         if (Valid::digit($action[$count])) {
             $action = $action[$count - 1];
         } else {
             $action = end($action);
         }
         switch ($action) {
             case 'add':
                 $html .= HTML::anchor($url, '<i class="fa fa-plus fa-fw"></i> ' . $title, $class) . PHP_EOL;
                 break;
             case 'edit':
                 $html .= HTML::anchor($url, '<i class="fa fa-edit fa-fw"></i> ' . $title, $class) . PHP_EOL;
                 break;
             case 'password':
                 $html .= HTML::anchor($url, '<i class="fa fa-key fa-fw"></i> ' . $title, $class) . PHP_EOL;
                 break;
             case 'profile':
                 $html .= HTML::anchor($url, '<i class="fa fa-user fa-fw"></i> ' . $title, $class) . PHP_EOL;
                 break;
             case 'filter':
                 if (Request::current()->action() == 'filter') {
                     $html .= HTML::anchor($url, '<i class="fa fa-filter fa-fw"></i> ' . $title, $class) . PHP_EOL;
                 }
                 break;
             case 'order':
                 $html .= HTML::anchor($url, '<i class="fa fa-sort fa-fw"></i> ' . $title, $class) . PHP_EOL;
                 break;
             case 'npupdate':
                 $html .= HTML::anchor($url, '<i class="fa fa-refresh fa-fw"></i> ' . $title, $class) . PHP_EOL;
                 break;
             case 'list':
                 if (Request::current()->query('colunm') and Request::current()->query('order')) {
                     $html .= HTML::anchor(Request::detect_uri(), '<i class="fa fa-angle-right fa-fw"></i> ' . $title, $class) . PHP_EOL;
                 } elseif (Request::current()->action() == 'deleted') {
                     $html .= HTML::anchor($url, '<i class="fa fa-list-ul fa-fw"></i> ' . $title, $class) . PHP_EOL;
                 }
                 break;
         }
     }
     return '<div class="btn-group">' . $html . '</div>';
 }
Пример #8
0
 public static function factory($object, $config = array(), Request $request = NULL, $query = FALSE)
 {
     $instance = parent::factory($object);
     $instance->set_config();
     $instance->set_config($config);
     $instance->query = $query;
     if ($request === NULL) {
         $request = Request::initial();
     }
     $instance->request = $request;
     $instance->route = $request->route();
     // Assign default route params
     $instance->route_params = array('directory' => $request->directory(), 'controller' => $request->controller(), 'action' => $request->action()) + $request->param();
     // get the current page
     $page = $request->param($instance->config['param']);
     if (!Valid::digit($page)) {
         $page = 1;
     }
     $instance->current_page = (int) $page;
     // limit the pagination results
     $instance->limit(($page - 1) * $instance->config['total_items'], $instance->config['total_items']);
     return $instance;
 }
Пример #9
0
Файл: sign.php Проект: anqh/core
 /**
  * Action: Password lost
  */
 public function action_password()
 {
     $this->history = false;
     $email = $message = '';
     // Handle request
     if ($_POST && ($email = trim(Arr::get($_POST, 'email', '')))) {
         $message = new View_Alert(__('We could not find any user or the user is missing email address, sorry.'), __('Uh oh,'));
         // Find the user, accept only strings
         $user = Valid::digit($email) ? false : Model_User::find_user(trim($email));
         // Send email
         if ($user && Valid::email($user->email)) {
             $subject = __('Your new :site password', array(':site' => Kohana::$config->load('site.site_name')));
             $mail = __("Forgot your password, :username?\n\nWe received a request to generate a new password for your :site account, please sign in and change your password. You should also delete this email.\n\nUsername: :username\nPassword: :password", array(':site' => Kohana::$config->load('site.site_name'), ':username' => Text::clean($user->username), ':password' => Visitor::generate_password($user->password)));
             if (Email::send($user->email, Kohana::$config->load('site.email_invitation'), $subject, $mail)) {
                 $message = new View_Alert(__(':email should soon receive the generated password in their inbox.', array(':email' => $email)), __('Mission accomplished!'), View_Alert::SUCCESS);
                 $email = '';
             }
         }
     }
     // Build page
     $this->view = View_Page::factory(__('Misplaced your password?'));
     $this->view->add(View_Page::COLUMN_MAIN, $this->section_password($message, $email));
 }
Пример #10
0
 public function validate($param)
 {
     return Valid::digit($param) and $param > 0;
 }
Пример #11
0
 protected function validate($value)
 {
     if (!Valid::digit($value)) {
         return 'digit';
     }
 }
Пример #12
0
 /**
  * @param null|string|array $key
  * @param null              $default
  * @param null              $delimiter
  *
  * @return array|mixed
  */
 protected function requestData($key = NULL, $default = NULL, $delimiter = NULL)
 {
     if (NULL === $this->_requestData) {
         $this->_requestData = Helpers_Arr::merge($this->request->query(), $this->request->post(), $this->_parse_request_body());
     }
     if (Kohana_Arr::is_array($key)) {
         $result = [];
         foreach ($key as $idx => $value) {
             if (!Valid::digit($idx)) {
                 $_key = $idx;
                 $_default = $value;
             } else {
                 $_key = $value;
                 $_default = $default;
             }
             $result[$_key] = Kohana_Arr::path($this->requestData(), $_key, $_default, $delimiter);
         }
     } else {
         $result = NULL === $key ? $this->_requestData : Kohana_Arr::path($this->requestData(), $key, $default, $delimiter);
     }
     return $result;
 }
Пример #13
0
<?php

include Kohana::find_file('views', 'errors/partial');
if (isset($oaclient->id) and Valid::digit($oaclient->id)) {
    $parms = array('id' => $oaclient->id, 'action' => 'edit');
    $btntxt = __("Save Changes");
} else {
    $parms = array('action' => 'register');
    $btntxt = __("Register");
}
echo Form::open(Route::get('oauth2/client')->uri($parms), array('class' => 'form form-horizontal', 'enctype' => 'multipart/form-data'));
?>
	<div class="row-fluid">
		<div class="form-group <?php 
echo isset($errors['title']) ? 'error' : '';
?>
">
			<?php 
echo Form::label('title', __('Title'), array('class' => 'control-label1'));
?>
			<div class="controls ">
				<?php 
echo Form::input('title', $oaclient->title, array('class' => 'col-sm-5'));
?>
			</div>
		</div>
		
		<div class="form-group <?php 
echo isset($errors['redirect_uri']) ? 'error' : '';
?>
">
Пример #14
0
 public function action_consume()
 {
     $item = ORM::factory('User_Item', $this->request->param('id'));
     $action = $this->request->post('action');
     $errors = array();
     if (!$item->loaded()) {
         Hint::error('You can\'t use an item that does not exist');
     } elseif ($item->user_id != $this->user->id) {
         Hint::error('You can\'t access another player\'s item');
     } elseif ($item->location != 'inventory') {
         Hint::error('The item you want to view is not located in your inventory');
     } elseif ($action == NULL) {
         Hint::error('No action to perform has been specified');
     } else {
         $def_cmd = Item_Command::factory($item->item->type->default_command);
         if (Valid::digit($action)) {
             // we'll want to perform an action on a pet
             $pet = ORM::factory('User_Pet', $action);
             if (!$pet->loaded()) {
                 Hint::error('No existing pet has been specified');
             } elseif ($pet->user_id != $this->user->id) {
                 Hint::error('You can\'t let a pet comsume this item if it\'s not yours');
             } elseif ($def_cmd->pets_required() == FALSE) {
                 Hint::error('can\'t perform this item action on a pet');
             } else {
                 $commands = $item->item->commands;
                 $results = array();
                 $db = Database::instance();
                 $db->begin();
                 $error = FALSE;
                 foreach ($commands as $command) {
                     $cmd = Item_Command::factory($command['name']);
                     $res = $cmd->perform($item, $command['param'], $pet);
                     if ($res == FALSE) {
                         // the command couldn't be performed, spit out error, rollback changes and break the loop
                         Hint::error(__(':item_name could not be used on :pet_name', array(':item_name' => $item->item->name, ':pet_name' => $pet->name)));
                         $error = TRUE;
                         $db->rollback();
                         break;
                     } else {
                         $results[] = $res;
                     }
                 }
                 if ($error == FALSE) {
                     $log = Journal::log('consume', 'item', ':item_name consumed', array(':item_name' => $item->item->name));
                     $log->notify('consume' . $item->item_id, 'item', ':item_name consumed');
                     if ($def_cmd->delete_after_consume == TRUE) {
                         $item->amount('-', 1);
                     }
                     $db->commit();
                 }
             }
         } else {
             $results = array();
             switch ($action) {
                 case 'consume':
                     $commands = $item->item->commands;
                     $results = array();
                     $db = Database::instance();
                     $db->begin();
                     $error = FALSE;
                     foreach ($commands as $command) {
                         $cmd = Item_Command::factory($command['name']);
                         $res = $cmd->perform($item, $command['param']);
                         if ($res == FALSE) {
                             // the command couldn't be performed, spit out error, rollback changes and break the loop
                             Hint::error(__(':item_name could not be used', array(':item_name' => $item->name)));
                             $db->rollback();
                             $error = TRUE;
                             break;
                         } else {
                             $results[] = $res;
                         }
                     }
                     if ($error = FALSE) {
                         Journal::log('consume' . $item->item_id, 'item', ':item_name consumed', array(':item_name' => $item->item->name));
                         if ($def_cmd->delete_after_consume == TRUE) {
                             $item->amount('-', 1);
                         }
                         $db->commit();
                     }
                     break;
                 case 'remove':
                     // takes an amount
                     $amount = $this->request->post('amount');
                     if ($amount == NULL) {
                         $amount = 1;
                     }
                     if (!Valid::digit($amount)) {
                         Hint::error('The amount you submitted isn\'t a number.');
                     } elseif ($amount <= 0 or $amount > $item->amount) {
                         Hint::error('You only have ' . $item->name() . ', not ' . $amount);
                     } else {
                         if ($amount > 1) {
                             $name = Inflector::plural($item->name(), $amount);
                             $verb = 'were';
                         } else {
                             $name = $item->item->name(1);
                             $verb = 'was';
                         }
                         $item->amount('-', $amount);
                         Journal::log('remove.' . $item->item_id, 'item', ':item_name removed', array(':item_name' => $name));
                         $results = __(':item :verb deleted successfully', array(':verb' => $verb, ':item' => $name));
                     }
                     break;
                 case 'gift':
                     // takes a username
                     $username = $this->request->post('username');
                     if ($this->user->username == $username) {
                         Hint::error('You can\'t send a gift to yourself');
                     } else {
                         $user = ORM::factory('User')->where('username', '=', $username)->find();
                         if ($user->loaded()) {
                             $log = $item->transfer($user);
                             $log->notify($user, 'items.gift', array(':item_name' => $item->item->name(1)));
                             $results = __('You\'ve successfully sent :item to :username', array(':item' => $item->item->name, ':username' => $user->username));
                         } else {
                             Hint::error(__('Couldn\'t find a user named ":username"', array(':username' => $username)));
                         }
                     }
                     break;
                 default:
                     // Moving items can take an amount
                     if (substr($action, 0, 5) == 'move_') {
                         $location = substr($action, 5);
                         $cmd = Item_Command::factory('Move_' . ucfirst($location));
                         $amount = $this->request->post('amount');
                         if ($amount == NULL) {
                             $amount = 1;
                         }
                         if (!Valid::digit($amount)) {
                             Hint::error('The amount you submitted isn\'t a number.');
                         } elseif ($amount <= 0 or $amount > $item->amount) {
                             Hint::error('You only have ' . $item->name() . ', not ' . $amount);
                         } else {
                             $results = $cmd->perform($item, $amount);
                         }
                     } else {
                         Hint::error('The action you want to perform with this item does not exist');
                     }
                     break;
             }
         }
     }
     $show = Kohana::$config->load('items.inventory.consume_show_results');
     $output = array();
     if (!is_array($results)) {
         $output[] = $results;
     } elseif ($show == 'first') {
         $output[] = $results[0];
     } elseif (!empty($results)) {
         foreach ($results as $result) {
             $output[] = $result;
         }
     }
     if ($this->request->is_ajax()) {
         $return = array();
         $return = Hint::dump();
         Hint::ajax_dump();
         if ($return['status'] == 'success') {
             $amount = $item->loaded() ? $item->name() : 0;
             $return = array_merge($return, array('result' => $output, 'new_amount' => $amount));
         }
         $this->response->headers('Content-Type', 'application/json');
         return $this->response->body(json_encode($return));
     }
     if (count($output) > 0) {
         foreach ($output as $result) {
             Hint::success($result);
         }
     }
     $this->redirect(Route::get('item.inventory')->uri());
 }
Пример #15
0
<?php

if (isset($widget->id) and Valid::digit($widget->id)) {
    $parms = array('id' => $widget->id, 'action' => 'edit');
    $split_name = explode('/', $widget->name);
    $static = ($split_name and $split_name[0] == 'static') ? TRUE : FALSE;
} else {
    $parms = array('action' => 'add');
    $static = TRUE;
}
echo Form::open(Route::get('admin/widget')->uri($parms), array('id' => 'widget-form', 'class' => 'form'));
?>

	<?php 
include Kohana::find_file('views', 'errors/partial');
?>

	<div class="row">
		<div class="col-md-6">

			<div class="form-group <?php 
echo isset($errors['title']) ? 'has-error' : '';
?>
">
				<?php 
echo Form::label('title', __('Title'), array('class' => 'control-label'));
?>
				<?php 
echo Form::input('title', $widget->title, array('class' => 'form-control'));
?>
			</div>
Пример #16
0
  public function get_items($limit = NULL, $offset = NULL, $orderby = NULL)
  {

    $items = $this->model
        ->order_by('created', $orderby)
        ->where('model_id', '=', $this->model->model_id)
        ->where('model_name', '=', $this->model->model_name);

    if (Valid::digit($limit))
    {
      $items->limit($limit);
    }
    if (Valid::digit($offset))
    {
      $items->offset($offset);
    }

    $items = $items->find_all();

    return $items;
  }
Пример #17
0
 /**
  * Create a reply for the provided topic.
  *
  * Required $values keys:
  *  - user_id
  *  - content
  *
  * Updates reply count for the topic, if enabled.
  * Adds last_post_user_id if enabled.
  *
  * if none of the above is enabled it 'touches' the topic to update the column 'updated_at' for ordering.
  *
  * @param Model_Quill_Topic|int $topic_id
  * @param array $values
  * @param null|Kohana_Validation $extra_validation
  * @return Model_Quill_Reply
  * @throws Kohana_Exception
  */
 public function create_reply($topic_id, $values, $extra_validation = null)
 {
     $topic = null;
     // Retrieve the topic
     if (is_a($topic_id, 'Kohana_Model_Quill_Topic')) {
         $topic = $topic_id;
     } else {
         if (!Valid::digit($topic)) {
             throw new Quill_Exception_Topic_Load('The provided topic id is not a number.');
         } else {
             $topic = ORM::factory('Quill_Topic', $topic_id);
         }
     }
     // check if the topic actually exists before going further
     if (!$topic->loaded()) {
         throw new Quill_Exception_Topic_Load('There\'s no topic to reply to.');
     }
     return $topic->create_reply($values, $extra_validation);
 }
Пример #18
0
 /**
  * Checks whether the given page number exists.
  *
  * @param   integer  page number
  * @return  boolean
  * @since   3.0.7
  */
 public function valid_page($page)
 {
     // Page number has to be a clean integer
     if (!Valid::digit($page)) {
         return FALSE;
     }
     return $page > 0 and $page <= $this->total_pages;
 }
Пример #19
0
 /**
  * @param array  $array
  * @param string $keyPrefix
  * @param string $delimeter
  * @param bool   $trimAsNULL
  *
  * @return array
  */
 public static function flattenExtended($array, $keyPrefix = '', $delimeter = '.', $trimAsNULL = TRUE)
 {
     $keyPrefix = trim($keyPrefix);
     $flat = [];
     foreach ($array as $key => $value) {
         $newKey = $keyPrefix . $key;
         if (static::is_array($value)) {
             $flat[Valid::digit($newKey) ? (int) $newKey : $newKey] = $value;
             $flat = static::merge($flat, static::flattenExtended($value, $newKey . $delimeter, $delimeter));
         } else {
             $flat[Valid::digit($newKey) ? (int) $newKey : $newKey] = $trimAsNULL ? Helpers_Text::trimAsNULL($value) : $value;
         }
     }
     return $flat;
 }
Пример #20
0
 public function action_inventory()
 {
     $shop = $this->_check_shop();
     if ($shop == FALSE) {
         $this->redirect(Route::get('item.user_shop.create')->uri());
     }
     if ($this->request->method() == HTTP_Request::POST and count($this->request->post('item')) > 0) {
         $lost_items = 0;
         $errors = FALSE;
         foreach ($this->request->post('item') as $id => $param) {
             $item = ORM::factory('User_Item', $id);
             if (!$item->loaded()) {
                 $lost_items++;
                 $errors = TRUE;
             } elseif ($item->user_id != $this->user->id) {
                 Hint::error('you\'re trying to change an item you don\'t own');
                 $errors = TRUE;
             } elseif ($item->location != 'shop') {
                 Hint::error('You\'re trying to change an item that\'s not located in your shop');
                 $errors = TRUE;
             } elseif (isset($param['remove']) and $param['remove'] == TRUE) {
                 // move the item to the inventory
                 $item->move('inventory', '*');
             } elseif (Valid::digit($param['price']) and $param['price'] > -1) {
                 // update the item's price
                 $item->parameter = $param['price'];
                 $item->save();
             }
         }
         if ($lost_items > 0) {
             Hint::error('Some items don\'t seem to exist anymore.');
         } elseif ($errors != TRUE) {
             Hint::success('You\'ve successfully updated your shop\'s stock.');
         }
     }
     $this->redirect(Route::get('item.user_shop.stock')->uri(array('page' => $this->request->param('page'))));
 }
Пример #21
0
 /**
  * Merge 2 replies into 1.
  *
  * @param integer|Model_Quill_Reply $reply
  * @param bool $same_user Should the replies be made by the same user?
  * @throws Kohana_Exception
  */
 public static function merge_prev_reply($reply, $same_user = true)
 {
     // if an ID was specified
     if (Valid::digit($reply)) {
         $reply = ORM::factory('Quill_Reply', $reply);
     }
     //if the model wasn't loaded
     if (!is_a($reply, 'Kohana_Model_Quill_Reply') || !$reply->loaded()) {
         throw new Kohana_Exception('No reply to merge');
     }
     //load the previous reply
     $prev_reply = ORM::factory('Quill_Reply')->where('id', '<', $reply->id)->where('topic_id', '=', $reply->topic_id)->order_by('id', 'DESC')->limit(1)->find();
     //check if it's there
     if (!$prev_reply->loaded()) {
         throw new Kohana_Exception('No previous reply to merge with');
     }
     //check if the replies were made by the same user
     if ($same_user == true && $reply->user_id != $prev_reply->user_id) {
         throw new Kohana_Exception('Both replies come from a different user.');
     }
     //if the content is different we'll append it
     if ($prev_reply->content != $reply->content) {
         $reply->content .= '\\n\\n' . $prev_reply->content;
         $reply->save(null, false);
     }
     //delete the previous reply
     $prev_reply->delete();
 }
Пример #22
0
 /**
  * Move this topic to a different category.
  *
  * @param integer|Kohana_Model_Quill_Category $location
  * @throws Kohana_Exception
  */
 public function move($location)
 {
     if (Valid::digit($location)) {
         $location = ORM::factory('Quill_Category', $location);
     }
     if (!is_a($location, 'Model_Quill_Category') || !$location->loaded()) {
         throw new Quill_Exception_Topic_Move('Specify a category to which you want to move topic ":id" to.', array(':id' => $this->id));
     }
     if ($this->status == 'active') {
         $this->category->topic_count -= 1;
         $this->category->save();
     }
     $this->category_id = $location->id;
     $this->save();
     if ($this->status == 'active') {
         $location->topic_count += 1;
         $location->save();
     }
     return $this;
 }
Пример #23
0
 /**
  * Tests Valid::digit()
  *
  * @test
  * @dataProvider provider_digit
  * @param mixed   $input     Input to validate
  * @param boolean $expected  Is $input valid
  */
 public function test_digit($input, $expected, $contains_utf8 = FALSE)
 {
     if (!$contains_utf8) {
         $this->assertSame($expected, Valid::digit($input));
     }
     $this->assertSame($expected, Valid::digit($input, TRUE));
 }
Пример #24
0
 public function action_save()
 {
     if (!$this->user->can('Admin_Item_Recipes_Save')) {
         throw HTTP_Exception::factory('403', 'Permission denied to view admin item recipes save');
     }
     $this->view = NULL;
     $values = $this->request->post();
     if ($values['id'] == 0) {
         $values['id'] = NULL;
     }
     $id = $values['id'];
     $this->response->headers('Content-Type', 'application/json');
     try {
         // validate crafted item
         $crafted = ORM::factory('Item')->where('item.name', '=', $values['crafted_item'])->find();
         if ($crafted->loaded()) {
             // validate item materials
             $mat_fail = FALSE;
             if (count($values['materials']) > 0) {
                 foreach ($values['materials'] as $index => $material) {
                     $mat = ORM::factory('Item')->where('item.name', '=', $material['name'])->find();
                     if (!$mat->loaded()) {
                         $mat_fail = $material['name'] . ' does not exist';
                         break;
                     } elseif (!Valid::digit($material['amount'])) {
                         $mat_fail = $material['name'] . '\'s amount should be a number';
                         break;
                     } else {
                         $values['materials'][$index]['item'] = $mat->id;
                     }
                 }
             }
             if ($mat_fail == FALSE) {
                 $values['crafted_item_id'] = $crafted->id;
                 $item = ORM::factory('Item_Recipe', $values['id']);
                 $item->values($values, array('name', 'description', 'crafted_item_id'));
                 $item->save();
                 if (count($values['materials']) > 0) {
                     // if we're updating delete old data
                     if ($values['id'] != NULL) {
                         foreach ($item->materials->find_all() as $mat) {
                             $mat->delete();
                         }
                     }
                     foreach ($values['materials'] as $key => $ingredient) {
                         $mat = ORM::factory('Item_Recipe_Material');
                         $mat->item_id = $ingredient['item'];
                         $mat->amount = $ingredient['amount'];
                         $mat->item_recipe_id = $item->id;
                         $mat->save();
                     }
                 }
                 $data = array('action' => 'saved', 'type' => $id == NULL ? 'new' : 'update', 'row' => array($item->name, $item->materials->count_all(), URL::base() . $item->item->img(), $item->id));
                 $this->response->body(json_encode($data));
             } else {
                 return $this->response->body(json_encode(array('action' => 'error', 'errors' => array(array('field' => 'ingredients', 'msg' => array($mat_fail))))));
             }
         } else {
             return $this->response->body(json_encode(array('action' => 'error', 'errors' => array(array('field' => 'crafted_item', 'msg' => array('This item does not seem to exist.'))))));
         }
     } catch (ORM_Validation_Exception $e) {
         $errors = array();
         $list = $e->errors('models');
         foreach ($list as $field => $er) {
             if (!is_array($er)) {
                 $er = array($er);
             }
             $errors[] = array('field' => $field, 'msg' => $er);
         }
         $this->response->body(json_encode(array('action' => 'error', 'errors' => $errors)));
     }
 }