Class: ActiveSP::List

Inherits:
Base
  • Object
show all
Extended by:
Caching, PersistentCaching
Includes:
InSite, Util
Defined in:
lib/activesp/list.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#attribute, #attribute_type, #attribute_types, #attributes, #has_attribute?, #has_writable_attribute?, #method_missing, #reload, #set_attribute

Constructor Details

#initialize(site, id, title = nil, attributes_before_type_cast1 = nil, attributes_before_type_cast2 = nil) ⇒ List

Returns a new instance of List.



44
45
46
47
48
49
# File 'lib/activesp/list.rb', line 44

def initialize(site, id, title = nil, attributes_before_type_cast1 = nil, attributes_before_type_cast2 = nil)
  @site, @id = site, id
  @Title = title if title
  @attributes_before_type_cast1 = attributes_before_type_cast1 if attributes_before_type_cast1
  @attributes_before_type_cast2 = attributes_before_type_cast2 if attributes_before_type_cast2
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class ActiveSP::Base

Instance Attribute Details

#idString (readonly)

The ID of the list

Returns:

  • (String)


40
41
42
# File 'lib/activesp/list.rb', line 40

def id
  @id
end

#siteSite (readonly)

The containing site

Returns:



37
38
39
# File 'lib/activesp/list.rb', line 37

def site
  @site
end

Instance Method Details

#==(object) ⇒ Object



326
327
328
# File 'lib/activesp/list.rb', line 326

def ==(object)
  ::ActiveSP::List === object && self.ID == object.ID
end

#__each_item(query_options, query) ⇒ Object



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/activesp/list.rb', line 282

def __each_item(query_options, query)
  get_list_items("<ViewFields/>", query_options, query) do |attributes|
    yield attributes
  end
rescue Savon::SOAPFault => e
  # This is where it gets ugly... Apparently there is a limit to the number of columns
  # you can retrieve with this operation. Joy!
  if e.message[/lookup column threshold/]
    fields = self.fields.map { |f| f.Name }
    split_factor = 2
    begin
      split_size = (fields.length + split_factor - 1) / split_factor
      parts = []
      split_factor.times do |i|
        lo = i * split_size
        hi = [(i + 1) * split_size, fields.length].min - 1
        view_fields = Builder::XmlMarkup.new.ViewFields do |xml|
          fields[lo..hi].each { |f| xml.FieldRef("Name" => f) }
        end
        by_id = {}
        get_list_items(view_fields, query_options, query) do |attributes|
          by_id[attributes["ID"]] = attributes
        end
        parts << by_id
      end
      parts[0].each do |id, attrs|
        parts[1..-1].each do |part|
          attrs.merge!(part[id])
        end
        yield attrs
      end
    rescue Savon::SOAPFault => e
      if e.message[/lookup column threshold/]
        split_factor += 1
        retry
      else
        raise
      end
    end
  else
    raise
  end
end

#changes_since_token(token, options = {}) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/activesp/list.rb', line 181

def changes_since_token(token, options = {})
  options = options.dup
  no_preload = options.delete(:no_preload)
  options.empty? or raise ArgumentError, "unknown options #{options.keys.map { |k| k.inspect }.join(", ")}"
  
  if no_preload
    view_fields = Builder::XmlMarkup.new.ViewFields do |xml|
      %w[FSObjType ID UniqueId ServerUrl].each { |f| xml.FieldRef("Name" => f) }
    end
  else
    view_fields = Builder::XmlMarkup.new.ViewFields
  end
  result = call("Lists", "get_list_item_changes_since_token", "listName" => @id, 'queryOptions' => '<QueryOptions xmlns:s="http://schemas.microsoft.com/sharepoint/soap/" ><QueryOptions/></QueryOptions>', 'changeToken' => token, 'viewFields' => view_fields)
  updates = []
  result.xpath("//z:row", NS).each do |row|
    attributes = clean_item_attributes(row.attributes)
    updates << construct_item(:unset, attributes, no_preload ? nil : attributes)
  end
  deletes = []
  result.xpath("//sp:Changes/sp:Id", NS).each do |row|
    if row["ChangeType"].to_s == "Delete"
      deletes << encode_key("I", [key, row.text.to_s])
    end
  end
  new_token = result.xpath("//sp:Changes", NS).first["LastChangeToken"].to_s
  { :updates => updates, :deletes => deletes, :new_token => new_token }
