--[[ - @author Bruno Massa - @file common.lua - This file group togheter many function that dont have - a clear category. These functions deals with many different - tasks. ]] do C.SCHEMA_UNINSTALLED = -1 C.SCHEMA_INSTALLED = 0 C.REQUIREMENT_INFO = -1 C.REQUIREMENT_OK = 0 C.REQUIREMENT_WARNING = 1 C.REQUIREMENT_ERROR = 2 C.FILE_EXIST = 1 C.FILE_READABLE = 2 C.FILE_WRITABLE = 4 C.FILE_EXECUTABLE = 8 C.FILE_NOT_EXIST = 16 C.FILE_NOT_READABLE = 32 C.FILE_NOT_WRITABLE = 64 C.FILE_NOT_EXECUTABLE = 128 end --[[ - Show the value of a variable, to rapidly see the content - of a variable. This variable can be a number, string ou table - - If no err variable is given, the default output is a standard - Ajato message. If err is true, it stops the Ajato and print - it as a Lua error. - - @param variable - Any type, a variable that we need to see the value - @param err - Boolean, true to stop Lua execution and print it as an error ]] function ad(variable, err) -- Closes the program and show traceback if err then error(variable) end -- Display the debug info using debug messages ajato_add_message(variable, 'debug') end --[[ - This dispatch function hands off structured Ajato tables to - type-specific-_alter implementations. It ensures a consistent - interface for all altering operations. - - @param type - String, The data type of the structured table. 'form', 'links', - 'node_content', and so on are several examples. - @param data - Table, The data to be altered. - @param ... - Any type, Any additional params will be passed on to the called - hook_[type]_alter functions. ]] function ajato_alter(alter_type, data, ...) -- Hang onto a reference to the data table so that it isn't blown away later. args = {...} for module in pairs(ajato_module_implements(alter_type ..'_alter')) do data = ajato_tables_merge(data, _G[module ..'_'.. alter_type ..'_alter'](data, unpack(args))) end return data end --[[ - Simulate parcially the "test ? yes : no" operator - on PHP and C/C++. The fisrt argument should be - a variable only. It doesnt evaluate statements like - these languages. - - @param test - Any type, the function will check if the variable - is nil or blank. In case it is, return the third - argument - @param yes - Any type, return it in case the test if successful - @param no - Any type, return it in case the test failed - @return - Any type, yes in case the test is valid. ]] function ajato_choose(test, yes, no) if test then return yes else return no end end --[[ - Simulate the explode() function from PHP. It split a given - string into table values. But this function only split - with one character - - @param original_string - String, the original string - @param match - String, the character that mark transition between pieces - in a string - @param max - Number, the maximun number of children - @return - Table, all pieces from the string ]] function ajato_explode(original_string, match, max) local result = {} for word in string.gmatch(original_string, '([^'.. match ..']*)') do if hv(word) then result[#result + 1] = word end if max then max = max - 1 if max == 0 then break end end end return result end --[[ - Send the user to a different Ajato page. - - This issues an on-site HTTP redirect. The function makes sure the redirected - URL is formatted correctly. - - Usually the redirected URL is constructed from this function's input - parameters. However you may override that behavior by setting a - destination in either the $_REQUEST-array (i.e. by using - the query string of an URI) or the $_REQUEST['edit']-array (i.e. by - using a hidden form field). This is used to direct the user back to - the proper page after completing a form. For example, after editing - a post on the 'admin/content/node'-page or after having logged on using the - 'user login'-block in a sidebar. The function ajato_get_destination() - can be used to help set the destination URL. - - - This function ends the request; use it rather than a print theme('page') - statement in your menu callback. - - @param path - String, A internal path or a full URL. - @param query - Table, The query string component, if any. - @param fragment - String, The destination fragment identifier (named anchor). - @param http_response_code - Number, Valid values for an actual "goto" as per RFC 2616 section 10.3 are: - - 301 Moved Permanently (the recommended value for most redirects) - - 302 Found (default in Ajato, sometimes used for spamming search engines) - - 303 See Other - - 304 Not Modified - - 305 Use Proxy - - 307 Temporary Redirect (an alternative to "503 Site Down for Maintenance") - Note: Other values are defined by RFC 2616, but are rarely used and poorly - supported. - @see ajato_get_destination() ]] function ajato_goto(path, query, fragment, http_response_code) path = path or '' http_response_code = http_response_code or 302 local url = ajato_path_format(path, query, fragment) -- Before the redirect, allow modules to react to the end of the page request. ajato_module_hook('exit', url) cgilua.redirect (url) end --[[ - Form an associative table from a linear table (enter a just numeric table - and convert it to ) - - This function walks through the provided table and constructs an associative - table out of it. The keys of the resulting table will be the values of the - input table. The values will be the same as the keys unless a function is - specified, in which case the output of the function is used for the values - instead. - - @param original_table - Table, A numeric index table. - @param func - String, The function to apply to all values before output. - @return - Table, An associative table ]] function ajato_map_assoc(original_table, func) if not func then local result = {} for _, value in pairs(original_table) do result[value] = value end return result elseif _G[func] then local result = {} for _, value in pairs(original_table) do result[value] = _G[func](value) end return result end end --[[ - Generates a site off-line message ]] function ajato_page_site_offline() -- Set the maintenance theme ajato_maintenance_theme() -- Send the HTTP error cgilua.htmlheader('HTTP/1.1 503 Service unavailable') ajato_set_title(t('Site off-line')) local result = ajato_variable_get('site_offline_message' , t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', {['@site'] = ajato_variable_get('site_name', 'Ajato')})) return result end --[[ - Generates a 404 error if the request can not be handled. ]] function ajato_page_not_found() -- Send the HTTP error cgilua.htmlheader('HTTP/1.1 404 Not Found') -- watchdog('page not found', check_plain(sys['get']['q']), nil, C.WATCHDOG_WARNING) local result local path = ajato_path_get_normal(ajato_variable_get('site_404', '')) if hv(path) and path ~= sys['get']['q'] then result = ajato_menu_execute(path) end if not hv(result) then ajato_set_title(t('Page not found')) result = t('Page not found') end return result end --[[ - Generates a 403 error if the request is not allowed. ]] function ajato_page_access_denied() -- Send the HTTP error cgilua.htmlheader('HTTP/1.1 403 Forbidden') -- watchdog('access denied', check_plain(sys['get']['q']), nil, C.WATCHDOG_WARNING) local result local path = ajato_path_normal_get(ajato_variable_get('site_403', '')) if hv(path) and path ~= sys['get']['q'] then result = ajato_menu_execute(path) end if not hv(result) then ajato_set_title(t('Access denied')) result = t('You are not authorized to access this page.') end return result end --[[ - Serialize a table using the small presentation. - - Example result: - table1={['field1']="string",['field2']=123,['field3']={['field3a']="string"}} - - @param object - Any type, the object to be serialized - @param mode - String, it can be: - - '' or nil for the compact mode - - 'clear' to indent and make new lines for plain text - - 'html' to indent and make new lines fot HTML - @param count - Number (internal), the current indent level - @param tables - Tables (internal), internal table that control which tables have - been already scanned. It avoids self referencing and - infinit loop - @return - String, the serialized object ]] function ajato_serialize(object, mode, count, tables) -- Initializing variables tables = tables or {} count = count or 0 if type(object) == 'table' and (#object == 0 or not tables[object]) then -- serial representation to build local serial = {} -- Remembering which functions have been scanned tables[object] = true local indent = '' local new_line = '' if mode then if mode == 'html' then indent = '    ' new_line = '
\n' elseif mode == 'clear' then indent = ' ' new_line = '\n' end end -- Scan every single value on this table for index, value in pairs(object) do -- Insert quotes for strings if type(i) == 'string' then index = string.format('%q', index) end serial[#serial + 1] = string.rep(indent, count + 1) ..'['.. index ..']='.. ajato_serialize(value, mode, count + 1, tables) end -- Return the table creation pattern {} return '{'.. (((#serial >= 1) and new_line .. table.concat(serial, ','.. new_line) .. new_line .. string.rep(indent, count)) or '') .. '}' end return ajato_serialize_basic(object) end --[[ - Serialize a table using the big and redundant presentation - - @param variable - String or Number, the variable name - @param object - String or Number, the variable value - @param args - table, some features - @param saved - String or Number, the variable value - @return - String, the serialized object ]] function ajato_serialize_big(name, object, args, saved) -- Initial value saved = saved or {} args = args or {} args['newline'] = args['newline'] or '\n' local output = {} if not args['no_blank_table'] then output = {name ..' = '} end if type(object) == 'number' or type(object) == 'string' or type(object) == 'boolean' then output[#output + 1] = ajato_serialize_basic(object) .. args['newline'] elseif type(object) == 'table' then -- Check if the object is already saved if saved[object] then -- Use its previous name output[#output + 1] = saved[object] .. args['newline'] else -- Save name for next time saved[object] = name if not args['no_blank_table'] then -- Create a new table output[#output + 1] = '{}'.. args['newline'] else args['no_blank_table'] = nil end -- Save its fields for k,v in pairs(object) do local fieldname = string.format('%s[%s]', name, ajato_serialize_basic(k)) output[#output + 1] = ajato_serialize_big(fieldname, v, args, saved) end end end return table.concat(output, '') end --[[ - Serialize all types of value. Functions and userdata - are considered nil - - @param variable - Any type, the original variable value - @return - String, the variable value ]] function ajato_serialize_basic(object) if not object or type(object) == 'number' or type(object) == 'boolean' then return tostring(object) elseif type(object) == 'string' then return string.format('%q', object) end -- Everything else is considered nil return 'nil --[['.. type(object) ..']]' end --[[ - Retrieves the current status of a series of files in the system table. - - @param files - Table, list of files - @param type - String, the plugin type (module, template, etc) - @return - Table, ]] function ajato_system_get_files_database(files, type) -- Extract current files from database. local result = db_query([[SELECT filename, name, type, status, throttle, schema_version FROM {system} WHERE type = %q]], type) if hv(result) then for file in pairs(db_rows(result)) do if files[file['name']] and type(files[file['name']]) == 'table' then file['old_filename'] = file['filename'] for key, value in pairs(file) do if not files[file['name']] or not files[file['name']]['key'] then files[file['name']]['key'] = value end end end end end return files end --[[ - Merge two tables. It maintain the table1 index and add - table 2 values. - - @param table1 - Table, the primary table - @param table2 - Table, the secondary table - @param not_overwrite - Boolean, true to not overwrite values when found same index, - creating a numeric and sequencial index - @param not_recursive - Boolean, true to not go to next table levels - @return - Table, the merged table ]] function ajato_tables_merge(table1, table2, not_overwrite, not_recursive) -- First, fill the result table with the data from the -- first table local result = {} if type(table1) == 'table' then for index, value in pairs(table1) do if not_overwrite then result[#result + 1] = value else result[index] = value end end end -- Now add the data from the second table if type(table2) == 'table' then for index, value in pairs(table2) do if not_overwrite then result[#result + 1] = value else if not not_recursive and type(result[index]) == 'table' and type(value) == 'table' then result[index] = ajato_tables_merge(result[index], value, true) else result[index] = value end end end end return result end --[[ - Unserialize a string. In case of being table, it - will only work in case the table is serialized using - small method - - @param object - String, the object to be unserialized - @return - Any type, the unserialized object ]] function ajato_unserialize(object) if type(object) ~= 'string' then return object elseif tonumber(object) then -- Seems to be a simple number return tonumber(object) elseif object == tostring(nil) then -- Nil return nil elseif string.sub(object, 0, 1) == '{' then -- Table return loadstring('return '.. object)() else -- Consider it a string return string.format('%q', object) end end