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
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



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

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

#__each_item(query_options, query) ⇒ Object



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

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

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



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

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



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

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

#content_typesObject



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

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



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

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



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

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



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

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



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

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
# 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>" }
  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



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

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

#fieldsObject



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

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



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

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:



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

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)


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

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

#permission_setObject



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

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

#raise_on_unknown_typeObject



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

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



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

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



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

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



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

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

#when_listObject



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

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