end

#content_type(id) ⇒ Object



238
239
240
# File 'lib/activesp/list.rb', line 238

def content_type(id)
  content_types.find { |t| t.id == id }
end

#content_typesObject



229
230
231
232
233
234
# File 'lib/activesp/list.rb', line 229

def content_types
  result = call("Lists", "get_list_content_types", "listName" => @id)
  result.xpath("//sp:ContentType", NS).map do |content_type|
    ContentType.new(@site, self, content_type["ID"], content_type["Name"], content_type["Description"], content_type["Version"], content_type["Group"])
  end
end

#create_document(parameters = {}) ⇒ Object



169
170
171
172
173
# File 'lib/activesp/list.rb', line 169

def create_document(parameters = {})
  when_list { return create_list_item(parameters) }
  when_document_library { return create_library_document(parameters) }
  raise_on_unknown_type
end

#create_folder(parameters = {}) ⇒ Object



175
176
177
178
179
# File 'lib/activesp/list.rb', line 175

def create_folder(parameters = {})
  name = parameters.delete("FileLeafRef") or raise ArgumentError, "Specify the folder name in the 'FileLeafRef' parameter"
  
  create_list_item(parameters.merge(:folder_name => name))
end

#each_document(parameters = {}, &blk) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
# File 'lib/activesp/list.rb', line 119

def each_document(parameters = {}, &blk)
  query = Builder::XmlMarkup.new.Query do |xml|
    xml.Where do |xml|
      xml.Neq do |xml|
        xml.FieldRef(:Name => "FSObjType")
        xml.Value(1, :Type => "Text")
      end
    end
  end
  each_item(parameters.merge(:query => query), &blk)
end

#each_folder(parameters = {}, &blk) ⇒ Object



136
137
138
139
140
141
142
143
144
145
146
# File 'lib/activesp/list.rb', line 136

def each_folder(parameters = {}, &blk)
  query = Builder::XmlMarkup.new.Query do |xml|
    xml.Where do |xml|
      xml.Eq do |xml|
        xml.FieldRef(:Name => "FSObjType")
        xml.Value(1, :Type => "Text")
      end
    end
  end
  each_item(parameters.merge(:query => query), &blk)
end

#each_item(options = {}) {|item| ... } ⇒ Object

Yields the items in this list according to the given options. Note that this method does not recurse into folders. I believe specifying a folder of ” actually does recurse

Parameters:

  • options (Hash) (defaults to: {})

    Options

Options Hash (options):

  • :folder (Folder, :all) — default: nil

    The folder to search in

  • :query (String) — default: nil

    The query to execute as an XML fragment

  • :no_preload (Boolean) — default: nil

    If set to true, the attributes are not preloaded. Can be more efficient if you only need the list of items and not their attributes

Yield Parameters:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/activesp/list.rb', line 89

def each_item(options = {})
  options = options.dup
  folder = options.delete(:folder)
  # Always include a query because for some reason SP is capable of not finding certain
  # items otherwise.
  query = { "query" => options.delete(:query) || "" }
  no_preload = options.delete(:no_preload)
  options.empty? or raise ArgumentError, "unknown options #{options.keys.map { |k| k.inspect }.join(", ")}"
  query_options = Builder::XmlMarkup.new.QueryOptions do |xml|
	if folder
		xml.Folder(folder == :all ? "" : folder.url)
else
		xml.QeryOptions
