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 included from Caching

extended

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
50
51
# 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
  # This testing for emptiness of RootFolder is necessary because it is empty
  # in bulk calls.
  @attributes_before_type_cast1 = attributes_before_type_cast1 if attributes_before_type_cast1 && attributes_before_type_cast1["RootFolder"] != ""
  @attributes_before_type_cast2 = attributes_before_type_cast2 if attributes_before_type_cast2 && attributes_before_type_cast2["RootFolder"] != ""
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



334
335
336
# File 'lib/activesp/list.rb', line 334

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

#__each_item(query_options, query) ⇒ Object



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
325
326
327
328
329
330
331
332
# File 'lib/activesp/list.rb', line 290

def __each_item(query_options, query)
  get_list_items("<ViewFields></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

#__item(name, options = {}) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
# File 'lib/activesp/list.rb', line 159

def __item(name, options = {})
  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(options.merge(:query => query)).first
end

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



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/activesp/list.rb', line 185

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
  if token
    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)
  else
    result = call("Lists", "get_list_item_changes_since_token", "listName" => @id, 'queryOptions' => '<queryOptions xmlns:s="http://schemas.microsoft.com/sharepoint/soap/" ><QueryOptions/></queryOptions>', 'viewFields' => view_fields)
  end
  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



246
247
248
# File 'lib/activesp/list.rb', line 246

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

#content_typesObject



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

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



173
174
175
176
177
# File 'lib/activesp/list.rb', line 173

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



179
180
181
182
183
# File 'lib/activesp/list.rb', line 179

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:



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 92

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) || "<Query><Where></Where></Query>" }
  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|
    xml.Folder(folder == :all ? "" : folder.url) if folder
  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



233
234
235
# File 'lib/activesp/list.rb', line 233

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

#fieldsObject



217
218
219
220
221
222
223
224
# File 'lib/activesp/list.rb', line 217

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



227
228
229
# File 'lib/activesp/list.rb', line 227

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
# File 'lib/activesp/list.rb', line 155

def item(name)
  __item(name)
end

#keyString

See Base#key

Returns:

  • (String)


75
76
77
# File 'lib/activesp/list.rb', line 75

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

#permission_setObject



250
251
252
253
254
255
256
# File 'lib/activesp/list.rb', line 250

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

#raise_on_unknown_typeObject



284
285
286
287
# File 'lib/activesp/list.rb', line 284

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



69
70
71
# File 'lib/activesp/list.rb', line 69

def relative_url
  @site.relative_url(url)
end

#savevoid

This method returns an undefined value.

See Base#save



261
262
263
# File 'lib/activesp/list.rb', line 261

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

#TitleObject



80
81
82
# File 'lib/activesp/list.rb', line 80

def Title
  data1["Title"].to_s
end

#to_sObject Also known as: inspect



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

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

#urlString

The URL of the list

Returns:

  • (String)


55
56
57
58
59
60
61
62
63
64
65
# File 'lib/activesp/list.rb', line 55

def url
  URL(@site.url).join(attributes["RootFolder"]).to_s
  # # 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



274
275
276
# File 'lib/activesp/list.rb', line 274

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

#when_listObject



279
280
281
# File 'lib/activesp/list.rb', line 279

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