werein/prestashop

View on GitHub
lib/prestashop/mapper/extension.rb

Summary

Maintainability
A
1 hr
Test Coverage
module Prestashop
  module Mapper
    module Extension
      module ClassMethods

        # Determinate if model with class resource exists with given id
        #
        #   Car.exists?(1) # => true # if given car exist
        #   Car.exists?(2) # => false # if given car don't exist
        #
        def exists? id
          Client.check self.resource, id
        end

        # Find model by class resource and given id, returns hash
        # with all nodes, based on node name as key, node value as value
        #
        #   Car.find(1) # => { id: 1, name: 'BMW' }
        #   Car.find(2) # => nil
        #
        def find id
          result = Client.read self.resource, id
          result ? result[self.model] : nil
        end

        # Find model by class resource and params in hash
        # Returns first result, see #where for more informations
        #
        #   Car.find_by(name: 'BMW') # => 1
        #
        def find_by options = {}
          results = where(options)
          results ? results.first : nil
        end

        # Get models all results by class resource, you can specifi what
        # you should to see as result by specifiyng +:display+
        #
        #   Car.all # => [1,2,3]
        #   Car.all(display: ['name']) # => [{ name: { language: { attr: { id: 2, href: 'http://localhost.com/api/languages/2'}, val: 'BMW 7'} }]
        #
        def all options = {}
          result = Client.read self.resource, nil, options
          handle_result result, options
        end
        
        # Get results by class resource and given conditionals
        #
        #   Car.where('filter[id_supplier' => 1) # => [1, 2]
        # 
        def where options = {}
          result = Client.read self.resource, nil, options
          handle_result result, options
        end

        # Destroy model by class resource and given id
        #
        #   Car.destroy(1) # => true
        #
        def destroy id
          Client.delete self.resource, id
        end

        # Create hash suitable for update, contains #fixed_hash as hash with deleted
        # keys, which shouldn't be in payload, if exist
        #
        #   Car.update_hash(1, name: 'BMW7') # => {name: 'BMW7', manufacturer: 'BMW'}
        #
        def update_hash id, options = {}
          original = defined?(fixed_hash(nil)) ? fixed_hash(id) : find(id)
          original.merge(options)
        end

        # Create payload for update, converts hash to XML
        #
        #   Car.update_payload(1, name: 'BMW 7') # => <prestashop xmlns:xlink="http://www.w3.org/1999/xlink"><car><name><![CDATA[BMW 7]]></name></car></prestashop>
        #
        def update_payload id, options = {}
          Api::Converter.build(self.resource, self.model, update_hash(id, options))
        end

        # Update model, with class resource by +id+ and given updates
        #
        #   Car.update(1, name: 'BMW 7') # => {id: 1, name: 'BMW 7'}
        #
        def update id, options = {}
          result = Client.update self.resource, id, update_payload(id, options)
          result ? result[self.model] : nil
        end 

        private
          # Handle result to return +id+ or array with +ids+ of requested objects
          # 
          #   handle_result({ customers: { customer: [ 1,2 ] } }) # => [1, 2]
          #   handle_result({ customers: { customer: { attr: { id: 1 }} } }) # => [1]
          #
          def handle_result result, options = {}
            if options[:display]
              if result[self.resource].kind_of?(Hash) and result[self.resource][self.model]
                objects = result[self.resource][self.model]
                objects.kind_of?(Array) ? objects : [objects]
              end
            else
              if result[self.resource].kind_of?(Hash) and result[self.resource][self.model]
                [objects = result[self.resource][self.model]]
                objects.kind_of?(Array) ? objects.map{ |o| o[:attr][:id] } : [ objects[:attr][:id] ]
              else
                nil
              end    
            end
          end
      end
      
      module InstanceMethods

        # Generate hash with ID
        #
        #   car.hash_id(1) # => {id: 1}
        #
        def hash_id id
          { id: id } if id
        end

        # Make array of unique IDs in hash
        #
        #   car.hash_ids(1,2,3) # => [{id: 1},{id: 2},{id: 3}]
        # 
        def hash_ids ids
          ids.flatten.uniq.map{|id| hash_id(id)} if ids
        end

        # Create payload for create new object, coverts hash to XML
        #
        #   car.payload # => '<prestashop xmlns:xlink="http://www.w3.org/1999/xlink"><car><name><![CDATA[BMW 7]]></name><manufacturer><![CDATA[BMW]]></manufacturer></car></prestashop>'
        #
        def payload
          Api::Converter.build(self.class.resource, self.class.model, hash)
        end

        # Create new model from instance, based on class resource a payload generated from
        # hash method
        # 
        #   Car.new(name: 'BMW 7', manufacturer: 'BMW').create # => { id: 1, name: 'BMW 7', manufacturer: 'BMW' }
        # 
        def create
          result = Client.create self.class.resource, payload
          result ? result[self.class.model] : nil
        end
      end
      
      def self.included(receiver)
        receiver.extend         ClassMethods
        receiver.send :include, InstanceMethods
      end
    end
  end
end