bitrix_on_rails 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +20 -0
- data/LICENSE.txt +20 -0
- data/README +0 -0
- data/README.rdoc +86 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/app/models/iblock.rb +87 -0
- data/app/models/iblock_element.rb +108 -0
- data/app/models/iblock_element_property.rb +6 -0
- data/app/models/iblock_field.rb +6 -0
- data/app/models/iblock_group.rb +6 -0
- data/app/models/iblock_property.rb +32 -0
- data/app/models/iblock_property_enum.rb +6 -0
- data/app/models/iblock_section.rb +30 -0
- data/app/models/iblock_section_element.rb +8 -0
- data/app/models/iblock_type.rb +5 -0
- data/bitrix_on_rails.gemspec +77 -0
- data/init.rb +1 -0
- data/lib/active_record/connection_adapters/mysql2_downcase_adapter.rb +76 -0
- data/lib/bitrix_on_rails.rb +21 -0
- data/lib/bitrix_on_rails/active_record.rb +28 -0
- data/lib/bitrix_on_rails/engine.rb +4 -0
- data/lib/bitrix_on_rails/iblock_element_prop_m.rb +64 -0
- data/lib/bitrix_on_rails/iblock_element_prop_s.rb +119 -0
- data/test/helper.rb +18 -0
- data/test/test_bitrix_on_rails.rb +7 -0
- metadata +125 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.6.4"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
git (1.2.5)
|
5
|
+
jeweler (1.6.4)
|
6
|
+
bundler (~> 1.0)
|
7
|
+
git (>= 1.2.5)
|
8
|
+
rake
|
9
|
+
rake (0.9.2)
|
10
|
+
rcov (0.9.9)
|
11
|
+
shoulda (2.11.3)
|
12
|
+
|
13
|
+
PLATFORMS
|
14
|
+
ruby
|
15
|
+
|
16
|
+
DEPENDENCIES
|
17
|
+
bundler (~> 1.0.0)
|
18
|
+
jeweler (~> 1.6.4)
|
19
|
+
rcov
|
20
|
+
shoulda
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Danil Pismenny
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
File without changes
|
data/README.rdoc
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
= bitrix_on_rails
|
2
|
+
|
3
|
+
Приблуды для использования под рельсами базы 1С:Битрикс.
|
4
|
+
|
5
|
+
Для каждого инфоблока что лежит в b_iblock есть своя таблица название которой с номером инфоблока, например b_iblock_element_prop_s7
|
6
|
+
prop_s - для одиночных свойтсв, prop_m - для множестенный.
|
7
|
+
У каждого инфоблока нескоолько секций (iblock_section), в каждой секции несколько элементов (iblock_element) у каждого элемента разные свойства которые лежат в prop_s/_m.
|
8
|
+
Соответсвенно я эти свойства вытащил в одно место - они все доступны из модели IblockElement. Или напрямую; IblockElement.find(123).НАЗВАНИЕ_СВОЙСТВА или через метод properties
|
9
|
+
|
10
|
+
== Что есть:
|
11
|
+
|
12
|
+
=== mysql2_downcase адаптер
|
13
|
+
1. Адаптер mysql2_downcase для автоматической конвертации заглавных наименований полей в прописные.
|
14
|
+
|
15
|
+
=== Инфоблоки
|
16
|
+
|
17
|
+
1. Все модели для таблиц b_iblock_*
|
18
|
+
2. Автоматическая установка свойств из таблиц prop_s*/prop_m* в методы объекта IblockElement.
|
19
|
+
Например IblockElement.find(1).name_emittents, где name_emittent - свойство из prop_s.
|
20
|
+
Все подобные свойства также доступны через метод IblockElement#properties.
|
21
|
+
|
22
|
+
3. IblockElementS*
|
23
|
+
1. Тоже самое и для моделей IblockElementPropertyS*, плюс в них значения полей можно еще и устанавливать:
|
24
|
+
|
25
|
+
p = IblockElementPropertyS3.find(1)
|
26
|
+
p.name_emittents='новое имя'
|
27
|
+
p.save
|
28
|
+
|
29
|
+
2. Поиск по кодовым названиям полей таблицы
|
30
|
+
|
31
|
+
IblockElementPropertyS3.find_by_post_id(123)
|
32
|
+
|
33
|
+
вместо
|
34
|
+
|
35
|
+
.find_by_property_149(123)
|
36
|
+
|
37
|
+
Таким образом если мы знаем что инфоблок S3 связан с таблицей постов и хотим получить все свойства поста 63, делаем:
|
38
|
+
|
39
|
+
IblockElementPropS3.find_by_post_id(63).iblock_element.properties
|
40
|
+
|
41
|
+
3. IblockElement.properties выдает хеш соответсвия кодов свойств и названия их полей в prop_s
|
42
|
+
Автоматическое определение привязки элемента к объекту. Например: если мы спрашиваем iblock_element.post
|
43
|
+
то он ищет ключ :post_id в свойствах элемента, и если находит, то возвращает Post.find_by_id(properties[:post_id])
|
44
|
+
|
45
|
+
4. Все свойства IblockProperty кешируются и доступны через find(id)
|
46
|
+
|
47
|
+
5. В IblockElement автоматически добавляются has_one :iblock_element_prop_s* и has_many :iblock_element_prop_m* при создании соответвующих классов.
|
48
|
+
|
49
|
+
6. Модель можно расширять инфоблоком с помощью:
|
50
|
+
|
51
|
+
class Post << ActiveRecord::Base
|
52
|
+
|
53
|
+
has_infoblock(3, :property_19) # где property_19 поле ссылающееся на Post
|
54
|
+
|
55
|
+
для этой модели автоматически создадутся ассоциации
|
56
|
+
|
57
|
+
:iblock_element - класс PostElement
|
58
|
+
|
59
|
+
Класс PostElement будет иметь ассоциации
|
60
|
+
|
61
|
+
:property_set (он же iblock_element_prop_sNUMBER) и
|
62
|
+
:m_prop_values
|
63
|
+
|
64
|
+
а также default_scope с номером инфоблока, поэтому PostElement.all выдаст только элементы к специфичному инфоблоку
|
65
|
+
|
66
|
+
|
67
|
+
=== Битрикс-авторизация
|
68
|
+
|
69
|
+
== mysql2_downcase
|
70
|
+
|
71
|
+
Подключать просто:
|
72
|
+
|
73
|
+
development:
|
74
|
+
adapter: mysql2_downcase
|
75
|
+
encoding: cp1251
|
76
|
+
...
|
77
|
+
|
78
|
+
== Contributing to bitrix_on_rails
|
79
|
+
|
80
|
+
* С нетерпением жду форков, пулеквестов, замечаний и предложений.
|
81
|
+
|
82
|
+
== Copyright
|
83
|
+
|
84
|
+
Copyright (c) 2011 Danil Pismenny. See LICENSE.txt for
|
85
|
+
further details.
|
86
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "bitrix_on_rails"
|
18
|
+
gem.homepage = "http://github.com/dapi/bitrix_on_rails"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Работа с инфоблоками 1С-Битрикс}
|
21
|
+
gem.description = %Q{Использование инфоблоков 1С-Битрикс в Ruby On Rails проектах}
|
22
|
+
gem.email = "danil@orionet.ru"
|
23
|
+
gem.authors = ["Danil Pismenny"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'rcov/rcovtask'
|
36
|
+
Rcov::RcovTask.new do |test|
|
37
|
+
test.libs << 'test'
|
38
|
+
test.pattern = 'test/**/test_*.rb'
|
39
|
+
test.verbose = true
|
40
|
+
test.rcov_opts << '--exclude "gems/*"'
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "bitrix_on_rails #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class Iblock < ActiveRecord::Base
|
3
|
+
set_table_name :b_iblock
|
4
|
+
|
5
|
+
# version - 1 или 2
|
6
|
+
|
7
|
+
# iblock_type_id это строка, поэтом он срабатывает только если его указывать явано в foreign_key
|
8
|
+
belongs_to :iblock_type, :foreign_key=>'iblock_type_id'
|
9
|
+
|
10
|
+
# Они еще связаны между собой через iblock_section_element
|
11
|
+
has_many :iblock_sections
|
12
|
+
has_many :iblock_elements
|
13
|
+
|
14
|
+
# has_many :iblock_section_elements, :through=>:iblock_sections
|
15
|
+
|
16
|
+
# Список типов свойств по номерам которых создаются поля в
|
17
|
+
# таблицах iblock_element_prop_sN
|
18
|
+
has_many :iblock_properties
|
19
|
+
|
20
|
+
has_many :iblock_fields
|
21
|
+
has_many :iblock_groups
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def s_props_class(id)
|
25
|
+
# raise 'Только для инфоблоков 2-й версии' unless version==2
|
26
|
+
"IblockElementPropS#{id}".constantize
|
27
|
+
end
|
28
|
+
|
29
|
+
def m_props_class(id)
|
30
|
+
# raise 'Только для инфоблоков 2-й версии' unless version==2
|
31
|
+
"IblockElementPropM#{id}".constantize
|
32
|
+
end
|
33
|
+
|
34
|
+
def all
|
35
|
+
@cached_all ||= super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
name
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def init_property_models
|
45
|
+
return unless version==2
|
46
|
+
iblock_id = self.id
|
47
|
+
|
48
|
+
# Создаем классы IblockElementPropSНОМЕР
|
49
|
+
#
|
50
|
+
const_name = "IblockElementPropS#{iblock_id}"
|
51
|
+
unless Kernel.const_defined? const_name
|
52
|
+
e = Class.new(ActiveRecord::Base) do
|
53
|
+
extend BitrixOnRails::IblockElementPropS
|
54
|
+
|
55
|
+
class << self
|
56
|
+
@m_prop_class = nil
|
57
|
+
@m_props = nil
|
58
|
+
|
59
|
+
def m_prop_class
|
60
|
+
Kernel.const_get(@m_prop_class)
|
61
|
+
end
|
62
|
+
|
63
|
+
def m_props
|
64
|
+
@m_props
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
acts_as_iblock_element_prop_s(iblock_id)
|
69
|
+
end
|
70
|
+
Kernel.const_set const_name, e
|
71
|
+
end
|
72
|
+
Kernel.const_get(const_name).init
|
73
|
+
|
74
|
+
# Создаем классы IblockElementPropMНОМЕР
|
75
|
+
#
|
76
|
+
const_name = "IblockElementPropM#{iblock_id}"
|
77
|
+
unless Kernel.const_defined? const_name
|
78
|
+
e = Class.new(ActiveRecord::Base) do
|
79
|
+
extend BitrixOnRails::IblockElementPropM
|
80
|
+
acts_as_iblock_element_prop_m(iblock_id)
|
81
|
+
end
|
82
|
+
Kernel.const_set "IblockElementPropM#{iblock_id}", e
|
83
|
+
end
|
84
|
+
Kernel.const_get(const_name).init
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class IblockElement < ActiveRecord::Base
|
3
|
+
class << self
|
4
|
+
@block_id = nil
|
5
|
+
@iblock_properties = nil
|
6
|
+
|
7
|
+
def iblock_id
|
8
|
+
@iblock_id
|
9
|
+
end
|
10
|
+
|
11
|
+
def iblock_properties
|
12
|
+
@iblock_properties
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
set_table_name :b_iblock_element
|
17
|
+
|
18
|
+
belongs_to :iblock
|
19
|
+
belongs_to :iblock_section
|
20
|
+
|
21
|
+
# Применяется только для iblock-ов 1-й версии
|
22
|
+
#
|
23
|
+
has_many :iblock_element_properties
|
24
|
+
|
25
|
+
# Применяется для iblock-ов 2-й версии
|
26
|
+
#
|
27
|
+
has_many :iblock_section_elements
|
28
|
+
has_many :iblock_sections, :through => :iblock_section_elements
|
29
|
+
|
30
|
+
after_find :initialize_properties
|
31
|
+
|
32
|
+
attr_accessor :properties
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
name
|
36
|
+
end
|
37
|
+
|
38
|
+
def s_props
|
39
|
+
# has_one
|
40
|
+
@s_props ||= Iblock.s_props_class(iblock_id).find_by_iblock_element_id( id )
|
41
|
+
end
|
42
|
+
|
43
|
+
def iblock_element_prop_m
|
44
|
+
Iblock.m_props_class(iblock_id).where(:iblock_element_id=>id)
|
45
|
+
end
|
46
|
+
|
47
|
+
def m_props
|
48
|
+
# TODO Cache
|
49
|
+
@m_props={}
|
50
|
+
iblock_element_prop_m.each do |p|
|
51
|
+
@m_props[p.code]||=[]
|
52
|
+
@m_props[p.code] << p.get_value
|
53
|
+
end
|
54
|
+
@m_props
|
55
|
+
end
|
56
|
+
|
57
|
+
# Если мы спрашиваем iblock_element.post
|
58
|
+
# то он ищет ключ :post_id в свойствах элемента
|
59
|
+
# и если находит, то возвращает Post.find_by_id(properties[:post_id])
|
60
|
+
#
|
61
|
+
def method_missing(method, *args)
|
62
|
+
id_name = "#{method}_id".to_sym
|
63
|
+
if properties and properties.include?(id_name)
|
64
|
+
# TODO Проверять на наличие такого класса и то что он ActiveRecord
|
65
|
+
# Кешировать
|
66
|
+
method.to_s.capitalize.constantize.find_by_id(properties[id_name])
|
67
|
+
else
|
68
|
+
super
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.set_iblock_id(id)
|
73
|
+
@iblock_id = id
|
74
|
+
@iblock_properties = IblockProperty.where(:iblock_id => id).inject({}){ |a,e| a[e.code] = e.id; a }
|
75
|
+
|
76
|
+
prop_s_class = "::IblockElementPropS#{id}"
|
77
|
+
prop_m_class = "::IblockElementPropM#{id}"
|
78
|
+
|
79
|
+
has_one :property_set, :class_name => prop_s_class, :foreign_key => 'iblock_element_id', :autosave => true
|
80
|
+
has_many :m_prop_values, :class_name => prop_m_class, :foreign_key => 'iblock_element_id'
|
81
|
+
|
82
|
+
default_scope where(:iblock_id => id, :active => 'Y')
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def initialize_properties
|
88
|
+
# TODO Могу повторяться именя в m_props, ругаться чтоли
|
89
|
+
@properties = (s_props ? s_props.properties : {}).merge m_props
|
90
|
+
|
91
|
+
# TODO Переписать на автоматическое определение названия свойства в моделях property_set и m_prop_values
|
92
|
+
# чтобы уйти от хеша @properties (оставить его массивом для дебаггинга)
|
93
|
+
|
94
|
+
# TODO Сделать в элементе автоделегейт
|
95
|
+
@properties.keys.each do |prop|
|
96
|
+
# TODO Перенести на прямой вызов объектов s_props/m_props
|
97
|
+
instance_eval "def #{prop}; @properties[:#{prop}]; end"
|
98
|
+
instance_eval "def #{prop}=(val); @properties[:#{prop}]=property_set.#{prop}=val; end"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# Это здесь для того чтобы при перезагрузке в development
|
106
|
+
# режиме заново создавались ассоциации iblock_element_prop_s3
|
107
|
+
# TODO переделать на более элегантное решение
|
108
|
+
Iblock.all.map &:init_property_models
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class IblockProperty < ActiveRecord::Base
|
3
|
+
set_table_name :b_iblock_property
|
4
|
+
|
5
|
+
belongs_to :iblock
|
6
|
+
|
7
|
+
# TODO Что это за link_iblock?
|
8
|
+
belongs_to :link_iblock, :class_name=>'Iblock'
|
9
|
+
|
10
|
+
has_many :iblock_property_enums, :foreign_key=>:property_id
|
11
|
+
has_many :iblock_element_properties
|
12
|
+
|
13
|
+
cattr_accessor :cache
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def find(id)
|
17
|
+
cache_all unless @@cache
|
18
|
+
@@cache[id] or raise "Не найдено такое свойство iblock_property #{id}"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Запускается в ./lib/bitrix_on_rails при загрузке
|
22
|
+
def cache_all
|
23
|
+
@@cache = IblockProperty.all.inject({}) { |hash, prop| hash[prop.id]=prop; hash }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def code
|
28
|
+
val = read_attribute('code')
|
29
|
+
return nil if val.nil?
|
30
|
+
val.downcase.to_sym
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class IblockSection < ActiveRecord::Base
|
3
|
+
class << self
|
4
|
+
@iblock_id = nil
|
5
|
+
|
6
|
+
def iblock_id
|
7
|
+
@iblock_id
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
set_table_name :b_iblock_section
|
12
|
+
|
13
|
+
belongs_to :iblock
|
14
|
+
|
15
|
+
default_scope order(:sort)
|
16
|
+
|
17
|
+
has_many :direct_iblock_elements, :class_name=>'IblockElement'
|
18
|
+
|
19
|
+
has_many :iblock_section_elements
|
20
|
+
has_many :iblock_elements, :through => :iblock_section_elements
|
21
|
+
|
22
|
+
def self.set_iblock_id(id)
|
23
|
+
@iblock_id = id
|
24
|
+
default_scope where(:iblock_id => id, :active => 'Y')
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
name
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{bitrix_on_rails}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Danil Pismenny"]
|
12
|
+
s.date = %q{2011-08-02}
|
13
|
+
s.description = %q{Использование инфоблоков 1С-Битрикс в Ruby On Rails проектах}
|
14
|
+
s.email = %q{danil@orionet.ru}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README",
|
18
|
+
"README.rdoc"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
".document",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README",
|
26
|
+
"README.rdoc",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"app/models/iblock.rb",
|
30
|
+
"app/models/iblock_element.rb",
|
31
|
+
"app/models/iblock_element_property.rb",
|
32
|
+
"app/models/iblock_field.rb",
|
33
|
+
"app/models/iblock_group.rb",
|
34
|
+
"app/models/iblock_property.rb",
|
35
|
+
"app/models/iblock_property_enum.rb",
|
36
|
+
"app/models/iblock_section.rb",
|
37
|
+
"app/models/iblock_section_element.rb",
|
38
|
+
"app/models/iblock_type.rb",
|
39
|
+
"bitrix_on_rails.gemspec",
|
40
|
+
"init.rb",
|
41
|
+
"lib/active_record/connection_adapters/mysql2_downcase_adapter.rb",
|
42
|
+
"lib/bitrix_on_rails.rb",
|
43
|
+
"lib/bitrix_on_rails/active_record.rb",
|
44
|
+
"lib/bitrix_on_rails/engine.rb",
|
45
|
+
"lib/bitrix_on_rails/iblock_element_prop_m.rb",
|
46
|
+
"lib/bitrix_on_rails/iblock_element_prop_s.rb",
|
47
|
+
"test/helper.rb",
|
48
|
+
"test/test_bitrix_on_rails.rb"
|
49
|
+
]
|
50
|
+
s.homepage = %q{http://github.com/dapi/bitrix_on_rails}
|
51
|
+
s.licenses = ["MIT"]
|
52
|
+
s.require_paths = ["lib"]
|
53
|
+
s.rubygems_version = %q{1.6.2}
|
54
|
+
s.summary = %q{Работа с инфоблоками 1С-Битрикс}
|
55
|
+
|
56
|
+
if s.respond_to? :specification_version then
|
57
|
+
s.specification_version = 3
|
58
|
+
|
59
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
60
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
61
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
62
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
63
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
66
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
67
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
68
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
69
|
+
end
|
70
|
+
else
|
71
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
72
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
73
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
74
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bitrix_on_rails'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Just use 'mysql2_downcase' adapter in database.yml
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'active_record/connection_adapters/mysql2_adapter'
|
6
|
+
|
7
|
+
module ActiveRecord
|
8
|
+
class Base
|
9
|
+
# Establishes a connection to the database that's used by all Active Record objects.
|
10
|
+
def self.mysql2_downcase_connection(config)
|
11
|
+
config[:username] = 'root' if config[:username].nil?
|
12
|
+
|
13
|
+
if Mysql2::Client.const_defined? :FOUND_ROWS
|
14
|
+
config[:flags] = Mysql2::Client::FOUND_ROWS
|
15
|
+
end
|
16
|
+
|
17
|
+
client = Mysql2::Client.new(config.symbolize_keys)
|
18
|
+
options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0]
|
19
|
+
ConnectionAdapters::Mysql2DowncaseAdapter.new(client, logger, options, config)
|
20
|
+
# ActiveRecord::Base.mysql2_connection(config)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Result
|
25
|
+
|
26
|
+
# Это выполняется через ActiveRecord::Result.new в mysql2_adapter
|
27
|
+
# при выполнении запроса
|
28
|
+
def initialize(columns, rows)
|
29
|
+
@columns = columns.map { |c| c.downcase }
|
30
|
+
@rows = rows
|
31
|
+
@hash_rows = nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module ConnectionAdapters
|
36
|
+
class Column
|
37
|
+
|
38
|
+
alias_method :old_initialize, :initialize
|
39
|
+
|
40
|
+
# Это выполняется при выборке списка аттрибутов на уровне класса
|
41
|
+
#
|
42
|
+
def initialize(name, default, sql_type = nil, null = true)
|
43
|
+
old_initialize name.downcase, default, sql_type, null
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
class Mysql2DowncaseAdapter < Mysql2Adapter
|
49
|
+
|
50
|
+
ADAPTER_NAME = 'Mysql2Downcase'
|
51
|
+
|
52
|
+
# Надо бы глобально сделать тут:
|
53
|
+
# def execute(sql, name = nil)
|
54
|
+
# debugger
|
55
|
+
# end
|
56
|
+
|
57
|
+
# Это чтобы нормально определся primary_key
|
58
|
+
def pk_and_sequence_for(table)
|
59
|
+
keys = []
|
60
|
+
result = execute("DESCRIBE #{quote_table_name(table)}", 'SCHEMA')
|
61
|
+
result.each(:symbolize_keys => true, :as => :hash) do |row|
|
62
|
+
keys << row[:Field].downcase if row[:Key] == "PRI"
|
63
|
+
end
|
64
|
+
keys.length == 1 ? [keys.first, nil] : nil
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
# Возможно понадобится исправить этот метод
|
73
|
+
# quote_column_name
|
74
|
+
|
75
|
+
# Хороший пример адаптера - http://virtuoso.rubyforge.org/activerecord-mysql2spatial-adapter/
|
76
|
+
# https://github.com/dazuma/activerecord-mysql2spatial-adapter
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# require 'rails'
|
3
|
+
|
4
|
+
module BitrixOnRails
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'active_record'
|
8
|
+
|
9
|
+
require 'bitrix_on_rails/active_record'
|
10
|
+
require 'bitrix_on_rails/iblock_element_prop_s'
|
11
|
+
require 'bitrix_on_rails/iblock_element_prop_m'
|
12
|
+
# require 'bitrix_on_rails/engine'
|
13
|
+
|
14
|
+
# ActiveRecord::Base.connection.tables
|
15
|
+
|
16
|
+
ActiveRecord::Base.extend BitrixOnRails::ActiveRecord
|
17
|
+
|
18
|
+
# Просто подгружаем модель, тогда в ней появятся ассоциации типа iblock_element_prop_s3
|
19
|
+
IblockElement.class
|
20
|
+
|
21
|
+
# IblockProperty.cache_all
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
IblockElement.class
|
4
|
+
|
5
|
+
module BitrixOnRails
|
6
|
+
module ActiveRecord
|
7
|
+
|
8
|
+
def has_infoblock(iblock_id, property_name, &blk)
|
9
|
+
prop_s_name = "iblock_element_prop_s#{iblock_id}".to_sym
|
10
|
+
has_one prop_s_name, :foreign_key=>property_name, :class_name=>"::IblockElementPropS#{iblock_id}", :autosave => true
|
11
|
+
|
12
|
+
element_class_name = self.name + 'Element'
|
13
|
+
unless Kernel.const_defined?(element_class_name)
|
14
|
+
element_class = Class.new(IblockElement) do
|
15
|
+
set_iblock_id iblock_id
|
16
|
+
end
|
17
|
+
|
18
|
+
if block_given?
|
19
|
+
element_class.instance_eval(&blk)
|
20
|
+
end
|
21
|
+
|
22
|
+
self.const_set(element_class_name, element_class)
|
23
|
+
end
|
24
|
+
|
25
|
+
has_one :iblock_element, :through => prop_s_name, :class_name => element_class_name, :autosave => true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
module BitrixOnRails::IblockElementPropM
|
4
|
+
def acts_as_iblock_element_prop_m(id)
|
5
|
+
extend ClassMethods
|
6
|
+
include InstanceMethods
|
7
|
+
|
8
|
+
# Убираем лишнюю s вконце
|
9
|
+
#set_table_name 'b_'+table_name.chop
|
10
|
+
set_table_name "b_iblock_element_prop_m#{id}"
|
11
|
+
|
12
|
+
# delegate :code, :to=>:property
|
13
|
+
|
14
|
+
belongs_to :iblock_element
|
15
|
+
belongs_to :iblock_property
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def init
|
20
|
+
self.to_s=~/(\d+)/
|
21
|
+
iblock_id = $1.to_i
|
22
|
+
IblockElement.send :has_many, "iblock_element_prop_m#{iblock_id}".to_sym, :class_name=>"::IblockElementPropM#{iblock_id}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module InstanceMethods
|
27
|
+
|
28
|
+
def property
|
29
|
+
# Достаем кешированный вариант
|
30
|
+
IblockProperty.find(iblock_property_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def code
|
34
|
+
@code||=property.code
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_value
|
38
|
+
case property.property_type
|
39
|
+
when 'S' # String
|
40
|
+
self.value
|
41
|
+
when 'N' # Numeric
|
42
|
+
self.value_num.to_i # Когда BigDecimal - не приятно
|
43
|
+
# when 'E' # Enum?
|
44
|
+
# self.value_enum
|
45
|
+
# when 'L' # WTF?
|
46
|
+
else
|
47
|
+
raise "Не установленный тип (#{iblock_property.property_type}) свойства (#{self.class} #{id})"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
# Table b_iblock_element_prop_m7
|
55
|
+
# ==============================
|
56
|
+
# ID, IBLOCK_ELEMENT_ID, IBLOCK_PROPERTY_ID, VALUE, VALUE_ENUM, VALUE_NUM, DESCRIPTION
|
57
|
+
# ------------------------------
|
58
|
+
# ID int(11) PK
|
59
|
+
# IBLOCK_ELEMENT_ID int(11)
|
60
|
+
# IBLOCK_PROPERTY_ID int(11)
|
61
|
+
# VALUE text
|
62
|
+
# VALUE_ENUM int(11)
|
63
|
+
# VALUE_NUM decimal(18,4)
|
64
|
+
# DESCRIPTION varchar(255)
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module BitrixOnRails::IblockElementPropS
|
3
|
+
def acts_as_iblock_element_prop_s(id)
|
4
|
+
extend ClassMethods
|
5
|
+
include InstanceMethods
|
6
|
+
|
7
|
+
@m_prop_class = "IblockElementPropM#{id}"
|
8
|
+
# Название свойства сохраняется только для наглядности, чтобы можно было через консоль понять
|
9
|
+
# что за свойство.
|
10
|
+
@m_props = IblockProperty.where(:iblock_id => id).inject({}){ |a,e| a[e.code] = e.id if e.multiple == 'Y'; a }
|
11
|
+
|
12
|
+
# Убираем лишнюю s вконце
|
13
|
+
#set_table_name 'b_'+table_name.chop
|
14
|
+
set_table_name "b_iblock_element_prop_s#{id}"
|
15
|
+
|
16
|
+
belongs_to :iblock_element
|
17
|
+
|
18
|
+
# Хеш соответсвия кодов свойств названию полей: post_id -> property_149
|
19
|
+
cattr_accessor :properties
|
20
|
+
|
21
|
+
# Хеш свойств объекта по кодам
|
22
|
+
attr_accessor :properties
|
23
|
+
|
24
|
+
after_find do
|
25
|
+
self.properties = self.class.properties.keys.inject({}) { |hash, prop| hash[prop] = send prop; hash }
|
26
|
+
end
|
27
|
+
|
28
|
+
before_save do
|
29
|
+
self.class.m_props.each_value { |id|
|
30
|
+
values = m_prop_values(id)
|
31
|
+
self.send("property_#{id}=", PHP.serialize({'VALUE' => values, 'DESCRIPTION' => Array.new(values.size, nil)}))
|
32
|
+
# self.send("property_#{id}=", PhpSerialization.dump({'VALUE' => values, 'DESCRIPTION' => Array.new(values.size, nil)}))
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_element_association
|
39
|
+
IblockElement.send :has_one, "iblock_element_prop_s#{id}".to_sym, :class_name=>"::IblockElementPropS#{id}"
|
40
|
+
end
|
41
|
+
|
42
|
+
module ClassMethods
|
43
|
+
|
44
|
+
# code - врое как кодовое название свойства
|
45
|
+
# name - русское описание
|
46
|
+
|
47
|
+
# Дальше идут пары:
|
48
|
+
# property_120
|
49
|
+
# description_120
|
50
|
+
# ..
|
51
|
+
# определяются они в iblock.iblock_properties
|
52
|
+
|
53
|
+
# Берем список свойств из таблицы iblock_properties
|
54
|
+
# и создаем такие же методы для опроса и установки, чтобы можно было использовать
|
55
|
+
# их напрямую:
|
56
|
+
#
|
57
|
+
# self.кодовое_имя_свойства
|
58
|
+
#
|
59
|
+
# Например:
|
60
|
+
#
|
61
|
+
# self.post_id вместо self.property_120
|
62
|
+
#
|
63
|
+
def init
|
64
|
+
self.to_s=~/(\d+)/
|
65
|
+
iblock_id = $1.to_i
|
66
|
+
|
67
|
+
IblockElement.send :has_one, "iblock_element_prop_s#{iblock_id}".to_sym, :class_name=>"::IblockElementPropS#{iblock_id}"
|
68
|
+
|
69
|
+
self.properties = {}
|
70
|
+
attribute_names.select {|a| a[0,4]=='prop' }.each do |name|
|
71
|
+
prop_id = name.slice(9,5).to_i
|
72
|
+
iblock_property = IblockProperty.find(prop_id)
|
73
|
+
code = iblock_property.code.downcase.to_sym
|
74
|
+
self.properties[code] = name
|
75
|
+
define_method code do
|
76
|
+
val = send name
|
77
|
+
return val.to_i if val.is_a?(BigDecimal)
|
78
|
+
|
79
|
+
# Вот так мы проверяем сериализацию
|
80
|
+
# Есть еще вариант что поле сериализовано если iblock_property.user_type=='HTML'
|
81
|
+
#
|
82
|
+
if val.is_a? String and val.length>5 and val[0,3]=~/[a-z]:\d/
|
83
|
+
res = PHP.unserialize(val)
|
84
|
+
# res = PhpSerialization.load(val)
|
85
|
+
return iblock_property.property_type=='S' && res.is_a?(Hash) && res.include?('TEXT') ? res['TEXT'] : res
|
86
|
+
end
|
87
|
+
val
|
88
|
+
end
|
89
|
+
define_method "#{code}=" do |val|
|
90
|
+
send "#{name}=", val
|
91
|
+
end
|
92
|
+
eval "def self.find_by_#{code}(val); find_by_#{name}(val); end"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
module InstanceMethods
|
98
|
+
|
99
|
+
# Возвращает десериализованное (при необходимости) значение свойства
|
100
|
+
#
|
101
|
+
# prop - код свойства (post_id к примеру)
|
102
|
+
def get_value(prop)
|
103
|
+
send prop
|
104
|
+
end
|
105
|
+
|
106
|
+
def m_prop_values(prop_id)
|
107
|
+
self.class.m_prop_class.where(:iblock_element_id => self.id, :iblock_property_id => prop_id).collect { |e| e.value }
|
108
|
+
end
|
109
|
+
|
110
|
+
def create_m_prop_value(prop_id, value)
|
111
|
+
self.class.m_prop_class.create(:iblock_element_id => self.id, :iblock_property_id => prop_id, :value => value)
|
112
|
+
end
|
113
|
+
|
114
|
+
def destroy_m_prop_value(prop_id, value)
|
115
|
+
m_props = self.class.m_prop_class.where(:iblock_element_id => self.iblock_element_id, :iblock_property_id => prop_id, :value => value)
|
116
|
+
m_props.each { |p| p.destroy } if m_props.any?
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'bitrix_on_rails'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bitrix_on_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Danil Pismenny
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-02 00:00:00.000000000 +04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: shoulda
|
17
|
+
requirement: &2155895220 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2155895220
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: bundler
|
28
|
+
requirement: &2155894360 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2155894360
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: jeweler
|
39
|
+
requirement: &2155893580 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.6.4
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *2155893580
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rcov
|
50
|
+
requirement: &2155892440 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *2155892440
|
59
|
+
description: Использование инфоблоков 1С-Битрикс в Ruby On Rails проектах
|
60
|
+
email: danil@orionet.ru
|
61
|
+
executables: []
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files:
|
64
|
+
- LICENSE.txt
|
65
|
+
- README
|
66
|
+
- README.rdoc
|
67
|
+
files:
|
68
|
+
- .document
|
69
|
+
- Gemfile
|
70
|
+
- Gemfile.lock
|
71
|
+
- LICENSE.txt
|
72
|
+
- README
|
73
|
+
- README.rdoc
|
74
|
+
- Rakefile
|
75
|
+
- VERSION
|
76
|
+
- app/models/iblock.rb
|
77
|
+
- app/models/iblock_element.rb
|
78
|
+
- app/models/iblock_element_property.rb
|
79
|
+
- app/models/iblock_field.rb
|
80
|
+
- app/models/iblock_group.rb
|
81
|
+
- app/models/iblock_property.rb
|
82
|
+
- app/models/iblock_property_enum.rb
|
83
|
+
- app/models/iblock_section.rb
|
84
|
+
- app/models/iblock_section_element.rb
|
85
|
+
- app/models/iblock_type.rb
|
86
|
+
- bitrix_on_rails.gemspec
|
87
|
+
- init.rb
|
88
|
+
- lib/active_record/connection_adapters/mysql2_downcase_adapter.rb
|
89
|
+
- lib/bitrix_on_rails.rb
|
90
|
+
- lib/bitrix_on_rails/active_record.rb
|
91
|
+
- lib/bitrix_on_rails/engine.rb
|
92
|
+
- lib/bitrix_on_rails/iblock_element_prop_m.rb
|
93
|
+
- lib/bitrix_on_rails/iblock_element_prop_s.rb
|
94
|
+
- test/helper.rb
|
95
|
+
- test/test_bitrix_on_rails.rb
|
96
|
+
has_rdoc: true
|
97
|
+
homepage: http://github.com/dapi/bitrix_on_rails
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
hash: 3152042687155228433
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 1.6.2
|
122
|
+
signing_key:
|
123
|
+
specification_version: 3
|
124
|
+
summary: Работа с инфоблоками 1С-Битрикс
|
125
|
+
test_files: []
|