end
  end
  if no_preload
    view_fields = Builder::XmlMarkup.new.ViewFields do |xml|
      %w[FSObjType ID UniqueId ServerUrl].each { |f| xml.FieldRef("Name" => f) }
    end
    get_list_items(view_fields, query_options, query) do |attributes|
      yield construct_item(folder, attributes, nil)
    end
  else
    __each_item(query_options, query) do |attributes|
      yield construct_item(folder, attributes, attributes)
    end
  end
end

#field(id) ⇒ Object



225
226
227
# File 'lib/activesp/list.rb', line 225

def field(id)
  fields.find { |f| f.ID == id }
end

#fieldsObject



209
210
211
212
213
214
215
216
# File 'lib/activesp/list.rb', line 209

def fields
  data1.xpath("//sp:Field", NS).map do |field|
    attributes = clean_attributes(field.attributes)
    if attributes["ID"] && attributes["StaticName"]
      Field.new(self, attributes["ID"].downcase, attributes["StaticName"], attributes["Type"], @site.field(attributes["ID"].downcase), attributes)
    end
  end.compact
end

#fields_by_nameObject



219
220
221
# File 'lib/activesp/list.rb', line 219

def fields_by_name
  fields.inject({}) { |h, f| h[decode_field_name(f.attributes["StaticName"])] = f ; h }
end

#item(name) ⇒ Item Also known as: /

Returns the item with the given name or nil if there is no item with the given name

Returns:



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/activesp/list.rb', line 155

def item(name)
  query = Builder::XmlMarkup.new.Query do |xml|
    xml.Where do |xml|
      xml.Eq do |xml|
        xml.FieldRef(:Name => "FileLeafRef")
        xml.Value(name, :Type => "Text")
      end
    end
  end
  items(:query => query).first
end

#keyString

See Base#key

Returns:

  • (String)


72
73
74
# File 'lib/activesp/list.rb', line 72

def key
  encode_key("L", [@site.key, @id])
end

#permission_setObject



242
243
244
245
246
247
248
# File 'lib/activesp/list.rb', line 242

def permission_set
  if attributes["InheritedSecurity"]
    @site.permission_set
  else
    PermissionSet.new(self)
  end
end

#raise_on_unknown_typeObject



276
277
278
279
# File 'lib/activesp/list.rb', line 276

def raise_on_unknown_type
  base_type = attributes["BaseType"]
  raise "not yet BaseType = #{base_type.inspect}" unless %w[0 1 5].include?(base_type)
end

#relative_urlObject



66
67
68
# File 'lib/activesp/list.rb', line 66

def relative_url
  @site.relative_url(url)
end

#savevoid

This method returns an undefined value.

See Base#save



253
254
255
# File 'lib/activesp/list.rb', line 253

def save
  p untype_cast_attributes(@site, nil, internal_attribute_types, changed_attributes)
end

#TitleObject



77
78
79
# File 'lib/activesp/list.rb', line 77

def Title
  data1["Title"].to_s
end

#to_sObject Also known as: inspect



258
259
260
# File 'lib/activesp/list.rb', line 258

def to_s
  "#<ActiveSP::List Title=#{self.Title}>"
end

#urlString

The URL of the list

Returns:

  • (String)


53
54
55
56
57
58
59
60
61
62
# File 'lib/activesp/list.rb', line 53

def url
  # Dirty. Used to use RootFolder, but if you get the data from the bulk calls, RootFolder is the empty
  # string rather than what it should be. That's what you get with web services as an afterthought I guess.
  view_url = ::File.dirname(attributes["DefaultViewUrl"])
  result = URL(@site.url).join(view_url).to_s
  if ::File.basename(result) == "Forms" and dir = ::File.dirname(result) and dir.length > @site.url.length
    result = dir
  end
  result
end

#when_document_libraryObject



266
267
268
# File 'lib/activesp/list.rb', line 266

def when_document_library
  yield if %w[1].include?(attributes["BaseType"])
end

#when_listObject



271
272
273
# File 'lib/activesp/list.rb', line 271

def when_list
  yield if %w[0 5].include?(attributes["BaseType"])
end